def get_assessment_qs(info): assessment_qs = Assessment.objects.filter(project=info.context.active_project) # Generate querset according to permission if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return assessment_qs elif PP.check_permission(info, PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD): return assessment_qs.filter(lead__confidentiality=Lead.Confidentiality.UNPROTECTED) return Assessment.objects.none()
def get_emm_entities_qs(info): emm_entity_qs = EMMEntity.objects.filter( lead__project=info.context.active_project).distinct() if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return emm_entity_qs elif PP.check_permission(info, PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD): return emm_entity_qs.filter( lead__confidentiality=Lead.Confidentiality.UNPROTECTED) return EMMEntity.objects.none()
def get_lead_emm_entities_qs(info): lead_emm_qs = LeadEMMTrigger.objects.filter( lead__project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return lead_emm_qs elif PP.check_permission(info, PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD): return lead_emm_qs.filter( lead__confidentiality=Lead.Confidentiality.UNPROTECTED) return LeadEMMTrigger.objects.none()
def get_entry_comment_qs(info): """ NOTE: To be used in EntryReviewCommentDetailType """ entry_comment_qs = EntryReviewComment.objects.filter( entry__project=info.context.active_project) # Generate queryset according to permission if PP.check_permission(info, PP.Permission.VIEW_ENTRY): if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return entry_comment_qs elif PP.check_permission(info, PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD): return entry_comment_qs.filter( entry__lead__confidentiality=Lead.Confidentiality.UNPROTECTED) return EntryReviewComment.objects.none()
def get_entry_qs(info): entry_qs = Entry.objects.filter( # Filter by project project=info.context.active_project, # Filter by project's active analysis_framework (Only show active AF's entries) analysis_framework=info.context.active_project.analysis_framework_id, ) # Generate queryset according to permission if PP.check_permission(info, PP.Permission.VIEW_ENTRY): if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return entry_qs elif PP.check_permission(info, PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD): return entry_qs.filter( lead__confidentiality=Lead.Confidentiality.UNPROTECTED) return Entry.objects.none()
def get_analysis_pillar_qs(info): pillar_qs = AnalysisPillar.objects.filter( # Filter by project analysis__project=info.context.active_project, ) # Generate queryset according to permission if PP.check_permission(info, PP.Permission.VIEW_ENTRY): return pillar_qs return AnalysisPillar.objects.none()
def validate_comment_type(self, comment_type): # No validation needed for edit since we don't allow changing it if self.instance: if self.instance.comment_type != comment_type: raise serializers.ValidationError( 'Changing comment type is not allowed') return comment_type if comment_type == EntryReviewComment.CommentType.COMMENT: return comment_type # No additional validation/action required current_user = self.context['request'].user verified_by_qs = Entry.verified_by.through.objects.filter( entry=self.entry, user=current_user) if (comment_type in [ EntryReviewComment.CommentType.CONTROL, EntryReviewComment.CommentType.UNCONTROL, ] and not PP.check_permission_from_serializer( self.context['request'], PP.Permission.CAN_QUALITY_CONTROL, )): raise serializers.ValidationError( 'Controlled/Uncontrolled comment are only allowd by QA!!') if comment_type == EntryReviewComment.CommentType.VERIFY: if verified_by_qs.exists(): raise serializers.ValidationError('Already verified!!') self.pending_commits.append( lambda: self.entry.verified_by.add(current_user)) elif comment_type == EntryReviewComment.CommentType.UNVERIFY: if not verified_by_qs.exists(): raise serializers.ValidationError( 'Need to be verified first!!') self.pending_commits.append( lambda: self.entry.verified_by.remove(current_user)) elif comment_type == EntryReviewComment.CommentType.CONTROL: if self.entry.controlled: raise serializers.ValidationError('Already controlled!!') self.pending_commits.append( lambda: self.entry.control(current_user)) elif comment_type == EntryReviewComment.CommentType.UNCONTROL: if not self.entry.controlled: raise serializers.ValidationError( 'Need to be controlled first!!') self.pending_commits.append( lambda: self.entry.control(current_user, controlled=False)) return comment_type
def _export_assessments(export, AssessmentModel, excel_sheet_data_generator): user = export.exported_by project = export.project export_type = export.export_type is_preview = export.is_preview arys = AssessmentModel.objects.filter( project=project).select_related('project').distinct() if AssessmentModel == Assessment: # Filter is only available for Assessments (not PlannedAssessment) user_project_permissions = PP.get_permissions(project, user) filters = copy.deepcopy( export.filters) # Avoid mutating database values # Lead filtered queryset leads_qs = Lead.objects.filter(project=export.project) if PP.Permission.VIEW_ALL_LEAD not in user_project_permissions: leads_qs = leads_qs.filter( confidentiality=Lead.Confidentiality.UNPROTECTED) dummy_request = LeadGQFilterSet.get_dummy_request(project) leads_qs = LeadGQFilterSet(data=filters, queryset=leads_qs, request=dummy_request).qs arys = arys.filter(lead__in=leads_qs) iterable_arys = arys[:Export. PREVIEW_ASSESSMENT_SIZE] if is_preview else arys if export_type == Export.ExportType.JSON: exporter = JsonExporter() exporter.data = { ary.project.title: ary.to_exportable_json() for ary in iterable_arys } export_data = exporter.export() elif export_type == Export.ExportType.EXCEL: sheets_data = excel_sheet_data_generator(iterable_arys) export_data = NewExcelExporter(sheets_data)\ .export() else: raise Exception( f'(Assessments Export) Unkown Export Type Provided: {export_type} for Export: {export.id}' ) return export_data
def resolve_public_lead(_, info, **kwargs): def _return(lead, project, has_access): _project = project if (project and project.is_private) and not has_access: _project = None if lead: lead.has_project_access = has_access return { 'project': _project, 'lead': lead, } def _get_lead_from_qs(qs): return qs\ .select_related( 'project', 'created_by', 'source', 'source__parent', ).filter(uuid=kwargs['uuid']).first() user = info.context.user if user is None or user.is_anonymous: lead = _get_lead_from_qs(get_public_lead_qs()) return _return(lead, None, False) lead = _get_lead_from_qs(Lead.objects.all()) if lead is None: return _return(None, None, False) user_permissions = PP.get_permissions(lead.project, user) has_access = len(user_permissions) > 0 if (PP.Permission.VIEW_ALL_LEAD in user_permissions or (PP.Permission.VIEW_ONLY_UNPROTECTED_LEAD in user_permissions and lead.confidentiality != Lead.Confidentiality.CONFIDENTIAL) or (lead.confidentiality == Lead.Confidentiality.UNPROTECTED and # IS public lead.project. has_publicly_viewable_leads # Project allows to share pubilc leads )): return _return(lead, lead.project, has_access) return _return(None, lead.project, has_access)
def get_draft_entry_qs(info): qs = DraftEntry.objects.filter(project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_ENTRY): return qs return qs.none()
def resolve_regions(root, info, **kwargs): # Need to have a base permission if PP.check_permission(info, PP.Permission.BASE_ACCESS): return info.context.dl.project.geo_region.load(root.pk) return info.context.dl.project.public_geo_region.load(root.pk)
def resolve_data_url(root, info, **_): url = root.file if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): url = root.confidential_file return url and info.context.request.build_absolute_uri( URLCachedFileField.name_to_representation(url))
def check_permissions(cls, info, **_): for permission in cls.permissions: if not PP.check_permission(info, permission): raise PermissionDenied(PP.get_permission_message(permission))
def get_lead_group_qs(info): lead_group_qs = LeadGroup.objects.filter( project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_ALL_LEAD): return lead_group_qs return LeadGroup.objects.none()
def get_unified_connector_qs(info): qs = UnifiedConnector.objects.filter(project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_UNIFIED_CONNECTOR): return qs return qs.none()
def export_entries(export): user = export.exported_by project = export.project export_type = export.export_type is_preview = export.is_preview user_project_permissions = PP.get_permissions(project, user) # Avoid mutating database values filters = copy.deepcopy(export.filters) extra_options = copy.deepcopy(export.extra_options) # Lead/Entry filtered queryset leads_qs = Lead.objects.filter(project=export.project) if PP.Permission.VIEW_ALL_LEAD not in user_project_permissions: leads_qs = leads_qs.filter( confidentiality=Lead.Confidentiality.UNPROTECTED) # Lead and Entry FilterSet needs request to work with active_project dummy_request = LeadGQFilterSet.get_dummy_request(project) leads_qs = LeadGQFilterSet(data=filters, queryset=leads_qs, request=dummy_request).qs entries_qs = EntryGQFilterSet( data=filters.get('entries_filter_data'), request=dummy_request, queryset=Entry.objects.filter( project=export.project, analysis_framework=export.project.analysis_framework_id, lead__in=leads_qs, )).qs # Prefetches entries_qs = entries_qs.prefetch_related( 'entrygrouplabel_set', 'lead__authors', 'lead__authors__organization_type', # Also organization parents 'lead__authors__parent', 'lead__authors__parent__organization_type', ) exportables = Exportable.objects.filter( analysis_framework__project=project, exportdata__isnull=False, ).distinct() regions = Region.objects.filter(project=project).distinct() if export_type == Export.ExportType.EXCEL: decoupled = extra_options.get('excel_decoupled', False) export_data = ExcelExporter(entries_qs, decoupled, project.id, is_preview=is_preview)\ .load_exportables(exportables, regions)\ .add_entries(entries_qs)\ .export() elif export_type == Export.ExportType.REPORT: # which widget data needs to be exported along with exporting_widgets = extra_options.get('report_exporting_widgets', []) report_show_attributes = dict( show_lead_entry_id=extra_options.get('report_show_lead_entry_id', True), show_assessment_data=extra_options.get( 'report_show_assessment_data', True), show_entry_widget_data=extra_options.get( 'report_show_entry_widget_data', True), ) report_structure = extra_options.get('report_structure') report_levels = extra_options.get('report_levels') text_widget_ids = extra_options.get('report_text_widget_ids') or [] show_groups = extra_options.get('report_show_groups') export_data = (ReportExporter( exporting_widgets=exporting_widgets, is_preview=is_preview, **report_show_attributes, ).load_exportables(exportables, regions).load_levels( report_levels).load_structure(report_structure).load_group_lables( entries_qs, show_groups).load_text_from_text_widgets( entries_qs, text_widget_ids).add_entries(entries_qs).export( pdf=export.format == Export.Format.PDF)) elif export_type == Export.ExportType.JSON: export_data = JsonExporter(is_preview=is_preview)\ .load_exportables(exportables)\ .add_entries(entries_qs)\ .export() else: raise Exception( '(Entries Export) Unkown Export Type Provided: {export_type} for Export: {export.id}' ) return export_data
def resolve_allowed_permissions(root, info) -> List[PP.Permission]: return PP.get_permissions(root, info.context.request.user)
def set_active_project(self, project): self.active_project = self.request.active_project = project self.project_permissions = self.request.project_permissions = PP.get_permissions( project, self.request.user)
def get_connector_source_lead_qs(info): qs = ConnectorSourceLead.objects.filter( source__unified_connector__project=info.context.active_project) if PP.check_permission(info, PP.Permission.VIEW_UNIFIED_CONNECTOR): return qs return qs.none()