XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Show pa-providers dir in safe mode

8a86515b
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

3 个文件 +27 -12
Modified etc/unittest/mcp.py +21 -6
@@ -352,12 +352,27 @@ class TestSafeMode(unittest.IsolatedAsyncioTestCase):
352 352 self.assertFalse(result.get("success"))
353 353 self.assertIn("error", result)
354 354
355 async def test_file_list_safe_mode_blocks_root(self):
356 """In safe mode, listing the workspace root is blocked."""
357 tool = FileListTool(safe_mode=True)
358 result = await tool.execute({})
359 self.assertIn("error", result)
360 self.assertIn("safe mode", result["error"])
355 async def test_file_list_safe_mode_shows_pa_providers_and_markdown(self):
356 """In safe mode, the root exposes pa-providers and Markdown files only."""
357 workspace = get_workspace_dir()
358 providers = workspace / "pa-providers"
359 markdown = workspace / "unittest_safe_mode.md"
360 other = workspace / "unittest_safe_mode.txt"
361 providers.mkdir(exist_ok=True)
362 markdown.write_text("# test")
363 other.write_text("test")
364 try:
365 tool = FileListTool(safe_mode=True)
366 result = await tool.execute({})
367 self.assertNotIn("error", result)
368 self.assertEqual(
369 {entry["path"] for entry in result["entries"]},
370 {"pa-providers", "unittest_safe_mode.md"},
371 )
372 finally:
373 markdown.unlink(missing_ok=True)
374 other.unlink(missing_ok=True)
375 providers.rmdir()
361 376
362 377 async def test_file_list_safe_mode_allows_subdir(self):
363 378 """In safe mode, listing a subdirectory is still allowed."""
Modified g4f/api/__init__.py +3 -2
@@ -263,6 +263,7 @@ function esc(s){return String(s??\'\'). replace(/&/g,\'&amp;\').replace(/</g,\'&
263 263 function fmt(v){if(v==null)return\'(empty)\';if(typeof v===\'object\')return JSON.stringify(v,null,2);return String(v);}
264 264 async function load(){
265 265 try{var r=await fetch(\'/api/logs?limit=500\', { credentials: 'include' });if(!r.ok)return;var d=await r.json();all=d.entries||[];render();}catch(e){}
266 clearTimeout(timer);timer = setTimeout(load,3000);
266 267 }
267 268 function render(){
268 269 var q=document.getElementById(\'q\').value.trim().toLowerCase();
@@ -301,8 +302,8 @@ function closeModal(){document.getElementById(\'ov\').classList.remove(\'active\
301 302 function overlayClick(ev){if(ev.target===document.getElementById(\'ov\'))closeModal();}
302 303 document.addEventListener(\'keydown\',function(e){if(e.key===\'Escape\')closeModal();});
303 304 async function clearLogs(){await fetch(\'/api/logs\',{method:\'DELETE\'});all=[];render();}
304 function toggleAuto(){clearInterval(timer);timer=null;if(document.getElementById(\'auto\').checked)timer=setInterval(load,3000);}
305 load();timer=setInterval(load,3000);
305 function toggleAuto(){clearTimeout(timer);timer=null;if(document.getElementById(\'auto\').checked)timer=setTimeout(load,3000);}
306 load();if(document.getElementById(\'auto\').checked)timer=setTimeout(load,3000);
306 307 </script>
307 308 </body></html>"""
308 309
Modified g4f/mcp/tools.py +3 -4
@@ -618,10 +618,6 @@ class FileListTool(MCPTool):
618 618 target = (workspace / rel_path).resolve() if rel_path else workspace
619 619 if not str(target).startswith(str(workspace)):
620 620 return {"error": "Access outside the workspace is not allowed"}
621 if self.safe_mode and target == workspace:
622 return {
623 "error": "Listing the workspace root directory is not allowed in safe mode"
624 }
625 621 if not target.exists():
626 622 return {"error": f"Directory not found: {rel_path or '/'}"}
627 623 if not target.is_dir():
@@ -635,6 +631,9 @@ class FileListTool(MCPTool):
635 631 rel = str(entry.relative_to(workspace))
636 632 if is_hidden_file(rel):
637 633 continue
634 if self.safe_mode and target == workspace:
635 if entry.name != "pa-providers" and (not entry.is_file() or entry.suffix.lower() != ".md"):
636 continue
638 637 info: Dict[str, Any] = {
639 638 "path": rel,
640 639 "type": "file" if entry.is_file() else "directory",