def validate_zds_username(value, check_username_available=True): """ Check if username is used by another user :param value: value to validate (str or None) :return: """ msg = None user_count = User.objects.filter(username=value).count() skeleton_user_count = Profile.objects.filter( username_skeleton=Profile.find_username_skeleton(value)).count() if ',' in value: msg = _('Le nom d\'utilisateur ne peut contenir de virgules') elif contains_utf8mb4(value): msg = _( 'Le nom d\'utilisateur ne peut pas contenir des caractères utf8mb4' ) elif check_username_available and user_count > 0: msg = _('Ce nom d\'utilisateur est déjà utilisé') elif check_username_available and skeleton_user_count > 0: msg = _( 'Un nom d\'utilisateur visuellement proche du votre existe déjà') elif not check_username_available and user_count == 0: msg = _('Ce nom d\'utilisateur n\'existe pas') if msg is not None: raise ValidationError(msg)
def __call__(self, value, check_username_available=True): value = force_text(value) if not value or '@' not in value: raise ValidationError(self.message, code=self.code) user_part, domain_part = value.rsplit('@', 1) if not self.user_regex.match(user_part) or contains_utf8mb4(user_part): raise ValidationError(self.message, code=self.code) # check if provider is blacklisted blacklist = BannedEmailProvider.objects.values_list('provider', flat=True) for provider in blacklist: if '@{}'.format(provider) in value.lower(): raise ValidationError(_('Ce fournisseur ne peut pas être utilisé.'), code=self.code) # check if email is used by another user user_count = User.objects.filter(email=value).count() if check_username_available and user_count > 0: raise ValidationError(_('Cette adresse courriel est déjà utilisée'), code=self.code) # check if email exists in database elif not check_username_available and user_count == 0: raise ValidationError(_('Cette adresse courriel n\'existe pas'), code=self.code) if domain_part and not self.validate_domain_part(domain_part): # Try for possible IDN domain-part try: domain_part = domain_part.encode('idna').decode('ascii') if self.validate_domain_part(domain_part): return except UnicodeError: pass raise ValidationError(self.message, code=self.code)
def clean_hat(self): data = self.cleaned_data['hat'] user = get_current_user() if contains_utf8mb4(data): raise forms.ValidationError( _('Les caractères utf8mb4 ne sont pas autorisés dans les casquettes.' )) if data.lower() in [ hat.name.lower() for hat in user.profile.get_hats() ]: raise forms.ValidationError( _('Vous possédez déjà cette casquette.')) if data.lower() in [ hat.lower() for hat in user.requested_hats.values_list('hat', flat=True) ]: raise forms.ValidationError( _('Vous avez déjà demandé cette casquette.')) try: hat = Hat.objects.get(name__iexact=data) if hat.group: raise forms.ValidationError( _('Cette casquette n\'est accordée qu\'aux membres ' 'd\'un groupe particulier. Vous ne pouvez pas ' 'la demander.')) except Hat.DoesNotExist: pass return data
def add_hat(request, user_pk): """ Add a hat to a user. Creates the hat if it doesn't exist. """ user = get_object_or_404(User, pk=user_pk) hat_name = request.POST.get('hat', '').strip() if not hat_name: messages.error(request, _('Aucune casquette saisie.')) if contains_utf8mb4(hat_name): messages.error(request, _('Les caractères utf8mb4 ne sont pas autorisés dans les casquettes.')) elif len(hat_name) > 40: messages.error(request, _('Une casquette ne peut dépasser 40 caractères.')) else: hat, created = Hat.objects.get_or_create(name__iexact=hat_name, defaults={'name': hat_name}) if created: messages.success(request, _('La casquette « {} » a été créée.').format(hat_name)) if hat.group: messages.error(request, _('Cette casquette est accordée aux membres d\'un groupe particulier. ' 'Elle ne peut pas être ajoutée individuellement.')) else: user.profile.hats.add(hat) messages.success(request, _('La casquette a bien été ajoutée.')) # if hat was asked, remove request HatRequest.objects.filter(user=user, hat__iexact=hat_name).delete() return redirect(user.profile.get_absolute_url())
def get_hat_to_add(hat_name, user): """ Return a hat that will be added to a user. This function creates the hat if it does not exist, so be sure you will need it! """ hat_name = hat_name.strip() if not hat_name: raise ValueError(_('Veuillez saisir une casquette.')) if contains_utf8mb4(hat_name): raise ValueError( _('La casquette saisie contient des caractères utf8mb4, ' 'ceux-ci ne peuvent pas être utilisés.')) if len(hat_name) > 40: raise ValueError( _('La longueur des casquettes est limitée à 40 caractères.')) hat, created = Hat.objects.get_or_create(name__iexact=hat_name, defaults={'name': hat_name}) if created: logger.info('Hat #{0} "{1}" has been created.'.format( hat.pk, hat.name)) if hat in user.profile.get_hats(): raise ValueError( _('{0} possède déjà la casquette « {1} ».'.format( user.username, hat.name))) if hat.group: raise ValueError( _('La casquette « {} » est accordée automatiquement aux membres d\'un groupe particulier ' 'et ne peut donc pas être ajoutée à un membre externe à ce groupe.' .format(hat.name))) return hat
def clean_hat(self): data = self.cleaned_data['hat'] user = get_current_user() if contains_utf8mb4(data): raise forms.ValidationError( _('Les caractères utf8mb4 ne sont pas autorisés dans les casquettes.' )) if HatRequest.objects.filter(user=user, hat__iexact=data, is_granted__isnull=True).exists(): raise forms.ValidationError( _('Vous avez déjà une demande en cours pour cette casquette.')) try: hat = Hat.objects.get(name__iexact=data) if hat in user.profile.get_hats(): raise forms.ValidationError( _('Vous possédez déjà cette casquette.')) if hat.group: raise forms.ValidationError( _('Cette casquette n\'est accordée qu\'aux membres ' 'd\'un groupe particulier. Vous ne pouvez pas ' 'la demander.')) except Hat.DoesNotExist: pass return data
def validate_zds_username(value, check_username_available=True): """ Check if username is used by another user :param value: value to validate (str or None) :return: """ msg = None user_count = User.objects.filter(username=value).count() if ',' in value: msg = _(u'Le nom d\'utilisateur ne peut contenir de virgules') elif value != value.strip(): msg = _( u'Le nom d\'utilisateur ne peut commencer ou finir par des espaces' ) elif contains_utf8mb4(value): msg = _( u'Le nom d\'utilisateur ne peut pas contenir des caractères utf8mb4' ) elif check_username_available and user_count > 0: msg = _(u'Ce nom d\'utilisateur est déjà utilisé') elif not check_username_available and user_count == 0: msg = _(u'Ce nom d\'utilisateur n\'existe pas') if msg is not None: raise ValidationError(msg)
def validate_zds_password(value): """ :param value: :return: """ if contains_utf8mb4(value): raise ValidationError(_('Le mot de passe ne peut pas contenir des caractères utf8mb4'))
def validate_zds_password(value): """ :param value: :return: """ if contains_utf8mb4(value): raise ValidationError( _('Le mot de passe ne peut pas contenir des caractères utf8mb4'))
def validate_utf8mb4(self, tag): """ Checks the tag does not contain utf8mb4 chars. :param tag: :return: ``True`` if no utf8mb4 string is found """ if contains_utf8mb4(tag): self.errors.append(_('Le tag {} contient des caractères utf8mb4').format(tag)) self.logger.warn('%s contains utf8mb4 char', tag) return False return True
def validate_utf8mb4(self, tag): """ Checks the tag does not contain utf8mb4 chars. :param tag: :return: ``True`` if no utf8mb4 string is found """ if contains_utf8mb4(tag): self.errors.append(_(u'Le tag {} contient des caractères utf8mb4').format(tag)) self.logger.warn('%s contains utf8mb4 char', tag) return False return True
def validate_utf8mb4(self, tag): """ Checks the tag does not contain utf8mb4 chars. :param tag: :return: ``True`` if no utf8mb4 string is found """ if contains_utf8mb4(tag): self.errors.append(TagValidator.error_utf8mb4.format(tag)) self.logger.warning("%s contains utf8mb4 char", tag) return False return True
def test_utf8mb4(self): self.assertFalse(contains_utf8mb4('abc')) self.assertFalse(contains_utf8mb4('abc')) self.assertFalse(contains_utf8mb4('abc€')) self.assertFalse(contains_utf8mb4('abc€')) self.assertTrue(contains_utf8mb4('a🐙tbc€')) self.assertTrue(contains_utf8mb4('a🐙tbc€'))
def test_utf8mb4(self): self.assertFalse(contains_utf8mb4('abc')) self.assertFalse(contains_utf8mb4('abc')) self.assertFalse(contains_utf8mb4('abc€')) self.assertFalse(contains_utf8mb4('abc€')) self.assertTrue(contains_utf8mb4('a🐙tbc€')) self.assertTrue(contains_utf8mb4('a🐙tbc€'))
def test_utf8mb4(self): self.assertFalse(contains_utf8mb4("abc")) self.assertFalse(contains_utf8mb4("abc")) self.assertFalse(contains_utf8mb4("abc€")) self.assertFalse(contains_utf8mb4("abc€")) self.assertTrue(contains_utf8mb4("a🐙tbc€")) self.assertTrue(contains_utf8mb4("a🐙tbc€"))
def get_tag_by_title(title): """ Extract tags from title. In a title, tags can be set this way: > [Tag 1][Tag 2] There is the real title Rules to detect tags: - Tags are enclosed in square brackets. This allows multi-word tags instead of hashtags. - Tags can embed square brackets: [Tag] is a valid tag and must be written [[Tag]] in the raw title - All tags must be declared at the beginning of the title. Example: _"Title [tag]"_ will not create a tag. - Tags and title correctness (example: empty tag/title detection) is **not** checked here :param title: The raw title :return: A tuple: (the tag list, the title without the tags). """ nb_bracket = 0 current_tag = u'' current_title = u'' tags = [] continue_parsing_tags = True original_title = title for char in title: if char == u'[' and nb_bracket == 0 and continue_parsing_tags: nb_bracket += 1 elif nb_bracket > 0 and char != u']' and continue_parsing_tags: current_tag = current_tag + char if char == u'[': nb_bracket += 1 elif char == u']' and nb_bracket > 0 and continue_parsing_tags: nb_bracket -= 1 if nb_bracket == 0 and current_tag.strip() != u'': tags.append(current_tag.strip()) current_tag = u'' elif current_tag.strip() != u'' and nb_bracket > 0: current_tag = current_tag + char elif (char != u'[' and char.strip() != '') or not continue_parsing_tags: continue_parsing_tags = False current_title = current_title + char title = current_title # if we did not succed in parsing the tags if nb_bracket != 0: return [], original_title tags = filter(lambda tag: not contains_utf8mb4(tag), tags) return tags, title.strip()
def get_tag_by_title(title): """ Extract tags from title. In a title, tags can be set this way: > [Tag 1][Tag 2] There is the real title Rules to detect tags: - Tags are enclosed in square brackets. This allows multi-word tags instead of hashtags. - Tags can embed square brackets: [Tag] is a valid tag and must be written [[Tag]] in the raw title - All tags must be declared at the beginning of the title. Example: _"Title [tag]"_ will not create a tag. - Tags and title correctness (example: empty tag/title detection) is **not** checked here :param title: The raw title :return: A tuple: (the tag list, the title without the tags). """ nb_bracket = 0 current_tag = '' current_title = '' tags = [] continue_parsing_tags = True original_title = title for char in title: if char == '[' and nb_bracket == 0 and continue_parsing_tags: nb_bracket += 1 elif nb_bracket > 0 and char != ']' and continue_parsing_tags: current_tag = current_tag + char if char == '[': nb_bracket += 1 elif char == ']' and nb_bracket > 0 and continue_parsing_tags: nb_bracket -= 1 if nb_bracket == 0 and current_tag.strip() != '': tags.append(current_tag.strip()) current_tag = '' elif current_tag.strip() != '' and nb_bracket > 0: current_tag = current_tag + char elif (char != '[' and char.strip() != '') or not continue_parsing_tags: continue_parsing_tags = False current_title = current_title + char title = current_title # if we did not succed in parsing the tags if nb_bracket != 0: return [], original_title tags = [tag for tag in tags if not contains_utf8mb4(tag)] return tags, title.strip()
def validate_zds_username(value, check_username_available=True): """ Check if username is used by another user :param value: value to validate (str or None) :return: """ msg = None user_count = User.objects.filter(username=value).count() if ',' in value: msg = _('Le nom d\'utilisateur ne peut contenir de virgules') elif value != value.strip(): msg = _('Le nom d\'utilisateur ne peut commencer ou finir par des espaces') elif contains_utf8mb4(value): msg = _('Le nom d\'utilisateur ne peut pas contenir des caractères utf8mb4') elif check_username_available and user_count > 0: msg = _('Ce nom d\'utilisateur est déjà utilisé') elif not check_username_available and user_count == 0: msg = _('Ce nom d\'utilisateur n\'existe pas') if msg is not None: raise ValidationError(msg)
def __call__(self, value, check_username_available=True): value = force_text(value) if not value or '@' not in value: raise ValidationError(self.message, code=self.code) user_part, domain_part = value.rsplit('@', 1) if not self.user_regex.match(user_part) or contains_utf8mb4(user_part): raise ValidationError(self.message, code=self.code) # check if provider is blacklisted blacklist = BannedEmailProvider.objects.values_list('provider', flat=True) for provider in blacklist: if '@{}'.format(provider) in value.lower(): raise ValidationError( _('Ce fournisseur ne peut pas être utilisé.'), code=self.code) # check if email is used by another user user_count = User.objects.filter(email=value).count() if check_username_available and user_count > 0: raise ValidationError( _('Cette adresse courriel est déjà utilisée'), code=self.code) # check if email exists in database elif not check_username_available and user_count == 0: raise ValidationError(_('Cette adresse courriel n\'existe pas'), code=self.code) if domain_part and not self.validate_domain_part(domain_part): # Try for possible IDN domain-part try: domain_part = domain_part.encode('idna').decode('ascii') if self.validate_domain_part(domain_part): return except UnicodeError: pass raise ValidationError(self.message, code=self.code)
def __call__(self, value, check_username_available=True): value = force_text(value) if not value or '@' not in value: raise ValidationError(self.message, code=self.code) user_part, domain_part = value.rsplit('@', 1) if not self.user_regex.match(user_part) or contains_utf8mb4(user_part): raise ValidationError(self.message, code=self.code) # check if provider is blacklisted with open(os.path.join(BASE_DIR, 'forbidden_email_providers.txt'), 'r') as black_list: for provider in black_list: if provider.strip() in value: raise ValidationError(_( u'Utilisez un autre fournisseur d\'adresses courriel'), code=self.code) # check if email is used by another user user_count = User.objects.filter(email=value).count() if check_username_available and user_count > 0: raise ValidationError( _(u'Cette adresse courriel est déjà utilisée'), code=self.code) # check if email exists in database elif not check_username_available and user_count == 0: raise ValidationError(_(u'Cette adresse courriel n\'existe pas'), code=self.code) if domain_part and not self.validate_domain_part(domain_part): # Try for possible IDN domain-part try: domain_part = domain_part.encode('idna').decode('ascii') if self.validate_domain_part(domain_part): return except UnicodeError: pass raise ValidationError(self.message, code=self.code)