def validate(self, attrs): if attrs.get('approved', None): if not all(perm in attrs for perm in PERMISSION_FIELD_LIST): raise serializers.ValidationError( 'Full list of permissions must be passed in request for approval' ) # Validate that request does not have ALL PermissionLevel.NONE current_permissions = { perm: getattr(self.instance, perm) if self.instance else PermissionLevel.NONE for perm in PERMISSION_FIELD_LIST } updated_permissions = { **current_permissions, **{ field: attrs[field] for field in attrs if field.endswith('_permission') } } if (updated_permissions['tags_permission'] > PermissionLevel.NONE and updated_permissions['shipment_permission'] == PermissionLevel.NONE): raise serializers.ValidationError( 'Cannot request to view tags without shipment read access') for field in updated_permissions: if updated_permissions[field] != PermissionLevel.NONE: return attrs raise serializers.ValidationError( "Access requests must contain at least one requested permission")
def initial(self, request, *args, **kwargs): ret = super().initial(request, *args, **kwargs) lookup_key = self.lookup_url_kwarg or self.lookup_field if lookup_key not in self.kwargs: return ret lookup = self.kwargs[lookup_key] expected_model = self.get_serializer_class().Meta.model # Decode id's before the all the internal dispatching try: model, id = IDObfuscator().decode(lookup) except InvalidID: if re.fullmatch(r'\d+', lookup): # Allow primary keys for debugging convenience. # Mabye remove if people start abusing this to harvest by sequential PK. return ret raise serializers.ValidationError('Invalid ID') if not issubclass(expected_model, model): raise serializers.ValidationError('Invalid ID') self.kwargs[lookup_key] = str(id) return ret
def get_object(self): queryset = self.filter_queryset(self.get_queryset(False)) # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( 'Expected view %s to be called with a URL keyword argument ' 'named "%s". Fix your URL conf, or set the `.lookup_field` ' 'attribute on the view correctly.' % (self.__class__.__name__, lookup_url_kwarg)) try: (model, decoded_pk) = IDObfuscator.decode(self.kwargs[lookup_url_kwarg]) concrete_model = self.serializer_class.Meta.model._meta.concrete_model if model is not concrete_model: raise serializers.ValidationError( 'The specified ID refers to an {}. Expected {}'.format( model._meta.model_name, concrete_model._meta.model_name)) except InvalidID: raise serializers.ValidationError('Invalid ID') filter_kwargs = {self.lookup_field: decoded_pk} obj = get_object_or_404(queryset, **filter_kwargs) # May raise a permission denied self.check_object_permissions(self.request, obj) return obj
def validate_geometry(self, value): if not isinstance(value, Point): raise serializers.ValidationError('Location.geometry must be of type Point') if not value.coords: raise serializers.ValidationError('Location.geometry must include coordinates') if abs(value.coords[0]) > 180: raise serializers.ValidationError('Location.geometry longitude is out of range (-180, 180)') if abs(value.coords[1]) > 90: raise serializers.ValidationError('Location.geometry latitude is out of range (-90, 90)') return value
def _fetch_icon_file(self, icon_url): try: r = requests.get(icon_url, timeout=5) header_type = r.headers['content-type'].split(';')[0].lower() if header_type not in self.VALID_ICON_TYPES: raise serializers.ValidationError('Invalid image type.') return ContentFile(r.content) except Exception as e: logger.warning('Exception occured while downloading icon %s', e) raise serializers.ValidationError( 'Could not download/process image.')
def validate_nombre(self, nombre): nombre = nombre.lower() if Servicio.objects.activos().filter(nombre=nombre).exists(): raise serializers.ValidationError( 'El servicio {} ya existe'.format(nombre)) if nombre.startswith(LISTA_NOMBRE_NO_PERMITIDOS): raise serializers.ValidationError( 'El nombre indicado comienza con un valor no permitido') return nombre
def validate_tags(self, tags): tag_list = set() for tag_dict in tags: if 'tag_value' not in tag_dict or 'tag_type' not in tag_dict: raise serializers.ValidationError('Tags items must contain `tag_value` and `tag_type`.') tag_list.add(tuple(tag_dict.items())) if len(tags) != len(tag_list): raise serializers.ValidationError('Tags field cannot contain duplicates') return tags
def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) log_metric('transmission.info', tags={ 'method': 'transaction.list', 'module': __name__ }) shipment_pk = kwargs.get('shipment_pk', None) if shipment_pk: LOG.debug(f'Getting transactions for shipment: {shipment_pk}.') queryset = queryset.filter(shipment__id=shipment_pk) else: LOG.debug('Getting tx details filtered by wallet address.') if not settings.PROFILES_ENABLED: if 'wallet_address' not in self.request.query_params: raise serializers.ValidationError( 'wallet_address required in query parameters') from_address = self.request.query_params.get('wallet_address') else: if 'wallet_id' not in self.request.query_params: raise serializers.ValidationError( 'wallet_id required in query parameters') wallet_id = self.request.query_params.get('wallet_id') wallet_response = settings.REQUESTS_SESSION.get( f'{settings.PROFILES_URL}/api/v1/wallet/{wallet_id}/?is_active', headers={ 'Authorization': f'JWT {get_jwt_from_request(request)}' }) if not wallet_response.status_code == status.HTTP_200_OK: raise serializers.ValidationError( 'Error retrieving Wallet from ShipChain Profiles') wallet_details = wallet_response.json() from_address = wallet_details['data']['attributes']['address'] queryset = queryset.filter( transactionreceipt__from_address__iexact=from_address) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
def validate(self, data): # The `validate` method is where we make sure that the current # instance of `LoginSerializer` has "valid". In the case of logging a # user in, this means validating that they've provided an email # and password and that this combination matches one of the users in # our database. email = data.get('email', None) password = data.get('password', None) # As mentioned above, an email is required. Raise an exception if an # email is not provided. if email is None: raise serializers.ValidationError( 'An email address is required to log in.' ) # As mentioned above, a password is required. Raise an exception if a # password is not provided. if password is None: raise serializers.ValidationError( 'A password is required to log in.' ) # The `authenticate` method is provided by Django and handles checking # for a user that matches this email/password combination. Notice how # we pass `email` as the `username` value. Remember that, in our User # model, we set `USERNAME_FIELD` as `email`. user = authenticate(username=email, password=password) # If no user was found matching this email/password combination then # `authenticate` will return `None`. Raise an exception in this case. if user is None: raise serializers.ValidationError( 'A user with this email and password was not found.' ) # Django provides a flag on our `User` model called `is_active`. The # purpose of this flag to tell us whether the user has been banned # or otherwise deactivated. This will almost never be the case, but # it is worth checking for. Raise an exception in this case. if not user.is_active: raise serializers.ValidationError( 'This user has been deactivated.' ) # The `validate` method should return a dictionary of validated data. # This is the data that is passed to the `create` and `update` methods # that we will see later on. return user
def validate(self, data): # Check current password if not data['user'].check_password(data['current_password']): raise serializers.ValidationError( 'Current password is not correct' ) # Perform server side validation if data['password'] != data['confirm_password']: raise serializers.ValidationError( 'Password and Confirm Password should be the same' ) return data
def validate(self, attrs): """ Object level validation method for TaskSerializer """ if not self.instance: attrs = self._validate_new(attrs) # If end date is present we validate that it is greater than start_date if attrs.get('end') is not None: # If end date is lesser than the start date raise an error the_start = attrs.get('start') if the_start is None and self.instance is not None: the_start = self.instance.start if not the_start: raise serializers.ValidationError( {'start': INVALID_START_DATE}) if attrs['end'] < the_start: raise serializers.ValidationError({'end': INVALID_END_DATE}) # if status is active and end date is in the past raise an error if attrs['end'] < timezone.now() and\ attrs.get('status') == Task.ACTIVE: raise serializers.ValidationError({'end': PAST_END_DATE}) # If start date is present and this is an existing object, we validate # that the start date is not greater than the existing end date if attrs.get('start') is not None and self.instance is not None\ and self.instance.end is not None and attrs.get('start') >\ self.instance.end: raise serializers.ValidationError({'start': INVALID_START_DATE}) # set automated statuses # scheduled => tasks which start in the future if attrs.get('start') and attrs.get('start') > timezone.now(): attrs['status'] = Task.SCHEDULED # draft => tasks with no form target_object_id = attrs.get('target_object_id') if target_object_id is None and self.instance is not None: target_object_id = self.instance.target_object_id if target_object_id is None: attrs['status'] = Task.DRAFT return super().validate(attrs)
def validate(self, attrs): """ Validate target id """ if self.instance is not None: # we are doing an update target_id = attrs.get('target_object_id', self.instance.target_object_id) target_model_contenttype = attrs.get( 'target_content_type', self.instance.target_content_type) else: # we are creating a new object target_id = attrs.get('target_object_id') target_model_contenttype = attrs.get('target_content_type') # Target_id is not required as such this may be none # If target_id is none there is no need to validate it if target_id is not None: target_model_class = target_model_contenttype.model_class() try: target_model_class.objects.get(pk=target_id) except target_model_class.DoesNotExist: raise serializers.ValidationError( {'target_id': TARGET_DOES_NOT_EXIST}) return attrs return attrs
def validate(self, data): if self.instance: user = self.instance else: user = User(**data) password = data.get('password') if password is None: # if password is None it means it is not required return super(UserSerializer, self).validate(data) errors = dict() try: validators.validate_password(password=password, user=user) except core_exceptions.ValidationError as e: errors['password'] = list(e.messages) except Exception as e: raise e if self.instance and \ not self.instance.check_password(data.get('old_password')): errors['old_password'] = _('Old password isn\'t valid.') if errors: raise serializers.ValidationError(errors) return super(UserSerializer, self).validate(data)
def validate_medicamento(self, medicamento): try: MedicamentoAntecedenteSugerido.objects.get(pk=medicamento) return medicamento except MedicamentoAntecedenteSugerido.DoesNotExist: raise serializers.ValidationError( 'El medicamento ingresado no existe.')
def _process_request(self, request, update_instance=None): data = deepcopy(request.data) if 'profile' in data and data['profile'] == 'flow-results-package': data['profile'] = 'data-package' descriptor = BytesIO(json.dumps(data).encode('utf-8')) descriptor.seek(0, os.SEEK_END) floip_file = InMemoryUploadedFile(descriptor, 'floip_file', request.data.get('name') + '.json', 'application/json', descriptor.tell(), charset=None) kwargs = { 'user': request.user, 'post': None, 'files': { 'floip_file': floip_file }, 'owner': request.user, } if update_instance: kwargs['id_string'] = update_instance.id_string kwargs['project'] = update_instance.project instance = do_publish_xlsform(**kwargs) if isinstance(instance, XForm): return instance raise serializers.ValidationError(instance)
def validate_geofences(self, geofences): for geofence in geofences: if not validate_uuid4(geofence): raise serializers.ValidationError(f'Invalid UUIDv4 {geofence} provided in Geofences') # Deduplicate list return list(set(geofences))
def validate_ciudadano(self, ciudadano): try: Ciudadano.objects.get(uuid=ciudadano) return ciudadano except Ciudadano.DoesNotExist: raise serializers.ValidationError( 'El ciudadano ingresado no existe.')
def validate(self, data): """ TODO: We're currently passing org data into the user serializer model. This might cause conflicts. Consider doing something smarter. :param data: :return: """ # # User Validation # Perform server side validation if data['password'] != data['confirm_password']: raise serializers.ValidationError( 'Password and Confirm Password should be the same' ) user_serializer = UserSerializer(data=data) user_serializer.is_valid(raise_exception=True) organization_data = { 'name': data['organization_name'] } organization_serializer = OrganizationSerializer(data=organization_data) organization_serializer.is_valid(raise_exception=True) data['user_serializer'] = user_serializer data['organization_serializer'] = organization_serializer return data
def validate_quickadd_tracking(self, quickadd_tracking): response = requests.post(f'{settings.AFTERSHIP_URL}couriers/detect', headers={'aftership-api-key': settings.AFTERSHIP_API_KEY}, json={'tracking': {'tracking_number': quickadd_tracking}}) if not response.ok: raise serializers.ValidationError('Invalid quickadd_tracking value') return quickadd_tracking
def validate_familia_medicamento(self, familia_medicamento): try: FamiliaMedicamentoAntecedenteSugerido.objects.get( pk=familia_medicamento) return familia_medicamento except FamiliaMedicamentoAntecedenteSugerido.DoesNotExist: raise serializers.ValidationError( 'La familia de medicamentos no existe.')
def validate_parent(self, value): """ Validate location parent field """ if self.instance is not None and not validate_parent_field( self.instance, value): # locations cannot be their own parents raise serializers.ValidationError(SAME_PARENT) return value
def validate_company(self, value): user = self.context['request'].user if not Employment.objects.filter( company=value, user=user, role=Employment.ROLE_ADMIN).exists(): raise serializers.ValidationError( "You are not admin in the specified company", code='user_not_admin') return value
def validate_shipper_wallet_id(self, shipper_wallet_id): if settings.PROFILES_ENABLED: response = settings.REQUESTS_SESSION.get(f'{settings.PROFILES_URL}/api/v1/wallet/{shipper_wallet_id}/', headers={'Authorization': 'JWT {}'.format(self.auth)}) if response.status_code != status.HTTP_200_OK: raise serializers.ValidationError('User does not have access to this wallet in ShipChain Profiles') return shipper_wallet_id
def validate_approved(self, approved): if settings.PROFILES_ENABLED: if approved: if not Shipment.objects.filter( owner_access_filter(self.context['request'])).exists(): raise serializers.ValidationError( 'User does not have access to approve this access request' ) if self.instance.approved: raise serializers.ValidationError( 'This access request has already been approved') self.instance.approved_at = datetime.now(timezone.utc) self.instance.approved_by = self.context['request'].user.id else: self.instance.approved_at = None self.instance.approved_by = None return approved
def prepare_for_reassignment(self): if hasattr(self, 'shipment'): if not self.shipment.can_disassociate_device(): raise serializers.ValidationError( 'Device is already assigned to a Shipment in progress') from apps.shipments.models import Shipment shipment = Shipment.objects.get(pk=self.shipment.id) shipment.device_id = None shipment.save() if hasattr(self, 'route'): if not self.route.can_disassociate_device(): raise serializers.ValidationError( 'Device is already assigned to a Route in progress') from apps.routes.models import Route route = Route.objects.get(pk=self.route.id) route.device_id = None route.save()
def validate(self, attrs): body_text = attrs["body_text"] if len(body_text) < 5: raise serializers.ValidationError({ "body_text": { "title": "Too Short title", "detail": "Too short" } })
def validate(self, attrs): body_text = attrs['body_text'] if len(body_text) < 5: raise serializers.ValidationError({ 'body_text': { 'title': 'Too Short title', 'detail': 'Too short' } })
def validate_parent(self, value): """ Validate task parent field """ valid_parent = validate_parent_field(self.instance, value) if not valid_parent and self.instance is not None: # tasks cannot be their own parents raise serializers.ValidationError(SAME_PARENT) return value
def validate_timing_rule(self, value): """ Validate timing rule """ if value is not None: if validate_rrule(value) is True: return value raise serializers.ValidationError(INVALID_TIMING_RULE) return None
def validate(self, attrs): """ Ensure that the node is owned by the same organization as the room. """ logger.debug( "For a new or updated installation, validate that node and room belong to the same owner." ) try: room = attrs["room"] node = attrs["node"] except KeyError: raise serializers.ValidationError( "Both the Room reference and the node reference must be provided." ) if room.site.operator != node.owner: raise serializers.ValidationError( "In an installation, Node and room must belong to the same owner." ) return attrs