def validate_user(a_tuple: UserBasedTuple, user_service: UserService, principal_service: PrincipalService) -> None: if not principal_service.is_admin(): raise_403() if is_blank(a_tuple.userId): if principal_service.is_super_admin(): raise_400('User id is required.') elif principal_service.is_tenant_admin(): a_tuple.userId = principal_service.get_user_id() else: raise_403() else: if a_tuple.userId == principal_service.get_user_id(): if principal_service.is_super_admin(): raise_400(f'Incorrect user id[{a_tuple.userId}].') else: user: Optional[User] = user_service.find_by_id(a_tuple.userId) if user is None: raise_400('User id is required.') if principal_service.is_super_admin(): if user.tenantId == principal_service.get_tenant_id(): raise_400(f'Incorrect user id[{a_tuple.userId}].') elif principal_service.is_tenant_admin(): if user.tenantId != principal_service.get_tenant_id(): raise_400(f'Incorrect user id[{a_tuple.userId}].')
def try_to_lock_scheduler( scheduler: TopicSnapshotScheduler, process_date: date, principal_service: PrincipalService ) -> Tuple[Optional[TopicSnapshotJobLock], bool]: if isinstance(process_date, datetime): process_date = process_date.date() lock_service = get_lock_service(principal_service) lock_service.begin_transaction() # noinspection PyBroadException try: lock = TopicSnapshotJobLock( tenantId=principal_service.get_tenant_id(), schedulerId=scheduler.schedulerId, frequency=scheduler.frequency, processDate=process_date, rowCount=0, status=TopicSnapshotJobLockStatus.READY, userId=principal_service.get_user_id(), ) lock_service.create(lock) lock_service.commit_transaction() return lock, True except Exception: lock_service.rollback_transaction() return None, False
def try_to_lock_topic_for_monitor( topic: Topic, frequency: MonitorRuleStatisticalInterval, process_date: date, principal_service: PrincipalService ) -> Tuple[Optional[MonitorJobLock], bool]: if isinstance(process_date, datetime): process_date = process_date.date() lock_service = get_lock_service(principal_service) lock_service.begin_transaction() try: lock = MonitorJobLock( # lockId: MonitorJobLockId = None tenantId=principal_service.get_tenant_id(), topicId=topic.topicId, frequency=frequency, processDate=process_date, status=MonitorJobLockStatus.READY, userId=principal_service.get_user_id(), ) lock_service.create(lock) lock_service.commit_transaction() return lock, True except Exception: lock_service.rollback_transaction() return None, False
def prepare_and_validate_request( request: MixImportDataRequest, user_service: UserService, principal_service: PrincipalService) -> None: tenant_id = validate_tenant_id(request, user_service, principal_service) clear_data_source_id(request.topics) clear_user_group_ids(request.spaces) def set_user_id_to_report(report: Report, user_id: UserId) -> None: report.userId = user_id def set_user_id_to_subject(subject: SubjectWithReports, user_id: UserId) -> None: subject.userId = user_id ArrayHelper(subject.reports) \ .flatten() \ .filter(lambda x: x is not None) \ .each(lambda x: set_user_id_to_report(x, user_id)) def set_user_id_to_connected_space(connected_space: ConnectedSpaceWithSubjects, user_id: UserId) -> None: connected_space.userId = user_id ArrayHelper(connected_space.subjects) \ .flatten() \ .filter(lambda x: x is not None) \ .each(lambda x: set_user_id_to_subject(x, user_id)) if principal_service.is_super_admin(): # to find a tenant admin tenant_admin: Optional[User] = user_service.find_admin(tenant_id) if tenant_admin is None: raise_400(f'Admin user on tenant[{tenant_id}] to receive imported data is not found.') elif principal_service.is_tenant_admin(): ArrayHelper(request.connectedSpaces).each( lambda x: set_user_id_to_connected_space(x, principal_service.get_user_id())) else: raise_403()
async def load_user_by_id( user_id: Optional[UserId] = None, principal_service: PrincipalService = Depends(get_any_principal) ) -> User: if is_blank(user_id): raise_400('User id is required.') if not principal_service.is_admin(): # console user cannot visit other users if user_id != principal_service.get_user_id(): raise_403() user_service = get_user_service(principal_service) def action() -> User: # noinspection PyTypeChecker user: User = user_service.find_by_id(user_id) if user is None: raise_404() # check tenant id if not principal_service.is_super_admin(): # tenant id must match current principal's, except current is super admin if user.tenantId != principal_service.get_tenant_id(): raise_404() # remove password clear_pwd(user) return user return trans_readonly(user_service, action)
def validate_reports( dashboard: Dashboard, dashboard_service: DashboardService, principal_service: PrincipalService) -> None: reports = dashboard.reports if reports is None: dashboard.reports = [] return if len(reports) == 0: return report_ids = ArrayHelper(reports).map(lambda x: x.reportId).distinct().to_list() if len(report_ids) == 0: dashboard.reports = [] return report_service = get_report_service(dashboard_service) for report_id in report_ids: existing_one = report_service.find_tenant_and_user(report_id) if existing_one is None: raise_400('Report ids do not match.') existing_tenant_id, existing_user_id = existing_one if existing_tenant_id != principal_service.get_tenant_id(): raise_403() if existing_user_id != principal_service.get_user_id(): raise_403()
def fake_to_tenant(principal_service: PrincipalService, tenant_id: TenantId) -> PrincipalService: if principal_service.is_super_admin(): # fake principal as tenant admin return PrincipalService( User(userId=principal_service.get_user_id(), tenantId=tenant_id, name=principal_service.get_user_name(), role=UserRole.ADMIN)) else: return principal_service
def filter_indicators( indicators: List[Indicator], indicator_service: IndicatorService, principal_service: PrincipalService ) -> List[Indicator]: if principal_service.is_admin(): return indicators user_id = principal_service.get_user_id() user_service = get_user_service(indicator_service) user: Optional[User] = user_service.find_by_id(user_id) if user is None: raise_403() group_ids = user.groupIds return ArrayHelper(indicators).filter(lambda x: ArrayHelper(x.groupIds).some(lambda y: y in group_ids)).to_list()
def do_load_inspection_by_id( inspection_id: InspectionId, inspection_service: InspectionService, principal_service: PrincipalService) -> Inspection: # noinspection PyTypeChecker inspection: Inspection = inspection_service.find_by_id(inspection_id) if inspection is None: raise_404() # user id must match current principal's if inspection.userId != principal_service.get_user_id(): raise_404() # tenant id must match current principal's if inspection.tenantId != principal_service.get_tenant_id(): raise_404() return inspection
async def exchange_user(principal_service: PrincipalService = Depends(get_any_principal)) -> Optional[User]: """ returns current principal """ user_id = principal_service.get_user_id() user_service = UserService(ask_meta_storage(), ask_snowflake_generator(), principal_service) user_service.begin_transaction() try: # noinspection PyTypeChecker user: User = user_service.find_by_id(user_id) if user is None: return None else: del user.password return user finally: user_service.close_transaction()
def ask_principal_service(principal_service: PrincipalService, tenant_id: Optional[TenantId]) -> PrincipalService: if principal_service.is_tenant_admin(): if is_blank(tenant_id): return principal_service elif tenant_id != principal_service.get_tenant_id(): raise_400( f'Tenant id[{tenant_id}] does not match current principal.') else: return principal_service elif principal_service.is_super_admin(): if is_blank(tenant_id): raise_400('Tenant id is required.') tenant_service = get_tenant_service(principal_service) tenant: Optional[Tenant] = tenant_service.find_by_id(tenant_id) if tenant is None: raise_404(f'Tenant[id={tenant_id}] not found.') return PrincipalService( User(tenantId=tenant_id, userId=principal_service.get_user_id(), name=principal_service.get_user_name(), role=UserRole.ADMIN))
async def fetch_pipeline_logs( criteria: PipelineMonitorLogCriteria, principal_service: PrincipalService = Depends(get_any_admin_principal) ) -> PipelineMonitorLogDataPage: if principal_service.is_super_admin(): if is_blank(criteria.tenantId): raise_400('Tenant id is required.') # fake principal as tenant admin principal_service = PrincipalService(User( userId=principal_service.get_user_id(), tenantId=criteria.tenantId, name=principal_service.get_user_name(), role=UserRole.ADMIN)) else: criteria.tenantId = principal_service.get_tenant_id() page = PipelineMonitorLogDataService(principal_service).page(criteria) # translate dataId to string def translate_data_id_to_str(log: PipelineMonitorLog) -> None: log.dataId = str(log.dataId) page.data = ArrayHelper(page.data).each(translate_data_id_to_str).to_list() # noinspection PyTypeChecker return page
def load_standalone_dashboard( admin_dashboard_id: Optional[DashboardId], dashboard_service: DashboardService, principal_service: PrincipalService ) -> StandaloneDashboard: if is_blank(admin_dashboard_id): return as_empty_dashboard() dashboard: Optional[Dashboard] = dashboard_service.find_by_id(admin_dashboard_id) if dashboard is None: return as_empty_dashboard() if dashboard.tenantId != principal_service.get_tenant_id() or dashboard.userId != principal_service.get_user_id(): raise_403() report_ids = ArrayHelper(dashboard.reports).map(lambda x: x.reportId).to_list() if len(report_ids) == 0: return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) report_service = get_report_service(dashboard_service) reports: List[Report] = ArrayHelper(report_ids).map(lambda x: report_service.find_by_id(x)).to_list() if len(reports) == 0: return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) if ArrayHelper(reports).some( lambda x: x.tenantId != principal_service.get_tenant_id() and x.userId != principal_service.get_user_id()): # something wrong with data logger.error(f'Something wrong with report data for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) report_map: Dict[SubjectId, List[Report]] = ArrayHelper(reports).group_by(lambda x: x.subjectId) subject_ids = ArrayHelper(reports).map(lambda x: x.subjectId).distinct().to_list() subject_service = get_subject_service(dashboard_service) subjects = ArrayHelper(subject_ids).map(lambda x: subject_service.find_by_id(x)).to_list() if len(subjects) == 0: logger.error(f'Subject data not found for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) if ArrayHelper(subjects).some( lambda x: x.tenantId != principal_service.get_tenant_id() and x.userId != principal_service.get_user_id()): # something wrong with data logger.error(f'Something wrong with subject data for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) def get_my_reports(subject_id: SubjectId) -> List[Report]: my_reports = report_map.get(subject_id) return [] if my_reports is None else my_reports subject_map: Dict[ConnectedSpaceId, List[SubjectWithReports]] = ArrayHelper(subjects) \ .map(lambda x: SubjectWithReports(**x.dict(), reports=get_my_reports(x.subjectId))) \ .filter(lambda x: x.reports is not None and len(x.reports) != 0) \ .group_by(lambda x: x.connectId) connect_ids = ArrayHelper(subjects).map(lambda x: x.connectId).distinct().to_list() connected_space_service = get_connected_space_service(dashboard_service) connected_spaces = ArrayHelper(connect_ids).map(lambda x: connected_space_service.find_by_id(x)).to_list() if len(connected_spaces) == 0: logger.error(f'Connected space data not found for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) if ArrayHelper(connected_spaces).some( lambda x: x.tenantId != principal_service.get_tenant_id() and x.userId != principal_service.get_user_id()): # something wrong with data logger.error(f'Something wrong with connected space data for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) def get_my_subjects(connect_id: ConnectedSpaceId) -> List[SubjectWithReports]: my_subjects = subject_map.get(connect_id) return [] if my_subjects is None else my_subjects connected_spaces_with_subjects = ArrayHelper(connected_spaces) \ .map(lambda x: ConnectedSpaceWithSubjects(**x.dict(), subjects=get_my_subjects(x.connectId))) \ .filter(lambda x: x.subjects is not None and len(x.subjects) != 0) \ .to_list() if len(connected_spaces_with_subjects) == 0: # something wrong with data logger.error(f'Something wrong with connected space data for dashboard[{dashboard.dashboardId}]') return as_empty_dashboard(dashboard=Dashboard(**dashboard.dict(), reports=[])) # get available reports available_report_map = ArrayHelper(reports).to_map(lambda x: x.reportId, lambda x: x) return StandaloneDashboard( dashboard=Dashboard( # **dashboard.dict(), dashboardId=dashboard.dashboardId, name=dashboard.name, paragraphs=dashboard.paragraphs, autoRefreshInterval=dashboard.autoRefreshInterval, # remove useless report data from dashboard reports=ArrayHelper(dashboard.reports).filter( lambda x: available_report_map[x.reportId] is not None).to_list() ), connected_spaces=connected_spaces_with_subjects )