From ff792aedc1ed84099d02a560fb23f48cefe24a73 Mon Sep 17 00:00:00 2001 From: Llloooggg Date: Sat, 14 Aug 2021 22:33:17 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D1=8C=20=D0=BF=D0=BE=D0=B2=D1=82=D0=BE=D1=80=D0=BD?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=BE=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B4=D1=82=D0=B2=D0=B5=D1=80=D0=B6=D0=B4=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D1=80=D0=B5=D0=B3=D0=B8=D1=81=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dyxless/__init__.py | 3 + dyxless/auth.py | 241 ++++++++++++--------- dyxless/config.json_template | 3 + dyxless/templates/index.html | 2 + dyxless/templates/resend_confirmation.html | 29 +++ dyxless/templates/signup.html | 2 +- 6 files changed, 180 insertions(+), 100 deletions(-) create mode 100644 dyxless/templates/resend_confirmation.html diff --git a/dyxless/__init__.py b/dyxless/__init__.py index 4c70c76..54295be 100644 --- a/dyxless/__init__.py +++ b/dyxless/__init__.py @@ -26,6 +26,9 @@ app.config.update(db_settings) mail_settings = config_data["mail_settings"] app.config.update(mail_settings) +auth_settings = config_data["auth_settings"] +app.config.update(auth_settings) + db.init_app(app) mail.init_app(app) diff --git a/dyxless/auth.py b/dyxless/auth.py index b659397..f7a64a6 100644 --- a/dyxless/auth.py +++ b/dyxless/auth.py @@ -21,6 +21,145 @@ from .mails import send_async_email auth = Blueprint("auth", __name__) +def generate_confirmation_token(email): + serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) + return serializer.dumps( + email, salt=current_app.config["SECURITY_PASSWORD_SALT"] + ) + + +def send_confirmation_email(email): + + token = generate_confirmation_token(email) + confirm_url = url_for("auth.confirm_email", token=token, _external=True) + + try: + send_async_email( + subject="Подтверждение регистрации", + recipients=[email], + html=render_template( + "mail/confirmation_mail.html", confirm_url=confirm_url + ), + ) + except: + return False + + return True + + +@auth.route("/signup", methods=["GET", "POST"]) +def signup(): + + if current_user.is_authenticated: + return redirect(url_for("main.index")) + + elif request.method == "GET": + return render_template("signup.html") + + elif request.method == "POST": + email = request.form.get("email") + username = request.form.get("username") + password = request.form.get("password") + + user = User.query.filter_by(email=email).first() + + if user: + flash( + Markup( + f"Указанная почта уже используется
Перейти к странице входа" + ), + "is-danger", + ) + return redirect(url_for("auth.signup")) + + user = User.query.filter_by(username=username).first() + + if user: + flash("Указанное имя уже используется", "is-danger") + return redirect(url_for("auth.signup")) + + new_user = User( + email=email, + password=password, + username=username, + ) + + db.session.add(new_user) + db.session.commit() + + confirmation_email_sending = send_confirmation_email(new_user.email) + + if confirmation_email_sending: + flash( + "На вашу почту была выслана ссылка для подтверждения регистрации", + "is-success", + ) + else: + flash( + "Что-то пошло не так, свяжитесь с администратором", + "is-danger", + ) + + return redirect(url_for("auth.login")) + + +@auth.route("/resend_confirmation", methods=["GET", "POST"]) +def resend_confirmation(): + + if current_user.is_authenticated and current_user.is_confirmed: + return redirect(url_for("main.index")) + + elif request.method == "GET": + return render_template("resend_confirmation.html") + + elif request.method == "POST": + email = request.form.get("email") + + confirmation_email_sending = send_confirmation_email(email) + + if confirmation_email_sending: + flash( + "На вашу почту была выслана новая ссылка для подтверждения регистрации", + "is-success", + ) + else: + flash( + "Что-то пошло не так, свяжитесь с администратором", + "is-danger", + ) + + return redirect(url_for("auth.login")) + + +def confirm_token(token, expiration): + serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) + try: + email = serializer.loads( + token, + salt=current_app.config["SECURITY_PASSWORD_SALT"], + max_age=expiration, + ) + except: + return False + return email + + +@auth.route("/confirm/") +def confirm_email(token): + try: + email = confirm_token(token, current_app.config["TOKEN_EXPIRATION"]) + except: + flash("Ссылка подтверждения невалидна или устарела", "is-danger") + user = User.query.filter_by(email=email).first_or_404() + if user.is_confirmed: + flash("Аккаунт уже подтвержден", "is-success") + else: + user.is_confirmed = True + db.session.commit() + flash("Ваш аккаунт подвтержден!", "is-success") + return redirect(url_for("auth.login")) + + @auth.route("/login", methods=["GET", "POST"]) def login(): @@ -42,7 +181,9 @@ def login(): return redirect(url_for("auth.login")) elif not user.is_confirmed: flash( - "Аккаунт еще не активирован. Пожалуйста, проверьте вашу почту", + Markup( + f"Аккаунт еще не активирован. Пожалуйста, проверьте вашу почту
Повторная отправка подвтерждения регистрации" + ), "is-warning", ) return redirect(url_for("auth.login")) @@ -56,104 +197,6 @@ def login(): return redirect(url_for("main.profile")) -@auth.route("/signup", methods=["GET", "POST"]) -def signup(): - - if current_user.is_authenticated: - return redirect(url_for("main.index")) - - elif request.method == "GET": - return render_template("signup.html") - - elif request.method == "POST": - email = request.form.get("email") - username = request.form.get("username") - password = request.form.get("password") - - user = User.query.filter_by(email=email).first() - - if user: - login_url = url_for("auth.login") - flash( - Markup( - f"Указанная почта уже используется.
Перейти к странице входа" - ), - "is-danger", - ) - return redirect(url_for("auth.signup")) - - user = User.query.filter_by(username=username).first() - - if user: - flash("Указанное имя уже используется", "is-danger") - return redirect(url_for("auth.signup")) - - new_user = User( - email=email, - password=password, - username=username, - ) - - db.session.add(new_user) - db.session.commit() - - token = generate_confirmation_token(new_user.email) - confirm_url = url_for( - "auth.confirm_email", token=token, _external=True - ) - - send_async_email( - subject="Подтверждение регистрации", - recipients=[new_user.email], - html=render_template( - "mail/confirmation_mail.html", confirm_url=confirm_url - ), - ) - - flash( - "На вашу почту была выслана ссылка для подтверждения регистрации", - "is-success", - ) - - return redirect(url_for("auth.login")) - - -def generate_confirmation_token(email): - serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) - return serializer.dumps( - email, salt=current_app.config["SECURITY_PASSWORD_SALT"] - ) - - -def confirm_token(token, expiration=3600): - serializer = URLSafeTimedSerializer(current_app.config["SECRET_KEY"]) - try: - email = serializer.loads( - token, - salt=current_app.config["SECURITY_PASSWORD_SALT"], - max_age=expiration, - ) - except: - return False - return email - - -@auth.route("/confirm/") -def confirm_email(token): - try: - email = confirm_token(token) - except: - flash("Ссылка подтверждения невалидна или устарела", "is-danger") - user = User.query.filter_by(email=email).first_or_404() - if user.is_confirmed: - flash("Аккаунт уже подтвержден", "is-success") - else: - user.is_confirmed = True - db.session.commit() - flash("Ваш аккаунт подвтержден!", "is-success") - return redirect(url_for("auth.login")) - - @auth.route("/logout") def logout(): logout_user() diff --git a/dyxless/config.json_template b/dyxless/config.json_template index 375bcb7..cd151ab 100644 --- a/dyxless/config.json_template +++ b/dyxless/config.json_template @@ -15,5 +15,8 @@ "MAIL_USE_SSL": true, "MAIL_USERNAME": "yourmail@gmail.com", "MAIL_PASSWORD": "yourpass" + }, + "auth_settings": { + "TOKEN_EXPIRATION": "3600" } } \ No newline at end of file diff --git a/dyxless/templates/index.html b/dyxless/templates/index.html index 57c9e14..84f1c3b 100644 --- a/dyxless/templates/index.html +++ b/dyxless/templates/index.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% block content %} +
@@ -13,4 +14,5 @@
+ {% endblock %} \ No newline at end of file diff --git a/dyxless/templates/resend_confirmation.html b/dyxless/templates/resend_confirmation.html new file mode 100644 index 0000000..65272a9 --- /dev/null +++ b/dyxless/templates/resend_confirmation.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} + +
+
+
+
+

Повторная отправка подтверждения регистрации

+
+ +

+ + + + +

+
+
+

+ +

+
+
+
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/dyxless/templates/signup.html b/dyxless/templates/signup.html index 291dcb4..a122803 100644 --- a/dyxless/templates/signup.html +++ b/dyxless/templates/signup.html @@ -10,7 +10,7 @@

- +