diff options
author | Daniel Schadt <kingdread@gmx.de> | 2022-12-10 17:42:32 +0100 |
---|---|---|
committer | Daniel Schadt <kingdread@gmx.de> | 2022-12-10 17:46:36 +0100 |
commit | 67b7f5ae3f20c930f5d633413bf27979c692c6a1 (patch) | |
tree | 6336d1697dc43eaec7573423462d64e67f332f0b | |
parent | 626c62e547cfa9dfa1fd3b18a524d62b61ccf0d3 (diff) | |
download | fietsboek-67b7f5ae3f20c930f5d633413bf27979c692c6a1.tar.gz fietsboek-67b7f5ae3f20c930f5d633413bf27979c692c6a1.tar.bz2 fietsboek-67b7f5ae3f20c930f5d633413bf27979c692c6a1.zip |
add a "Remember me" option for logins
The default session timeout is at 15 minutes, which can be rather short.
Therefore, we now have a "Remember me" option, which optionally saves
the authentication in a cookie (signed of course, so nobody can tamper
with it). This cookie is set to basically never expire, keeping the user
logged in while not messing with the session timeout (which is also used
for other things like flash messages).
We might think about just removing the session authentication completely
and doing everything with cookies, but we'll see about that. We
definitely want to keep two separate timeouts, but the cookie helper
doesn't seem to provide a way to have single cookies last for longer
(short of having a second helper like we currently do).
-rw-r--r-- | fietsboek/__init__.py | 3 | ||||
-rw-r--r-- | fietsboek/locale/de/LC_MESSAGES/messages.mo | bin | 11699 -> 11757 bytes | |||
-rw-r--r-- | fietsboek/locale/de/LC_MESSAGES/messages.po | 180 | ||||
-rw-r--r-- | fietsboek/locale/en/LC_MESSAGES/messages.mo | bin | 11018 -> 11069 bytes | |||
-rw-r--r-- | fietsboek/locale/en/LC_MESSAGES/messages.po | 180 | ||||
-rw-r--r-- | fietsboek/locale/fietslog.pot | 126 | ||||
-rw-r--r-- | fietsboek/security.py | 30 | ||||
-rw-r--r-- | fietsboek/templates/login.jinja2 | 10 | ||||
-rw-r--r-- | fietsboek/views/default.py | 11 |
9 files changed, 298 insertions, 242 deletions
diff --git a/fietsboek/__init__.py b/fietsboek/__init__.py index a248dc9..d45e9d5 100644 --- a/fietsboek/__init__.py +++ b/fietsboek/__init__.py @@ -73,6 +73,7 @@ def main(_global_config, **settings): return page_manager my_session_factory = SignedCookieSessionFactory(parsed_config.derive_secret("sessions")) + cookie_secret = parsed_config.derive_secret("auth-cookie") with Configurator(settings=settings) as config: config.include("pyramid_jinja2") config.include(".routes") @@ -82,7 +83,7 @@ def main(_global_config, **settings): for pack in parsed_config.language_packs: config.add_translation_dirs(f"{pack}:locale/") config.set_session_factory(my_session_factory) - config.set_security_policy(SecurityPolicy()) + config.set_security_policy(SecurityPolicy(cookie_secret)) config.set_csrf_storage_policy(CookieCSRFStoragePolicy()) config.set_default_csrf_options(require_csrf=True) config.set_locale_negotiator(locale_negotiator) diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.mo b/fietsboek/locale/de/LC_MESSAGES/messages.mo Binary files differindex 7efce7f..7092994 100644 --- a/fietsboek/locale/de/LC_MESSAGES/messages.mo +++ b/fietsboek/locale/de/LC_MESSAGES/messages.mo diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.po b/fietsboek/locale/de/LC_MESSAGES/messages.po index f4a7f03..dfa2bed 100644 --- a/fietsboek/locale/de/LC_MESSAGES/messages.po +++ b/fietsboek/locale/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-08-10 13:36+0200\n" +"POT-Creation-Date: 2022-12-10 17:37+0100\n" "PO-Revision-Date: 2022-07-02 17:35+0200\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language: de\n" @@ -16,41 +16,41 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.11.0\n" -#: fietsboek/util.py:282 +#: fietsboek/util.py:274 msgid "password_constraint.mismatch" msgstr "Passwörter stimmen nicht überein" -#: fietsboek/util.py:284 +#: fietsboek/util.py:276 msgid "password_constraint.length" msgstr "Passwort zu kurz" -#: fietsboek/models/track.py:526 +#: fietsboek/models/track.py:543 msgid "tooltip.table.length" msgstr "Länge" -#: fietsboek/models/track.py:527 +#: fietsboek/models/track.py:544 msgid "tooltip.table.uphill" msgstr "Bergauf" -#: fietsboek/models/track.py:528 +#: fietsboek/models/track.py:545 msgid "tooltip.table.downhill" msgstr "Bergab" -#: fietsboek/models/track.py:529 +#: fietsboek/models/track.py:546 msgid "tooltip.table.moving_time" msgstr "Fahrzeit" -#: fietsboek/models/track.py:530 +#: fietsboek/models/track.py:547 msgid "tooltip.table.stopped_time" msgstr "Haltezeit" -#: fietsboek/models/track.py:531 +#: fietsboek/models/track.py:549 msgid "tooltip.table.max_speed" msgstr "Maximalgeschwindigkeit" -#: fietsboek/models/track.py:533 +#: fietsboek/models/track.py:553 msgid "tooltip.table.avg_speed" msgstr "Durchschnittsgeschwindigkeit" @@ -154,43 +154,43 @@ msgstr "Dies ist eine Aufnahme einer Strecke" msgid "page.browse.synthetic_tooltip" msgstr "Dies ist eine geplante Strecke" -#: fietsboek/templates/browse.jinja2:132 fietsboek/templates/details.jinja2:88 +#: fietsboek/templates/browse.jinja2:132 fietsboek/templates/details.jinja2:90 msgid "page.details.date" msgstr "Datum" -#: fietsboek/templates/browse.jinja2:134 fietsboek/templates/details.jinja2:102 +#: fietsboek/templates/browse.jinja2:134 fietsboek/templates/details.jinja2:104 msgid "page.details.length" msgstr "Länge" -#: fietsboek/templates/browse.jinja2:139 fietsboek/templates/details.jinja2:93 +#: fietsboek/templates/browse.jinja2:139 fietsboek/templates/details.jinja2:95 msgid "page.details.start_time" msgstr "Startzeit" -#: fietsboek/templates/browse.jinja2:141 fietsboek/templates/details.jinja2:97 +#: fietsboek/templates/browse.jinja2:141 fietsboek/templates/details.jinja2:99 msgid "page.details.end_time" msgstr "Endzeit" -#: fietsboek/templates/browse.jinja2:146 fietsboek/templates/details.jinja2:106 +#: fietsboek/templates/browse.jinja2:146 fietsboek/templates/details.jinja2:108 msgid "page.details.uphill" msgstr "Bergauf" -#: fietsboek/templates/browse.jinja2:148 fietsboek/templates/details.jinja2:110 +#: fietsboek/templates/browse.jinja2:148 fietsboek/templates/details.jinja2:112 msgid "page.details.downhill" msgstr "Bergab" -#: fietsboek/templates/browse.jinja2:153 fietsboek/templates/details.jinja2:115 +#: fietsboek/templates/browse.jinja2:153 fietsboek/templates/details.jinja2:117 msgid "page.details.moving_time" msgstr "Fahrzeit" -#: fietsboek/templates/browse.jinja2:155 fietsboek/templates/details.jinja2:119 +#: fietsboek/templates/browse.jinja2:155 fietsboek/templates/details.jinja2:121 msgid "page.details.stopped_time" msgstr "Haltezeit" -#: fietsboek/templates/browse.jinja2:159 fietsboek/templates/details.jinja2:123 +#: fietsboek/templates/browse.jinja2:159 fietsboek/templates/details.jinja2:125 msgid "page.details.max_speed" msgstr "maximale Geschwindigkeit" -#: fietsboek/templates/browse.jinja2:161 fietsboek/templates/details.jinja2:127 +#: fietsboek/templates/browse.jinja2:161 fietsboek/templates/details.jinja2:129 msgid "page.details.avg_speed" msgstr "durchschnittliche Geschwindigkeit" @@ -208,43 +208,43 @@ msgstr "" "Es wurden keine Strecken gefunden, auf die Du Zugriff hast. Versuche, " "Dich anzumelden." -#: fietsboek/templates/create_account.jinja2:4 +#: fietsboek/templates/create_account.jinja2:5 msgid "page.create_account.title" msgstr "Konto Erstellen" -#: fietsboek/templates/create_account.jinja2:11 +#: fietsboek/templates/create_account.jinja2:13 msgid "page.create_account.email_invalid" msgstr "E-Mail-Adresse ungültig" -#: fietsboek/templates/create_account.jinja2:13 +#: fietsboek/templates/create_account.jinja2:15 msgid "page.create_account.email" msgstr "E-Mail-Adresse" -#: fietsboek/templates/create_account.jinja2:22 +#: fietsboek/templates/create_account.jinja2:24 msgid "page.create_account.name_invalid" msgstr "Name ungültig" -#: fietsboek/templates/create_account.jinja2:24 +#: fietsboek/templates/create_account.jinja2:26 msgid "page.create_account.name" msgstr "Name" -#: fietsboek/templates/create_account.jinja2:33 +#: fietsboek/templates/create_account.jinja2:35 msgid "page.create_account.password_invalid" msgstr "Password zu kurz" -#: fietsboek/templates/create_account.jinja2:35 +#: fietsboek/templates/create_account.jinja2:37 msgid "page.create_account.password" msgstr "Passwort" -#: fietsboek/templates/create_account.jinja2:44 +#: fietsboek/templates/create_account.jinja2:46 msgid "page.create_account.password_must_match" msgstr "Passwörter stimmen nicht überein" -#: fietsboek/templates/create_account.jinja2:46 +#: fietsboek/templates/create_account.jinja2:48 msgid "page.create_account.repeat_password" msgstr "Passwort wiederholen" -#: fietsboek/templates/create_account.jinja2:52 +#: fietsboek/templates/create_account.jinja2:54 msgid "page.create_account.create" msgstr "Erstellen" @@ -296,42 +296,42 @@ msgstr "Löschen" msgid "page.details.delete.close" msgstr "Abbrechen" -#: fietsboek/templates/details.jinja2:69 +#: fietsboek/templates/details.jinja2:70 msgid "page.details.tags" msgstr "Schlagwörter" -#: fietsboek/templates/details.jinja2:78 fietsboek/templates/edit.jinja2:10 +#: fietsboek/templates/details.jinja2:80 fietsboek/templates/edit.jinja2:10 #: fietsboek/templates/finish_upload.jinja2:10 msgid "page.noscript" msgstr "" "JavaScript ist deaktiviert, zum Nutzen aller Funktionen bitte JavaScript " "aktivieren" -#: fietsboek/templates/details.jinja2:83 +#: fietsboek/templates/details.jinja2:85 msgid "page.details.download" msgstr "Herunterladen" -#: fietsboek/templates/details.jinja2:172 +#: fietsboek/templates/details.jinja2:174 msgid "page.details.comments" msgstr "Kommentare" -#: fietsboek/templates/details.jinja2:176 +#: fietsboek/templates/details.jinja2:178 msgid "page.details.comments.author" msgstr "Kommentar von {}" -#: fietsboek/templates/details.jinja2:193 +#: fietsboek/templates/details.jinja2:195 msgid "page.details.comments.new.title" msgstr "Kommentar erstellen" -#: fietsboek/templates/details.jinja2:196 +#: fietsboek/templates/details.jinja2:198 msgid "page.details.comments.new.input_title" msgstr "Titel" -#: fietsboek/templates/details.jinja2:197 +#: fietsboek/templates/details.jinja2:199 msgid "page.details.comments.new.input_comment" msgstr "Kommentar" -#: fietsboek/templates/details.jinja2:200 +#: fietsboek/templates/details.jinja2:202 msgid "page.details.comments.new.submit" msgstr "Absenden" @@ -401,40 +401,40 @@ msgstr "Vorlage (synthetisch)" msgid "page.track.form.tags" msgstr "Schlagwörter" -#: fietsboek/templates/edit_form.jinja2:43 +#: fietsboek/templates/edit_form.jinja2:50 msgid "page.track.form.add_tag" msgstr "Schlagwort hinzufügen" -#: fietsboek/templates/edit_form.jinja2:48 +#: fietsboek/templates/edit_form.jinja2:55 msgid "page.track.form.tagged_people" msgstr "Markierte Personen" -#: fietsboek/templates/edit_form.jinja2:63 +#: fietsboek/templates/edit_form.jinja2:70 msgid "page.track.form.add_friend" msgstr "Freund suchen" -#: fietsboek/templates/edit_form.jinja2:83 +#: fietsboek/templates/edit_form.jinja2:90 msgid "page.track.form.badges" msgstr "Wappen" -#: fietsboek/templates/edit_form.jinja2:94 +#: fietsboek/templates/edit_form.jinja2:101 msgid "page.track.form.description" msgstr "Beschreibung" -#: fietsboek/templates/edit_form.jinja2:101 -#: fietsboek/templates/edit_form.jinja2:115 +#: fietsboek/templates/edit_form.jinja2:108 +#: fietsboek/templates/edit_form.jinja2:122 msgid "page.track.form.remove_image" msgstr "Bild entfernen" -#: fietsboek/templates/edit_form.jinja2:110 +#: fietsboek/templates/edit_form.jinja2:117 msgid "page.track.form.select_images" msgstr "Bilder auswählen" -#: fietsboek/templates/edit_form.jinja2:126 +#: fietsboek/templates/edit_form.jinja2:133 msgid "page.track.form.image_description_modal" msgstr "Bildbeschreibung" -#: fietsboek/templates/edit_form.jinja2:133 +#: fietsboek/templates/edit_form.jinja2:140 msgid "page.track.form.image_description_modal.save" msgstr "Übernehmen" @@ -460,7 +460,7 @@ msgstr "Startseite" msgid "page.home.total" msgstr "Gesamt" -#: fietsboek/templates/layout.jinja2:40 +#: fietsboek/templates/layout.jinja2:35 msgid "page.navbar.toggle" msgstr "Navigation umschalten" @@ -476,31 +476,31 @@ msgstr "Stöbern" msgid "page.navbar.upload" msgstr "Hochladen" -#: fietsboek/templates/layout.jinja2:57 +#: fietsboek/templates/layout.jinja2:62 msgid "page.navbar.user" msgstr "Nutzer" -#: fietsboek/templates/layout.jinja2:61 +#: fietsboek/templates/layout.jinja2:66 msgid "page.navbar.welcome_user" msgstr "Willkommen, {}!" -#: fietsboek/templates/layout.jinja2:64 +#: fietsboek/templates/layout.jinja2:69 msgid "page.navbar.logout" msgstr "Abmelden" -#: fietsboek/templates/layout.jinja2:67 +#: fietsboek/templates/layout.jinja2:72 msgid "page.navbar.profile" msgstr "Profil" -#: fietsboek/templates/layout.jinja2:71 +#: fietsboek/templates/layout.jinja2:76 msgid "page.navbar.admin" msgstr "Admin" -#: fietsboek/templates/layout.jinja2:77 +#: fietsboek/templates/layout.jinja2:82 msgid "page.navbar.login" msgstr "Anmelden" -#: fietsboek/templates/layout.jinja2:81 +#: fietsboek/templates/layout.jinja2:86 msgid "page.navbar.create_account" msgstr "Konto Erstellen" @@ -516,11 +516,15 @@ msgstr "E-Mail-Adresse" msgid "page.login.password" msgstr "Passwort" -#: fietsboek/templates/login.jinja2:28 +#: fietsboek/templates/login.jinja2:30 +msgid "page.login.remember-me" +msgstr "Eingeloggt bleiben" + +#: fietsboek/templates/login.jinja2:38 msgid "page.login.submit" msgstr "Anmelden" -#: fietsboek/templates/login.jinja2:33 +#: fietsboek/templates/login.jinja2:43 msgid "page.login.forgot_password" msgstr "Passwort vergessen" @@ -622,70 +626,70 @@ msgstr "Anfrage senden" msgid "page.upload.form.gpx" msgstr "GPX Datei" -#: fietsboek/views/account.py:48 +#: fietsboek/views/account.py:54 msgid "flash.invalid_name" msgstr "Ungültiger Name" -#: fietsboek/views/account.py:53 +#: fietsboek/views/account.py:59 msgid "flash.invalid_email" msgstr "Ungültige E-Mail-Adresse" -#: fietsboek/views/account.py:66 +#: fietsboek/views/account.py:72 msgid "email.verify_mail.subject" msgstr "Fietsboek Konto Bestätigung" -#: fietsboek/views/account.py:68 +#: fietsboek/views/account.py:75 msgid "email.verify.text" msgstr "" "Um Dein Fietsboek-Konto zu bestätigen, nutze diesen Link: {}\n" "\n" "Falls Du kein Konto angelegt hast, ignoriere diese E-Mail." -#: fietsboek/views/account.py:72 +#: fietsboek/views/account.py:86 msgid "flash.a_confirmation_link_has_been_sent" msgstr "Ein Bestätigungslink wurde versandt" -#: fietsboek/views/admin.py:45 +#: fietsboek/views/admin.py:49 msgid "flash.badge_added" msgstr "Wappen hinzugefügt" -#: fietsboek/views/admin.py:69 +#: fietsboek/views/admin.py:73 msgid "flash.badge_modified" msgstr "Wappen bearbeitet" -#: fietsboek/views/admin.py:89 +#: fietsboek/views/admin.py:93 msgid "flash.badge_deleted" msgstr "Wappen gelöscht" -#: fietsboek/views/default.py:75 +#: fietsboek/views/default.py:114 msgid "flash.invalid_credentials" msgstr "Ungültige Nutzerdaten" -#: fietsboek/views/default.py:79 +#: fietsboek/views/default.py:118 msgid "flash.account_not_verified" msgstr "Konto noch nicht bestätigt" -#: fietsboek/views/default.py:82 +#: fietsboek/views/default.py:121 msgid "flash.logged_in" msgstr "Du bist nun angemeldet" -#: fietsboek/views/default.py:96 +#: fietsboek/views/default.py:143 msgid "flash.logged_out" msgstr "Du bist nun abgemeldet" -#: fietsboek/views/default.py:127 +#: fietsboek/views/default.py:177 msgid "flash.reset_invalid_email" msgstr "Ungültige E-Mail-Adresse angegeben" -#: fietsboek/views/default.py:132 +#: fietsboek/views/default.py:182 msgid "flash.password_token_generated" msgstr "Ein Link zum Zurücksetzen des Passworts wurde versandt" -#: fietsboek/views/default.py:137 +#: fietsboek/views/default.py:187 msgid "page.password_reset.email.subject" msgstr "Fietsboek Passwortzurücksetzung" -#: fietsboek/views/default.py:141 +#: fietsboek/views/default.py:190 msgid "page.password_reset.email.body" msgstr "" "Du kannst Dein Fietsboek-Passwort hier zurücksetzen: {}\n" @@ -693,51 +697,51 @@ msgstr "" "Falls Du keine Passwortzurücksetzung beantragt hast, dann ignoriere diese" " E-Mail." -#: fietsboek/views/default.py:168 +#: fietsboek/views/default.py:223 msgid "flash.email_verified" msgstr "E-Mail-Adresse bestätigt" -#: fietsboek/views/default.py:182 +#: fietsboek/views/default.py:237 msgid "flash.password_updated" msgstr "Passwort aktualisiert" -#: fietsboek/views/detail.py:94 +#: fietsboek/views/detail.py:101 msgid "flash.track_deleted" msgstr "Strecke gelöscht" -#: fietsboek/views/profile.py:57 +#: fietsboek/views/profile.py:61 msgid "flash.personal_data_updated" msgstr "Persönliche Daten wurden gespeichert" -#: fietsboek/views/profile.py:77 +#: fietsboek/views/profile.py:79 msgid "flash.friend_not_found" msgstr "Das angegebene Konto wurde nicht gefunden" -#: fietsboek/views/profile.py:82 +#: fietsboek/views/profile.py:85 msgid "flash.friend_already_exists" msgstr "Dieser Freund existiert bereits" -#: fietsboek/views/profile.py:90 +#: fietsboek/views/profile.py:93 msgid "flash.friend_added" msgstr "Freund hinzugefügt" -#: fietsboek/views/profile.py:100 +#: fietsboek/views/profile.py:103 msgid "flash.friend_request_sent" msgstr "Freundschaftsanfrage gesendet" -#: fietsboek/views/upload.py:52 +#: fietsboek/views/upload.py:56 msgid "flash.no_file_selected" msgstr "Keine Datei ausgewählt" -#: fietsboek/views/upload.py:62 +#: fietsboek/views/upload.py:66 msgid "flash.invalid_file" msgstr "Ungültige GPX-Datei gesendet" -#: fietsboek/views/upload.py:179 +#: fietsboek/views/upload.py:189 msgid "flash.upload_success" msgstr "Hochladen erfolgreich" -#: fietsboek/views/upload.py:195 +#: fietsboek/views/upload.py:205 msgid "flash.upload_cancelled" msgstr "Hochladen abgebrochen" diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.mo b/fietsboek/locale/en/LC_MESSAGES/messages.mo Binary files differindex ee23eef..7827a62 100644 --- a/fietsboek/locale/en/LC_MESSAGES/messages.mo +++ b/fietsboek/locale/en/LC_MESSAGES/messages.mo diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.po b/fietsboek/locale/en/LC_MESSAGES/messages.po index 71c8b17..f4b0239 100644 --- a/fietsboek/locale/en/LC_MESSAGES/messages.po +++ b/fietsboek/locale/en/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-08-10 13:36+0200\n" +"POT-Creation-Date: 2022-12-10 17:37+0100\n" "PO-Revision-Date: 2022-06-28 13:11+0200\n" "Last-Translator: \n" "Language: en\n" @@ -16,41 +16,41 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.10.3\n" +"Generated-By: Babel 2.11.0\n" -#: fietsboek/util.py:282 +#: fietsboek/util.py:274 msgid "password_constraint.mismatch" msgstr "Passwords don't match" -#: fietsboek/util.py:284 +#: fietsboek/util.py:276 msgid "password_constraint.length" msgstr "Password not long enough" -#: fietsboek/models/track.py:526 +#: fietsboek/models/track.py:543 msgid "tooltip.table.length" msgstr "Length" -#: fietsboek/models/track.py:527 +#: fietsboek/models/track.py:544 msgid "tooltip.table.uphill" msgstr "Uphill" -#: fietsboek/models/track.py:528 +#: fietsboek/models/track.py:545 msgid "tooltip.table.downhill" msgstr "Downhill" -#: fietsboek/models/track.py:529 +#: fietsboek/models/track.py:546 msgid "tooltip.table.moving_time" msgstr "Moving Time" -#: fietsboek/models/track.py:530 +#: fietsboek/models/track.py:547 msgid "tooltip.table.stopped_time" msgstr "Stopped Time" -#: fietsboek/models/track.py:531 +#: fietsboek/models/track.py:549 msgid "tooltip.table.max_speed" msgstr "Max Speed" -#: fietsboek/models/track.py:533 +#: fietsboek/models/track.py:553 msgid "tooltip.table.avg_speed" msgstr "Average Speed" @@ -154,43 +154,43 @@ msgstr "This is a recording of a track" msgid "page.browse.synthetic_tooltip" msgstr "This is a pre-planned track" -#: fietsboek/templates/browse.jinja2:132 fietsboek/templates/details.jinja2:88 +#: fietsboek/templates/browse.jinja2:132 fietsboek/templates/details.jinja2:90 msgid "page.details.date" msgstr "Date" -#: fietsboek/templates/browse.jinja2:134 fietsboek/templates/details.jinja2:102 +#: fietsboek/templates/browse.jinja2:134 fietsboek/templates/details.jinja2:104 msgid "page.details.length" msgstr "Length" -#: fietsboek/templates/browse.jinja2:139 fietsboek/templates/details.jinja2:93 +#: fietsboek/templates/browse.jinja2:139 fietsboek/templates/details.jinja2:95 msgid "page.details.start_time" msgstr "Record Start" -#: fietsboek/templates/browse.jinja2:141 fietsboek/templates/details.jinja2:97 +#: fietsboek/templates/browse.jinja2:141 fietsboek/templates/details.jinja2:99 msgid "page.details.end_time" msgstr "Record End" -#: fietsboek/templates/browse.jinja2:146 fietsboek/templates/details.jinja2:106 +#: fietsboek/templates/browse.jinja2:146 fietsboek/templates/details.jinja2:108 msgid "page.details.uphill" msgstr "Uphill" -#: fietsboek/templates/browse.jinja2:148 fietsboek/templates/details.jinja2:110 +#: fietsboek/templates/browse.jinja2:148 fietsboek/templates/details.jinja2:112 msgid "page.details.downhill" msgstr "Downhill" -#: fietsboek/templates/browse.jinja2:153 fietsboek/templates/details.jinja2:115 +#: fietsboek/templates/browse.jinja2:153 fietsboek/templates/details.jinja2:117 msgid "page.details.moving_time" msgstr "Moving Time" -#: fietsboek/templates/browse.jinja2:155 fietsboek/templates/details.jinja2:119 +#: fietsboek/templates/browse.jinja2:155 fietsboek/templates/details.jinja2:121 msgid "page.details.stopped_time" msgstr "Stopped Time" -#: fietsboek/templates/browse.jinja2:159 fietsboek/templates/details.jinja2:123 +#: fietsboek/templates/browse.jinja2:159 fietsboek/templates/details.jinja2:125 msgid "page.details.max_speed" msgstr "Max Speed" -#: fietsboek/templates/browse.jinja2:161 fietsboek/templates/details.jinja2:127 +#: fietsboek/templates/browse.jinja2:161 fietsboek/templates/details.jinja2:129 msgid "page.details.avg_speed" msgstr "Average Speed" @@ -206,43 +206,43 @@ msgstr "No results matching the filters were found." msgid "page.browse.no_tracks" msgstr "You currently do not have access to any tracks. Try logging in." -#: fietsboek/templates/create_account.jinja2:4 +#: fietsboek/templates/create_account.jinja2:5 msgid "page.create_account.title" msgstr "Create Account" -#: fietsboek/templates/create_account.jinja2:11 +#: fietsboek/templates/create_account.jinja2:13 msgid "page.create_account.email_invalid" msgstr "Invalid email address" -#: fietsboek/templates/create_account.jinja2:13 +#: fietsboek/templates/create_account.jinja2:15 msgid "page.create_account.email" msgstr "E-Mail" -#: fietsboek/templates/create_account.jinja2:22 +#: fietsboek/templates/create_account.jinja2:24 msgid "page.create_account.name_invalid" msgstr "Name invalid" -#: fietsboek/templates/create_account.jinja2:24 +#: fietsboek/templates/create_account.jinja2:26 msgid "page.create_account.name" msgstr "Name" -#: fietsboek/templates/create_account.jinja2:33 +#: fietsboek/templates/create_account.jinja2:35 msgid "page.create_account.password_invalid" msgstr "Password not long enough" -#: fietsboek/templates/create_account.jinja2:35 +#: fietsboek/templates/create_account.jinja2:37 msgid "page.create_account.password" msgstr "Password" -#: fietsboek/templates/create_account.jinja2:44 +#: fietsboek/templates/create_account.jinja2:46 msgid "page.create_account.password_must_match" msgstr "Passwords must match" -#: fietsboek/templates/create_account.jinja2:46 +#: fietsboek/templates/create_account.jinja2:48 msgid "page.create_account.repeat_password" msgstr "Repeat password" -#: fietsboek/templates/create_account.jinja2:52 +#: fietsboek/templates/create_account.jinja2:54 msgid "page.create_account.create" msgstr "Create" @@ -294,40 +294,40 @@ msgstr "Delete" msgid "page.details.delete.close" msgstr "Abort" -#: fietsboek/templates/details.jinja2:69 +#: fietsboek/templates/details.jinja2:70 msgid "page.details.tags" msgstr "Tagged as" -#: fietsboek/templates/details.jinja2:78 fietsboek/templates/edit.jinja2:10 +#: fietsboek/templates/details.jinja2:80 fietsboek/templates/edit.jinja2:10 #: fietsboek/templates/finish_upload.jinja2:10 msgid "page.noscript" msgstr "JavaScript is disabled, please enable JavaScript" -#: fietsboek/templates/details.jinja2:83 +#: fietsboek/templates/details.jinja2:85 msgid "page.details.download" msgstr "Download Tour" -#: fietsboek/templates/details.jinja2:172 +#: fietsboek/templates/details.jinja2:174 msgid "page.details.comments" msgstr "Comments" -#: fietsboek/templates/details.jinja2:176 +#: fietsboek/templates/details.jinja2:178 msgid "page.details.comments.author" msgstr "Comment by {}" -#: fietsboek/templates/details.jinja2:193 +#: fietsboek/templates/details.jinja2:195 msgid "page.details.comments.new.title" msgstr "Create a new comment" -#: fietsboek/templates/details.jinja2:196 +#: fietsboek/templates/details.jinja2:198 msgid "page.details.comments.new.input_title" msgstr "Title" -#: fietsboek/templates/details.jinja2:197 +#: fietsboek/templates/details.jinja2:199 msgid "page.details.comments.new.input_comment" msgstr "Comment" -#: fietsboek/templates/details.jinja2:200 +#: fietsboek/templates/details.jinja2:202 msgid "page.details.comments.new.submit" msgstr "Submit" @@ -397,40 +397,40 @@ msgstr "Template (synthetic)" msgid "page.track.form.tags" msgstr "Tags" -#: fietsboek/templates/edit_form.jinja2:43 +#: fietsboek/templates/edit_form.jinja2:50 msgid "page.track.form.add_tag" msgstr "Add Tag" -#: fietsboek/templates/edit_form.jinja2:48 +#: fietsboek/templates/edit_form.jinja2:55 msgid "page.track.form.tagged_people" msgstr "Tagged People" -#: fietsboek/templates/edit_form.jinja2:63 +#: fietsboek/templates/edit_form.jinja2:70 msgid "page.track.form.add_friend" msgstr "Search friends" -#: fietsboek/templates/edit_form.jinja2:83 +#: fietsboek/templates/edit_form.jinja2:90 msgid "page.track.form.badges" msgstr "Badges" -#: fietsboek/templates/edit_form.jinja2:94 +#: fietsboek/templates/edit_form.jinja2:101 msgid "page.track.form.description" msgstr "Description" -#: fietsboek/templates/edit_form.jinja2:101 -#: fietsboek/templates/edit_form.jinja2:115 +#: fietsboek/templates/edit_form.jinja2:108 +#: fietsboek/templates/edit_form.jinja2:122 msgid "page.track.form.remove_image" msgstr "Remove image" -#: fietsboek/templates/edit_form.jinja2:110 +#: fietsboek/templates/edit_form.jinja2:117 msgid "page.track.form.select_images" msgstr "Select images" -#: fietsboek/templates/edit_form.jinja2:126 +#: fietsboek/templates/edit_form.jinja2:133 msgid "page.track.form.image_description_modal" msgstr "Image description" -#: fietsboek/templates/edit_form.jinja2:133 +#: fietsboek/templates/edit_form.jinja2:140 msgid "page.track.form.image_description_modal.save" msgstr "Apply" @@ -456,7 +456,7 @@ msgstr "Home" msgid "page.home.total" msgstr "Total" -#: fietsboek/templates/layout.jinja2:40 +#: fietsboek/templates/layout.jinja2:35 msgid "page.navbar.toggle" msgstr "Toggle navigation" @@ -472,31 +472,31 @@ msgstr "Browse" msgid "page.navbar.upload" msgstr "Upload" -#: fietsboek/templates/layout.jinja2:57 +#: fietsboek/templates/layout.jinja2:62 msgid "page.navbar.user" msgstr "User" -#: fietsboek/templates/layout.jinja2:61 +#: fietsboek/templates/layout.jinja2:66 msgid "page.navbar.welcome_user" msgstr "Welcome, {}!" -#: fietsboek/templates/layout.jinja2:64 +#: fietsboek/templates/layout.jinja2:69 msgid "page.navbar.logout" msgstr "Logout" -#: fietsboek/templates/layout.jinja2:67 +#: fietsboek/templates/layout.jinja2:72 msgid "page.navbar.profile" msgstr "Profile" -#: fietsboek/templates/layout.jinja2:71 +#: fietsboek/templates/layout.jinja2:76 msgid "page.navbar.admin" msgstr "Admin" -#: fietsboek/templates/layout.jinja2:77 +#: fietsboek/templates/layout.jinja2:82 msgid "page.navbar.login" msgstr "Login" -#: fietsboek/templates/layout.jinja2:81 +#: fietsboek/templates/layout.jinja2:86 msgid "page.navbar.create_account" msgstr "Create Account" @@ -512,11 +512,15 @@ msgstr "E-Mail" msgid "page.login.password" msgstr "Password" -#: fietsboek/templates/login.jinja2:28 +#: fietsboek/templates/login.jinja2:30 +msgid "page.login.remember-me" +msgstr "Remember me" + +#: fietsboek/templates/login.jinja2:38 msgid "page.login.submit" msgstr "Login" -#: fietsboek/templates/login.jinja2:33 +#: fietsboek/templates/login.jinja2:43 msgid "page.login.forgot_password" msgstr "Forgot password" @@ -618,121 +622,121 @@ msgstr "Send request" msgid "page.upload.form.gpx" msgstr "GPX file" -#: fietsboek/views/account.py:48 +#: fietsboek/views/account.py:54 msgid "flash.invalid_name" msgstr "Invalid name" -#: fietsboek/views/account.py:53 +#: fietsboek/views/account.py:59 msgid "flash.invalid_email" msgstr "Invalid email" -#: fietsboek/views/account.py:66 +#: fietsboek/views/account.py:72 msgid "email.verify_mail.subject" msgstr "Fietsboek Account Verification" -#: fietsboek/views/account.py:68 +#: fietsboek/views/account.py:75 msgid "email.verify.text" msgstr "" "To verify your Fietsboek account, please use this link: {}\n" "\n" "If you did not create an account, ignore this email." -#: fietsboek/views/account.py:72 +#: fietsboek/views/account.py:86 msgid "flash.a_confirmation_link_has_been_sent" msgstr "A confirmation link has been sent" -#: fietsboek/views/admin.py:45 +#: fietsboek/views/admin.py:49 msgid "flash.badge_added" msgstr "Badge has been added" -#: fietsboek/views/admin.py:69 +#: fietsboek/views/admin.py:73 msgid "flash.badge_modified" msgstr "Badge has been modified" -#: fietsboek/views/admin.py:89 +#: fietsboek/views/admin.py:93 msgid "flash.badge_deleted" msgstr "Badge has been deleted" -#: fietsboek/views/default.py:75 +#: fietsboek/views/default.py:114 msgid "flash.invalid_credentials" msgstr "Invalid login credentials" -#: fietsboek/views/default.py:79 +#: fietsboek/views/default.py:118 msgid "flash.account_not_verified" msgstr "Your account is not verified yet" -#: fietsboek/views/default.py:82 +#: fietsboek/views/default.py:121 msgid "flash.logged_in" msgstr "You are now logged in" -#: fietsboek/views/default.py:96 +#: fietsboek/views/default.py:143 msgid "flash.logged_out" msgstr "You have been logged out" -#: fietsboek/views/default.py:127 +#: fietsboek/views/default.py:177 msgid "flash.reset_invalid_email" msgstr "Invalid email address provided" -#: fietsboek/views/default.py:132 +#: fietsboek/views/default.py:182 msgid "flash.password_token_generated" msgstr "A password reset email has been sent" -#: fietsboek/views/default.py:137 +#: fietsboek/views/default.py:187 msgid "page.password_reset.email.subject" msgstr "Fietsboek Password Reset" -#: fietsboek/views/default.py:141 +#: fietsboek/views/default.py:190 msgid "page.password_reset.email.body" msgstr "" "You can reset your Fietsboek password here: {}\n" "\n" "If you did not request a password reset, ignore this email." -#: fietsboek/views/default.py:168 +#: fietsboek/views/default.py:223 msgid "flash.email_verified" msgstr "Your email address has been verified" -#: fietsboek/views/default.py:182 +#: fietsboek/views/default.py:237 msgid "flash.password_updated" msgstr "Password has been updated" -#: fietsboek/views/detail.py:94 +#: fietsboek/views/detail.py:101 msgid "flash.track_deleted" msgstr "Track has been deleted" -#: fietsboek/views/profile.py:57 +#: fietsboek/views/profile.py:61 msgid "flash.personal_data_updated" msgstr "Personal data has been updated" -#: fietsboek/views/profile.py:77 +#: fietsboek/views/profile.py:79 msgid "flash.friend_not_found" msgstr "The friend was not found" -#: fietsboek/views/profile.py:82 +#: fietsboek/views/profile.py:85 msgid "flash.friend_already_exists" msgstr "Friend already exists" -#: fietsboek/views/profile.py:90 +#: fietsboek/views/profile.py:93 msgid "flash.friend_added" msgstr "Friend has been added" -#: fietsboek/views/profile.py:100 +#: fietsboek/views/profile.py:103 msgid "flash.friend_request_sent" msgstr "Friend request sent" -#: fietsboek/views/upload.py:52 +#: fietsboek/views/upload.py:56 msgid "flash.no_file_selected" msgstr "No file selected" -#: fietsboek/views/upload.py:62 +#: fietsboek/views/upload.py:66 msgid "flash.invalid_file" msgstr "Invalid GPX file selected" -#: fietsboek/views/upload.py:179 +#: fietsboek/views/upload.py:189 msgid "flash.upload_success" msgstr "Upload successful" -#: fietsboek/views/upload.py:195 +#: fietsboek/views/upload.py:205 msgid "flash.upload_cancelled" msgstr "Upload cancelled" diff --git a/fietsboek/locale/fietslog.pot b/fietsboek/locale/fietslog.pot index abb2bfc..a86c43b 100644 --- a/fietsboek/locale/fietslog.pot +++ b/fietsboek/locale/fietslog.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-11-15 23:42+0100\n" +"POT-Creation-Date: 2022-12-10 17:37+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -17,39 +17,39 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.11.0\n" -#: fietsboek/util.py:282 +#: fietsboek/util.py:274 msgid "password_constraint.mismatch" msgstr "" -#: fietsboek/util.py:284 +#: fietsboek/util.py:276 msgid "password_constraint.length" msgstr "" -#: fietsboek/models/track.py:526 +#: fietsboek/models/track.py:543 msgid "tooltip.table.length" msgstr "" -#: fietsboek/models/track.py:527 +#: fietsboek/models/track.py:544 msgid "tooltip.table.uphill" msgstr "" -#: fietsboek/models/track.py:528 +#: fietsboek/models/track.py:545 msgid "tooltip.table.downhill" msgstr "" -#: fietsboek/models/track.py:529 +#: fietsboek/models/track.py:546 msgid "tooltip.table.moving_time" msgstr "" -#: fietsboek/models/track.py:530 +#: fietsboek/models/track.py:547 msgid "tooltip.table.stopped_time" msgstr "" -#: fietsboek/models/track.py:531 +#: fietsboek/models/track.py:549 msgid "tooltip.table.max_speed" msgstr "" -#: fietsboek/models/track.py:533 +#: fietsboek/models/track.py:553 msgid "tooltip.table.avg_speed" msgstr "" @@ -205,43 +205,43 @@ msgstr "" msgid "page.browse.no_tracks" msgstr "" -#: fietsboek/templates/create_account.jinja2:4 +#: fietsboek/templates/create_account.jinja2:5 msgid "page.create_account.title" msgstr "" -#: fietsboek/templates/create_account.jinja2:11 +#: fietsboek/templates/create_account.jinja2:13 msgid "page.create_account.email_invalid" msgstr "" -#: fietsboek/templates/create_account.jinja2:13 +#: fietsboek/templates/create_account.jinja2:15 msgid "page.create_account.email" msgstr "" -#: fietsboek/templates/create_account.jinja2:22 +#: fietsboek/templates/create_account.jinja2:24 msgid "page.create_account.name_invalid" msgstr "" -#: fietsboek/templates/create_account.jinja2:24 +#: fietsboek/templates/create_account.jinja2:26 msgid "page.create_account.name" msgstr "" -#: fietsboek/templates/create_account.jinja2:33 +#: fietsboek/templates/create_account.jinja2:35 msgid "page.create_account.password_invalid" msgstr "" -#: fietsboek/templates/create_account.jinja2:35 +#: fietsboek/templates/create_account.jinja2:37 msgid "page.create_account.password" msgstr "" -#: fietsboek/templates/create_account.jinja2:44 +#: fietsboek/templates/create_account.jinja2:46 msgid "page.create_account.password_must_match" msgstr "" -#: fietsboek/templates/create_account.jinja2:46 +#: fietsboek/templates/create_account.jinja2:48 msgid "page.create_account.repeat_password" msgstr "" -#: fietsboek/templates/create_account.jinja2:52 +#: fietsboek/templates/create_account.jinja2:54 msgid "page.create_account.create" msgstr "" @@ -453,47 +453,47 @@ msgstr "" msgid "page.home.total" msgstr "" -#: fietsboek/templates/layout.jinja2:40 +#: fietsboek/templates/layout.jinja2:35 msgid "page.navbar.toggle" msgstr "" -#: fietsboek/templates/layout.jinja2:51 +#: fietsboek/templates/layout.jinja2:46 msgid "page.navbar.home" msgstr "" -#: fietsboek/templates/layout.jinja2:54 +#: fietsboek/templates/layout.jinja2:49 msgid "page.navbar.browse" msgstr "" -#: fietsboek/templates/layout.jinja2:58 +#: fietsboek/templates/layout.jinja2:53 msgid "page.navbar.upload" msgstr "" -#: fietsboek/templates/layout.jinja2:67 +#: fietsboek/templates/layout.jinja2:62 msgid "page.navbar.user" msgstr "" -#: fietsboek/templates/layout.jinja2:71 +#: fietsboek/templates/layout.jinja2:66 msgid "page.navbar.welcome_user" msgstr "" -#: fietsboek/templates/layout.jinja2:74 +#: fietsboek/templates/layout.jinja2:69 msgid "page.navbar.logout" msgstr "" -#: fietsboek/templates/layout.jinja2:77 +#: fietsboek/templates/layout.jinja2:72 msgid "page.navbar.profile" msgstr "" -#: fietsboek/templates/layout.jinja2:81 +#: fietsboek/templates/layout.jinja2:76 msgid "page.navbar.admin" msgstr "" -#: fietsboek/templates/layout.jinja2:87 +#: fietsboek/templates/layout.jinja2:82 msgid "page.navbar.login" msgstr "" -#: fietsboek/templates/layout.jinja2:91 +#: fietsboek/templates/layout.jinja2:86 msgid "page.navbar.create_account" msgstr "" @@ -509,11 +509,15 @@ msgstr "" msgid "page.login.password" msgstr "" -#: fietsboek/templates/login.jinja2:28 +#: fietsboek/templates/login.jinja2:30 +msgid "page.login.remember-me" +msgstr "" + +#: fietsboek/templates/login.jinja2:38 msgid "page.login.submit" msgstr "" -#: fietsboek/templates/login.jinja2:33 +#: fietsboek/templates/login.jinja2:43 msgid "page.login.forgot_password" msgstr "" @@ -613,115 +617,115 @@ msgstr "" msgid "page.upload.form.gpx" msgstr "" -#: fietsboek/views/account.py:48 +#: fietsboek/views/account.py:54 msgid "flash.invalid_name" msgstr "" -#: fietsboek/views/account.py:53 +#: fietsboek/views/account.py:59 msgid "flash.invalid_email" msgstr "" -#: fietsboek/views/account.py:66 +#: fietsboek/views/account.py:72 msgid "email.verify_mail.subject" msgstr "" -#: fietsboek/views/account.py:68 +#: fietsboek/views/account.py:75 msgid "email.verify.text" msgstr "" -#: fietsboek/views/account.py:72 +#: fietsboek/views/account.py:86 msgid "flash.a_confirmation_link_has_been_sent" msgstr "" -#: fietsboek/views/admin.py:45 +#: fietsboek/views/admin.py:49 msgid "flash.badge_added" msgstr "" -#: fietsboek/views/admin.py:69 +#: fietsboek/views/admin.py:73 msgid "flash.badge_modified" msgstr "" -#: fietsboek/views/admin.py:89 +#: fietsboek/views/admin.py:93 msgid "flash.badge_deleted" msgstr "" -#: fietsboek/views/default.py:96 +#: fietsboek/views/default.py:114 msgid "flash.invalid_credentials" msgstr "" -#: fietsboek/views/default.py:100 +#: fietsboek/views/default.py:118 msgid "flash.account_not_verified" msgstr "" -#: fietsboek/views/default.py:103 +#: fietsboek/views/default.py:121 msgid "flash.logged_in" msgstr "" -#: fietsboek/views/default.py:117 +#: fietsboek/views/default.py:143 msgid "flash.logged_out" msgstr "" -#: fietsboek/views/default.py:148 +#: fietsboek/views/default.py:177 msgid "flash.reset_invalid_email" msgstr "" -#: fietsboek/views/default.py:153 +#: fietsboek/views/default.py:182 msgid "flash.password_token_generated" msgstr "" -#: fietsboek/views/default.py:158 +#: fietsboek/views/default.py:187 msgid "page.password_reset.email.subject" msgstr "" -#: fietsboek/views/default.py:162 +#: fietsboek/views/default.py:190 msgid "page.password_reset.email.body" msgstr "" -#: fietsboek/views/default.py:189 +#: fietsboek/views/default.py:223 msgid "flash.email_verified" msgstr "" -#: fietsboek/views/default.py:203 +#: fietsboek/views/default.py:237 msgid "flash.password_updated" msgstr "" -#: fietsboek/views/detail.py:94 +#: fietsboek/views/detail.py:101 msgid "flash.track_deleted" msgstr "" -#: fietsboek/views/profile.py:57 +#: fietsboek/views/profile.py:61 msgid "flash.personal_data_updated" msgstr "" -#: fietsboek/views/profile.py:77 +#: fietsboek/views/profile.py:79 msgid "flash.friend_not_found" msgstr "" -#: fietsboek/views/profile.py:82 +#: fietsboek/views/profile.py:85 msgid "flash.friend_already_exists" msgstr "" -#: fietsboek/views/profile.py:90 +#: fietsboek/views/profile.py:93 msgid "flash.friend_added" msgstr "" -#: fietsboek/views/profile.py:100 +#: fietsboek/views/profile.py:103 msgid "flash.friend_request_sent" msgstr "" -#: fietsboek/views/upload.py:52 +#: fietsboek/views/upload.py:56 msgid "flash.no_file_selected" msgstr "" -#: fietsboek/views/upload.py:62 +#: fietsboek/views/upload.py:66 msgid "flash.invalid_file" msgstr "" -#: fietsboek/views/upload.py:179 +#: fietsboek/views/upload.py:189 msgid "flash.upload_success" msgstr "" -#: fietsboek/views/upload.py:195 +#: fietsboek/views/upload.py:205 msgid "flash.upload_cancelled" msgstr "" diff --git a/fietsboek/security.py b/fietsboek/security.py index 84dd88a..6fbc5db 100644 --- a/fietsboek/security.py +++ b/fietsboek/security.py @@ -1,8 +1,10 @@ """Module implementing the user authentication.""" from pyramid.security import Allowed, Denied -from pyramid.authentication import SessionAuthenticationHelper +from pyramid.authentication import SessionAuthenticationHelper, AuthTktCookieHelper from pyramid.authorization import ACLHelper, Everyone, Authenticated from pyramid.traversal import DefaultRootFactory +from pyramid.interfaces import ISecurityPolicy +from zope.interface import implementer from sqlalchemy import select @@ -12,16 +14,28 @@ from . import models ADMIN_PERMISSIONS = {"admin"} +@implementer(ISecurityPolicy) class SecurityPolicy: """Implementation of the Pyramid security policy.""" - def __init__(self): + def __init__(self, cookie_secret): self.helper = SessionAuthenticationHelper() + # The cookie_helper is used for the "Remember me" function, as the + # authentication set by the cookie is deliberately kept for a long long + # time. The session authentication on the other hand expires after the + # set time (by default, 15 minutes). + self.cookie_helper = AuthTktCookieHelper(cookie_secret, max_age=2**31 - 1) def identity(self, request): """See :meth:`pyramid.interfaces.ISecurityPolicy.identity`""" userid = self.helper.authenticated_userid(request) if userid is None: + # Check if there is maybe a "Remember me" cookie + auth_info = self.cookie_helper.identify(request) or {} + userid = auth_info.get("userid") + + # Still no identity found + if userid is None: return None query = select(models.User).filter_by(id=int(userid)) @@ -62,6 +76,16 @@ class SecurityPolicy: """See :meth:`pyramid.interfaces.ISecurityPolicy.remember`""" return self.helper.remember(request, userid, **kw) + def remember_cookie(self, request, userid, **kw): + """Return the headers for remembering the user using the cookie method. + + This is used for the "Remember me" functionality, as the cookie doesn't + expire (unlike the session). + + The parameters are the same as for :meth:`remember`. + """ + return self.cookie_helper.remember(request, userid, **kw) + def forget(self, request, **kw): """See :meth:`pyramid.interfaces.ISecurityPolicy.forget`""" - return self.helper.forget(request, **kw) + return self.helper.forget(request, **kw) + self.cookie_helper.forget(request, **kw) diff --git a/fietsboek/templates/login.jinja2 b/fietsboek/templates/login.jinja2 index 86e9adb..7a9bf07 100644 --- a/fietsboek/templates/login.jinja2 +++ b/fietsboek/templates/login.jinja2 @@ -22,6 +22,16 @@ </div> </div> </div> + <div class="row justify-content-center"> + <div class="col-lg-5 mb-3"> + <div class="form-check"> + <input class="form-check-input" type="checkbox" name="remember-me" id="rememberMe" value="on"> + <label class="form-check-label" for="rememberMe"> + {{ _("page.login.remember-me") }} + </label> + </div> + </div> + </div> {{ util.hidden_csrf_input() }} <div class="row justify-content-center"> <div class="col-auto mb-3"> diff --git a/fietsboek/views/default.py b/fietsboek/views/default.py index 883d8d7..fe9df08 100644 --- a/fietsboek/views/default.py +++ b/fietsboek/views/default.py @@ -3,6 +3,7 @@ from pyramid.view import view_config from pyramid.httpexceptions import HTTPFound, HTTPNotFound from pyramid.security import remember, forget from pyramid.i18n import TranslationString as _ +from pyramid.interfaces import ISecurityPolicy from pyramid.renderers import render_to_response from sqlalchemy import select @@ -119,7 +120,15 @@ def do_login(request): request.session.flash(request.localizer.translate(_("flash.logged_in"))) headers = remember(request, str(user.id)) - return HTTPFound("/", headers=headers) + + if request.params.get("remember-me") == "on": + # We don't want this logic to be the default in + # SecurityPolicy.remember, so we manually fake it here: + policy = request.registry.getUtility(ISecurityPolicy) + headers += policy.remember_cookie(request, str(user.id)) + + response = HTTPFound("/", headers=headers) + return response @view_config(route_name="logout") |