| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | from typing import cast | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-06 11:58:49 +08:00
										 |  |  | from flask_login import current_user | 
					
						
							|  |  |  | from flask_restful import Resource, marshal_with, reqparse | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | from sqlalchemy.orm import Session | 
					
						
							|  |  |  | from werkzeug.exceptions import Forbidden | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from controllers.console.app.wraps import get_app_model | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | from controllers.console.wraps import ( | 
					
						
							|  |  |  |     account_initialization_required, | 
					
						
							| 
									
										
										
										
											2025-04-02 10:20:46 +08:00
										 |  |  |     cloud_edition_billing_resource_check, | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  |     setup_required, | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | from extensions.ext_database import db | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from fields.app_fields import app_import_check_dependencies_fields, app_import_fields | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | from libs.login import login_required | 
					
						
							|  |  |  | from models import Account | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | from models.model import App | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | from services.app_dsl_service import AppDslService, ImportStatus | 
					
						
							| 
									
										
										
										
											2025-06-19 17:14:28 +08:00
										 |  |  | from services.enterprise.enterprise_service import EnterpriseService | 
					
						
							|  |  |  | from services.feature_service import FeatureService | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppImportApi(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_import_fields) | 
					
						
							| 
									
										
										
										
											2025-04-02 10:20:46 +08:00
										 |  |  |     @cloud_edition_billing_resource_check("apps") | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  |     def post(self): | 
					
						
							|  |  |  |         # Check user role first | 
					
						
							|  |  |  |         if not current_user.is_editor: | 
					
						
							|  |  |  |             raise Forbidden() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         parser = reqparse.RequestParser() | 
					
						
							|  |  |  |         parser.add_argument("mode", type=str, required=True, location="json") | 
					
						
							|  |  |  |         parser.add_argument("yaml_content", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("yaml_url", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("name", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("description", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("icon_type", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("icon", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("icon_background", type=str, location="json") | 
					
						
							|  |  |  |         parser.add_argument("app_id", type=str, location="json") | 
					
						
							|  |  |  |         args = parser.parse_args() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Create service with session | 
					
						
							|  |  |  |         with Session(db.engine) as session: | 
					
						
							|  |  |  |             import_service = AppDslService(session) | 
					
						
							|  |  |  |             # Import app | 
					
						
							|  |  |  |             account = cast(Account, current_user) | 
					
						
							|  |  |  |             result = import_service.import_app( | 
					
						
							|  |  |  |                 account=account, | 
					
						
							|  |  |  |                 import_mode=args["mode"], | 
					
						
							|  |  |  |                 yaml_content=args.get("yaml_content"), | 
					
						
							|  |  |  |                 yaml_url=args.get("yaml_url"), | 
					
						
							|  |  |  |                 name=args.get("name"), | 
					
						
							|  |  |  |                 description=args.get("description"), | 
					
						
							|  |  |  |                 icon_type=args.get("icon_type"), | 
					
						
							|  |  |  |                 icon=args.get("icon"), | 
					
						
							|  |  |  |                 icon_background=args.get("icon_background"), | 
					
						
							|  |  |  |                 app_id=args.get("app_id"), | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             session.commit() | 
					
						
							| 
									
										
										
										
											2025-06-19 17:14:28 +08:00
										 |  |  |         if result.app_id and FeatureService.get_system_features().webapp_auth.enabled: | 
					
						
							|  |  |  |             # update web app setting as private | 
					
						
							|  |  |  |             EnterpriseService.WebAppAuth.update_app_access_mode(result.app_id, "private") | 
					
						
							| 
									
										
										
										
											2024-11-22 15:05:04 +08:00
										 |  |  |         # Return appropriate status code based on result | 
					
						
							|  |  |  |         status = result.status | 
					
						
							|  |  |  |         if status == ImportStatus.FAILED.value: | 
					
						
							|  |  |  |             return result.model_dump(mode="json"), 400 | 
					
						
							|  |  |  |         elif status == ImportStatus.PENDING.value: | 
					
						
							|  |  |  |             return result.model_dump(mode="json"), 202 | 
					
						
							|  |  |  |         return result.model_dump(mode="json"), 200 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppImportConfirmApi(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_import_fields) | 
					
						
							|  |  |  |     def post(self, import_id): | 
					
						
							|  |  |  |         # Check user role first | 
					
						
							|  |  |  |         if not current_user.is_editor: | 
					
						
							|  |  |  |             raise Forbidden() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Create service with session | 
					
						
							|  |  |  |         with Session(db.engine) as session: | 
					
						
							|  |  |  |             import_service = AppDslService(session) | 
					
						
							|  |  |  |             # Confirm import | 
					
						
							|  |  |  |             account = cast(Account, current_user) | 
					
						
							|  |  |  |             result = import_service.confirm_import(import_id=import_id, account=account) | 
					
						
							|  |  |  |             session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Return appropriate status code based on result | 
					
						
							|  |  |  |         if result.status == ImportStatus.FAILED.value: | 
					
						
							|  |  |  |             return result.model_dump(mode="json"), 400 | 
					
						
							|  |  |  |         return result.model_dump(mode="json"), 200 | 
					
						
							| 
									
										
										
										
											2025-02-17 17:05:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class AppImportCheckDependenciesApi(Resource): | 
					
						
							|  |  |  |     @setup_required | 
					
						
							|  |  |  |     @login_required | 
					
						
							|  |  |  |     @get_app_model | 
					
						
							|  |  |  |     @account_initialization_required | 
					
						
							|  |  |  |     @marshal_with(app_import_check_dependencies_fields) | 
					
						
							|  |  |  |     def get(self, app_model: App): | 
					
						
							|  |  |  |         if not current_user.is_editor: | 
					
						
							|  |  |  |             raise Forbidden() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         with Session(db.engine) as session: | 
					
						
							|  |  |  |             import_service = AppDslService(session) | 
					
						
							|  |  |  |             result = import_service.check_dependencies(app_model=app_model) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return result.model_dump(mode="json"), 200 |