diff --git a/ereuse_devicehub/forms.py b/ereuse_devicehub/forms.py index 2b2bce2d..0f4cefbe 100644 --- a/ereuse_devicehub/forms.py +++ b/ereuse_devicehub/forms.py @@ -1,20 +1,10 @@ -from flask import current_app as app -from flask import g, render_template +from flask import g from flask_wtf import FlaskForm from werkzeug.security import generate_password_hash -from wtforms import ( - BooleanField, - EmailField, - PasswordField, - StringField, - TelField, - validators, -) +from wtforms import BooleanField, EmailField, PasswordField, 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 +from ereuse_devicehub.resources.user.models import User class LoginForm(FlaskForm): @@ -111,100 +101,3 @@ class PasswordForm(FlaskForm): 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) diff --git a/ereuse_devicehub/register/__init__.py b/ereuse_devicehub/register/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/ereuse_devicehub/register/forms.py b/ereuse_devicehub/register/forms.py new file mode 100644 index 00000000..28b47ee6 --- /dev/null +++ b/ereuse_devicehub/register/forms.py @@ -0,0 +1,114 @@ +from flask import current_app as app +from flask import render_template +from flask_wtf import FlaskForm +from wtforms import EmailField, PasswordField, StringField, 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 UserNewRegisterForm(FlaskForm): + email = EmailField( + 'Email Address', [validators.DataRequired(), validators.Length(min=6, max=35)] + ) + password = PasswordField( + 'Password', [validators.DataRequired(), validators.Length(min=6, max=35)] + ) + password2 = PasswordField( + 'Password', [validators.DataRequired(), validators.Length(min=6, max=35)] + ) + name = StringField( + 'Name', [validators.DataRequired(), validators.Length(min=3, 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, + ) + + 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 = 'registration/email_validation.txt' + template_html = 'registration/email_validation.html' + context = { + 'name': self.name.data, + 'host': host, + 'url': url, + } + subject = "Please activate your Usody account" + message = render_template(template, **context) + message_html = render_template(template_html, **context) + + send_email(subject, [self.email.data], message, html_body=message_html) + + def send_mail_admin(self, user): + person = next(iter(user.individuals)) + context = { + 'email': person.email, + 'name': person.name, + } + template = 'registration/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) diff --git a/ereuse_devicehub/register/templates/registration/email_admin_new_user.txt b/ereuse_devicehub/register/templates/registration/email_admin_new_user.txt new file mode 100644 index 00000000..4b6344a2 --- /dev/null +++ b/ereuse_devicehub/register/templates/registration/email_admin_new_user.txt @@ -0,0 +1,4 @@ +A new user has been registered: + +Name: {{ name }} +Email: {{ email }} diff --git a/ereuse_devicehub/register/templates/registration/email_validation.html b/ereuse_devicehub/register/templates/registration/email_validation.html new file mode 100644 index 00000000..3779df3b --- /dev/null +++ b/ereuse_devicehub/register/templates/registration/email_validation.html @@ -0,0 +1,9 @@ +Welcome to Usody.com, {{ name }}!
+
+Please confirm your account by clicking on the following link:
+{{ url }}
+
+ +
+Plaça Eusebi Güell 6-7, Edifici Vèrtex (UPC), planta 0, Barcelona 08034, Spain
+Associació Pangea – Coordinadora Comunicació per a la Cooperació - NIF: G-60437761 diff --git a/ereuse_devicehub/register/templates/registration/email_validation.txt b/ereuse_devicehub/register/templates/registration/email_validation.txt new file mode 100644 index 00000000..760a1878 --- /dev/null +++ b/ereuse_devicehub/register/templates/registration/email_validation.txt @@ -0,0 +1,7 @@ +Welcome to Usody.com, {{ name }}! + +Please confirm your account by clicking on the following link: {{ url }} + +-- +Plaça Eusebi Güell 6-7, Edifici Vèrtex (UPC), planta 0, Barcelona 08034, Spain +Associació Pangea – Coordinadora Comunicació per a la Cooperació - NIF: G-60437761 diff --git a/ereuse_devicehub/register/templates/registration/user_registration.html b/ereuse_devicehub/register/templates/registration/user_registration.html new file mode 100644 index 00000000..74df13a4 --- /dev/null +++ b/ereuse_devicehub/register/templates/registration/user_registration.html @@ -0,0 +1,172 @@ +{% extends "ereuse_devicehub/base.html" %} + +{% block page_title %}Create your account{% endblock %} + +{% block body %} +
+
+ +
+
+
+
+ +
+ + + +
+ +
+ +
+ +
+
Create your account
+ {% if not form._token %} + {% if form.form_errors %} +

+ {% for error in form.form_errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} +
+ +
+ {{ form.csrf_token }} + +
+ + {% if form.name.errors %} +

+ {% for error in form.name.errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} +
+ +
+ +
Please enter your email.
+ {% if form.email.errors %} +

+ {% for error in form.email.errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} +
+ +
+
+ + +
+
Please enter a password!
+ {% if form.password.errors %} +

+ {% for error in form.password.errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} +
+ +
+
+ + +
+
Please enter a password again!
+ {% if form.password2.errors %} +

+ {% for error in form.password2.errors %} + {{ error }}
+ {% endfor %} +

+ {% endif %} +
+ +
+ Password must be at least 6 characters. +
+ +
+ + I accept the + terms and + privacy policy + +
+ +
+ +
+
+

+ Already have an account? Sign in +

+
+
+ {% else %} +
+
+ We have sent you a validation email.
+ Please check your email. +
+ {% endif %} + +
+
+ +
+ Help | + Privacy | + Terms +
+ +
+
+
+ + + + +
+{% endblock body %} diff --git a/ereuse_devicehub/templates/ereuse_devicehub/user_validation.html b/ereuse_devicehub/register/templates/registration/user_validation.html similarity index 69% rename from ereuse_devicehub/templates/ereuse_devicehub/user_validation.html rename to ereuse_devicehub/register/templates/registration/user_validation.html index dde06b84..c48ac592 100644 --- a/ereuse_devicehub/templates/ereuse_devicehub/user_validation.html +++ b/ereuse_devicehub/register/templates/registration/user_validation.html @@ -12,8 +12,8 @@
- +
@@ -25,9 +25,9 @@
User is valid
-
- Your new user is activate.
- Now you can do Login and entry. +
+ You have successfully activated your account!
+ Sign in.
{% else %} @@ -51,7 +51,9 @@
- Designed by BootstrapMade + Help | + Privacy | + Terms
diff --git a/ereuse_devicehub/register/views.py b/ereuse_devicehub/register/views.py new file mode 100644 index 00000000..d506ecba --- /dev/null +++ b/ereuse_devicehub/register/views.py @@ -0,0 +1,50 @@ +import flask +from flask import Blueprint +from flask.views import View + +from ereuse_devicehub import __version__ +from ereuse_devicehub.db import db +from ereuse_devicehub.register.forms import UserNewRegisterForm +from ereuse_devicehub.resources.user.models import UserValidation + +register = Blueprint('register', __name__, template_folder='templates') + + +class UserRegistrationView(View): + methods = ['GET', 'POST'] + template_name = 'registration/user_registration.html' + + def dispatch_request(self): + form = UserNewRegisterForm() + if form.validate_on_submit(): + form.save() + context = {'form': form, 'version': __version__} + return flask.render_template(self.template_name, **context) + + +class UserValidationView(View): + methods = ['GET'] + template_name = 'registration/user_validation.html' + + def dispatch_request(self, token): + context = {'is_valid': self.is_valid(token), 'version': __version__} + return flask.render_template(self.template_name, **context) + + def is_valid(self, token): + user_valid = UserValidation.query.filter_by(token=token).first() + if not user_valid: + return False + user = user_valid.user + user.active = True + db.session.commit() + return True + + +register.add_url_rule( + '/new_register/', + view_func=UserRegistrationView.as_view('user-registration'), +) +register.add_url_rule( + '/validate_user/', + view_func=UserValidationView.as_view('user-validation'), +) diff --git a/ereuse_devicehub/templates/ereuse_devicehub/email_admin_new_user.txt b/ereuse_devicehub/templates/ereuse_devicehub/email_admin_new_user.txt deleted file mode 100644 index 96759431..00000000 --- a/ereuse_devicehub/templates/ereuse_devicehub/email_admin_new_user.txt +++ /dev/null @@ -1,4 +0,0 @@ -A new user has been registered. These are your data -Name: {{ name }} -Telephone: {{ telephone }} -Email: {{ email }} diff --git a/ereuse_devicehub/templates/ereuse_devicehub/email_validation.txt b/ereuse_devicehub/templates/ereuse_devicehub/email_validation.txt deleted file mode 100644 index daeaf7fd..00000000 --- a/ereuse_devicehub/templates/ereuse_devicehub/email_validation.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello, you are register in Usody.com -Please for activate your account click in the next address: {{ url }} diff --git a/ereuse_devicehub/templates/ereuse_devicehub/user_login.html b/ereuse_devicehub/templates/ereuse_devicehub/user_login.html index 97e2c6cb..f6b9a490 100644 --- a/ereuse_devicehub/templates/ereuse_devicehub/user_login.html +++ b/ereuse_devicehub/templates/ereuse_devicehub/user_login.html @@ -61,7 +61,7 @@
-

Don't have account? Create an account

+

Don't have account? Create an account

diff --git a/ereuse_devicehub/templates/ereuse_devicehub/user_registration.html b/ereuse_devicehub/templates/ereuse_devicehub/user_registration.html deleted file mode 100644 index 1e969a97..00000000 --- a/ereuse_devicehub/templates/ereuse_devicehub/user_registration.html +++ /dev/null @@ -1,121 +0,0 @@ -{% extends "ereuse_devicehub/base.html" %} - -{% block page_title %}Login{% endblock %} - -{% block body %} -
-
- -
-
-
-
- -
- -
- -
- -
- -
-
Register as a new User
- {% if not form._token %} -

Enter an Email & password for to do a new register.

- {% if form.form_errors %} -

- {% for error in form.form_errors %} - {{ error }}
- {% endfor %} -

- {% endif %} -
- -
- {{ form.csrf_token }} - -
- - -
Please enter your email.
- {% if form.email.errors %} -

- {% for error in form.email.errors %} - {{ error }}
- {% endfor %} -

- {% endif %} -
- -
- - -
Please enter a password!
-
- -
- - -
Please enter a password again!
-
- -
- - - {% if form.name.errors %} -

- {% for error in form.name.errors %} - {{ error }}
- {% endfor %} -

- {% endif %} -
- -
- - - {% if form.telephone.errors %} -

- {% for error in form.telephone.errors %} - {{ error }}
- {% endfor %} -

- {% endif %} -
- -
- -
-
-

- You have account? do Login -

-
-
- {% else %} -
-
- We have sent you a validation email.
- Please check your email. -
- {% endif %} - -
-
- -
- Designed by BootstrapMade -
- -
-
-
- - - - -
-{% endblock body %} diff --git a/ereuse_devicehub/views.py b/ereuse_devicehub/views.py index 4c80b270..9b35834c 100644 --- a/ereuse_devicehub/views.py +++ b/ereuse_devicehub/views.py @@ -1,15 +1,17 @@ import flask -from flask import Blueprint, g +from flask import Blueprint +from flask import current_app as app +from flask import g from flask.views import View from flask_login import current_user, login_required, login_user, logout_user from sqlalchemy import or_ from ereuse_devicehub import __version__, messages from ereuse_devicehub.db import db -from ereuse_devicehub.forms import LoginForm, PasswordForm, UserNewRegisterForm +from ereuse_devicehub.forms import LoginForm, PasswordForm from ereuse_devicehub.resources.action.models import Trade from ereuse_devicehub.resources.lot.models import Lot -from ereuse_devicehub.resources.user.models import User, UserValidation +from ereuse_devicehub.resources.user.models import User from ereuse_devicehub.utils import is_safe_url core = Blueprint('core', __name__) @@ -39,8 +41,14 @@ class LoginView(View): return flask.abort(400) return flask.redirect(next_url or flask.url_for('inventory.devicelist')) - context = {'form': form, 'version': __version__} - return flask.render_template('ereuse_devicehub/user_login.html', **context) + + url_register = "#" + if 'register' in app.blueprints.keys(): + url_register = flask.url_for('register.user-registration') + + context = {'form': form, 'version': __version__, 'url_register': url_register} + + return flask.render_template(self.template_name, **context) class LogoutView(View): @@ -108,44 +116,7 @@ class UserPasswordView(View): return flask.redirect(flask.url_for('core.user-profile')) -class UserRegistrationView(View): - methods = ['GET', 'POST'] - template_name = 'ereuse_devicehub/user_registration.html' - - def dispatch_request(self): - form = UserNewRegisterForm() - if form.validate_on_submit(): - form.save() - context = {'form': form, 'version': __version__} - return flask.render_template(self.template_name, **context) - - -class UserValidationView(View): - methods = ['GET'] - template_name = 'ereuse_devicehub/user_validation.html' - - def dispatch_request(self, token): - context = {'is_valid': self.is_valid(token), 'version': __version__} - return flask.render_template(self.template_name, **context) - - def is_valid(self, token): - user_valid = UserValidation.query.filter_by(token=token).first() - if not user_valid: - return False - user = user_valid.user - user.active = True - db.session.commit() - return True - - core.add_url_rule('/login/', view_func=LoginView.as_view('login')) core.add_url_rule('/logout/', view_func=LogoutView.as_view('logout')) core.add_url_rule('/profile/', view_func=UserProfileView.as_view('user-profile')) -core.add_url_rule( - '/new_register/', view_func=UserRegistrationView.as_view('user-registration') -) -core.add_url_rule( - '/validate_user/', - view_func=UserValidationView.as_view('user-validation'), -) core.add_url_rule('/set_password/', view_func=UserPasswordView.as_view('set-password')) diff --git a/tests/conftest.py b/tests/conftest.py index 8e5c52d1..8a10cea8 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -22,6 +22,7 @@ from ereuse_devicehub.devicehub import Devicehub from ereuse_devicehub.inventory.views import devices from ereuse_devicehub.labels.views import labels from ereuse_devicehub.mail.flask_mail import Mail +from ereuse_devicehub.register.views import register from ereuse_devicehub.resources.agent.models import Person from ereuse_devicehub.resources.enums import SessionType from ereuse_devicehub.resources.tag import Tag @@ -65,6 +66,7 @@ def _app(config: TestConfig) -> Devicehub: app.register_blueprint(labels) app.register_blueprint(api) app.register_blueprint(workbench) + app.register_blueprint(register) app.config["SQLALCHEMY_RECORD_QUERIES"] = True app.config['PROFILE'] = True # app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) diff --git a/tests/test_render_2_0.py b/tests/test_render_2_0.py index 6cca84f5..f95adf40 100644 --- a/tests/test_render_2_0.py +++ b/tests/test_render_2_0.py @@ -46,7 +46,7 @@ def test_login(user: UserClient, app: Devicehub): body, status, headers = client.get('/login/') body = next(body).decode("utf-8") assert status == '200 OK' - assert "Login to Your Account" in body + assert "Sign in" in body data = { 'email': user.email, @@ -2586,14 +2586,15 @@ def test_snapshot_is_server_erase(user3: UserClientFlask): @pytest.mark.usefixtures(conftest.app_context.__name__) def test_new_register(user3: UserClientFlask, app: Devicehub): uri = '/new_register/' - user3.get(uri) + body, status = user3.get(uri) + assert "Create your account" in body + data = { 'csrf_token': generate_csrf(), 'email': "foo@bar.cxm", - 'password': "1234", - 'password2': "1234", + 'password': "123456", + 'password2': "123456", 'name': "booBar", - 'telephone': "555555555", } body, status = user3.post(uri, data=data) assert status == '200 OK' @@ -2605,7 +2606,7 @@ def test_new_register(user3: UserClientFlask, app: Devicehub): uri = '/validate_user/' + str(user_valid.token) body, status = user3.get(uri) assert status == '200 OK' - assert "Your new user is activate" in body + assert "You have successfully activated your account!" in body assert user_valid.user.active