| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | from functools import wraps | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-06 11:58:49 +08:00
										 |  |  | from flask_login import current_user | 
					
						
							|  |  |  | from flask_restful import Resource | 
					
						
							| 
									
										
										
										
											2024-02-06 13:21:13 +08:00
										 |  |  | from werkzeug.exceptions import NotFound | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  | from controllers.console.explore.error import AppAccessDeniedError | 
					
						
							| 
									
										
										
										
											2024-02-06 13:21:13 +08:00
										 |  |  | from controllers.console.wraps import account_initialization_required | 
					
						
							|  |  |  | from extensions.ext_database import db | 
					
						
							| 
									
										
										
										
											2024-01-12 12:34:01 +08:00
										 |  |  | from libs.login import login_required | 
					
						
							| 
									
										
										
										
											2024-10-21 10:43:49 +08:00
										 |  |  | from models import InstalledApp | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  | from services.app_service import AppService | 
					
						
							|  |  |  | from services.enterprise.enterprise_service import EnterpriseService | 
					
						
							|  |  |  | from services.feature_service import FeatureService | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def installed_app_required(view=None): | 
					
						
							|  |  |  |     def decorator(view): | 
					
						
							|  |  |  |         @wraps(view) | 
					
						
							|  |  |  |         def decorated(*args, **kwargs): | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |             if not kwargs.get("installed_app_id"): | 
					
						
							|  |  |  |                 raise ValueError("missing installed_app_id in path parameters") | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |             installed_app_id = kwargs.get("installed_app_id") | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  |             installed_app_id = str(installed_app_id) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |             del kwargs["installed_app_id"] | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |             installed_app = ( | 
					
						
							|  |  |  |                 db.session.query(InstalledApp) | 
					
						
							|  |  |  |                 .filter( | 
					
						
							|  |  |  |                     InstalledApp.id == str(installed_app_id), InstalledApp.tenant_id == current_user.current_tenant_id | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |                 .first() | 
					
						
							|  |  |  |             ) | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if installed_app is None: | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |                 raise NotFound("Installed app not found") | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if not installed_app.app: | 
					
						
							|  |  |  |                 db.session.delete(installed_app) | 
					
						
							|  |  |  |                 db.session.commit() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  |                 raise NotFound("Installed app not found") | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             return view(installed_app, *args, **kwargs) | 
					
						
							| 
									
										
										
										
											2024-08-26 15:29:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  |         return decorated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if view: | 
					
						
							|  |  |  |         return decorator(view) | 
					
						
							|  |  |  |     return decorator | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  | def user_allowed_to_access_app(view=None): | 
					
						
							|  |  |  |     def decorator(view): | 
					
						
							|  |  |  |         @wraps(view) | 
					
						
							|  |  |  |         def decorated(installed_app: InstalledApp, *args, **kwargs): | 
					
						
							|  |  |  |             feature = FeatureService.get_system_features() | 
					
						
							|  |  |  |             if feature.webapp_auth.enabled: | 
					
						
							|  |  |  |                 app_id = installed_app.app_id | 
					
						
							|  |  |  |                 app_code = AppService.get_app_code_by_id(app_id) | 
					
						
							|  |  |  |                 res = EnterpriseService.WebAppAuth.is_user_allowed_to_access_webapp( | 
					
						
							|  |  |  |                     user_id=str(current_user.id), | 
					
						
							|  |  |  |                     app_code=app_code, | 
					
						
							|  |  |  |                 ) | 
					
						
							|  |  |  |                 if not res: | 
					
						
							|  |  |  |                     raise AppAccessDeniedError() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return view(installed_app, *args, **kwargs) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return decorated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if view: | 
					
						
							|  |  |  |         return decorator(view) | 
					
						
							|  |  |  |     return decorator | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 15:54:45 +08:00
										 |  |  | class InstalledAppResource(Resource): | 
					
						
							|  |  |  |     # must be reversed if there are multiple decorators | 
					
						
							| 
									
										
										
										
											2025-05-20 12:07:50 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     method_decorators = [ | 
					
						
							|  |  |  |         user_allowed_to_access_app, | 
					
						
							|  |  |  |         installed_app_required, | 
					
						
							|  |  |  |         account_initialization_required, | 
					
						
							|  |  |  |         login_required, | 
					
						
							|  |  |  |     ] |