from flask import current_app as app from flask import g, render_template from flask_wtf import FlaskForm from werkzeug.security import generate_password_hash from wtforms import ( BooleanField, EmailField, PasswordField, StringField, TelField, validators, ) from ereuse_devicehub.db import db from ereuse_devicehub.mail.sender import send_email from ereuse_devicehub.resources.agent.models import Person from ereuse_devicehub.resources.user.models import User, UserValidation class LoginForm(FlaskForm): email = EmailField('Email Address', [validators.Length(min=6, max=35)]) password = PasswordField('Password', [validators.DataRequired()]) remember = BooleanField('Remember me') error_messages = { 'invalid_login': ( "Please enter a correct email and password. Note that both " "fields may be case-sensitive." ), 'inactive': "This account is inactive.", } def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) if not is_valid: return False email = self.email.data password = self.password.data self.user_cache = self.authenticate(email, password) if self.user_cache is None: self.form_errors.append(self.error_messages['invalid_login']) return False return self.confirm_login_allowed(self.user_cache) def authenticate(self, email, password): if email is None or password is None: return user = User.query.filter_by(email=email).first() if user is None: # Run the default password hasher once to reduce the timing # difference between an existing and a nonexistent user (#20760). generate_password_hash(password) else: if user.check_password(password): return user def confirm_login_allowed(self, user): """ Controls whether the given User may log in. This is a policy setting, independent of end-user authentication. This default behavior is to allow login by active users, and reject login by inactive users. If the given user cannot log in, this method should raise a ``ValidationError``. If the given user may log in, this method should return None. """ if not user.is_active: self.form_errors.append(self.error_messages['inactive']) return user.is_active class PasswordForm(FlaskForm): password = PasswordField( 'Current Password', [validators.DataRequired()], render_kw={'class': "form-control"}, ) newpassword = PasswordField( 'New Password', [validators.DataRequired()], render_kw={'class': "form-control"}, ) renewpassword = PasswordField( 'Re-enter New Password', [validators.DataRequired()], render_kw={'class': "form-control"}, ) def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) if not is_valid: return False if not g.user.check_password(self.password.data): return False if self.newpassword.data != self.renewpassword.data: return False return True def save(self, commit=True): g.user.password = self.newpassword.data db.session.add(g.user) if commit: db.session.commit() return class UserNewRegisterForm(FlaskForm): email = EmailField( 'Email Address', [validators.DataRequired(), validators.Length(min=6, max=35)] ) password = PasswordField('Password', [validators.DataRequired()]) password2 = PasswordField('Password', [validators.DataRequired()]) name = StringField( 'Name', [validators.DataRequired(), validators.Length(min=3, max=35)] ) telephone = TelField( 'Telephone', [validators.DataRequired(), validators.Length(min=9, max=35)] ) error_messages = { 'invalid_login': ( "Please enter a correct email and password. Note that both " "fields may be case-sensitive." ), 'inactive': "This account is inactive.", } def validate(self, extra_validators=None): is_valid = super().validate(extra_validators) if not is_valid: return False email = self.email.data password = self.password.data password2 = self.password2.data if password != password2: self.form_errors.append('The passwords are not equal.') return False txt = 'This email are in use.' email = self.email.data if User.query.filter_by(email=email).first(): self.form_errors.append(txt) return False self.email.data = self.email.data.strip() self.password.data = self.password.data.strip() return True def save(self, commit=True): user_validation = self.new_user() if commit: db.session.commit() self._token = user_validation.token self.send_mail() self.send_mail_admin(user_validation.user) def new_user(self): user = User(email=self.email.data, password=self.password.data, active=False) person = Person( email=self.email.data, name=self.name.data, telephone=self.telephone.data ) user.individuals.add(person) db.session.add(user) user_validation = UserValidation( user=user, ) db.session.add(user_validation) return user_validation def send_mail(self): host = app.config.get('HOST') token = self._token url = f'https://{ host }/validate_user/{ token }' template = 'ereuse_devicehub/email_validation.txt' message = render_template(template, url=url) subject = "Validate email for register in Usody.com" send_email(subject, [self.email.data], message) def send_mail_admin(self, user): person = next(iter(user.individuals)) context = { 'email': person.email, 'name': person.name, 'telephone': person.telephone, } template = 'ereuse_devicehub/email_admin_new_user.txt' message = render_template(template, **context) subject = "New Register" email_admin = app.config.get("EMAIL_ADMIN") if email_admin: send_email(subject, [email_admin], message)