aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2023-05-30 19:45:09 +0200
committerDaniel Schadt <kingdread@gmx.de>2023-05-30 19:45:09 +0200
commit42c99034be468f6968274700cd6c5abbd7da40ff (patch)
tree5b6b0a4819ed863aa54c904aa1b4296e21448d1a
parentc87903ca4d01382623fb1ac3ce076456c279b841 (diff)
downloadfietsboek-42c99034be468f6968274700cd6c5abbd7da40ff.tar.gz
fietsboek-42c99034be468f6968274700cd6c5abbd7da40ff.tar.bz2
fietsboek-42c99034be468f6968274700cd6c5abbd7da40ff.zip
de-duplicate verification token code
-rw-r--r--fietsboek/actions.py43
-rw-r--r--fietsboek/views/account.py23
-rw-r--r--fietsboek/views/default.py27
3 files changed, 49 insertions, 44 deletions
diff --git a/fietsboek/actions.py b/fietsboek/actions.py
index b9221c3..395843f 100644
--- a/fietsboek/actions.py
+++ b/fietsboek/actions.py
@@ -12,15 +12,17 @@ from typing import List, Optional
import brotli
import gpxpy
+from pyramid.i18n import TranslationString as _
from pyramid.request import Request
from sqlalchemy import select
from sqlalchemy.orm.session import Session
-from . import models
+from . import email, models
from . import transformers as mod_transformers
from . import util
from .data import DataManager, TrackDataDir
from .models.track import TrackType, Visibility
+from .models.user import TokenType
LOGGER = logging.getLogger(__name__)
@@ -219,3 +221,42 @@ def execute_transformers(request: Request, track: models.Track) -> Optional[gpxp
track.ensure_cache(gpx)
request.dbsession.add(track.cache)
return gpx
+
+
+def send_verification_token(request: Request, user: models.User):
+ """Creates a verification token and sends it to the user.
+
+ If no verification token exists yet, a fresh one is created.
+
+ If a token already exists, a fresh one is still created. The old token
+ stays valid until its expiry date.
+
+ Note that this function does not provide the user with feedback other than
+ the email. You may want to show a flash message or similar to show that
+ something has happened.
+
+ :param request: The request.
+ :param user: The user who to generate a verification token for.
+ """
+ # Some of this code appears in the password reset form as well, but that's
+ # fine for now.
+ # pylint: disable=duplicate-code
+ token = models.Token.generate(user, TokenType.VERIFY_EMAIL)
+ request.dbsession.add(token)
+
+ message = email.prepare_message(
+ request.config.email_from,
+ user.email,
+ request.localizer.translate(_("email.verify_mail.subject")),
+ )
+ message.set_content(
+ request.localizer.translate(_("email.verify.text")).format(
+ request.route_url("use-token", uuid=token.uuid)
+ )
+ )
+ email.send_message(
+ request.config.email_smtp_url,
+ request.config.email_username,
+ request.config.email_password.get_secret_value(),
+ message,
+ )
diff --git a/fietsboek/views/account.py b/fietsboek/views/account.py
index 39a62e5..5400f0a 100644
--- a/fietsboek/views/account.py
+++ b/fietsboek/views/account.py
@@ -3,8 +3,7 @@ from pyramid.httpexceptions import HTTPForbidden, HTTPFound
from pyramid.i18n import TranslationString as _
from pyramid.view import view_config
-from .. import email, models, util
-from ..models.user import TokenType
+from .. import actions, models, util
@view_config(
@@ -63,25 +62,7 @@ def do_create_account(request):
user.set_password(password)
request.dbsession.add(user)
- token = models.Token.generate(user, TokenType.VERIFY_EMAIL)
- request.dbsession.add(token)
-
- message = email.prepare_message(
- request.config.email_from,
- user.email,
- request.localizer.translate(_("email.verify_mail.subject")),
- )
- message.set_content(
- request.localizer.translate(_("email.verify.text")).format(
- request.route_url("use-token", uuid=token.uuid)
- )
- )
- email.send_message(
- request.config.email_smtp_url,
- request.config.email_username,
- request.config.email_password.get_secret_value(),
- message,
- )
+ actions.send_verification_token(request, user)
request.session.flash(request.localizer.translate(_("flash.a_confirmation_link_has_been_sent")))
return HTTPFound(request.route_url("login"))
diff --git a/fietsboek/views/default.py b/fietsboek/views/default.py
index b3cad40..f9942c3 100644
--- a/fietsboek/views/default.py
+++ b/fietsboek/views/default.py
@@ -12,7 +12,7 @@ from sqlalchemy import select
from sqlalchemy.exc import NoResultFound
from sqlalchemy.orm import aliased
-from .. import email, models, summaries, util
+from .. import actions, email, models, summaries, util
from ..models.track import TrackType, TrackWithMetadata
from ..models.user import TOKEN_LIFETIME, PasswordMismatch, TokenType
@@ -201,7 +201,7 @@ def do_password_reset(request: Request) -> Response:
request_method="GET",
renderer="fietsboek:templates/resend_verification.jinja2",
)
-def resend_verification(request: Request) -> Response:
+def resend_verification(_request: Request) -> Response:
"""Form to request a new verification mail.
:param request: The Pyramid request.
@@ -221,30 +221,13 @@ def do_resend_verification(request: Request) -> Response:
user = request.dbsession.execute(query).scalar_one_or_none()
if user is None or user.is_verified:
request.session.flash(
- request.localizer.translate(_("flash.resend_verification_email_fail")))
+ request.localizer.translate(_("flash.resend_verification_email_fail"))
+ )
return HTTPFound(request.route_url("resend-verification"))
- token = models.Token.generate(user, TokenType.VERIFY_EMAIL)
- request.dbsession.add(token)
+ actions.send_verification_token(request, user)
request.session.flash(request.localizer.translate(_("flash.verification_token_generated")))
- mail = email.prepare_message(
- request.config.email_from,
- user.email,
- request.localizer.translate(_("email.verify_mail.subject")),
- )
- mail.set_content(
- request.localizer.translate(_("email.verify.text")).format(
- request.route_url("use-token", uuid=token.uuid)
- )
- )
- email.send_message(
- request.config.email_smtp_url,
- request.config.email_username,
- request.config.email_password.get_secret_value(),
- mail,
- )
-
return HTTPFound(request.route_url("login"))