142 |
142 |
no_email_validation = serializers.BooleanField(required=False)
|
143 |
143 |
return_url = serializers.URLField(required=False, allow_blank=True)
|
144 |
144 |
|
145 |
|
def validate(self, data):
|
|
145 |
def validate(self, attrs):
|
146 |
146 |
request = self.context.get('request')
|
147 |
|
ou = data.get('ou')
|
|
147 |
ou = attrs.get('ou')
|
148 |
148 |
if request:
|
149 |
149 |
perm = 'custom_user.add_user'
|
150 |
150 |
if ou:
|
151 |
|
authorized = request.user.has_ou_perm(perm, data['ou'])
|
|
151 |
authorized = request.user.has_ou_perm(perm, attrs['ou'])
|
152 |
152 |
else:
|
153 |
153 |
authorized = request.user.has_perm(perm)
|
154 |
154 |
if not authorized:
|
... | ... | |
156 |
156 |
User = get_user_model()
|
157 |
157 |
if ou:
|
158 |
158 |
if app_settings.A2_EMAIL_IS_UNIQUE or app_settings.A2_REGISTRATION_EMAIL_IS_UNIQUE:
|
159 |
|
if 'email' not in data:
|
|
159 |
if 'email' not in attrs:
|
160 |
160 |
raise serializers.ValidationError(_('Email is required'))
|
161 |
|
if User.objects.filter(email__iexact=data['email']).exists():
|
|
161 |
if User.objects.filter(email__iexact=attrs['email']).exists():
|
162 |
162 |
raise serializers.ValidationError(_('Account already exists'))
|
163 |
163 |
|
164 |
164 |
if ou.email_is_unique:
|
165 |
|
if 'email' not in data:
|
|
165 |
if 'email' not in attrs:
|
166 |
166 |
raise serializers.ValidationError(_('Email is required in this ou'))
|
167 |
|
if User.objects.filter(ou=ou, email__iexact=data['email']).exists():
|
|
167 |
if User.objects.filter(ou=ou, email__iexact=attrs['email']).exists():
|
168 |
168 |
raise serializers.ValidationError(_('Account already exists in this ou'))
|
169 |
169 |
|
170 |
170 |
if app_settings.A2_USERNAME_IS_UNIQUE or app_settings.A2_REGISTRATION_USERNAME_IS_UNIQUE:
|
171 |
|
if 'username' not in data:
|
|
171 |
if 'username' not in attrs:
|
172 |
172 |
raise serializers.ValidationError(_('Username is required'))
|
173 |
|
if User.objects.filter(username=data['username']).exists():
|
|
173 |
if User.objects.filter(username=attrs['username']).exists():
|
174 |
174 |
raise serializers.ValidationError(_('Account already exists'))
|
175 |
175 |
|
176 |
176 |
if ou.username_is_unique:
|
177 |
|
if 'username' not in data:
|
|
177 |
if 'username' not in attrs:
|
178 |
178 |
raise serializers.ValidationError(_('Username is required in this ou'))
|
179 |
|
if User.objects.filter(ou=ou, username=data['username']).exists():
|
|
179 |
if User.objects.filter(ou=ou, username=attrs['username']).exists():
|
180 |
180 |
raise serializers.ValidationError(_('Account already exists in this ou'))
|
181 |
|
return data
|
|
181 |
return attrs
|
182 |
182 |
|
183 |
183 |
|
184 |
184 |
class RpcMixin:
|
... | ... | |
319 |
319 |
old_password = serializers.CharField(required=True, allow_null=True)
|
320 |
320 |
new_password = serializers.CharField(required=True, allow_null=True)
|
321 |
321 |
|
322 |
|
def validate(self, data):
|
|
322 |
def validate(self, attrs):
|
323 |
323 |
User = get_user_model()
|
324 |
|
qs = User.objects.filter(email__iexact=data['email'])
|
325 |
|
if data['ou']:
|
326 |
|
qs = qs.filter(ou=data['ou'])
|
|
324 |
qs = User.objects.filter(email__iexact=attrs['email'])
|
|
325 |
if attrs['ou']:
|
|
326 |
qs = qs.filter(ou=attrs['ou'])
|
327 |
327 |
try:
|
328 |
328 |
self.user = qs.get()
|
329 |
329 |
except User.DoesNotExist:
|
330 |
330 |
raise serializers.ValidationError('no user found')
|
331 |
331 |
except MultipleObjectsReturned:
|
332 |
332 |
raise serializers.ValidationError('more than one user have this email')
|
333 |
|
if not self.user.check_password(data['old_password']):
|
|
333 |
if not self.user.check_password(attrs['old_password']):
|
334 |
334 |
raise serializers.ValidationError('old_password is invalid')
|
335 |
|
return data
|
|
335 |
return attrs
|
336 |
336 |
|
337 |
337 |
|
338 |
338 |
class PasswordChange(BaseRpcView):
|
... | ... | |
491 |
491 |
instance.save()
|
492 |
492 |
return instance
|
493 |
493 |
|
494 |
|
def validate(self, data):
|
|
494 |
def validate(self, attrs):
|
495 |
495 |
User = get_user_model()
|
496 |
496 |
qs = User.objects.all()
|
497 |
497 |
|
... | ... | |
499 |
499 |
|
500 |
500 |
if self.instance:
|
501 |
501 |
ou = self.instance.ou
|
502 |
|
if 'ou' in data and not ou:
|
503 |
|
ou = data['ou']
|
|
502 |
if 'ou' in attrs and not ou:
|
|
503 |
ou = attrs['ou']
|
504 |
504 |
|
505 |
505 |
get_or_create_fields = self.context['view'].request.GET.getlist('get_or_create')
|
506 |
506 |
update_or_create_fields = self.context['view'].request.GET.getlist('update_or_create')
|
... | ... | |
509 |
509 |
if (
|
510 |
510 |
'email' not in get_or_create_fields
|
511 |
511 |
and 'email' not in update_or_create_fields
|
512 |
|
and data.get('email')
|
513 |
|
and (not self.instance or data.get('email') != self.instance.email)
|
|
512 |
and attrs.get('email')
|
|
513 |
and (not self.instance or attrs.get('email') != self.instance.email)
|
514 |
514 |
):
|
515 |
|
if app_settings.A2_EMAIL_IS_UNIQUE and qs.filter(email__iexact=data['email']).exists():
|
|
515 |
if app_settings.A2_EMAIL_IS_UNIQUE and qs.filter(email__iexact=attrs['email']).exists():
|
516 |
516 |
already_used = True
|
517 |
|
if ou and ou.email_is_unique and qs.filter(ou=ou, email__iexact=data['email']).exists():
|
|
517 |
if ou and ou.email_is_unique and qs.filter(ou=ou, email__iexact=attrs['email']).exists():
|
518 |
518 |
already_used = True
|
519 |
519 |
|
520 |
520 |
errors = {}
|
521 |
521 |
if already_used:
|
522 |
522 |
errors['email'] = 'email already used'
|
523 |
|
if data.get('password') and data.get('hashed_password'):
|
|
523 |
if attrs.get('password') and attrs.get('hashed_password'):
|
524 |
524 |
errors['password'] = 'conflict with provided hashed_password'
|
525 |
|
if data.get('hashed_password'):
|
|
525 |
if attrs.get('hashed_password'):
|
526 |
526 |
try:
|
527 |
|
hasher = identify_hasher(data.get('hashed_password'))
|
|
527 |
hasher = identify_hasher(attrs.get('hashed_password'))
|
528 |
528 |
except ValueError:
|
529 |
529 |
errors['hashed_password'] = "unknown hash format"
|
530 |
530 |
else:
|
531 |
531 |
try:
|
532 |
|
hasher.safe_summary(data.get('hashed_password'))
|
|
532 |
hasher.safe_summary(attrs.get('hashed_password'))
|
533 |
533 |
except Exception:
|
534 |
534 |
errors['hashed_password'] = "hash format error"
|
535 |
535 |
if errors:
|
536 |
536 |
raise serializers.ValidationError(errors)
|
537 |
|
return data
|
|
537 |
return attrs
|
538 |
538 |
|
539 |
539 |
class Meta:
|
540 |
540 |
model = get_user_model()
|
... | ... | |
746 |
746 |
return new_qs
|
747 |
747 |
return qs
|
748 |
748 |
|
749 |
|
def filter_queryset(self, qs):
|
750 |
|
qs = super().filter_queryset(qs)
|
751 |
|
qs = self.request.user.filter_by_perm(['custom_user.view_user'], qs)
|
|
749 |
def filter_queryset(self, queryset):
|
|
750 |
queryset = super().filter_queryset(queryset)
|
|
751 |
queryset = self.request.user.filter_by_perm(['custom_user.view_user'], queryset)
|
752 |
752 |
# filter users authorized for a specified service
|
753 |
753 |
if 'service-slug' in self.request.GET:
|
754 |
754 |
service_slug = self.request.GET['service-slug']
|
... | ... | |
760 |
760 |
)
|
761 |
761 |
if service:
|
762 |
762 |
if service.authorized_roles.all():
|
763 |
|
qs = qs.filter(roles__in=service.authorized_roles.children())
|
764 |
|
qs = qs.distinct()
|
|
763 |
queryset = queryset.filter(roles__in=service.authorized_roles.children())
|
|
764 |
queryset = queryset.distinct()
|
765 |
765 |
else:
|
766 |
|
qs = qs.none()
|
767 |
|
return qs
|
|
766 |
queryset = queryset.none()
|
|
767 |
return queryset
|
768 |
768 |
|
769 |
769 |
def update(self, request, *args, **kwargs):
|
770 |
770 |
kwargs['partial'] = True
|
... | ... | |
1147 |
1147 |
|
1148 |
1148 |
|
1149 |
1149 |
class ServiceOUField(serializers.ListField):
|
1150 |
|
def to_internal_value(self, data_list):
|
1151 |
|
data = data_list[0].split(' ')
|
|
1150 |
def to_internal_value(self, data):
|
|
1151 |
data = data[0].split(' ')
|
1152 |
1152 |
if not len(data) == 2:
|
1153 |
1153 |
raise ValidationError('This field should be a service slug and an OU slug separated by space.')
|
1154 |
1154 |
return super().to_internal_value(data)
|