feat: support check dependencies through url

This commit is contained in:
Yeuoly 2024-11-13 15:19:20 +08:00
parent 5828abcd62
commit 183b943803
No known key found for this signature in database
GPG Key ID: A66E7E320FB19F61
2 changed files with 38 additions and 2 deletions

View File

@ -168,6 +168,22 @@ class AppImportFromUrlApi(Resource):
return app, 201 return app, 201
class AppImportFromUrlDependenciesCheckApi(Resource):
@setup_required
@login_required
@account_initialization_required
def post(self):
parser = reqparse.RequestParser()
parser.add_argument("url", type=str, required=True, nullable=False, location="json")
args = parser.parse_args()
leaked_dependencies = AppDslService.check_dependencies_from_url(
tenant_id=current_user.current_tenant_id, url=args["url"], account=current_user
)
return jsonable_encoder({"leaked": leaked_dependencies}), 200
class AppApi(Resource): class AppApi(Resource):
@setup_required @setup_required
@login_required @login_required
@ -391,6 +407,7 @@ api.add_resource(AppListApi, "/apps")
api.add_resource(AppImportDependenciesCheckApi, "/apps/import/dependencies/check") api.add_resource(AppImportDependenciesCheckApi, "/apps/import/dependencies/check")
api.add_resource(AppImportApi, "/apps/import") api.add_resource(AppImportApi, "/apps/import")
api.add_resource(AppImportFromUrlApi, "/apps/import/url") api.add_resource(AppImportFromUrlApi, "/apps/import/url")
api.add_resource(AppImportFromUrlDependenciesCheckApi, "/apps/import/url/dependencies/check")
api.add_resource(AppApi, "/apps/<uuid:app_id>") api.add_resource(AppApi, "/apps/<uuid:app_id>")
api.add_resource(AppCopyApi, "/apps/<uuid:app_id>/copy") api.add_resource(AppCopyApi, "/apps/<uuid:app_id>/copy")
api.add_resource(AppExportApi, "/apps/<uuid:app_id>/export") api.add_resource(AppExportApi, "/apps/<uuid:app_id>/export")

View File

@ -37,6 +37,7 @@ from .exc import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
current_dsl_version = "0.1.3" current_dsl_version = "0.1.3"
dsl_max_size = 10 * 1024 * 1024 # 10MB
class AppDslService: class AppDslService:
@ -49,12 +50,11 @@ class AppDslService:
:param args: request args :param args: request args
:param account: Account instance :param account: Account instance
""" """
max_size = 10 * 1024 * 1024 # 10MB
response = ssrf_proxy.get(url.strip(), follow_redirects=True, timeout=(10, 10)) response = ssrf_proxy.get(url.strip(), follow_redirects=True, timeout=(10, 10))
response.raise_for_status() response.raise_for_status()
content = response.content content = response.content
if len(content) > max_size: if len(content) > dsl_max_size:
raise FileSizeLimitExceededError("File size exceeds the limit of 10MB") raise FileSizeLimitExceededError("File size exceeds the limit of 10MB")
if not content: if not content:
@ -67,6 +67,25 @@ class AppDslService:
return cls.import_and_create_new_app(tenant_id, data, args, account) return cls.import_and_create_new_app(tenant_id, data, args, account)
@classmethod
def check_dependencies_from_url(cls, tenant_id: str, url: str, account: Account) -> list[PluginDependency]:
"""
Check dependencies from url
"""
response = ssrf_proxy.get(url.strip(), follow_redirects=True, timeout=(10, 10))
response.raise_for_status()
content = response.content
if len(content) > dsl_max_size:
raise FileSizeLimitExceededError("File size exceeds the limit of 10MB")
try:
data = content.decode("utf-8")
except UnicodeDecodeError as e:
raise ContentDecodingError(f"Error decoding content: {e}")
return cls.check_dependencies(tenant_id, data, account)
@classmethod @classmethod
def check_dependencies(cls, tenant_id: str, data: str, account: Account) -> list[PluginDependency]: def check_dependencies(cls, tenant_id: str, data: str, account: Account) -> list[PluginDependency]:
""" """