class ProjectAdminSerializer(ProjectMemberSerializer): name = serializers.CharField(max_length=200) slug = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) team = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) digestsMinDelay = serializers.IntegerField(min_value=60, max_value=3600) digestsMaxDelay = serializers.IntegerField(min_value=60, max_value=3600) subjectPrefix = serializers.CharField(max_length=200) subjectTemplate = serializers.CharField(max_length=200) securityToken = serializers.RegexField(r'^[-a-zA-Z0-9+/=\s]+$', max_length=255) securityTokenHeader = serializers.RegexField(r'^[a-zA-Z0-9_\-]+$', max_length=20) verifySSL = serializers.BooleanField(required=False) defaultEnvironment = serializers.CharField(required=False) dataScrubber = serializers.BooleanField(required=False) dataScrubberDefaults = serializers.BooleanField(required=False) sensitiveFields = ListField(child=serializers.CharField(), required=False) safeFields = ListField(child=serializers.CharField(), required=False) scrubIPAddresses = serializers.BooleanField(required=False) scrapeJavaScript = serializers.BooleanField(required=False) allowedDomains = ListField(child=OriginField(), required=False) resolveAge = serializers.IntegerField(required=False) platform = serializers.CharField(required=False) def validate_digestsMaxDelay(self, attrs, source): if attrs[source] < attrs['digestsMinDelay']: raise serializers.ValidationError( 'The maximum delay on digests must be higher than the minimum.' ) return attrs def validate_allowedDomains(self, attrs, source): allowed_domains = attrs[source] if len(allowed_domains) == 0: raise serializers.ValidationError( 'Empty value will block all requests, use * to accept from all domains' ) return attrs def validate_slug(self, attrs, source): slug = attrs[source] project = self.context['project'] other = Project.objects.filter( slug=slug, organization=project.organization, ).exclude(id=project.id).first() if other is not None: raise serializers.ValidationError( 'Another project (%s) is already using that slug' % other.name) return attrs
class ProjectAdminSerializer(ProjectMemberSerializer): name = serializers.CharField(max_length=200) slug = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) team = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) digestsMinDelay = serializers.IntegerField(min_value=60, max_value=3600) digestsMaxDelay = serializers.IntegerField(min_value=60, max_value=3600) subjectPrefix = serializers.CharField(max_length=200) subjectTemplate = serializers.CharField(max_length=200) securityToken = serializers.RegexField(r'^[-a-zA-Z0-9+/=\s]+$', max_length=255) securityTokenHeader = serializers.RegexField(r'^[a-zA-Z0-9_\-]+$', max_length=20) verifySSL = serializers.BooleanField(required=False) defaultEnvironment = serializers.CharField(required=False, allow_none=True) dataScrubber = serializers.BooleanField(required=False) dataScrubberDefaults = serializers.BooleanField(required=False) sensitiveFields = ListField(child=serializers.CharField(), required=False) safeFields = ListField(child=serializers.CharField(), required=False) storeCrashReports = serializers.BooleanField(required=False) relayPiiConfig = serializers.CharField(required=False) builtinSymbolSources = ListField(child=serializers.CharField(), required=False) symbolSources = serializers.CharField(required=False) scrubIPAddresses = serializers.BooleanField(required=False) groupingConfig = serializers.CharField(required=False) groupingEnhancements = serializers.CharField(required=False) groupingEnhancementsBase = serializers.CharField(required=False) fingerprintingRules = serializers.CharField(required=False) scrapeJavaScript = serializers.BooleanField(required=False) allowedDomains = ListField(child=OriginField(), required=False) resolveAge = serializers.IntegerField(required=False) platform = serializers.CharField(required=False) copy_from_project = serializers.IntegerField(required=False) def validate_digestsMinDelay(self, attrs, source): max_delay = attrs[ 'digestsMaxDelay'] if 'digestsMaxDelay' in attrs else self.context[ 'project'].get_option('digests:mail:maximum_delay') # allow min to be set if max is not set if max_delay is not None and attrs[source] > max_delay: raise serializers.ValidationError( 'The minimum delay on digests must be lower than the maximum.') return attrs def validate_digestsMaxDelay(self, attrs, source): min_delay = attrs[ 'digestsMinDelay'] if 'digestsMinDelay' in attrs else self.context[ 'project'].get_option('digests:mail:minimum_delay') # allows max to be set if min is not set if min_delay is not None and attrs[source] < min_delay: raise serializers.ValidationError( 'The maximum delay on digests must be higher than the minimum.' ) return attrs def validate_allowedDomains(self, attrs, source): attrs[source] = filter(bool, attrs[source]) if len(attrs[source]) == 0: raise serializers.ValidationError( 'Empty value will block all requests, use * to accept from all domains' ) return attrs def validate_slug(self, attrs, source): slug = attrs[source] if slug in RESERVED_PROJECT_SLUGS: raise serializers.ValidationError( 'The slug "%s" is reserved and not allowed.' % (slug, )) project = self.context['project'] other = Project.objects.filter( slug=slug, organization=project.organization, ).exclude(id=project.id).first() if other is not None: raise serializers.ValidationError( 'Another project (%s) is already using that slug' % other.name) return attrs def validate_relayPiiConfig(self, attrs, source): if not attrs[source]: return attrs from sentry import features organization = self.context['project'].organization request = self.context["request"] has_relays = features.has('organizations:relay', organization, actor=request.user) if not has_relays: raise serializers.ValidationError( 'Organization does not have the relay feature enabled') return attrs def validate_builtinSymbolSources(self, attrs, source): if not attrs[source]: return attrs from sentry import features organization = self.context['project'].organization request = self.context["request"] has_sources = features.has('organizations:symbol-sources', organization, actor=request.user) if not has_sources: raise serializers.ValidationError( 'Organization is not allowed to set symbol sources') return attrs def validate_symbolSources(self, attrs, source): sources_json = attrs[source] if not sources_json: return attrs from sentry import features organization = self.context['project'].organization request = self.context["request"] has_sources = features.has('organizations:symbol-sources', organization, actor=request.user) if not has_sources: raise serializers.ValidationError( 'Organization is not allowed to set symbol sources') try: sources = parse_sources(sources_json.strip()) attrs[source] = json.dumps(sources) if sources else '' except InvalidSourcesError as e: raise serializers.ValidationError(e.message) return attrs def validate_groupingEnhancements(self, attrs, source): if not attrs[source]: return attrs try: Enhancements.from_config_string(attrs[source]) except InvalidEnhancerConfig as e: raise serializers.ValidationError(e.message) return attrs def validate_fingerprintingRules(self, attrs, source): if not attrs[source]: return attrs try: FingerprintingRules.from_config_string(attrs[source]) except InvalidFingerprintingConfig as e: raise serializers.ValidationError(e.message) return attrs def validate_copy_from_project(self, attrs, source): other_project_id = attrs[source] try: other_project = Project.objects.filter( id=other_project_id, organization_id=self.context['project'].organization_id, ).prefetch_related('teams')[0] except IndexError: raise serializers.ValidationError( 'Project to copy settings from not found.') request = self.context['request'] if not request.access.has_project_access(other_project): raise serializers.ValidationError( 'Project settings cannot be copied from a project you do not have access to.' ) for project_team in other_project.projectteam_set.all(): if not request.access.has_team_scope(project_team.team, 'team:write'): raise serializers.ValidationError( 'Project settings cannot be copied from a project with a team you do not have write access to.' ) return attrs
class ProjectAdminSerializer(ProjectMemberSerializer): name = serializers.CharField(max_length=200) slug = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) team = serializers.RegexField(r'^[a-z0-9_\-]+$', max_length=50) digestsMinDelay = serializers.IntegerField(min_value=60, max_value=3600) digestsMaxDelay = serializers.IntegerField(min_value=60, max_value=3600) subjectPrefix = serializers.CharField(max_length=200) subjectTemplate = serializers.CharField(max_length=200) securityToken = serializers.RegexField(r'^[-a-zA-Z0-9+/=\s]+$', max_length=255) securityTokenHeader = serializers.RegexField(r'^[a-zA-Z0-9_\-]+$', max_length=20) verifySSL = serializers.BooleanField(required=False) defaultEnvironment = serializers.CharField(required=False, allow_none=True) dataScrubber = serializers.BooleanField(required=False) dataScrubberDefaults = serializers.BooleanField(required=False) sensitiveFields = ListField(child=serializers.CharField(), required=False) safeFields = ListField(child=serializers.CharField(), required=False) storeCrashReports = serializers.BooleanField(required=False) relayPiiConfig = serializers.CharField(required=False) scrubIPAddresses = serializers.BooleanField(required=False) groupingConfig = serializers.CharField(required=False) scrapeJavaScript = serializers.BooleanField(required=False) allowedDomains = ListField(child=OriginField(), required=False) resolveAge = serializers.IntegerField(required=False) platform = serializers.CharField(required=False) def validate_digestsMinDelay(self, attrs, source): max_delay = attrs[ 'digestsMaxDelay'] if 'digestsMaxDelay' in attrs else self.context[ 'project'].get_option('digests:mail:maximum_delay') # allow min to be set if max is not set if max_delay is not None and attrs[source] > max_delay: raise serializers.ValidationError( 'The minimum delay on digests must be lower than the maximum.') return attrs def validate_digestsMaxDelay(self, attrs, source): min_delay = attrs[ 'digestsMinDelay'] if 'digestsMinDelay' in attrs else self.context[ 'project'].get_option('digests:mail:minimum_delay') # allows max to be set if min is not set if min_delay is not None and attrs[source] < min_delay: raise serializers.ValidationError( 'The maximum delay on digests must be higher than the minimum.' ) return attrs def validate_allowedDomains(self, attrs, source): attrs[source] = filter(bool, attrs[source]) if len(attrs[source]) == 0: raise serializers.ValidationError( 'Empty value will block all requests, use * to accept from all domains' ) return attrs def validate_slug(self, attrs, source): slug = attrs[source] if slug in RESERVED_PROJECT_SLUGS: raise serializers.ValidationError( 'The slug "%s" is reserved and not allowed.' % (slug, )) project = self.context['project'] other = Project.objects.filter( slug=slug, organization=project.organization, ).exclude(id=project.id).first() if other is not None: raise serializers.ValidationError( 'Another project (%s) is already using that slug' % other.name) return attrs def validate_relayPiiConfig(self, attrs, source): if not attrs[source]: return attrs from sentry import features organization = self.context['project'].organization request = self.context["request"] has_relays = features.has('organizations:relay', organization, actor=request.user) if not has_relays: raise serializers.ValidationError( 'Organization does not have the relay feature enabled') return attrs
class DummySerializer(serializers.Serializer): origin_field = OriginField()