From 152ad394e0ac44f8d69b2f4a61899811c3fe50ac Mon Sep 17 00:00:00 2001 From: Sebastiaan van Doorn Date: Tue, 24 Sep 2013 20:06:31 +0200 Subject: [PATCH] Included the htmls #243 Invite User by email workflow Added config and description for #251 User location based selection of TnC/AGB Implemented #258 Ask for password reset after activation; does not lead to activation --- README.md | 5 ++ boilerplate/handlers.py | 36 ++++++++----- boilerplate/lib/basehandler.py | 8 ++- .../templates/emails/account_activation.txt | 13 +++-- .../templates/emails/account_invite.txt | 16 ++++++ .../templates/emails/password_changed.txt | 2 +- .../templates/emails/reset_password.txt | 2 +- boilerplate/templates/invite.html | 36 +++++++++++++ boilerplate/templates/invite_activate.html | 54 +++++++++++++++++++ boilerplate/templates/register.html | 2 + boilerplate/templates/tnc-de_DE.html | 2 + boilerplate/templates/tnc-en_US.html | 2 + boilerplate/templates/tnc.html | 2 + 13 files changed, 160 insertions(+), 20 deletions(-) create mode 100644 boilerplate/templates/emails/account_invite.txt create mode 100644 boilerplate/templates/invite.html create mode 100644 boilerplate/templates/invite_activate.html create mode 100644 boilerplate/templates/tnc-de_DE.html create mode 100644 boilerplate/templates/tnc-en_US.html create mode 100644 boilerplate/templates/tnc.html diff --git a/README.md b/README.md index ae10c55b..7b4eb3a9 100755 --- a/README.md +++ b/README.md @@ -151,6 +151,11 @@ Adding or updating text to be translated or adding new languages requires more w 1. Compile translations Run: pybabel compile -f -d ./locale +1. In addition to this locale specific configuration files can be realized by using standard Jinja2 import functionality + For examples see register.html and account_activation.txt + {% include ['tnc-'+ locale_iso.language + '_'+locale_iso.territory+ '.html', 'tnc.html'] ignore missing %} + + See [webapp2's tutorial](http://webapp-improved.appspot.com/tutorials/i18n.html) and [pybabel's docs](http://babel.edgewall.org/wiki/Documentation/cmdline.html) for more details. **Disabling i18n** diff --git a/boilerplate/handlers.py b/boilerplate/handlers.py index 45ebcfb4..18bf5c80 100644 --- a/boilerplate/handlers.py +++ b/boilerplate/handlers.py @@ -823,7 +823,8 @@ def post(self): "app_name": self.app.config.get('app_name'), "username": username, "confirmation_url": confirmation_url, - "support_url": self.uri_for("contact", _full=True) + "support_url": self.uri_for("contact", _full=True), + "locale_iso": self.locale_iso, } body_path = "emails/account_activation.txt" body = self.jinja2.render_template(body_path, **template_val) @@ -1163,7 +1164,9 @@ def get(self, user_id, token): "app_name": self.app.config.get('app_name'), "username": user.username, "confirmation_url": confirmation_url, - "support_url": self.uri_for("contact", _full=True) + "support_url": self.uri_for("contact", _full=True), + "locale_iso": self.locale_iso, + } body_path = "emails/account_activation.txt" body = self.jinja2.render_template(body_path, **template_val) @@ -1432,7 +1435,7 @@ def post(self): "first_name": user.name, "username": user.username, "email": user.email, - "reset_password_url": self.uri_for("password-reset", _full=True) + "verification_url": self.uri_for("password-reset", _full=True) } email_body_path = "emails/password_changed.txt" email_body = self.jinja2.render_template(email_body_path, **template_val) @@ -1635,28 +1638,37 @@ def post(self): user_id = user.get_id() token = models.User.create_auth_token(user_id) email_url = self.uri_for('taskqueue-send-email') - reset_url = self.uri_for('password-reset-check', user_id=user_id, token=token, _full=True) - subject = _("%s Password Assistance" % self.app.config.get('app_name')) + + if (user.activated == False): + subject = _("%s Account Verification" % self.app.config.get('app_name')) + verification_url = self.uri_for("account-activation",user_id=user_id,token=token,_full=True) + body_path = "emails/account_activation.txt" + else: + subject = _("%s Password Assistance" % self.app.config.get('app_name')) + verification_url = self.uri_for('password-reset-check', user_id=user_id, token=token, _full=True) + body_path = "emails/reset_password.txt" # load email's template template_val = { + "app_name": self.app.config.get('app_name'), "username": user.username, - "email": user.email, - "reset_password_url": reset_url, + "verification_url": verification_url, "support_url": self.uri_for("contact", _full=True), - "app_name": self.app.config.get('app_name'), + "locale_iso": self.locale_iso, } - - body_path = "emails/reset_password.txt" + body = self.jinja2.render_template(body_path, **template_val) + message = _('The verification email has been resent to %s. ' + 'Please check your email to activate your account.' % user.email) + self.add_message(message, 'success') taskqueue.add(url=email_url, params={ 'to': user.email, 'subject': subject, 'body': body, 'sender': self.app.config.get('contact_sender'), }) - self.add_message(_message, 'warning') - return self.redirect_to('login') + + return self.redirect_to('home') class PasswordResetCompleteHandler(BaseHandler): diff --git a/boilerplate/lib/basehandler.py b/boilerplate/lib/basehandler.py index d8af824d..11c86140 100644 --- a/boilerplate/lib/basehandler.py +++ b/boilerplate/lib/basehandler.py @@ -69,7 +69,7 @@ def __init__(self, request, response): """ self.initialize(request, response) self.locale = i18n.set_locale(self) - self.view = ViewClass() + self.view = ViewClass() def dispatch(self): """ @@ -124,6 +124,10 @@ def auth_config(self): def language(self): return str(Locale.parse(self.locale).language) + @webapp2.cached_property + def locale_iso(self): + return Locale.parse(self.locale) + @webapp2.cached_property def user(self): return self.auth.get_user_by_session() @@ -283,7 +287,7 @@ def render_template(self, filename, **kwargs): territory_id = locale_iso.territory language = locale_iso.languages[language_id] territory = locale_iso.territories[territory_id] - + # make all self.view variables available in jinja2 templates if hasattr(self, 'view'): kwargs.update(self.view.__dict__) diff --git a/boilerplate/templates/emails/account_activation.txt b/boilerplate/templates/emails/account_activation.txt index 51ecc6eb..0154e6e9 100644 --- a/boilerplate/templates/emails/account_activation.txt +++ b/boilerplate/templates/emails/account_activation.txt @@ -1,11 +1,14 @@

Hello {{username}},

-You just have registered in {{ app_name }} as @{{username}}. In order to activate your account, -please verify your email by clicking this link: +You just have registered in {{ app_name }} as @{{username}}. By activating your account you acknowledge to have read +and accepted our terms and conditions as shown at the end of this email. + + +In order to activate your account, please verify your email by clicking the following link:

-{{confirmation_url}} +{{verification_url}}

If you have any question, please do not hesitate to contact us at:
@@ -13,4 +16,6 @@ If you have any question, please do not hesitate to contact us at:

Sincerely,
-{{ app_name }} Team \ No newline at end of file +{{ app_name }} Team + +{% include ['tnc-'+ locale_iso.language + '_'+locale_iso.territory+ '.html', 'tnc.html'] ignore missing %} diff --git a/boilerplate/templates/emails/account_invite.txt b/boilerplate/templates/emails/account_invite.txt new file mode 100644 index 00000000..ce8e9efa --- /dev/null +++ b/boilerplate/templates/emails/account_invite.txt @@ -0,0 +1,16 @@ +

Hello {{email}},

+ +

+You just have been invited to {{ app_name }} as @{{username}}. In order to activate your account, +please verify your email by clicking this link: +

+ +{{confirmation_url}} + +

+If you have any question, please do not hesitate to contact us at:
+{{support_url}} +

+ +

Sincerely,
+{{ app_name }} Team diff --git a/boilerplate/templates/emails/password_changed.txt b/boilerplate/templates/emails/password_changed.txt index aff43389..6d098e24 100644 --- a/boilerplate/templates/emails/password_changed.txt +++ b/boilerplate/templates/emails/password_changed.txt @@ -7,7 +7,7 @@ was recently changed. As a security precaution, this notification has been sent

If you didn't change your password, your account might have been hijacked. Please follow the link to regain control over your account:

-{{reset_password_url}} +{{verification_url}}

Important account security tips:

diff --git a/boilerplate/templates/emails/reset_password.txt b/boilerplate/templates/emails/reset_password.txt index 6e22f1e0..60b63f2b 100644 --- a/boilerplate/templates/emails/reset_password.txt +++ b/boilerplate/templates/emails/reset_password.txt @@ -2,7 +2,7 @@

To initiate the password reset process for your {{ app_name }} Account ({{email}}), click the link below:

-{{reset_password_url}} +{{verification_url}}

If clicking the link above doesn't work, please copy and paste the URL in a new browser window instead.

diff --git a/boilerplate/templates/invite.html b/boilerplate/templates/invite.html new file mode 100644 index 00000000..b85bd330 --- /dev/null +++ b/boilerplate/templates/invite.html @@ -0,0 +1,36 @@ +{% extends base_layout %} + +{% block header_title %} + {% trans %}Invite User{% endtrans %} +{% endblock %} + +{% block content %} + +
+
+ + {{ macros.field(form.username, label=_("Username"), placeholder=_("Enter a")+" "+_("Username"), class="input-xlarge focused required") }} + {{ macros.field(form.email, label=_("Email"), placeholder=_("Enter their")+" "+_("Email"), class="input-xlarge focused required email", type="email") }} +
+ +
+
+
+ +{% endblock %} + +{% block mediaJS %} + +{% endblock %} diff --git a/boilerplate/templates/invite_activate.html b/boilerplate/templates/invite_activate.html new file mode 100644 index 00000000..bf86ac1f --- /dev/null +++ b/boilerplate/templates/invite_activate.html @@ -0,0 +1,54 @@ +{% extends base_layout %} + +{% block header_title %} + {% trans %}Set your password{% endtrans %} +{% endblock %} + +{% block content %} + +
+
+ + {{ macros.field(form.password, label=_("New Password"), placeholder=_("Enter your")+" "+_("New Password"), class="input-xlarge focused required", type="password") }} + {% if not is_mobile %} + {{ macros.field(form.c_password, label=_("Confirm Password"), placeholder=_("Confirm Password"), class="input-xlarge focused required", type="password") }} + {% endif %} + {{ macros.field(form.name, label=_("Name"), placeholder=_("Enter your")+" "+_("Name"), class="input-xlarge focused") }} + {{ macros.field(form.last_name, label=_("Last Name"), placeholder=_("Enter your")+" "+_("Last Name"), class="input-xlarge focused") }} + {{ macros.field(form.country, label=_("Country")) }} +
+ +
+
+
+ +{% endblock %} + +{% block mediaJS %} + +{% endblock %} diff --git a/boilerplate/templates/register.html b/boilerplate/templates/register.html index fbc1c6bd..3675a141 100644 --- a/boilerplate/templates/register.html +++ b/boilerplate/templates/register.html @@ -23,6 +23,8 @@ +{% include ['tnc-'+ locale_iso.language + '_'+locale_iso.territory+ '.html', 'tnc.html'] ignore missing %} + {% endblock %} {% block mediaJS %} diff --git a/boilerplate/templates/tnc-de_DE.html b/boilerplate/templates/tnc-de_DE.html new file mode 100644 index 00000000..8720c0c2 --- /dev/null +++ b/boilerplate/templates/tnc-de_DE.html @@ -0,0 +1,2 @@ +Wenn Sie sich auf diese Seite registrieren, bestätigen Sie dass Sie unsere AGB gelesen haben, und sie akzeptieren. +

Das sind die de_DE AGB

diff --git a/boilerplate/templates/tnc-en_US.html b/boilerplate/templates/tnc-en_US.html new file mode 100644 index 00000000..aa39afa1 --- /dev/null +++ b/boilerplate/templates/tnc-en_US.html @@ -0,0 +1,2 @@ +By registering with this website you acknowledge that you have read and accepted the following terms and conditions +

These are the en_US terms and conditions

diff --git a/boilerplate/templates/tnc.html b/boilerplate/templates/tnc.html new file mode 100644 index 00000000..59614831 --- /dev/null +++ b/boilerplate/templates/tnc.html @@ -0,0 +1,2 @@ +By registering with this website you acknowledge that you have read and accepted the following terms and conditions +

These are the default terms and conditions