class LoginForm(SecurityLoginForm): username = StringField( get_form_field_label("username"), validators=[], ) jwt = StringField( get_form_field_label("jwt"), validators=[], ) def validate(self): username = self.data.get('username', '') password = self.data.get('password', '') ip = get_ip() err, jwt = validate_user(username, password, ip) if err: return False err, result = pyutil_mongo.db_find_one('user', {'user_id': username}, ["_id"]) if err: return False the_id = str(result.get("_id", '')) self.user = User() self.user.id = the_id self.user.is_active = True self.user.jwt = jwt return True
class LoginForm(Form): """The default login form""" email = StringField(get_form_field_label('email'), validators=[Required(message='EMAIL_NOT_PROVIDED')]) password = PasswordField(get_form_field_label('password'), validators=[password_required]) remember = BooleanField(get_form_field_label('remember_me')) submit = SubmitField(get_form_field_label('login')) def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) self.remember.default = False def validate(self): from core.model.user import User if not super(LoginForm, self).validate(): return False User.query.all() # self.user = User.query.filter(User.email=self.email.data).first() if self.user is None: self.email.errors.append("User does not exist") return False if not self.user.password: self.password.errors.append("Password is not specified") return False return True
class ChangePasswordForm(Form, PasswordFormMixin): """The default change password form""" new_password = PasswordField( get_form_field_label('new_password'), validators=[password_required, password_length, PasswordPolicy()]) new_password_confirm = PasswordField( get_form_field_label('retype_password'), validators=[ EqualTo('new_password', message='RETYPE_PASSWORD_MISMATCH'), password_required ]) submit = SubmitField(get_form_field_label('change_password')) def validate(self): if not super(ChangePasswordForm, self).validate(): return False if not verify_and_update_password(self.password.data, current_user): self.password.errors.append(get_message('INVALID_PASSWORD')[0]) return False if self.password.data.strip() == self.new_password.data.strip(): self.password.errors.append(get_message('PASSWORD_IS_THE_SAME')[0]) return False return True
class UsersLoginForm(LoginForm): """ 定义登陆表单 """ email = StringField(get_form_field_label('email'), render_kw={'placeholder': '*****@*****.**'}) password = PasswordField(get_form_field_label('password'), render_kw={'placeholder': 'your password'}) remember = BooleanField(get_form_field_label('remember_me')) submit = SubmitField(get_form_field_label('login')) fa_addon = {'email': 'fa-envelope-o', 'password': '******'}
class LoginForm(FlaskForm, NextFormMixin): """Username login form""" username = StringField(get_form_field_label("username")) password = PasswordField(get_form_field_label("password")) remember = BooleanField(get_form_field_label("remember_me")) submit = SubmitField(get_form_field_label("login")) def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs) if not self.next.data: self.next.data = request.args.get("next", "") self.remember.default = config_value("DEFAULT_REMEMBER_ME") def validate(self): if not super(LoginForm, self).validate(): return False if not self.username.data.strip(): self.username.errors.append("Username not provided") return False if not self.password.data.strip(): self.password.errors.append( get_message("PASSWORD_NOT_PROVIDED")[0]) return False username = self.username.data self.user = _security.datastore.find_user(username=username) if not self.user: logger.warning("not found {} using username field, " "now using fallback with email".format(username)) self.user = _security.datastore.find_user(email=username) if self.user is None: self.username.errors.append(get_message("USER_DOES_NOT_EXIST")[0]) return False if not self.user.password: self.password.errors.append(get_message("PASSWORD_NOT_SET")[0]) return False if not verify_and_update_password(self.password.data, self.user): self.password.errors.append(get_message("INVALID_PASSWORD")[0]) return False if requires_confirmation(self.user): self.username.errors.append( get_message("CONFIRMATION_REQUIRED")[0]) return False if not self.user.is_active: self.username.errors.append(get_message("DISABLED_ACCOUNT")[0]) return False return True
class EditEmailFormMixin(): email = StringField(get_form_field_label('email'), validators=[ Length(max=DEFAULT_STRING_LENGTH), email_required, email_validator, unique_or_original_email ])
class RegisterForm(ConfirmRegisterForm, NextFormMixin): password_confirm = PasswordField( get_form_field_label("retype_password"), validators=[ EqualTo("password", message="RETYPE_PASSWORD_MISMATCH"), validators.Optional(), ], ) csrf_token = uuid.uuid4() def validate(self): if not super(RegisterForm, self).validate(): return False if not config_value("UNIFIED_SIGNIN"): # password_confirm required if not self.password_confirm.data or not self.password_confirm.data.strip( ): self.password_confirm.errors.append( get_message("PASSWORD_NOT_PROVIDED")[0]) return False return True def __init__(self, *args, **kwargs): super(RegisterForm, self).__init__(*args, **kwargs) if not self.next.data: self.next.data = request.args.get("next", "")
class PasswordConfirmFormMixin(): password_confirm = PasswordField( get_form_field_label('retype_password'), validators=[ EqualTo('password', message='RETYPE_PASSWORD_MISMATCH'), password_required ])
class NewPasswordFormMixin(): random_password = BooleanField('Generate random password', default=True) password = PasswordField( get_form_field_label('password'), validators=[OptionalIf('random_password'), password_strength])
class PasswordConfirmFormMixin(): password_confirm = PasswordField( get_form_field_label('retype_password'), validators=[ OptionalIf('random_password'), EqualTo('password', message='RETYPE_PASSWORD_MISMATCH') ])
class PasswordConfirmFormMixin: password_confirm = PasswordField( get_form_field_label("retype_password"), validators=[ EqualTo("password", message="RETYPE_PASSWORD_MISMATCH"), password_required, ], )
class LoginForm(SecurityLoginForm): """customized login form. validating with backend. Attributes: jwt (TYPE): Description user (TYPE): Description username (TYPE): Description """ username = StringField( get_form_field_label("username"), validators=[], ) jwt = StringField( get_form_field_label("jwt"), validators=[], ) def validate(self): """validate user. Returns: TYPE: Description """ username = self.data.get('username', '') password = self.data.get('password', '') err, jwt = validate_user(username, password) if err: return False err, result = pyutil_mongo.db_find_one('user', {'user_id': username}, ["_id"]) if err: return False the_id = str(result.get("_id", '')) self.user = User() self.user.id = the_id self.user.is_active = True self.user.jwt = jwt return True
class ExtendedRegisterForm(RegisterForm): """ Add user_mail field to the register's class """ user_mail = StringField( get_form_field_label('email'), validators=[email_required, email_validator, unique_user_email]) # TODO: Maybe the validate method is not needed now? """
class ExtendedLoginForm(LoginForm): # New field username = StringField('Username') # We don't want email to be compulsory email = StringField(get_form_field_label('email')) def validate(self): if not super(ExtendedLoginForm, self).validate(): return False self.user = _datastore.get_user(self.username.data) if self.user is None: self.username.errors.append(get_message('USER_DOES_NOT_EXIST')[0]) return False # class
class RegisterFormMixin(object): """RegisterFormMixin for RegisterForm. Attributes: submit (TYPE): Description """ submit = SubmitField(get_form_field_label("register")) def to_dict(self, only_user): """ Return form data as dictionary :param only_user: bool, if True then only fields that have corresponding members in UserModel are returned :return: dict Args: only_user (TYPE): Description Returns: TYPE: Description """ def is_field_and_user_attr(member): """is_field_and_user_attr Args: member (TYPE): Description Returns: TYPE: Description """ # If only fields recorded on UserModel should be returned, # perform check on user model, else return True if only_user is True: return hasattr(_datastore.user_model, getattr(member, 'name', '')) else: return True fields = inspect.getmembers(self, is_field_and_user_attr) the_dict = dict( (key, getattr(value, 'data', '')) for key, value in fields) return the_dict
def monkey_patch_email_field(form_class): """ We use our monkey patched Email validator, and also a html5 email input. """ from wtforms.fields.html5 import EmailField from flask_security.forms import (email_required, unique_user_email, get_form_field_label) import wtforms.validators from pygameweb.user.rbl import rbl def rbl_spamlist_validator(form, field): """ If the ip address of the person signing up is listed in a spam list, we abort with an error. """ remote_addr = request.remote_addr or None if rbl(remote_addr): abort(500) email_validator = wtforms.validators.Email(message='INVALID_EMAIL_ADDRESS') form_class.email = EmailField(get_form_field_label('email'), validators=[ email_required, email_validator, rbl_spamlist_validator, unique_user_email ])
class ResetPasswordForm(Form, NewPasswordFormMixin, PasswordConfirmFormMixin): """The default reset password form""" submit = SubmitField(get_form_field_label('reset_password'))
class NewPasswordFormMixin(): password = PasswordField( get_form_field_label('password'), validators=[password_required, password_length, PasswordPolicy()])
class ConfirmRegisterForm(Form, RegisterFormMixin): user_id = StringField( get_form_field_label("username"), validators=[], ) username = StringField( get_form_field_label("username"), validators=[], ) password = PasswordField( get_form_field_label("password"), validators=[validators.Optional()] ) email = StringField( get_form_field_label("email"), validators=[validators.Optional()] ) nickname = StringField( get_form_field_label("nickname"), validators=[validators.Optional()] ) realname = StringField( get_form_field_label("realname"), validators=[validators.Optional()] ) career = StringField( get_form_field_label("career"), validators=[validators.Optional()] ) address = StringField( get_form_field_label("address"), validators=[validators.Optional()] ) over18 = BooleanField( get_form_field_label("over18"), validators=[validators.Optional()] ) jwt = StringField( get_form_field_label("jwt"), validators=[], ) def validate(self): if not super(ConfirmRegisterForm, self).validate(): return False # XXX hack with user_id data if not self.user_id.data and self.username.data: self.user_id.data = self.username.data # To support unified sign in - we permit registering with no password. if not config_value("UNIFIED_SIGNIN"): # password required if not self.password.data or not self.password.data.strip(): self.password.errors.append(get_message("PASSWORD_NOT_PROVIDED")[0]) return False if not self.password.data: return False if self.password.data: # We do explicit validation here for passwords # (rather than write a validator class) for 2 reasons: # 1) We want to control which fields are passed - # sometimes that's current_user # other times it's the registration fields. # 2) We want to be able to return multiple error messages. rfields = {} for k, v in self.data.items(): if hasattr(_datastore.user_model, k): rfields[k] = v if 'password' in rfields: del rfields["password"] pbad = _security._password_validator(self.password.data, True, **rfields) # validate with ptt-server user_id = self.user_id.data password = self.password.data ip = get_ip() email = self.email.data nickname = self.nickname.data realname = self.realname.data career = self.career.data address = self.address.data over18 = self.over18.data err, result = register_user(user_id, password, ip, email, nickname, realname, career, address, over18) if err is not None: self.user_id.errors = result['err'] return False self.jwt.data = result return True
class ExtendedRegisterForm(RegisterForm): """Extends the Flask-Security registration form.""" name = StringField('Name', [DataRequired()]) submit = SubmitField(get_form_field_label('register'))
class RADIUSLoginForm(Form, NextFormMixin): """Login form for RADIUS users.""" email = StringField("User ID") password = PasswordField(get_form_field_label("password")) remember = BooleanField(get_form_field_label("remember_me")) submit = SubmitField(get_form_field_label("login")) def __init__(self, *args, **kwargs): """Init new RADIUS login form.""" super(RADIUSLoginForm, self).__init__(*args, **kwargs) self._args = args self._kwargs = kwargs if not self.next.data: self.next.data = request.args.get("next", "") self.remember.default = config_value("DEFAULT_REMEMBER_ME") def validate(self): """Validate.""" log = current_app.artemis_logger log.info("RADIUS authenticate() using username %s" % self.email.data) if not super(RADIUSLoginForm, self).validate(): log.warn("super() validate was false!") return False if self.email.data.strip() == "": self.email.errors.append(get_message("USERID_NOT_PROVIDED")[0]) log.warn("userid was not provided") return False if self.password.data.strip() == "": log.warn("password was not provided") self.password.errors.append( get_message("PASSWORD_NOT_PROVIDED")[0]) return False try: admin_user = _datastore.get_user(1) if self.email.data == admin_user.username: log.info("Login using Super-user login") return self._try_local_auth() auth_result, role = _datastore.authenticate( self.email.data, self.password.data) if auth_result is None: self.password.errors.append("No response from RADIUS") log.info("RADIUS authenticate() returned None") return False if not auth_result: self.password.errors.append(get_message("INVALID_PASSWORD")[0]) log.info("RADIUS authenticate() returned False") return False log.info("RADIUS authenticate() returned True. Assigning role %s" % role) username = self.email.data self.user = _datastore.find_user(username=username) if self.user: self.user.password = None self.user.email = username else: self.user = _datastore.create_user(username=username, email=username, password=None, active=True) self._set_role(self.user, _datastore.find_role(role)) _datastore.commit() except Exception: self.password.errors.append( "Internal error. Contact developer and/or check the logs.") log.exception("Unexpected error while handling RADIUS form") return False return True def _set_role(self, user, role): _datastore.remove_role_from_user(user, _datastore.find_role("admin")) _datastore.remove_role_from_user(user, _datastore.find_role("user")) _datastore.add_role_to_user(user, role) def _try_local_auth(self): self.user = _datastore.find_user(username=self.email.data) if not self.user: self.email.errors.append(get_message("USER_DOES_NOT_EXIST")[0]) return False if not self.user.password: self.password.errors.append(get_message("PASSWORD_NOT_SET")[0]) return False if not verify_and_update_password(self.password.data, self.user): self.password.errors.append(get_message("INVALID_PASSWORD")[0]) return False if requires_confirmation(self.user): self.email.errors.append(get_message("CONFIRMATION_REQUIRED")[0]) return False if not self.user.is_active: self.email.errors.append(get_message("DISABLED_ACCOUNT")[0]) return False return True
class LDAPLoginForm(Form, NextFormMixin): """Login form for LDAP users.""" email = StringField('User ID') password = PasswordField(get_form_field_label('password')) remember = BooleanField(get_form_field_label('remember_me')) submit = SubmitField(get_form_field_label('login')) def __init__(self, *args, **kwargs): """Init new LDAP login form.""" super(LDAPLoginForm, self).__init__(*args, **kwargs) self._args = args self._kwargs = kwargs if not self.next.data: self.next.data = request.args.get('next', '') self.remember.default = config_value('DEFAULT_REMEMBER_ME') def validate(self): """Validate LDAP logins against AD.""" if not super(LDAPLoginForm, self).validate(): return False if self.email.data.strip() == '': self.email.errors.append(get_message('USERID_NOT_PROVIDED')[0]) return False if self.password.data.strip() == '': self.password.errors.append( get_message('PASSWORD_NOT_PROVIDED')[0]) return False try: # first we try authenticating against ldap user_dn, ldap_data = _datastore.query_ldap_user(self.email.data) if not _datastore.verify_password(user_dn, self.password.data): self.password.errors.append(get_message('INVALID_PASSWORD')[0]) return False ldap_email = ldap_data[config_value('LDAP_EMAIL_FIELDNAME')].value password = encrypt_password(self.password.data) if _datastore.find_user(email=ldap_email): self.user = _datastore.get_user(ldap_email) # note that this is being stored per user login self.user.password = password else: self.user = _datastore.create_user(email=ldap_email, password=password) _datastore.commit() except LDAPExceptionError: self.email.errors.append(get_message('LDAP_SERVER_DOWN')[0]) return self._try_local_auth() except UserNotFoundInLDAP: return self._try_local_auth() return True def _try_local_auth(self): self.user = _datastore.get_user(self.email.data) if not self.user: self.email.errors.append(get_message('USER_DOES_NOT_EXIST')[0]) return False if not self.user.password: self.password.errors.append(get_message('PASSWORD_NOT_SET')[0]) return False if not verify_and_update_password(self.password.data, self.user): self.password.errors.append(get_message('INVALID_PASSWORD')[0]) return False if requires_confirmation(self.user): self.email.errors.append(get_message('CONFIRMATION_REQUIRED')[0]) return False if not self.user.is_active: self.email.errors.append(get_message('DISABLED_ACCOUNT')[0]) return False return True
class LDAPLoginForm(Form, NextFormMixin): """Login form for LDAP users.""" email = StringField("User ID") password = PasswordField(get_form_field_label("password")) remember = BooleanField(get_form_field_label("remember_me")) submit = SubmitField(get_form_field_label("login")) def __init__(self, *args, **kwargs): """Init new LDAP login form.""" super(LDAPLoginForm, self).__init__(*args, **kwargs) self._args = args self._kwargs = kwargs if not self.next.data: self.next.data = request.args.get("next", "") self.remember.default = config_value("DEFAULT_REMEMBER_ME") def validate(self): """Validate LDAP logins against AD.""" if not super(LDAPLoginForm, self).validate(): return False if self.email.data.strip() == "": self.email.errors.append(get_message("USERID_NOT_PROVIDED")[0]) return False if self.password.data.strip() == "": self.password.errors.append(get_message("PASSWORD_NOT_PROVIDED")[0]) return False try: admin_user = _datastore.get_user(1) if self.email.data == admin_user.username: current_app.artemis_logger.info("Super-user login") return self._try_local_auth() # first we try authenticating against ldap user_dn, ldap_data = _datastore.query_ldap_user(self.email.data) if not _datastore.verify_password(user_dn, self.password.data): self.password.errors.append(get_message("INVALID_PASSWORD")[0]) return False ldap_email = ldap_data[config_value("LDAP_EMAIL_FIELDNAME")].value password = encrypt_password(self.password.data) self.user = _datastore.find_user(email=ldap_email) if self.user: # note that this is being stored per user login self.user.password = password else: self.user = _datastore.create_user( username=ldap_email, email=ldap_email, password=password, active=True, ) # need to somehow decide what role they are groups = config_value("LDAP_ADMIN_GROUPS") field = ldap_data[config_value("LDAP_ADMIN_GROUPS_FIELDNAME")].values if ( isinstance(field, str) and any([group == field for group in groups]) ) or ( isinstance(field, list) and any([group in field for group in groups]) ): add_role = _datastore.find_role("admin") remove_role = _datastore.find_role("user") else: add_role = _datastore.find_role("user") remove_role = _datastore.find_role("admin") _datastore.add_role_to_user(self.user, add_role) _datastore.remove_role_from_user(self.user, remove_role) _datastore.commit() except LDAPKeyError: current_app.artemis_logger.exception("") self.email.errors.append("LDAP Key failure") if self.user: add_role = _datastore.find_role("user") remove_role = _datastore.find_role("admin") _datastore.add_role_to_user(self.user, add_role) _datastore.remove_role_from_user(self.user, remove_role) _datastore.commit() return True return False except LDAPSocketOpenError: current_app.artemis_logger.info("LDAP offline.. Trying local auth") self.email.errors.append("LDAP Server offline") return self._try_local_auth() except LDAPExceptionError: current_app.artemis_logger.exception("") self.email.errors.append("LDAP Auth failed") return False return True def _try_local_auth(self): self.user = _datastore.find_user(username=self.email.data) if not self.user: self.email.errors.append(get_message("USER_DOES_NOT_EXIST")[0]) return False if not self.user.password: self.password.errors.append(get_message("PASSWORD_NOT_SET")[0]) return False if not verify_and_update_password(self.password.data, self.user): self.password.errors.append(get_message("INVALID_PASSWORD")[0]) return False if requires_confirmation(self.user): self.email.errors.append(get_message("CONFIRMATION_REQUIRED")[0]) return False if not self.user.is_active: self.email.errors.append(get_message("DISABLED_ACCOUNT")[0]) return False return True
class ExtendedRegisterForm(RegisterForm): first_name = StringField('First Name', [DataRequired()]) last_name = StringField('Last Name', [DataRequired()]) submit = SubmitField(get_form_field_label('register'))
class UserLeaveForm(Form, PasswordFormMixin): submit = SubmitField(get_form_field_label('leave')) pass