class CourseSerializer(ChisubmitSerializer): course_id = serializers.SlugField() name = serializers.CharField(max_length=64) url = serializers.SerializerMethodField() instructors_url = serializers.SerializerMethodField() graders_url = serializers.SerializerMethodField() students_url = serializers.SerializerMethodField() assignments_url = serializers.SerializerMethodField() teams_url = serializers.SerializerMethodField() git_server_connstr = serializers.CharField(max_length=256, required=False) git_staging_connstr = serializers.CharField(max_length=256, required=False) git_usernames = serializers.ChoiceField( choices=Course.GIT_USERNAME_CHOICES, default=Course.GIT_USERNAME_USER) git_staging_usernames = serializers.ChoiceField( choices=Course.GIT_USERNAME_CHOICES, default=Course.GIT_USERNAME_USER) extension_policy = serializers.ChoiceField(choices=Course.EXT_CHOICES, default=Course.EXT_PER_STUDENT) default_extensions = serializers.IntegerField(default=0, min_value=0) hidden_fields = { "git_staging_connstr": Students, "git_usernames": GradersAndStudents, "git_staging_usernames": GradersAndStudents, "extension_policy": GradersAndStudents, "default_extensions": GradersAndStudents } readonly_fields = { "course_id": AllExceptAdmin, "name": AllExceptAdmin, "git_server_connstr": AllExceptAdmin, "git_staging_connstr": AllExceptAdmin, "git_usernames": AllExceptAdmin, "git_staging_usernames": AllExceptAdmin, "extension_policy": AllExceptAdmin, "default_extensions": AllExceptAdmin } def get_url(self, obj): return reverse('course-detail', args=[obj.course_id], request=self.context["request"]) def get_instructors_url(self, obj): return reverse('instructor-list', args=[obj.course_id], request=self.context["request"]) def get_graders_url(self, obj): return reverse('grader-list', args=[obj.course_id], request=self.context["request"]) def get_students_url(self, obj): return reverse('student-list', args=[obj.course_id], request=self.context["request"]) def get_assignments_url(self, obj): return reverse('assignment-list', args=[obj.course_id], request=self.context["request"]) def get_teams_url(self, obj): return reverse('team-list', args=[obj.course_id], request=self.context["request"]) def create(self, validated_data): return Course.objects.create(**validated_data) def update(self, instance, validated_data): instance.course_id = validated_data.get('course_id', instance.course_id) instance.name = validated_data.get('name', instance.name) instance.git_server_connstr = validated_data.get( 'git_server_connstr', instance.git_server_connstr) instance.git_staging_connstr = validated_data.get( 'git_staging_connstr', instance.git_staging_connstr) instance.git_usernames = validated_data.get('git_usernames', instance.git_usernames) instance.git_staging_usernames = validated_data.get( 'git_staging_usernames', instance.git_staging_usernames) instance.extension_policy = validated_data.get( 'extension_policy', instance.extension_policy) instance.default_extensions = validated_data.get( 'default_extensions', instance.default_extensions) instance.save() return instance
class NodeSerializer(JSONAPISerializer): # TODO: If we have to redo this implementation in any of the other serializers, subclass ChoiceField and make it # handle blank choices properly. Currently DRF ChoiceFields ignore blank options, which is incorrect in this # instance filterable_fields = frozenset([ 'title', 'description', 'public', 'registration', 'tags', 'category', ]) id = IDField(source='_id', read_only=True) type = TypeField() category_choices = Node.CATEGORY_MAP.keys() category_choices_string = ', '.join(["'{}'".format(choice) for choice in category_choices]) title = ser.CharField(required=True) description = ser.CharField(required=False, allow_blank=True, allow_null=True) category = ser.ChoiceField(choices=category_choices, help_text="Choices: " + category_choices_string) date_created = ser.DateTimeField(read_only=True) date_modified = ser.DateTimeField(read_only=True) registration = ser.BooleanField(read_only=True, source='is_registration') collection = ser.BooleanField(read_only=True, source='is_folder') dashboard = ser.BooleanField(read_only=True, source='is_dashboard') tags = ser.ListField(child=NodeTagField(), required=False) public = ser.BooleanField(source='is_public', read_only=True, help_text='Nodes that are made public will give read-only access ' 'to everyone. Private nodes require explicit read ' 'permission. Write and admin access are the same for ' 'public and private nodes. Administrators on a parent ' 'node have implicit read permissions for all child nodes', ) links = LinksField({'html': 'get_absolute_url'}) # TODO: When we have osf_permissions.ADMIN permissions, make this writable for admins children = JSONAPIHyperlinkedIdentityField(view_name='nodes:node-children', lookup_field='pk', link_type='related', lookup_url_kwarg='node_id', meta={'count': 'get_node_count'}) contributors = JSONAPIHyperlinkedIdentityField(view_name='nodes:node-contributors', lookup_field='pk', link_type='related', lookup_url_kwarg='node_id', meta={'count': 'get_contrib_count'}) files = JSONAPIHyperlinkedIdentityField(view_name='nodes:node-providers', lookup_field='pk', lookup_url_kwarg='node_id', link_type='related') node_links = DevOnly(JSONAPIHyperlinkedIdentityField(view_name='nodes:node-pointers', lookup_field='pk', link_type='related', lookup_url_kwarg='node_id', meta={'count': 'get_pointers_count'})) parent = JSONAPIHyperlinkedIdentityField(view_name='nodes:node-detail', lookup_field='parent_id', link_type='self', lookup_url_kwarg='node_id') registrations = DevOnly(JSONAPIHyperlinkedIdentityField(view_name='nodes:node-registrations', lookup_field='pk', link_type='related', lookup_url_kwarg='node_id', meta={'count': 'get_registration_count'})) class Meta: type_ = 'nodes' def get_absolute_url(self, obj): return obj.absolute_url # TODO: See if we can get the count filters into the filter rather than the serializer. def get_user_auth(self, request): user = request.user if user.is_anonymous(): auth = Auth(None) else: auth = Auth(user) return auth def get_node_count(self, obj): auth = self.get_user_auth(self.context['request']) nodes = [node for node in obj.nodes if node.can_view(auth) and node.primary and not node.is_deleted] return len(nodes) def get_contrib_count(self, obj): return len(obj.contributors) def get_registration_count(self, obj): auth = self.get_user_auth(self.context['request']) registrations = [node for node in obj.node__registrations if node.can_view(auth)] return len(registrations) def get_pointers_count(self, obj): return len(obj.nodes_pointer) def create(self, validated_data): node = Node(**validated_data) try: node.save() except ValidationValueError as e: raise InvalidModelValueError(detail=e.message) return node def update(self, node, validated_data): """Update instance with the validated data. Requires the request to be in the serializer context. """ assert isinstance(node, Node), 'node must be a Node' auth = self.get_user_auth(self.context['request']) tags = validated_data.get('tags') if tags is not None: del validated_data['tags'] current_tags = set(tags) else: current_tags = set() old_tags = set([tag._id for tag in node.tags]) for new_tag in (current_tags - old_tags): node.add_tag(new_tag, auth=auth) for deleted_tag in (old_tags - current_tags): node.remove_tag(deleted_tag, auth=auth) if validated_data: try: node.update(validated_data, auth=auth) except ValidationValueError as e: raise InvalidModelValueError(detail=e.message) return node
class RqStatusSerializer(serializers.Serializer): state = serializers.ChoiceField( choices=["Queued", "Started", "Finished", "Failed"]) message = serializers.CharField(allow_blank=True, default="")
class OrganizationMemberSerializer(serializers.Serializer): reinvite = serializers.BooleanField() regenerate = serializers.BooleanField() role = serializers.ChoiceField(choices=roles.get_choices(), required=True) teams = ListField(required=False, allow_null=False)
class CloseOrderSerializer(serializers.Serializer): new_status = serializers.ChoiceField(choices=(('Closed', 'Closed'))) guest_money = serializers.IntegerField(min_value=0)
class BatchRequestSerializer(serializers.Serializer): method = serializers.ChoiceField(choices=('GET', 'POST', 'PUT', 'PATCH', 'DELETE')) path = LowercaseCharField(max_length=8192, validators=[PathValidator()]) body = JSONField(default={}, validators=[validate_batch_body])
class UserUpdateSerializer(SingleUserBaseSerializer): expose_email_address = serializers.BooleanField( source='profile.expose_email_address', required=False, ) image_id = UploaderFilteredPrimaryKeyRelatedField( queryset=Image.objects.all( ), # filtered to images uploaded by the user required=False, source='profile.image', ) interested_in_theme_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=Theme.objects.all(), required=False, source='profile.interested_in_themes', ) language = serializers.ChoiceField( source='profile.language', choices=settings.LANGUAGES, required=False, ) looking_for_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=UserLookingForOption.objects.all(), required=False, source='profile.looking_for', ) offering_ids = serializers.PrimaryKeyRelatedField( many=True, queryset=UserLookingForOption.objects.all(), required=False, source='profile.offering', ) status_id = serializers.PrimaryKeyRelatedField( queryset=UserStatusOption.objects.all(), required=False, source='profile.status', ) class Meta(SingleUserBaseSerializer.Meta): fields = SingleUserBaseSerializer.Meta.fields + ( 'expose_email_address', 'image_id', 'interested_in_theme_ids', 'language', 'looking_for_ids', 'offering_ids', 'status_id') def update(self, instance, validated_data): profile_data = validated_data.pop('profile', {}) with transaction.atomic(): instance = super().update(instance, validated_data) profile, created = UserProfile.objects.get_or_create(user=instance) for field in ('description', 'expose_email_address', 'image', 'language', 'status', 'facebook_url', 'instagram_url', 'linkedin_url', 'twitter_url', 'send_experiment_notification'): if field in profile_data: setattr(profile, field, profile_data[field]) if 'interested_in_themes' in profile_data: profile.interested_in_themes.set( profile_data['interested_in_themes']) if 'looking_for' in profile_data: profile.looking_for.set(profile_data['looking_for']) if 'offering' in profile_data: profile.offering.set(profile_data['offering']) profile.save() return instance def create(self, validated_data): raise NotImplementedError('`create()` not allowed.')
class MyUserSerializer(serializers.Serializer): email = serializers.EmailField(validators=[UniqueValidator(queryset=MyUser.objects.all())]) password1=serializers.CharField() password2=serializers.CharField() first_name=serializers.CharField() middle_name = serializers.CharField(allow_blank=True) last_name = serializers.CharField(allow_blank=True) contact=serializers.IntegerField() designation_choices = ( ('Employee', 'Employee'), ('Manager', 'Manager'), ) department_choices = ( ('HR', 'HR'), ('Marketing', 'Marketing'), ('Accounts', 'Accounts'), ('IT', 'IT'), ) gender_choice = ( ('M', 'M'), ('F', 'F'), ('Other', 'Other'), ) department=serializers.ChoiceField( label='department', choices=department_choices ) gender=serializers.ChoiceField( label='gender', choices=gender_choice ) designation=serializers.ChoiceField( label='designation', choices=designation_choices ) def create(self,validated_data): print('*******************') print(validated_data) validated_data.pop('password1') validated_data.pop('password2') print(validated_data,"filtered") myuser=MyUser(**validated_data) myuser.username=myuser.email.split('@')[0] myuser.save() if myuser.designation == 'Admin': group_user = Group.objects.get_by_natural_key('Admin Group') group_user.user_set.add(myuser) elif myuser.designation == 'Manager' and myuser.department == 'Marketing': group_user = Group.objects.get_by_natural_key('Marketing Manager Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Marketing Employee Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Employee Group') group_user.user_set.add(myuser) elif myuser.designation == 'Manager' and myuser.department == 'HR': group_user = Group.objects.get_by_natural_key('HR Manager Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('HR Employee Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Employee Group') group_user.user_set.add(myuser) elif myuser.designation == 'Manager' and myuser.department == 'IT': group_user = Group.objects.get_by_natural_key('IT Manager Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('IT Employee Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Employee Group') group_user.user_set.add(myuser) elif myuser.department == 'Accounts' and myuser.designation == 'Manager': group_user = Group.objects.get_by_natural_key('Account Manager Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Account Employee Group') group_user.user_set.add(myuser) group_user = Group.objects.get_by_natural_key('Employee Group') group_user.user_set.add(myuser) elif myuser.designation == 'Employee': group_user = Group.objects.get_by_natural_key('Employee Group') group_user.user_set.add(myuser) if myuser.department == 'HR': group_user = Group.objects.get_by_natural_key('HR Employee Group') group_user.user_set.add(myuser) elif myuser.department == 'IT': group_user = Group.objects.get_by_natural_key('IT Employee Group') group_user.user_set.add(myuser) elif myuser.department == 'Marketing': group_user = Group.objects.get_by_natural_key('Marketing Employee Group') group_user.user_set.add(myuser) elif myuser.department == 'Accounts': group_user = Group.objects.get_by_natural_key('Account Employee Group') group_user.user_set.add(myuser) elif myuser.designation == 'Client': group_user = Group.objects.get_by_natural_key('Client Group') group_user.user_set.add(myuser) elif myuser.designation == myuser.department: raise serializers.ValidationError("designation and department both can not be NA") elif myuser.designation == 'Client' and myuser.department != 'NA': raise serializers.ValidationError('not correct match of designation and department') else: raise Exception("Not correct designation or department") return myuser def validate(self, data): print(type(data)) print(data) passwd1=data.get('password1') print(passwd1,'%%%%%%%%%%%%%%%%') passwd2=data.get('password2') print(passwd2,'$$$$$$$$$$$$$$$') if not data.get('password1') or not data.get('password2'): raise serializers.ValidationError("Please enter a password and " "confirm it.") if data.get('password1') != data.get('password2'): raise serializers.ValidationError("Those passwords don't match.") passw=data.get('password1') data['password']=make_password(passw) print(data) # data.pop('password1') # data.pop('password2') print(data,'~!@#$%^&*()') return data def validate_email(self,email): try: MyUser.objects.get(email=email) raise serializers.ValidationError("Email already exists") except MyUser.DoesNotExist: return email def validate_first_name(self,firstname): if re.match('^[a-zA-Z]*$',firstname): return firstname else: raise serializers.ValidationError("Only alphabets are allowed") def validate_middle_name(self, middlename): if re.match('^[a-zA-Z]*$', middlename): return middlename else: raise serializers.ValidationError("Only alphabets are allowed") def validate_last_name(self, lastname): if re.match('^[a-zA-Z]*$', lastname): return lastname else: raise serializers.ValidationError("Only alphabets are allowed") def validate_contact_number(self,val): if val==None: pass else: if re.search('[+-]', val): raise serializers.ValidationError("'+', '-' are not allowed") elif re.search('^[0-9]+$') & len(val) == 10: return val else: raise serializers.ValidationError("Please enter a 10 digit number") def validate_salary(self,salary): if salary == None: pass else: salary = str(salary) if re.search('[+-]', salary): raise serializers.ValidationError("'+', '-' are not allowed") else: return salary def validate_designation(self, design): return design
class RateSerializer(serializers.ModelSerializer): """Rate Serializer.""" DECIMALS = ('value', 'usage_start', 'usage_end') uuid = serializers.UUIDField(read_only=True) provider_uuid = UUIDKeyRelatedField(queryset=Provider.objects.all(), pk_field='uuid') metric = serializers.ChoiceField(choices=Rate.METRIC_CHOICES, required=True) tiered_rate = TieredRateSerializer(required=False, many=True) @staticmethod def _convert_to_decimal(rate): for decimal_key in RateSerializer.DECIMALS: if decimal_key in rate: value = rate.get(decimal_key) if value is not None: decimal_value = Decimal(value) rate[decimal_key] = decimal_value return rate @staticmethod def _validate_continuouse_tiers(tiers): """Validate tiers have no gaps.""" if len(tiers) < 1: raise serializers.ValidationError( 'tiered_rate must have at least one tier.') sorted_tiers = sorted(tiers, key=lambda tier: Decimal('-Infinity') if tier.get('usage_start') is None else Decimal( tier.get('usage_start'))) # noqa: E501 start = sorted_tiers[0].get('usage_start') end = sorted_tiers[-1].get('usage_end') if start is not None or end is not None: error_msg = 'tiered_rate must have a tier with usage_start as null' \ ' and a tier with usage_end as null.' raise serializers.ValidationError(error_msg) else: next_tier = None for tier in sorted_tiers: usage_start = tier.get('usage_start') usage_end = tier.get('usage_end') if (next_tier is not None and usage_start is not None and Decimal(usage_start) > Decimal(next_tier)): # noqa:W503 error_msg = 'tiered_rate must not have gaps between tiers.' \ 'usage_start of {} should be less than or equal to the' \ ' usage_end {} of the previous tier.'.format(usage_start, next_tier) raise serializers.ValidationError(error_msg) next_tier = usage_end def validate_provider_uuid(self, provider_uuid): """Check that provider_uuid is a valid identifier.""" if Provider.objects.filter(uuid=provider_uuid).count() == 1: return provider_uuid else: raise serializers.ValidationError( 'Provider object does not exist with given uuid.') def validate(self, data): """Validate that a rate must be defined.""" rate_keys = ('tiered_rate', ) if any(data.get(rate_key) is not None for rate_key in rate_keys): tiered_rate = data.get('tiered_rate') if tiered_rate is not None: RateSerializer._validate_continuouse_tiers(tiered_rate) return data else: rate_keys_str = ', '.join(str(rate_key) for rate_key in rate_keys) error_msg = 'A rated must be provided (e.g. {}).'.format( rate_keys_str) raise serializers.ValidationError(error_msg) def to_representation(self, rate): """Create external representation of a rate.""" rates = rate.rates out = { 'uuid': rate.uuid, 'provider_uuid': rate.provider_uuid, 'metric': rate.metric } for rate_type in rates.values(): if isinstance(rate_type, list): for rate_item in rate_type: RateSerializer._convert_to_decimal(rate_item) else: RateSerializer._convert_to_decimal(rate_type) out.update(rates) return out def create(self, validated_data): """Create the rate object in the database.""" provider_uuid = validated_data.pop('provider_uuid') metric = validated_data.pop('metric') return Rate.objects.create(provider_uuid=provider_uuid, metric=metric, rates=validated_data) def update(self, instance, validated_data): """Update the rate object in the database.""" provider_uuid = validated_data.pop('provider_uuid') metric = validated_data.pop('metric') instance.provider_uuid = provider_uuid instance.metric = metric instance.rates = validated_data instance.save() return instance class Meta: model = Rate fields = ('uuid', 'provider_uuid', 'metric', 'tiered_rate')
class ImportScanSerializer(TaggitSerializer, serializers.Serializer): scan_date = serializers.DateField(default=datetime.date.today) minimum_severity = serializers.ChoiceField( choices=SEVERITY_CHOICES, default='Info') active = serializers.BooleanField(default=True) verified = serializers.BooleanField(default=True) scan_type = serializers.ChoiceField( choices=ImportScanForm.SCAN_TYPE_CHOICES) test_type = serializers.ChoiceField( choices=ImportScanForm.SCAN_TYPE_CHOICES, required=False) file = serializers.FileField() engagement = serializers.PrimaryKeyRelatedField( queryset=Engagement.objects.all()) lead = serializers.PrimaryKeyRelatedField( allow_null=True, default=None, queryset=User.objects.all()) tags = TagListSerializerField(required=False) skip_duplicates = serializers.BooleanField(required=False, default=False) close_old_findings = serializers.BooleanField(required=False, default=False) def save(self): data = self.validated_data skip_duplicates = data['skip_duplicates'] close_old_findings = data['close_old_findings'] test_type, created = Test_Type.objects.get_or_create( name=data.get('test_type', data['scan_type'])) environment, created = Development_Environment.objects.get_or_create( name='Development') test = Test( engagement=data['engagement'], lead=data['lead'], test_type=test_type, target_start=data['scan_date'], target_end=data['scan_date'], environment=environment, percent_complete=100) try: test.full_clean() except ValidationError: pass test.save() test.tags = u' '.join(data['tags']) try: parser = import_parser_factory(data['file'], test, data['scan_type'],) except ValueError: raise Exception('FileParser ValueError') skipped_hashcodes = [] try: for item in parser.items: if skip_duplicates: hash_code = item.compute_hash_code() if Finding.objects.filter(Q(active=True) | Q(false_p=True) | Q(duplicate=True), test__engagement__product=test.engagement.product, hash_code=hash_code).exists(): skipped_hashcodes.append(hash_code) continue sev = item.severity if sev == 'Information' or sev == 'Informational': sev = 'Info' item.severity = sev if (Finding.SEVERITIES[sev] > Finding.SEVERITIES[data['minimum_severity']]): continue item.test = test item.date = test.target_start item.reporter = self.context['request'].user item.last_reviewed = timezone.now() item.last_reviewed_by = self.context['request'].user item.active = data['active'] item.verified = data['verified'] item.save() if (hasattr(item, 'unsaved_req_resp') and len(item.unsaved_req_resp) > 0): for req_resp in item.unsaved_req_resp: burp_rr = BurpRawRequestResponse( finding=item, burpRequestBase64=req_resp["req"], burpResponseBase64=req_resp["resp"]) burp_rr.clean() burp_rr.save() if (item.unsaved_request is not None and item.unsaved_response is not None): burp_rr = BurpRawRequestResponse( finding=item, burpRequestBase64=item.unsaved_request, burpResponseBase64=item.unsaved_response) burp_rr.clean() burp_rr.save() for endpoint in item.unsaved_endpoints: ep, created = Endpoint.objects.get_or_create( protocol=endpoint.protocol, host=endpoint.host, path=endpoint.path, query=endpoint.query, fragment=endpoint.fragment, product=test.engagement.product) item.endpoints.add(ep) # if item.unsaved_tags is not None: # item.tags = item.unsaved_tags except SyntaxError: raise Exception('Parser SyntaxError') if close_old_findings: # Close old active findings that are not reported by this scan. new_hash_codes = test.finding_set.values('hash_code') for old_finding in Finding.objects.exclude(test=test) \ .exclude(hash_code__in=new_hash_codes) \ .exclude(hash_code__in=skipped_hashcodes) \ .filter(test__engagement__product=test.engagement.product, test__test_type=test_type, active=True): old_finding.active = False old_finding.mitigated = datetime.datetime.combine( test.target_start, timezone.now().time()) old_finding.mitigated_by = self.context['request'].user old_finding.notes.create(author=self.context['request'].user, entry="This finding has been automatically closed" " as it is not present anymore in recent scans.") old_finding.save() title = 'An old finding has been closed for "{}".' \ .format(test.engagement.product.name) description = 'See <a href="{}">{}</a>' \ .format(reverse('view_finding', args=(old_finding.id, )), old_finding.title) create_notification(event='other', title=title, description=description, icon='bullseye', objowner=self.context['request'].user) return test def validate_scan_data(self, value): if value.date() > datetime.today().date(): raise serializers.ValidationError( 'The date cannot be in the future!') return value
class ReImportScanSerializer(TaggitSerializer, serializers.Serializer): scan_date = serializers.DateField() minimum_severity = serializers.ChoiceField( choices=SEVERITY_CHOICES, default='Info') active = serializers.BooleanField(default=True) verified = serializers.BooleanField(default=True) scan_type = serializers.ChoiceField( choices=ImportScanForm.SCAN_TYPE_CHOICES) tags = TagListSerializerField(required=False) file = serializers.FileField() test = serializers.PrimaryKeyRelatedField( queryset=Test.objects.all()) def save(self): data = self.validated_data test = data['test'] scan_type = data['scan_type'] min_sev = data['minimum_severity'] scan_date = data['scan_date'] verified = data['verified'] active = data['active'] try: parser = import_parser_factory(data['file'], test, data['scan_type'],) except ValueError: raise Exception("Parser ValueError") try: items = parser.items original_items = list(test.finding_set.all()) new_items = [] mitigated_count = 0 finding_count = 0 finding_added_count = 0 reactivated_count = 0 for item in items: sev = item.severity if sev == 'Information' or sev == 'Informational': sev = 'Info' if (Finding.SEVERITIES[sev] > Finding.SEVERITIES[min_sev]): continue if scan_type == 'Veracode Scan' or scan_type == 'Arachni Scan': findings = Finding.objects.filter( title=item.title, test=test, severity=sev, numerical_severity=Finding.get_numerical_severity(sev), description=item.description).all() else: findings = Finding.objects.filter( title=item.title, test=test, severity=sev, numerical_severity=Finding.get_numerical_severity(sev)).all() if findings: finding = findings[0] if finding.mitigated: finding.mitigated = None finding.mitigated_by = None finding.active = True finding.verified = verified finding.save() note = Notes( entry="Re-activated by %s re-upload." % scan_type, author=self.context['request'].user) note.save() finding.notes.add(note) reactivated_count += 1 new_items.append(finding) else: item.test = test item.date = test.target_start item.reporter = self.context['request'].user item.last_reviewed = timezone.now() item.last_reviewed_by = self.context['request'].user item.verified = verified item.active = active item.save() finding_added_count += 1 new_items.append(item.id) finding = item if hasattr(item, 'unsaved_req_resp'): for req_resp in item.unsaved_req_resp: burp_rr = BurpRawRequestResponse( finding=finding, burpRequestBase64=req_resp['req'], burpResponseBase64=req_resp['resp']) burp_rr.clean() burp_rr.save() if item.unsaved_request and item.unsaved_response: burp_rr = BurpRawRequestResponse( finding=finding, burpRequestBase64=item.unsaved_request, burpResponseBase64=item.unsaved_response) burp_rr.clean() burp_rr.save() if finding: finding_count += 1 for endpoint in item.unsaved_endpoints: ep, created = Endpoint.objects.get_or_create( protocol=endpoint.protocol, host=endpoint.host, path=endpoint.path, query=endpoint.query, fragment=endpoint.fragment, product=test.engagement.product) finding.endpoints.add(ep) # if item.unsaved_tags: # finding.tags = item.unsaved_tags to_mitigate = set(original_items) - set(new_items) for finding in to_mitigate: finding.mitigated = datetime.datetime.combine( scan_date, timezone.now().time()) finding.mitigated_by = self.context['request'].user finding.active = False finding.save() note = Notes(entry="Mitigated by %s re-upload." % scan_type, author=self.context['request'].user) note.save() finding.notes.add(note) mitigated_count += 1 except SyntaxError: raise Exception("Parser SyntaxError") return test def validate_scan_data(self, value): if value.date() > datetime.today().date(): raise serializers.ValidationError( 'The date cannot be in the future!') return value
class SalesOrderLineItemSerializer(InvenTreeModelSerializer): """Serializer for a SalesOrderLineItem object.""" @staticmethod def annotate_queryset(queryset): """Add some extra annotations to this queryset: - "overdue" status (boolean field) - "available_quantity" """ queryset = queryset.annotate( overdue=Case( When( Q(order__status__in=SalesOrderStatus.OPEN) & order.models.SalesOrderLineItem.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()), ), default=Value(False, output_field=BooleanField()), ) ) # Annotate each line with the available stock quantity # To do this, we need to look at the total stock and any allocations queryset = queryset.alias( total_stock=part.filters.annotate_total_stock(reference='part__'), allocated_to_sales_orders=part.filters.annotate_sales_order_allocations(reference='part__'), allocated_to_build_orders=part.filters.annotate_build_order_allocations(reference='part__'), ) queryset = queryset.annotate( available_stock=ExpressionWrapper( F('total_stock') - F('allocated_to_sales_orders') - F('allocated_to_build_orders'), output_field=models.DecimalField() ) ) return queryset def __init__(self, *args, **kwargs): """Initializion routine for the serializer: - Add extra related serializer information if required """ part_detail = kwargs.pop('part_detail', False) order_detail = kwargs.pop('order_detail', False) allocations = kwargs.pop('allocations', False) super().__init__(*args, **kwargs) if part_detail is not True: self.fields.pop('part_detail') if order_detail is not True: self.fields.pop('order_detail') if allocations is not True: self.fields.pop('allocations') order_detail = SalesOrderSerializer(source='order', many=False, read_only=True) part_detail = PartBriefSerializer(source='part', many=False, read_only=True) allocations = SalesOrderAllocationSerializer(many=True, read_only=True, location_detail=True) # Annotated fields overdue = serializers.BooleanField(required=False, read_only=True) available_stock = serializers.FloatField(read_only=True) quantity = InvenTreeDecimalField() allocated = serializers.FloatField(source='allocated_quantity', read_only=True) shipped = InvenTreeDecimalField(read_only=True) sale_price = InvenTreeMoneySerializer( allow_null=True ) sale_price_string = serializers.CharField(source='sale_price', read_only=True) sale_price_currency = serializers.ChoiceField( choices=currency_code_mappings(), help_text=_('Sale price currency'), ) class Meta: """Metaclass options.""" model = order.models.SalesOrderLineItem fields = [ 'pk', 'allocated', 'allocations', 'available_stock', 'quantity', 'reference', 'notes', 'order', 'order_detail', 'overdue', 'part', 'part_detail', 'sale_price', 'sale_price_currency', 'sale_price_string', 'shipped', 'target_date', ]
class PurchaseOrderLineItemReceiveSerializer(serializers.Serializer): """A serializer for receiving a single purchase order line item against a purchase order.""" class Meta: """Metaclass options.""" fields = [ 'barcode', 'line_item', 'location', 'quantity', 'status', 'batch_code' 'serial_numbers', ] line_item = serializers.PrimaryKeyRelatedField( queryset=order.models.PurchaseOrderLineItem.objects.all(), many=False, allow_null=False, required=True, label=_('Line Item'), ) def validate_line_item(self, item): """Validation for the 'line_item' field""" if item.order != self.context['order']: raise ValidationError(_('Line item does not match purchase order')) return item location = serializers.PrimaryKeyRelatedField( queryset=stock.models.StockLocation.objects.all(), many=False, allow_null=True, required=False, label=_('Location'), help_text=_('Select destination location for received items'), ) quantity = serializers.DecimalField( max_digits=15, decimal_places=5, min_value=0, required=True, ) def validate_quantity(self, quantity): """Validation for the 'quantity' field""" if quantity <= 0: raise ValidationError(_("Quantity must be greater than zero")) return quantity batch_code = serializers.CharField( label=_('Batch Code'), help_text=_('Enter batch code for incoming stock items'), required=False, default='', allow_blank=True, ) serial_numbers = serializers.CharField( label=_('Serial Numbers'), help_text=_('Enter serial numbers for incoming stock items'), required=False, default='', allow_blank=True, ) status = serializers.ChoiceField( choices=list(StockStatus.items()), default=StockStatus.OK, label=_('Status'), ) barcode = serializers.CharField( label=_('Barcode Hash'), help_text=_('Unique identifier field'), default='', required=False, allow_null=True, allow_blank=True, ) def validate_barcode(self, barcode): """Cannot check in a LineItem with a barcode that is already assigned.""" # Ignore empty barcode values if not barcode or barcode.strip() == '': return None if stock.models.StockItem.objects.filter(uid=barcode).exists(): raise ValidationError(_('Barcode is already in use')) return barcode def validate(self, data): """Custom validation for the serializer: - Integer quantity must be provided for serialized stock - Validate serial numbers (if provided) """ data = super().validate(data) line_item = data['line_item'] quantity = data['quantity'] serial_numbers = data.get('serial_numbers', '').strip() base_part = line_item.part.part # Does the quantity need to be "integer" (for trackable parts?) if base_part.trackable: if Decimal(quantity) != int(quantity): raise ValidationError({ 'quantity': _('An integer quantity must be provided for trackable parts'), }) # If serial numbers are provided if serial_numbers: try: # Pass the serial numbers through to the parent serializer once validated data['serials'] = extract_serial_numbers(serial_numbers, quantity, base_part.getLatestSerialNumberInt()) except DjangoValidationError as e: raise ValidationError({ 'serial_numbers': e.messages, }) return data
class PurchaseOrderLineItemSerializer(InvenTreeModelSerializer): """Serializer class for the PurchaseOrderLineItem model""" @staticmethod def annotate_queryset(queryset): """Add some extra annotations to this queryset: - Total price = purchase_price * quantity - "Overdue" status (boolean field) """ queryset = queryset.annotate( total_price=ExpressionWrapper( F('purchase_price') * F('quantity'), output_field=models.DecimalField() ) ) queryset = queryset.annotate( overdue=Case( When( Q(order__status__in=PurchaseOrderStatus.OPEN) & order.models.PurchaseOrderLineItem.OVERDUE_FILTER, then=Value(True, output_field=BooleanField()) ), default=Value(False, output_field=BooleanField()), ) ) return queryset def __init__(self, *args, **kwargs): """Initialization routine for the serializer""" part_detail = kwargs.pop('part_detail', False) order_detail = kwargs.pop('order_detail', False) super().__init__(*args, **kwargs) if part_detail is not True: self.fields.pop('part_detail') self.fields.pop('supplier_part_detail') if order_detail is not True: self.fields.pop('order_detail') quantity = serializers.FloatField(min_value=0, required=True) def validate_quantity(self, quantity): """Validation for the 'quantity' field""" if quantity <= 0: raise ValidationError(_("Quantity must be greater than zero")) return quantity def validate_purchase_order(self, purchase_order): """Validation for the 'purchase_order' field""" if purchase_order.status not in PurchaseOrderStatus.OPEN: raise ValidationError(_('Order is not open')) return purchase_order received = serializers.FloatField(default=0, read_only=True) overdue = serializers.BooleanField(required=False, read_only=True) total_price = serializers.FloatField(read_only=True) part_detail = PartBriefSerializer(source='get_base_part', many=False, read_only=True) supplier_part_detail = SupplierPartSerializer(source='part', many=False, read_only=True) purchase_price = InvenTreeMoneySerializer( allow_null=True ) purchase_price_string = serializers.CharField(source='purchase_price', read_only=True) destination_detail = stock.serializers.LocationBriefSerializer(source='get_destination', read_only=True) purchase_price_currency = serializers.ChoiceField( choices=currency_code_mappings(), help_text=_('Purchase price currency'), ) order_detail = PurchaseOrderSerializer(source='order', read_only=True, many=False) def validate(self, data): """Custom validation for the serializer: - Ensure the supplier_part field is supplied - Ensure the purchase_order field is supplied - Ensure that the supplier_part and supplier references match """ data = super().validate(data) supplier_part = data.get('part', None) purchase_order = data.get('order', None) if not supplier_part: raise ValidationError({ 'part': _('Supplier part must be specified'), }) if not purchase_order: raise ValidationError({ 'order': _('Purchase order must be specified'), }) # Check that the supplier part and purchase order match if supplier_part is not None and supplier_part.supplier != purchase_order.supplier: raise ValidationError({ 'part': _('Supplier must match purchase order'), 'order': _('Purchase order must match supplier'), }) return data class Meta: """Metaclass options.""" model = order.models.PurchaseOrderLineItem fields = [ 'pk', 'quantity', 'reference', 'notes', 'order', 'order_detail', 'overdue', 'part', 'part_detail', 'supplier_part_detail', 'received', 'purchase_price', 'purchase_price_currency', 'purchase_price_string', 'destination', 'destination_detail', 'target_date', 'total_price', ]
class SetTimeZoneSerializer(serializers.Serializer): timezone = serializers.ChoiceField(choices=pytz.common_timezones)
class AppAccountSerializer(AppSerializerMixin, AuthSerializerMixin, BulkOrgResourceModelSerializer): category = serializers.ChoiceField(label=_('Category'), choices=const.AppCategory.choices, read_only=True) category_display = serializers.SerializerMethodField( label=_('Category display')) type = serializers.ChoiceField(label=_('Type'), choices=const.AppType.choices, read_only=True) type_display = serializers.SerializerMethodField(label=_('Type display')) date_created = serializers.DateTimeField(label=_('Date created'), format="%Y/%m/%d %H:%M:%S", read_only=True) date_updated = serializers.DateTimeField(label=_('Date updated'), format="%Y/%m/%d %H:%M:%S", read_only=True) category_mapper = dict(const.AppCategory.choices) type_mapper = dict(const.AppType.choices) class Meta: model = models.Account fields_mini = ['id', 'username', 'version'] fields_write_only = [ 'password', 'private_key', 'public_key', 'passphrase' ] fields_other = ['date_created', 'date_updated'] fields_fk = ['systemuser', 'systemuser_display', 'app', 'app_display'] fields = fields_mini + fields_fk + fields_write_only + fields_other + [ 'type', 'type_display', 'category', 'category_display', 'attrs' ] extra_kwargs = { 'username': { 'default': '', 'required': False }, 'password': { 'write_only': True }, 'app_display': { 'label': _('Application display') }, 'systemuser_display': { 'label': _('System User') } } use_model_bulk_create = True model_bulk_create_kwargs = {'ignore_conflicts': True} @property def app(self): if isinstance(self.instance, models.Account): instance = self.instance.app else: instance = None return instance def get_category_display(self, obj): return self.category_mapper.get(obj.category) def get_type_display(self, obj): return self.type_mapper.get(obj.type) @classmethod def setup_eager_loading(cls, queryset): """ Perform necessary eager loading of data. """ queryset = queryset.prefetch_related('systemuser', 'app') return queryset def to_representation(self, instance): instance.load_auth() return super().to_representation(instance)
class AccountSerializer(serializers.ModelSerializer): user = UserSerializer(required=True, partial=True) timezone = serializers.ChoiceField(required=True, choices=TIMEZONES) class Meta: model = SciriusUser fields = ('pk', 'user', 'timezone') def to_representation(self, instance): data = super(AccountSerializer, self).to_representation(instance) user = data.pop('user', None) if user is not None: user.pop('password', None) data.update(user) return data def to_internal_value(self, data): data = data.copy() timezone = data.pop('timezone', None) user_serializer = UserSerializer(data=data) user_serializer.is_valid(raise_exception=True) res = {'user': user_serializer.validated_data} if timezone is not None: res['timezone'] = timezone return res def create(self, validated_data): user_data = validated_data.pop('user') errors = {} if 'username' not in user_data: errors['username'] = ['This field is required.'] if 'password' not in user_data: errors['password'] = ['This field is required.'] if len(errors) > 0: raise serializers.ValidationError(errors) if 'timezone' not in validated_data: validated_data['timezone'] = 'UTC' if validated_data['timezone'] not in pytz.all_timezones: raise serializers.ValidationError( {'timezone': ['Not a valid choice.']}) password = user_data.pop('password') try: password_validation.validate_password(password=password, user=User) except exceptions.ValidationError as e: raise serializers.ValidationError({'password': [e.message]}) user = User.objects.create(**user_data) user.set_password(password) user.save() return SciriusUser.objects.create(user=user, **validated_data) def update(self, instance, validated_data): user_data = validated_data.pop('user') user = instance.user for key, value in user_data.items(): if key == 'password': raise serializers.ValidationError({ 'password': '******' }) if hasattr(user, key): setattr(user, key, value) timezone = validated_data.get('timezone', instance.timezone) if timezone not in pytz.all_timezones: # to avoid deadlock if instance.timezone not in pytz.all_timezones: instance.timezone = 'UTC' instance.save() raise serializers.ValidationError( {'timezone': ['Not a valid choice.']}) instance.timezone = timezone instance.save() user.save() return instance
class ResourceCreateRequestValidator(ResourceUpdateRequestValidator): resource_type = serializers.ChoiceField( choices=zip( [x.__name__ for x in hydroshare.get_resource_types()], [x.__name__ for x in hydroshare.get_resource_types()] ), default='GenericResource')
class ExperimentTimelinePopSerializer(ChangelogSerializerMixin, serializers.ModelSerializer): proposed_start_date = serializers.DateField(required=False, allow_null=True, default=None) proposed_duration = serializers.IntegerField(required=False, allow_null=True, default=None) proposed_enrollment = serializers.IntegerField(required=False, allow_null=True, default=None) rollout_playbook = serializers.ChoiceField( choices=ExperimentConstants.ROLLOUT_PLAYBOOK_CHOICES, required=False, allow_null=True, default=None, allow_blank=True, ) population_percent = serializers.DecimalField( required=False, max_digits=7, decimal_places=4, max_value=100.0000, min_value=0, allow_null=True, default=None, ) firefox_channel = serializers.ChoiceField( choices=ExperimentConstants.CHANNEL_CHOICES, required=False, allow_null=True, default=None, allow_blank=True, ) firefox_min_version = serializers.ChoiceField( choices=ExperimentConstants.VERSION_CHOICES, required=False, allow_null=True, default=None, allow_blank=True, ) firefox_max_version = serializers.ChoiceField( choices=ExperimentConstants.VERSION_CHOICES, required=False, allow_null=True, default=None, allow_blank=True, ) locales = LocaleSerializerMultiSelect(many=True, required=False, allow_null=True, default=None) countries = CountrySerializerMultiSelect(many=True, required=False, allow_null=True, default=None) platforms = serializers.ListField(child=PlatformsMultiSelectSerializer(), allow_empty=True, required=False) windows_versions = serializers.ListField( child=GenericMultiSelectSerializer(), allow_null=True, allow_empty=True, required=False, ) client_matching = serializers.CharField(required=False, allow_null=True, default=None, allow_blank=True) class Meta: fields = ( "proposed_start_date", "proposed_enrollment", "rollout_playbook", "proposed_duration", "population_percent", "firefox_channel", "firefox_min_version", "firefox_max_version", "locales", "countries", "platforms", "windows_versions", "profile_age", "client_matching", ) model = Experiment def validate_proposed_start_date(self, value): if value and value < datetime.date.today(): raise serializers.ValidationError( "The delivery start date must be no earlier than the current date." ) return value def validate_platforms(self, value): if value == []: raise serializers.ValidationError( "You must select at least one platform.") return value def validate(self, data): data = super().validate(data) if data["proposed_enrollment"] and data["proposed_duration"]: if data["proposed_enrollment"] >= data["proposed_duration"]: raise serializers.ValidationError({ "proposed_enrollment": ("Enrollment duration is optional," " but if set, must be lower than the delivery " "duration. If enrollment duration is not " "specified - users are enrolled for the" "entire delivery.") }) if data["firefox_min_version"] and data["firefox_max_version"]: if float(data["firefox_min_version"]) > float( data["firefox_max_version"]): raise serializers.ValidationError({ "firefox_max_version": ("The max version must be larger " "than or equal to the min version.") }) return data def update(self, instance, validated_data): countries_data = validated_data.pop("countries") locales_data = validated_data.pop("locales") instance = super().update(instance, validated_data) countries_list = [] if len(countries_data) > 0: countries_list = [int(country["id"]) for country in countries_data] instance.countries.set(countries_list) locales_list = [] if len(locales_data) > 0: locales_list = [int(locale["id"]) for locale in locales_data] instance.locales.set(locales_list) validated_data["countries"] = countries_list validated_data["locales"] = locales_list self.update_changelog(instance, validated_data) return instance
class BulkEditSerializer(DocumentListSerializer): method = serializers.ChoiceField( choices=[ "set_correspondent", "set_document_type", "add_tag", "remove_tag", "modify_tags", "delete" ], label="Method", write_only=True, ) parameters = serializers.DictField(allow_empty=True) def _validate_tag_id_list(self, tags, name="tags"): if not type(tags) == list: raise serializers.ValidationError(f"{name} must be a list") if not all([type(i) == int for i in tags]): raise serializers.ValidationError( f"{name} must be a list of integers") count = Tag.objects.filter(id__in=tags).count() if not count == len(tags): raise serializers.ValidationError( f"Some tags in {name} don't exist or were specified twice.") def validate_method(self, method): if method == "set_correspondent": return bulk_edit.set_correspondent elif method == "set_document_type": return bulk_edit.set_document_type elif method == "add_tag": return bulk_edit.add_tag elif method == "remove_tag": return bulk_edit.remove_tag elif method == "modify_tags": return bulk_edit.modify_tags elif method == "delete": return bulk_edit.delete else: raise serializers.ValidationError("Unsupported method.") def _validate_parameters_tags(self, parameters): if 'tag' in parameters: tag_id = parameters['tag'] try: Tag.objects.get(id=tag_id) except Tag.DoesNotExist: raise serializers.ValidationError("Tag does not exist") else: raise serializers.ValidationError("tag not specified") def _validate_parameters_document_type(self, parameters): if 'document_type' in parameters: document_type_id = parameters['document_type'] if document_type_id is None: # None is ok return try: DocumentType.objects.get(id=document_type_id) except DocumentType.DoesNotExist: raise serializers.ValidationError( "Document type does not exist") else: raise serializers.ValidationError("document_type not specified") def _validate_parameters_correspondent(self, parameters): if 'correspondent' in parameters: correspondent_id = parameters['correspondent'] if correspondent_id is None: return try: Correspondent.objects.get(id=correspondent_id) except Correspondent.DoesNotExist: raise serializers.ValidationError( "Correspondent does not exist") else: raise serializers.ValidationError("correspondent not specified") def _validate_parameters_modify_tags(self, parameters): if "add_tags" in parameters: self._validate_tag_id_list(parameters['add_tags'], "add_tags") else: raise serializers.ValidationError("add_tags not specified") if "remove_tags" in parameters: self._validate_tag_id_list(parameters['remove_tags'], "remove_tags") else: raise serializers.ValidationError("remove_tags not specified") def validate(self, attrs): method = attrs['method'] parameters = attrs['parameters'] if method == bulk_edit.set_correspondent: self._validate_parameters_correspondent(parameters) elif method == bulk_edit.set_document_type: self._validate_parameters_document_type(parameters) elif method == bulk_edit.add_tag or method == bulk_edit.remove_tag: self._validate_parameters_tags(parameters) elif method == bulk_edit.modify_tags: self._validate_parameters_modify_tags(parameters) return attrs
class RepoRequestSerializer(ReadOnlySerializer): operation = serializers.ChoiceField(choices=('commit', 'pull', 'push', 'reset', 'cleanup'))
class ParamsSerializer(serializers.Serializer): PROPERTY_TYPE_SF = 'SF' PROPERTY_TYPE_COOP = 'COOP' PROPERTY_TYPE_CONDO = 'CONDO' PROPERTY_TYPE_CHOICES = ( (PROPERTY_TYPE_SF, 'Single Family'), (PROPERTY_TYPE_COOP, 'Co-operative'), (PROPERTY_TYPE_CONDO, 'Condominum'), ) ARM_TYPE_3_1 = '3-1' ARM_TYPE_5_1 = '5-1' ARM_TYPE_7_1 = '7-1' ARM_TYPE_10_1 = '10-1' ARM_TYPE_CHOICES = ( (ARM_TYPE_3_1, '3/1 ARM'), (ARM_TYPE_5_1, '5/1 ARM'), (ARM_TYPE_7_1, '7/1 ARM'), (ARM_TYPE_10_1, '10/1 ARM'), ) # Default LOCK = 60 POINTS = 0 IO = 0 PROPERTY_TYPE = PROPERTY_TYPE_SF LOAN_PURPOSE = Product.PURCH lock = serializers.IntegerField(default=LOCK, required=False) min_lock = serializers.IntegerField(required=False) max_lock = serializers.IntegerField(required=False) points = serializers.IntegerField(default=POINTS, required=False) property_type = serializers.ChoiceField(choices=PROPERTY_TYPE_CHOICES, default=PROPERTY_TYPE, required=False) loan_purpose = serializers.ChoiceField( choices=Product.LOAN_PURPOSE_CHOICES, default=LOAN_PURPOSE, required=False) io = serializers.IntegerField(default=IO, required=False) institution = serializers.CharField(max_length=20, required=False) loan_amount = serializers.DecimalField(max_digits=12, decimal_places=2) price = serializers.DecimalField(max_digits=12, decimal_places=2) state = serializers.ChoiceField(choices=STATE_CHOICES) loan_type = serializers.ChoiceField(choices=Product.LOAN_TYPE_CHOICES) minfico = serializers.IntegerField() maxfico = serializers.IntegerField() rate_structure = serializers.ChoiceField( choices=Product.PAYMENT_TYPE_CHOICES) arm_type = serializers.ChoiceField(choices=ARM_TYPE_CHOICES, required=False) loan_term = serializers.IntegerField() ltv = serializers.DecimalField(max_digits=6, decimal_places=3, required=False) min_ltv = serializers.DecimalField(max_digits=6, decimal_places=3, required=False) max_ltv = serializers.DecimalField(max_digits=6, decimal_places=3, required=False) def validate(self, attrs): """ Validate parameters that are required due to the value of other parameters. """ if attrs['rate_structure'] == Product.ARM: if not attrs.get('arm_type'): raise serializers.ValidationError( "arm_type is required if rate_structure is ARM.") # @TODO: Maybe this is some kind of violation # Fill out the min/max ltv attrs['min_ltv'] = Decimal( "%f" % (attrs['loan_amount'] / attrs['price'] * 100)).quantize( Decimal('.001')) attrs['max_ltv'] = attrs['min_ltv'] if attrs.get('ltv') and abs(attrs['ltv'] - attrs['max_ltv']) < 1: attrs['max_ltv'] = attrs['min_ltv'] = attrs['ltv'] # Fix the min/max ltv attrs['minfico'] = abs(attrs['minfico']) attrs['maxfico'] = abs(attrs['maxfico']) if attrs['minfico'] > attrs['maxfico']: attrs['minfico'], attrs['maxfico'] = attrs['maxfico'], attrs[ 'minfico'] return attrs def validate_price(self, attrs, source): """ Validate price and convert to positive if negative """ if attrs[source] < 0: attrs[source] = abs(attrs[source]) return attrs def validate_lock(self, attrs, source): """ Check that the lock is 30, 45, or 60 """ # @TODO maybe there's a better way to do this with integer choice? if attrs[source] not in (30, 45, 60): raise serializers.ValidationError( "lock needs to be 30, 45, or 60.") # @TODO: Maybe this is some kind of violation locks = {30: (0, 30), 45: (31, 45), 60: (46, 60)} attrs['min_lock'], attrs['max_lock'] = locks.get(attrs[source]) return attrs def validate_io(self, attrs, source): """ Check that the io is 0 or 1 """ # @TODO maybe there's a better way to do this with integer choice? if attrs[source] not in (0, 1): raise serializers.ValidationError("io needs to be 0 or 1.") return attrs def validate_loan_amount(self, attrs, source): """ Change loan amount to positive if negative """ if attrs[source] < 0: attrs[source] = abs(attrs[source]) return attrs def validate_loan_term(self, attrs, source): """ Check that loan term is 15 or 30 """ # @TODO maybe there's a better way to do this with integer choice? if attrs[source] < 0: attrs[source] = abs(attrs[source]) if attrs[source] not in (15, 30): raise serializers.ValidationError( "loan_term needs to be 15 or 30.") return attrs
class ExportRegexesRequestSerializer(serializers.Serializer): file_type = serializers.ChoiceField(choices=['csv'], required=True)
class BadgeCreateSerializer(serializers.Serializer): user = serializers.SlugField( required=True, write_only=True, ) type_of = serializers.ChoiceField( required=True, allow_null=False, choices=Badge.TYPE_OF_CHOICES, write_only=True, ) type_of_other = serializers.CharField( #TODO: Required if ```type_of == 1```. required=False, allow_blank=True, allow_null=True, write_only=True, ) description_other = serializers.CharField( #TODO: Required if ```type_of == 1```. required=False, allow_blank=True, allow_null=True, write_only=True, ) icon = serializers.CharField( #TODO: Required if ```type_of == 1```. required=False, allow_blank=True, allow_null=True, write_only=True, ) colour = serializers.CharField( #TODO: Required if ```type_of == 1```. required=False, allow_blank=True, allow_null=True, write_only=True, ) # tags = serializers.PrimaryKeyRelatedField(many=True, queryset=Tag.objects.all(), allow_null=True, write_only=True,) def validate_user(self, value): #TODO: ADD SECURITY SO NON-EXECUTIVES CANNOT ATTACH TO OTHER USERS. if not SharedUser.objects.filter(slug=value).exists(): raise serializers.ValidationError("User does not exist") return value # def validate_organization_name(self, value): # """ # Custom validation to handle case of user selecting an organization type # of member but then forgetting to fill in the `organization_name` field. # """ # request = self.context.get('request') # type_of = request.data.get('type_of') # if type_of == Badge.MEMBER_TYPE_OF.BUSINESS: # if value == None or value == "": # raise serializers.ValidationError(_('Please fill this field in.')) # return value def create(self, validated_data): """ Override the `create` function to add extra functinality. """ slug = validated_data.get('user') user = SharedUser.objects.get(slug=slug) request = self.context.get("request") type_of = validated_data.get('type_of') type_of_other = validated_data.get('type_of_other', "") description_other = validated_data.get('description_other', "") icon = validated_data.get('icon', "") colour = validated_data.get('colour', "") if type_of == Badge.TYPE_OF.SUPPORTER: icon = "donate" colour = "green" badge = Badge.objects.create( user=user, type_of=type_of, type_of_other=type_of_other, description_other=description_other, icon=icon, colour=colour, ) logger.info("Awarded score points to the user\'s account.") tags = validated_data.get('tags', None) if tags is not None: if len(tags) > 0: badge.tags.set(tags) logger.info("Awarded score has tags attached to it.") # raise serializers.ValidationError({ # Uncomment when not using this code but do not delete! # "error": "Terminating for debugging purposes only." # }) return badge
class NodeContributorsSerializer(JSONAPISerializer): """ Separate from UserSerializer due to necessity to override almost every field as read only """ filterable_fields = frozenset([ 'full_name', 'given_name', 'middle_names', 'family_name', 'id', 'bibliographic', 'permissions' ]) id = IDField(source='_id', required=True) type = TypeField() full_name = ser.CharField(source='fullname', read_only=True, help_text='Display name used in the general user interface') given_name = ser.CharField(read_only=True, help_text='For bibliographic citations') middle_names = ser.CharField(read_only=True, help_text='For bibliographic citations') family_name = ser.CharField(read_only=True, help_text='For bibliographic citations') suffix = ser.CharField(read_only=True, help_text='For bibliographic citations') date_registered = ser.DateTimeField(read_only=True) bibliographic = ser.BooleanField(help_text='Whether the user will be included in citations for this node or not.', default=True) permission = ser.ChoiceField(choices=osf_permissions.PERMISSIONS, required=False, allow_null=True, default=osf_permissions.reduce_permissions(osf_permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS), help_text='User permission level. Must be "read", "write", or "admin". Defaults to "write".') links = LinksField({ 'html': 'absolute_url', 'self': 'get_absolute_url' }) nodes = JSONAPIHyperlinkedIdentityField(view_name='users:user-nodes', lookup_field='pk', lookup_url_kwarg='user_id', link_type='related') profile_image_url = ser.SerializerMethodField(required=False, read_only=True) def get_profile_image_url(self, user): size = self.context['request'].query_params.get('profile_image_size') return user.profile_image_url(size=size) class Meta: type_ = 'contributors' def absolute_url(self, obj): return obj.absolute_url def get_absolute_url(self, obj): node_id = self.context['request'].parser_context['kwargs']['node_id'] return absolute_reverse( 'nodes:node-contributor-detail', kwargs={ 'node_id': node_id, 'user_id': obj._id } ) def create(self, validated_data): auth = Auth(self.context['request'].user) node = self.context['view'].get_node() contributor = get_object_or_error(User, validated_data['_id'], display_name='user') # Node object checks for contributor existence but can still change permissions anyway if contributor in node.contributors: raise exceptions.ValidationError('{} is already a contributor'.format(contributor.fullname)) bibliographic = validated_data['bibliographic'] permissions = osf_permissions.expand_permissions(validated_data.get('permission')) or osf_permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS node.add_contributor(contributor=contributor, auth=auth, visible=bibliographic, permissions=permissions, save=True) contributor.permission = osf_permissions.reduce_permissions(node.get_permissions(contributor)) contributor.bibliographic = node.get_visible(contributor) contributor.node_id = node._id return contributor
class WritableAccountSerializer(AccountSerializer): """Serializer to create account.""" random_password = serializers.BooleanField(default=False) role = serializers.ChoiceField(choices=core_constants.ROLES) password = serializers.CharField(required=False) class Meta(AccountSerializer.Meta): fields = AccountSerializer.Meta.fields + ("password", "random_password") def __init__(self, *args, **kwargs): """Adapt fields to current user.""" super(WritableAccountSerializer, self).__init__(*args, **kwargs) request = self.context.get("request") if not request: return user = self.context["request"].user self.fields["role"] = serializers.ChoiceField( choices=permissions.get_account_roles(user)) self.fields["domains"] = serializers.ListField( child=serializers.CharField(), allow_empty=False, required=False) def validate(self, data): """Check constraints.""" master_user = data.get("master_user", False) role = data.get("role") if master_user and role != "SuperAdmins": raise serializers.ValidationError( {"master_user": _("Not allowed for this role.")}) if role == "SimpleUsers": mailbox = data.get("mailbox") if mailbox is None: if not self.instance: data["mailbox"] = { "full_address": data["username"], "use_domain_quota": True } elif mailbox["full_address"] != data["username"]: raise serializers.ValidationError( {"username": _("Must be equal to mailbox full_address")}) if not data.get("random_password"): password = data.get("password") if password: try: password_validation.validate_password( data["password"], self.instance) except ValidationError as exc: raise serializers.ValidationError( {"password": exc.messages[0]}) elif not self.instance: raise serializers.ValidationError( {"password": _("This field is required.")}) domain_names = data.get("domains") if not domain_names: return data domains = [] for name in domain_names: domain = admin_models.Domain.objects.filter(name=name).first() if domain: domains.append(domain) continue raise serializers.ValidationError( {"domains": _("Local domain {} does not exist").format(name)}) data["domains"] = domains return data def _create_mailbox(self, creator, account, data): """Create a new Mailbox instance.""" full_address = data.pop("full_address") address, domain_name = email_utils.split_mailbox(full_address) domain = get_object_or_404(admin_models.Domain, name=domain_name) if not creator.can_access(domain): raise serializers.ValidationError( {"domain": _("Permission denied.")}) try: core_signals.can_create_object.send(sender=self.__class__, context=creator, klass=admin_models.Mailbox) core_signals.can_create_object.send(sender=self.__class__, context=domain, object_type="mailboxes") except lib_exceptions.ModoboaException as inst: raise serializers.ValidationError({"domain": force_text(inst)}) quota = data.pop("quota", None) mb = admin_models.Mailbox(user=account, address=address, domain=domain, **data) mb.set_quota(quota, creator.has_perm("admin.add_domain")) mb.save(creator=creator) account.email = full_address return mb def set_permissions(self, account, domains): """Assign permissions on domain(s).""" if account.role not in ["DomainAdmins", "Resellers"]: return current_domains = admin_models.Domain.objects.get_for_admin(account) for domain in current_domains: if domain not in domains: domain.remove_admin(account) else: domains.remove(domain) for domain in domains: domain.add_admin(account) def create(self, validated_data): """Create appropriate objects.""" creator = self.context["request"].user mailbox_data = validated_data.pop("mailbox", None) role = validated_data.pop("role") domains = validated_data.pop("domains", []) random_password = validated_data.pop("random_password", False) user = core_models.User(**validated_data) if random_password: password = lib.make_password() else: password = validated_data.pop("password") user.set_password(password) if "language" not in validated_data: user.language = settings.LANGUAGE_CODE user.save(creator=creator) if mailbox_data: self._create_mailbox(creator, user, mailbox_data) user.role = role self.set_permissions(user, domains) return user def update(self, instance, validated_data): """Update account and associated objects.""" mailbox_data = validated_data.pop("mailbox", None) password = validated_data.pop("password", None) domains = validated_data.pop("domains", []) for key, value in validated_data.items(): setattr(instance, key, value) if password: instance.set_password(password) if mailbox_data: creator = self.context["request"].user if instance.mailbox: if "full_address" in mailbox_data: # FIXME: compat, to remove ASAP. mailbox_data["email"] = mailbox_data["full_address"] instance.email = mailbox_data["full_address"] instance.mailbox.update_from_dict(creator, mailbox_data) else: self._create_mailbox(creator, instance, mailbox_data) instance.save() self.set_permissions(instance, domains) return instance
class TestSerializer(serializers.Serializer): test_field = serializers.ChoiceField(choices=choices, initial=2)
class BaseRegistrationSerializer(NodeSerializer): title = ser.CharField(read_only=True) description = ser.CharField(read_only=True) category_choices = NodeSerializer.category_choices category_choices_string = NodeSerializer.category_choices_string category = HideIfWithdrawal( ser.ChoiceField(read_only=True, choices=category_choices, help_text='Choices: ' + category_choices_string)) date_modified = VersionedDateTimeField(source='last_logged', read_only=True) fork = HideIfWithdrawal(ser.BooleanField(read_only=True, source='is_fork')) collection = HideIfWithdrawal( ser.BooleanField(read_only=True, source='is_collection')) access_requests_enabled = HideIfWithdrawal( ser.BooleanField(read_only=True)) node_license = HideIfWithdrawal(NodeLicenseSerializer(read_only=True)) tags = HideIfWithdrawal( ValuesListField(attr_name='name', child=ser.CharField(), required=False)) public = HideIfWithdrawal( ser.BooleanField( source='is_public', required=False, help_text='Nodes that are made public will give read-only access ' 'to everyone. Private nodes require explicit read ' 'permission. Write and admin access are the same for ' 'public and private nodes. Administrators on a parent ' 'node have implicit read permissions for all child nodes')) current_user_permissions = HideIfWithdrawal( ser.SerializerMethodField( help_text='List of strings representing the permissions ' 'for the current user on this node.')) pending_embargo_approval = HideIfWithdrawal( ser.BooleanField( read_only=True, source='is_pending_embargo', help_text= 'The associated Embargo is awaiting approval by project admins.')) pending_registration_approval = HideIfWithdrawal( ser.BooleanField( source='is_pending_registration', read_only=True, help_text= 'The associated RegistrationApproval is awaiting approval by project admins.' )) pending_withdrawal = HideIfWithdrawal( ser.BooleanField( source='is_pending_retraction', read_only=True, help_text= 'The registration is awaiting withdrawal approval by project admins.' )) withdrawn = ser.BooleanField( source='is_retracted', read_only=True, help_text='The registration has been withdrawn.') date_registered = VersionedDateTimeField( source='registered_date', read_only=True, help_text='Date time of registration.') date_withdrawn = VersionedDateTimeField( source='retraction.date_retracted', read_only=True, help_text='Date time of when this registration was retracted.') embargo_end_date = HideIfWithdrawal( ser.SerializerMethodField( help_text='When the embargo on this registration will be lifted.')) withdrawal_justification = ser.CharField(source='retraction.justification', read_only=True) template_from = HideIfWithdrawal( ser.CharField( read_only=True, allow_blank=False, allow_null=False, help_text= 'Specify a node id for a node you would like to use as a template for the ' 'new node. Templating is like forking, except that you do not copy the ' 'files, only the project structure. Some information is changed on the top ' 'level project by submitting the appropriate fields in the request body, ' 'and some information will not change. By default, the description will ' 'be cleared and the project will be made private.')) registration_supplement = ser.SerializerMethodField() registered_meta = HideIfWithdrawal( ser.SerializerMethodField( help_text= 'A dictionary with supplemental registration questions and responses.' )) registered_by = HideIfWithdrawal( RelationshipField( related_view='users:user-detail', related_view_kwargs={'user_id': '<registered_user._id>'})) registered_from = HideIfWithdrawal( RelationshipField( related_view='nodes:node-detail', related_view_kwargs={'node_id': '<registered_from._id>'})) children = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-children', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_node_count'}, )) comments = HideIfWithdrawal( RelationshipField(related_view='registrations:registration-comments', related_view_kwargs={'node_id': '<_id>'}, related_meta={'unread': 'get_unread_comments_count'}, filter={'target': '<_id>'})) contributors = RelationshipField( related_view='registrations:registration-contributors', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_contrib_count'}) implicit_contributors = RelationshipField( related_view='registrations:registration-implicit-contributors', related_view_kwargs={'node_id': '<_id>'}, help_text= 'This feature is experimental and being tested. It may be deprecated.') files = HideIfWithdrawal( RelationshipField(related_view='registrations:registration-providers', related_view_kwargs={'node_id': '<_id>'})) wikis = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-wikis', related_view_kwargs={'node_id': '<_id>'}, )) forked_from = HideIfWithdrawal( RelationshipField( related_view=lambda n: 'registrations:registration-detail' if getattr(n, 'is_registration', False) else 'nodes:node-detail', related_view_kwargs={'node_id': '<forked_from_id>'})) template_node = HideIfWithdrawal( RelationshipField( related_view='nodes:node-detail', related_view_kwargs={'node_id': '<template_node._id>'})) license = HideIfWithdrawal( RelationshipField( related_view='licenses:license-detail', related_view_kwargs={ 'license_id': '<node_license.node_license._id>' }, )) logs = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-logs', related_view_kwargs={'node_id': '<_id>'}, )) forks = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-forks', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_forks_count'}, )) node_links = ShowIfVersion(HideIfWithdrawal( RelationshipField( related_view='registrations:registration-pointers', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_pointers_count'}, help_text= 'This feature is deprecated as of version 2.1. Use linked_nodes instead.' )), min_version='2.0', max_version='2.0') linked_by_nodes = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-linked-by-nodes', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_linked_by_nodes_count'}, )) linked_by_registrations = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-linked-by-registrations', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_linked_by_registrations_count'}, )) parent = HideIfWithdrawal( RelationshipField(related_view='registrations:registration-detail', related_view_kwargs={'node_id': '<parent_node._id>'}, filter_key='parent_node')) root = HideIfWithdrawal( RelationshipField(related_view='registrations:registration-detail', related_view_kwargs={'node_id': '<root._id>'})) affiliated_institutions = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-institutions', related_view_kwargs={'node_id': '<_id>'})) registration_schema = RelationshipField( related_view='schemas:registration-schema-detail', related_view_kwargs={'schema_id': '<registered_schema_id>'}) settings = HideIfRegistration( RelationshipField(related_view='nodes:node-settings', related_view_kwargs={'node_id': '<_id>'})) registrations = HideIfRegistration( RelationshipField(related_view='nodes:node-registrations', related_view_kwargs={'node_id': '<_id>'})) draft_registrations = HideIfRegistration( RelationshipField(related_view='nodes:node-draft-registrations', related_view_kwargs={'node_id': '<_id>'})) preprints = HideIfWithdrawal( HideIfRegistration( RelationshipField(related_view='nodes:node-preprints', related_view_kwargs={'node_id': '<_id>'}))) identifiers = HideIfWithdrawal( RelationshipField(related_view='registrations:identifier-list', related_view_kwargs={'node_id': '<_id>'})) linked_nodes = HideIfWithdrawal( RelationshipField(related_view='registrations:linked-nodes', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_node_links_count'}, self_view='registrations:node-pointer-relationship', self_view_kwargs={'node_id': '<_id>'})) linked_registrations = HideIfWithdrawal( RelationshipField( related_view='registrations:linked-registrations', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_registration_links_count'}, self_view='registrations:node-registration-pointer-relationship', self_view_kwargs={'node_id': '<_id>'})) view_only_links = HideIfWithdrawal( RelationshipField( related_view='registrations:registration-view-only-links', related_view_kwargs={'node_id': '<_id>'}, related_meta={'count': 'get_view_only_links_count'}, )) citation = HideIfWithdrawal( RelationshipField(related_view='registrations:registration-citation', related_view_kwargs={'node_id': '<_id>'})) links = LinksField({ 'self': 'get_registration_url', 'html': 'get_absolute_html_url' }) def get_registration_url(self, obj): return absolute_reverse( 'registrations:registration-detail', kwargs={ 'node_id': obj._id, 'version': self.context['request'].parser_context['kwargs']['version'] }) def get_absolute_url(self, obj): return self.get_registration_url(obj) def create(self, validated_data): auth = get_user_auth(self.context['request']) draft = validated_data.pop('draft') registration_choice = validated_data.pop('registration_choice', 'immediate') embargo_lifted = validated_data.pop('lift_embargo', None) reviewer = is_prereg_admin_not_project_admin(self.context['request'], draft) try: draft.validate_metadata(metadata=draft.registration_metadata, reviewer=reviewer, required_fields=True) except ValidationValueError as e: raise exceptions.ValidationError(e.message) registration = draft.register(auth, save=True) if registration_choice == 'embargo': if not embargo_lifted: raise exceptions.ValidationError( 'lift_embargo must be specified.') embargo_end_date = embargo_lifted.replace(tzinfo=pytz.utc) try: registration.embargo_registration(auth.user, embargo_end_date) except ValidationError as err: raise exceptions.ValidationError(err.message) else: try: registration.require_approval(auth.user) except NodeStateError as err: raise exceptions.ValidationError(err) registration.save() return registration def get_registered_meta(self, obj): if obj.registered_meta: meta_values = obj.registered_meta.values()[0] try: return json.loads(meta_values) except TypeError: return meta_values except ValueError: return meta_values return None def get_embargo_end_date(self, obj): if obj.embargo_end_date: return obj.embargo_end_date return None def get_registration_supplement(self, obj): if obj.registered_schema: schema = obj.registered_schema.first() if schema is None: return None return schema.name return None def get_current_user_permissions(self, obj): return NodeSerializer.get_current_user_permissions(self, obj) def get_view_only_links_count(self, obj): return obj.private_links.filter(is_deleted=False).count() def update(self, registration, validated_data): auth = Auth(self.context['request'].user) # Update tags if 'tags' in validated_data: new_tags = validated_data.pop('tags', []) try: registration.update_tags(new_tags, auth=auth) except NodeStateError as err: raise Conflict(err.message) is_public = validated_data.get('is_public', None) if is_public is not None: if is_public: try: registration.update(validated_data, auth=auth) except NodeUpdateError as err: raise exceptions.ValidationError(err.reason) except NodeStateError as err: raise exceptions.ValidationError(err.message) else: raise exceptions.ValidationError( 'Registrations can only be turned from private to public.') return registration class Meta: type_ = 'registrations'
class FileInfoSerializer(serializers.Serializer): name = serializers.CharField(max_length=1024) type = serializers.ChoiceField(choices=["REG", "DIR"])
class TemporarySerializer(serializers.Serializer): field_1 = serializers.CharField() field_2 = serializers.ChoiceField(choices=("choice_1", "choice_2"))