diff --git a/budget/forms.py b/budget/forms.py index 499f382..cf5068b 100644 --- a/budget/forms.py +++ b/budget/forms.py @@ -87,6 +87,16 @@ class AuthenticationForm(Form): submit = SubmitField("Get in") +class PasswordReminder(Form): + id = TextField("Project identifier", validators=[Required()]) + submit = SubmitField("Send me the code by email") + + def validate_id(form, field): + if not Project.query.get(field.data): + raise ValidationError("This project does not exists") + + + class BillForm(Form): date = DateField("Date", validators=[Required()], default=datetime.now) what = TextField("What?", validators=[Required()]) diff --git a/budget/static/main.css b/budget/static/main.css index de3d675..fc8d284 100644 --- a/budget/static/main.css +++ b/budget/static/main.css @@ -98,3 +98,9 @@ div.topbar ul.secondary-nav { padding-right: 75px; } text-align: right; margin-top: -15px; } + +.password-reminder{ + float: right; + margin-right: 20px; + margin-top: 5px; +} diff --git a/budget/templates/authenticate.html b/budget/templates/authenticate.html index 9852d6a..83839e1 100644 --- a/budget/templates/authenticate.html +++ b/budget/templates/authenticate.html @@ -2,10 +2,6 @@ {% block content %}

Authentication

-{% for errors in form.errors.values() %} -

{{ ", ".join(errors) }}

-{% endfor %} - {% if create_project %}

The project you are trying to access do not exist, do you want to create it? diff --git a/budget/templates/forms.html b/budget/templates/forms.html index 80a0d17..beb714b 100644 --- a/budget/templates/forms.html +++ b/budget/templates/forms.html @@ -21,7 +21,7 @@

{% if home %} - Go back Home + Can't remember the password? {% endif %} {% if cancel %} @@ -32,6 +32,7 @@ {% macro authenticate(form, home=False) %} {% include "display_errors.html" %} + {{ form.hidden_tag() }} {{ input(form.id) }} {{ input(form.password) }} @@ -111,3 +112,12 @@
{% endmacro %} + +{% macro remind_password(form) %} + + {% include "display_errors.html" %} + {{ form.hidden_tag() }} + {{ input(form.id) }} + {{ submit(form.submit) }} + +{% endmacro %} diff --git a/budget/templates/home.html b/budget/templates/home.html index ceb3b57..bf74767 100644 --- a/budget/templates/home.html +++ b/budget/templates/home.html @@ -26,6 +26,7 @@

Log to an existing project...

{{ forms.authenticate(auth_form, home=True) }} + can't remember your password?
diff --git a/budget/templates/password_reminder b/budget/templates/password_reminder new file mode 100644 index 0000000..fc24a6f --- /dev/null +++ b/budget/templates/password_reminder @@ -0,0 +1,8 @@ +Hi, + +You requested to be reminded about your password for "{{ project.name }}". + +You can access it here: {{ config['SITE_URL'] }}{{ url_for(".list_bills", project_id=project.id) }}, the private code is "{{ project.password }}". + +Hope this helps, +Some weird guys (with beards) diff --git a/budget/templates/password_reminder.html b/budget/templates/password_reminder.html new file mode 100644 index 0000000..0110cb8 --- /dev/null +++ b/budget/templates/password_reminder.html @@ -0,0 +1,8 @@ +{% extends "layout.html" %} + +{% block content %} +

Password reminder

+
+{{ forms.remind_password(form) }} +
+{% endblock %} diff --git a/budget/tests.py b/budget/tests.py index 2b573f4..a3fbd89 100644 --- a/budget/tests.py +++ b/budget/tests.py @@ -96,6 +96,24 @@ class BudgetTestCase(TestCase): self.assertEqual(len(outbox), 0) + def test_password_reminder(self): + # test that it is possible to have an email cotaining the password of a + # project in case people forget it (and it happens!) + + self.create_project("raclette") + + with run.mail.record_messages() as outbox: + # a nonexisting project should not send an email + self.app.post("/password-reminder", data={"id": "unexisting"}) + self.assertEqual(len(outbox), 0) + + # a mail should be sent when a project exists + self.app.post("/password-reminder", data={"id": "raclette"}) + self.assertEqual(len(outbox), 1) + self.assertIn("raclette", outbox[0].body) + self.assertIn("raclette@notmyidea.org", outbox[0].recipients) + + def test_project_creation(self): with run.app.test_client() as c: diff --git a/budget/web.py b/budget/web.py index 28740fc..8b251a1 100644 --- a/budget/web.py +++ b/budget/web.py @@ -6,8 +6,7 @@ import werkzeug # local modules from models import db, Project, Person, Bill -from forms import (get_billform_for, ProjectForm, AuthenticationForm, BillForm, - MemberForm, InviteForm, CreateArchiveForm, EditProjectForm) +from forms import * from utils import Redirect303 """ @@ -149,6 +148,23 @@ def create_project(): return render_template("create_project.html", form=form) +@main.route("/password-reminder", methods=["GET", "POST"]) +def remind_password(): + form = PasswordReminder() + if request.method == "POST": + if form.validate(): + # get the project + project = Project.query.get(form.id.data) + + # send the password reminder + mail.send(Message("password recovery", + body=render_template("password_reminder", project=project), + recipients=[project.contact_email])) + flash("a mail has been sent to you with the password") + + return render_template("password_reminder.html", form=form) + + @main.route("//edit", methods=["GET", "POST"]) def edit_project(): form = EditProjectForm()