def validate_phone(self, field): # Step 1: Validate number try: # Assume Indian number if no country code is specified # TODO: Guess country from IP address parsed_number = phonenumbers.parse(field.data, 'IN') if not phonenumbers.is_valid_number(parsed_number): raise ValueError("Invalid number") except (phonenumbers.NumberParseException, ValueError): raise forms.StopValidation( _("This does not appear to be a valid phone number")) number = phonenumbers.format_number( parsed_number, phonenumbers.PhoneNumberFormat.E164) # Step 2: Check if number has already been claimed existing = UserPhone.get(phone=number) if existing is not None: if existing.user == current_auth.user: raise forms.ValidationError( _("You have already registered this phone number")) else: raise forms.ValidationError( _("This phone number has already been claimed")) existing = UserPhoneClaim.get_for(user=current_auth.user, phone=number) if existing is not None: raise forms.ValidationError( _("This phone number is pending verification")) # Step 3: If validations pass, use the reformatted number field.data = number # Save stripped number
def validate_apply_message(form, field): words = get_word_bag(field.data) form.words = words similar = False for oldapp in JobApplication.query.filter( JobApplication.response.SPAM).all(): if oldapp.words: s = SequenceMatcher(None, words, oldapp.words) if s.ratio() > 0.8: similar = True break if similar: raise forms.ValidationError( _("Your application is very similar to one previously identified as spam" )) # Check for email and phone numbers in the message # Prepare text by replacing non-breaking spaces with spaces (for phone numbers) and removing URLs. # URLs may contain numbers that are not phone numbers. phone_search_text = URL_RE.sub( '', field.data.replace(' ', ' ').replace(' ', ' ').replace(u'\xa0', ' ')) if EMAIL_RE.search(field.data) is not None or PHONE_DETECT_RE.search( phone_search_text) is not None: raise forms.ValidationError( _("Do not include your email address or phone number in the application" ))
def validate_job_headline(self, field): if simplify_text(field.data) in ( 'awesome coder wanted at awesome company', 'pragmatic programmer wanted at outstanding organisation', 'pragmatic programmer wanted at outstanding organization', ) or ( g.board and g.board.newjob_headline and simplify_text(field.data) == simplify_text(g.board.newjob_headline) ): raise forms.ValidationError( _( "Come on, write your own headline. You aren’t just another run-of-the-mill employer, right?" ) ) caps = len(CAPS_RE.findall(field.data)) small = len(SMALL_RE.findall(field.data)) if small == 0 or caps / float(small) > 1.0: raise forms.ValidationError( _( "No shouting, please. Reduce the number of capital letters in your headline" ) ) for word_list, message in app.config.get('BANNED_WORDS', []): for word in word_list: if word in field.data.lower(): raise forms.ValidationError(message)
def validate_job_location(form, field): if QUOTES_RE.search(field.data) is not None: raise forms.ValidationError(_(u"Don’t use quotes in the location name")) caps = len(CAPS_RE.findall(field.data)) small = len(SMALL_RE.findall(field.data)) if small == 0 or caps / float(small) > 1.0: raise forms.ValidationError(_("Surely this location isn't named in uppercase?"))
def validate_name(self, field): field.data = field.data.lower() if not valid_username(field.data): raise forms.ValidationError(_("Name contains invalid characters")) existing = self.edit_resource.get_action(field.data) if existing and existing.id != self.edit_id: raise forms.ValidationError(_("An action with that name already exists for this resource"))
def validate_namespace(self, field): if field.data: if not domain_namespace_match(self.website.data, field.data): raise forms.ValidationError(_(u"The namespace should be derived from your application’s website domain")) client = self.edit_model.get(namespace=field.data) if client: if client == self.edit_obj: return raise forms.ValidationError(_("This namespace has been claimed by another client app"))
def validate_username(self, field): if field.data in current_app.config['RESERVED_USERNAMES']: raise forms.ValidationError, _("This name is reserved") if not valid_username(field.data): raise forms.ValidationError( _(u"Invalid characters in name. Names must be made of ‘a-z’, ‘0-9’ and ‘-’, without trailing dashes" )) existing = User.get(username=field.data) if existing is not None: raise forms.ValidationError(_("This username is taken"))
def validate_name(self, field): field.data = field.data.lower() if not valid_username(field.data): raise forms.ValidationError(_("Name contains invalid characters")) if field.data in resource_registry: raise forms.ValidationError(_("This name is reserved for internal use")) existing = Resource.get(name=field.data, client=self.client) if existing and existing.id != self.edit_id: raise forms.ValidationError(_("A resource with that name already exists"))
def validate_username(self, field): # # Usernames are now mandatory. This should be commented out: # if not field.data: # field.data = None # return field.data = field.data.lower() # Usernames can only be lowercase if not valid_username(field.data): raise forms.ValidationError(_("Usernames can only have alphabets, numbers and dashes (except at the ends)")) if field.data in current_app.config.get('RESERVED_USERNAMES', []): raise forms.ValidationError(_("This name is reserved")) if not self.edit_user.is_valid_username(field.data): raise forms.ValidationError(_("This username is taken"))
def validate_job_pay_cash_min(self, field): if self.job_pay_type.data in (PAY_TYPE.ONETIME, PAY_TYPE.RECURRING): data = field.data.strip() if not data: raise forms.ValidationError(_("Please specify what this job pays")) data = string_to_number(data) if data is None: raise forms.ValidationError(_("Unrecognised value %s") % field.data) else: field.data = data else: field.data = None
def validate_company_logo(self, field): if not ('company_logo' in request.files and request.files['company_logo']): return try: g.company_logo = process_image(request.files['company_logo']) except IOError as e: raise forms.ValidationError(e.message) except KeyError: raise forms.ValidationError(_("Unknown file format")) except UploadNotAllowed: raise forms.ValidationError( _("Unsupported file format. We accept JPEG, PNG and GIF") )
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: if existing.user == current_auth.user: raise forms.ValidationError( _("You have already registered this email address")) else: raise forms.ValidationError( _("This email address has already been claimed")) existing = UserEmailClaim.get(email=field.data, user=current_auth.user) if existing is not None: raise forms.ValidationError( _("This email address is pending verification"))
def validate_company_name(form, field): if len(field.data) > 6: caps = len(CAPS_RE.findall(field.data)) small = len(SMALL_RE.findall(field.data)) if small == 0 or caps / float(small) > 0.8: raise forms.ValidationError( u"Surely your organization isn’t named in uppercase?")
def validate_email(form, field): oldapp = JobApplication.query.filter_by(jobpost=form.post, user=None, email=field.data).count() if oldapp: raise forms.ValidationError( "You have already applied for this position")
def validate_password(self, field): if not self.user: # Can't validate password without a user return if not self.user.pw_hash: raise LoginPasswordResetException() if not self.user.password_is(field.data, upgrade_hash=True): if not self.username.errors: raise forms.ValidationError(_("Incorrect password")) # Test for weak password. This gives us two options: # # 1. Flag it but allow login to proceed. Let the view ask the user nicely. # The user may ignore it or may comply and change their password. # # 2. Block the login and force the user to reset their password. Makes for # stronger policy, with the risk the user will (a) abandon the login, or # (b) not have a valid email address on file (for example, an expired # employer-owned email address they can no longer access). # # We're using option 1 here, but can switch to option 2 by raising # LoginPasswordWeakException after the test. The calling code in views/login.py # supports both outcomes. # password_policy.test_password(<password>)['is_weak'] returns True/False self.weak_password = password_policy.test_password( field.data)['is_weak']
def validate_company_logo(form, field): if not ('company_logo' in request.files and request.files['company_logo']): return try: g.company_logo = process_image(request.files['company_logo']) except IOError, e: raise forms.ValidationError(e.message)
def validate_twitter(self, field): if field.data.startswith('@'): field.data = field.data[1:] if INVALID_TWITTER_RE.search(field.data): raise forms.ValidationError( _("That does not appear to be a valid Twitter account") )
def validate_team_id(self, field): teams = [ team for team in self.organization.teams if team.buid == field.data ] if len(teams) != 1: raise forms.ValidationError(_("Unknown team")) self.team = teams[0]
def validate_job_pay_equity_max(form, field): if form.job_pay_equity.data: data = field.data.strip() if data: if not data[-1].isdigit(): data = field.data[:-1] # Remove % symbol data = data.replace(',', '').strip() # Remove thousands separator try: field.data = Decimal(data) except InvalidOperation: raise forms.ValidationError(_("Please enter a percentage between 0%% and 100%%")) else: raise forms.ValidationError(_("Unrecognised value %%s") % field.data) else: # Discard submission if equity checkbox is unchecked field.data = None
def validate_password(self, field): user = getuser(self.username.data) if user and not user.pw_hash: raise LoginPasswordResetException() if user is None or not user.password_is(field.data): if not self.username.errors: raise forms.ValidationError(_("Incorrect password")) self.user = user
def validate_name(self, field): if not valid_username(field.data): raise forms.ValidationError(_("Invalid characters in name")) if field.data in current_app.config['RESERVED_USERNAMES']: raise forms.ValidationError(_("This name is reserved")) existing = User.get(username=field.data) if existing is not None: if existing == current_auth.user: raise forms.ValidationError(Markup(_(u"This is <em>your</em> current username. " u'You must change it first from <a href="{profile}">your profile</a> ' u"before you can assign it to an organization").format( profile=url_for('profile')))) else: raise forms.ValidationError(_("This name is taken")) existing = Organization.get(name=field.data) if existing is not None and existing.id != self.edit_id: raise forms.ValidationError(_("This name is taken"))
def permission_validator(form, field): permlist = field.data.split() for perm in permlist: if not valid_name(perm): raise forms.ValidationError( _("Permission ‘{perm}’ is malformed").format(perm=perm)) permlist.sort() field.data = ' '.join(permlist)
def validate_email(self, field): field.data = field.data.lower() # Convert to lowercase existing = UserEmail.get(email=field.data) if existing is not None: raise forms.ValidationError( Markup( _("This email address is already registered. Do you want to <a href=\"{loginurl}\">login</a> instead?" ).format(loginurl=escape(url_for('.login')))))
def validate_name(self, field): if field.data.lower() in current_app.config['RESERVED_USERNAMES']: raise forms.ValidationError(_("This name is reserved")) # To be deprecated in favour of one below if self.edit_obj: reason = self.edit_obj.validate_name_candidate(field.data) else: reason = Name.validate_name_candidate(field.data) if not reason: return # Name is available if reason == 'invalid': raise forms.ValidationError(_("Names can only have alphabets, numbers and dashes (except at the ends)")) elif reason == 'reserved': raise forms.ValidationError(_("This name is reserved")) elif reason == 'user': if field.data == current_auth.user.username: raise forms.ValidationError(Markup(_(u"This is <em>your</em> current username. " u'You must change it first from <a href="{account}">your account</a> ' u"before you can assign it to an organization").format( account=url_for('account')))) else: raise forms.ValidationError(_("This name has been taken by another user")) elif reason == 'org': raise forms.ValidationError(_("This name has been taken by another organization")) else: raise forms.ValidationError(_("This name is not available"))
def validate_job_pay_cash_max(self, field): if self.job_pay_type.data in (PAY_TYPE.ONETIME, PAY_TYPE.RECURRING): data = string_to_number(field.data.strip()) if data is None: raise forms.ValidationError(_("Unrecognised value %s") % field.data) else: field.data = data else: field.data = None
def validate_client_owner(self, field): if field.data == self.edit_user.userid: self.user = self.edit_user self.org = None else: orgs = [org for org in self.edit_user.organizations_owned() if org.userid == field.data] if len(orgs) != 1: raise forms.ValidationError(_("Invalid owner")) self.user = None self.org = orgs[0]
def validate_company_name(form, field): if len(field.data) > 6: caps = len(CAPS_RE.findall(field.data)) # small = len(SMALL_RE.findall(field.data)) # deprecated on 30-11-2018 # if small == 0 or caps / float(small) > 0.8: # deprecated on 30-11-2018 # For now, only 6 capital letters are allowed in company name if caps > 6: raise forms.ValidationError(_(u"Surely your organization isn’t named in uppercase?"))
def validate_username(self, field): if field.data.lower() in current_app.config['RESERVED_USERNAMES']: raise forms.ValidationError( _("This name is reserved" )) # To be deprecated in favour of one below reason = self.edit_obj.validate_name_candidate(field.data) if not reason: return # Username is available if reason == 'invalid': raise forms.ValidationError( _("Usernames can only have alphabets, numbers and dashes (except at the ends)" )) elif reason == 'reserved': raise forms.ValidationError(_("This username is reserved")) elif reason in ('user', 'org'): raise forms.ValidationError(_("This username has been taken")) else: raise forms.ValidationError(_("This username is not available"))
def validate_phone(self, field): # Step 1: Remove punctuation in number number = strip_phone(field.data) # Step 2: Check length if len(number) > 16: raise forms.ValidationError( _("This is too long to be a valid phone number")) # Step 3: Validate number format if not valid_phone(number): raise forms.ValidationError( _("Invalid phone number (must be in international format with a leading + symbol)" )) # Step 4: Check if Indian number (startswith('+91')) if number.startswith('+91') and len(number) != 13: raise forms.ValidationError( _("This does not appear to be a valid Indian mobile number")) # Step 5: Check if number has already been claimed existing = UserPhone.get(phone=number) if existing is not None: if existing.user == current_auth.user: raise forms.ValidationError( _("You have already registered this phone number")) else: raise forms.ValidationError( _("This phone number has already been claimed")) existing = UserPhoneClaim.get(phone=number, user=current_auth.user) if existing is not None: raise forms.ValidationError( _("This phone number is pending verification")) field.data = number # Save stripped number
def validate_email(self, field): existing_assignees = ( Assignee.query.join(LineItem).join(Item).join(Order).filter( LineItem.item_id == self.edit_parent.item_id).filter( Order.status != ORDER_STATUS.CANCELLED).filter( Assignee.current.is_(True)).filter( Assignee.email == field.data)) if self.edit_obj is not None: existing_assignees = existing_assignees.filter( Assignee.id != self.edit_obj.id) if existing_assignees.count() > 0: raise forms.ValidationError( __("Email address has been already used"))