Пример #1
0
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
Пример #2
0
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
Пример #3
0
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)
Пример #5
0
class CloseOrderSerializer(serializers.Serializer):
    new_status = serializers.ChoiceField(choices=(('Closed', 'Closed')))
    guest_money = serializers.IntegerField(min_value=0)
Пример #6
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])
Пример #7
0
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.')
Пример #8
0
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
Пример #9
0
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')
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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',
        ]
Пример #13
0
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
Пример #14
0
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',
        ]
Пример #15
0
class SetTimeZoneSerializer(serializers.Serializer):
    timezone = serializers.ChoiceField(choices=pytz.common_timezones)
Пример #16
0
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)
Пример #17
0
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')
Пример #19
0
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
Пример #20
0
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
Пример #21
0
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
Пример #23
0
class ExportRegexesRequestSerializer(serializers.Serializer):
    file_type = serializers.ChoiceField(choices=['csv'], required=True)
Пример #24
0
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
Пример #25
0
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
Пример #26
0
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
Пример #27
0
 class TestSerializer(serializers.Serializer):
     test_field = serializers.ChoiceField(choices=choices, initial=2)
Пример #28
0
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'
Пример #29
0
class FileInfoSerializer(serializers.Serializer):
    name = serializers.CharField(max_length=1024)
    type = serializers.ChoiceField(choices=["REG", "DIR"])
Пример #30
0
class TemporarySerializer(serializers.Serializer):
    field_1 = serializers.CharField()
    field_2 = serializers.ChoiceField(choices=("choice_1", "choice_2"))