From 402f43601164e26390cf7c78a383537eb009e499 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Thu, 11 Jul 2013 16:16:41 -0700 Subject: [PATCH 1/4] maybe have change password and email on same page --- mediagoblin/edit/forms.py | 16 +++-- mediagoblin/edit/routing.py | 2 + mediagoblin/edit/views.py | 68 ++++++++++++------- .../mediagoblin/edit/change_email.html | 45 ++++++++++++ .../mediagoblin/edit/edit_account.html | 5 ++ 5 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 mediagoblin/templates/mediagoblin/edit/change_email.html diff --git a/mediagoblin/edit/forms.py b/mediagoblin/edit/forms.py index 85c243a0..71f30520 100644 --- a/mediagoblin/edit/forms.py +++ b/mediagoblin/edit/forms.py @@ -61,10 +61,6 @@ class EditProfileForm(wtforms.Form): class EditAccountForm(wtforms.Form): - new_email = wtforms.TextField( - _('New email address'), - [wtforms.validators.Optional(), - normalize_user_or_email_field(allow_user=False)]) wants_comment_notification = wtforms.BooleanField( description=_("Email me when others comment on my media")) license_preference = wtforms.SelectField( @@ -111,3 +107,15 @@ class ChangePassForm(wtforms.Form): [wtforms.validators.Required(), wtforms.validators.Length(min=6, max=30)], id="password") + + +class ChangeEmailForm(wtforms.Form): + new_email = wtforms.TextField( + _('New email address'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_user=False)]) + password = wtforms.PasswordField( + _('Password'), + [wtforms.validators.Required()], + description=_( + "Enter your password to prove you own this account.")) diff --git a/mediagoblin/edit/routing.py b/mediagoblin/edit/routing.py index 3592f708..75f5a6d8 100644 --- a/mediagoblin/edit/routing.py +++ b/mediagoblin/edit/routing.py @@ -28,3 +28,5 @@ add_route('mediagoblin.edit.pass', '/edit/password/', 'mediagoblin.edit.views:change_pass') add_route('mediagoblin.edit.verify_email', '/edit/verify_email/', 'mediagoblin.edit.views:verify_email') +add_route('mediagoblin.edit.email', '/edit/email/', + 'mediagoblin.edit.views:change_email') diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 6aa2acd9..82cec8da 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -425,30 +425,52 @@ def verify_email(request): user=user.username) -def _update_email(request, form, user): - new_email = form.new_email.data - users_with_email = User.query.filter_by( - email=new_email).count() +def change_email(request): + """ View to change the user's email """ + form = forms.ChangeEmailForm(request.form) + user = request.user - if users_with_email: - form.new_email.errors.append( - _('Sorry, a user with that email address' - ' already exists.')) + # If no password authentication, no need to enter a password + if 'pass_auth' not in request.template_env.globals or not user.pw_hash: + form.__delitem__('password') - elif not users_with_email: - verification_key = get_timed_signer_url( - 'mail_verification_token').dumps({ - 'user': user.id, - 'email': new_email}) + if request.method == 'POST' and form.validate(): + new_email = form.new_email.data + users_with_email = User.query.filter_by( + email=new_email).count() - rendered_email = render_template( - request, 'mediagoblin/edit/verification.txt', - {'username': user.username, - 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( - uri=request.urlgen('mediagoblin.edit.verify_email', - qualified=True), - verification_key=verification_key)}) + if users_with_email: + form.new_email.errors.append( + _('Sorry, a user with that email address' + ' already exists.')) - email_debug_message(request) - auth_tools.send_verification_email(user, request, new_email, - rendered_email) + if user.pw_hash and not auth.check_password( + form.password.data, user.pw_hash): + form.password.errors.append( + _('Wrong password')) + + if not form.errors: + verification_key = get_timed_signer_url( + 'mail_verification_token').dumps({ + 'user': user.id, + 'email': new_email}) + + rendered_email = render_template( + request, 'mediagoblin/edit/verification.txt', + {'username': user.username, + 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format( + uri=request.urlgen('mediagoblin.edit.verify_email', + qualified=True), + verification_key=verification_key)}) + + email_debug_message(request) + auth_tools.send_verification_email(user, request, new_email, + rendered_email) + + return redirect(request, 'mediagoblin.edit.account') + + return render_to_response( + request, + 'mediagoblin/edit/change_email.html', + {'form': form, + 'user': user}) diff --git a/mediagoblin/templates/mediagoblin/edit/change_email.html b/mediagoblin/templates/mediagoblin/edit/change_email.html new file mode 100644 index 00000000..76cc4771 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/edit/change_email.html @@ -0,0 +1,45 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block title -%} + {% trans username=user.username -%} + Changing {{ username }}'s email + {%- endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} +
+
+

+ {%- trans username=user.username -%} + Changing {{ username }}'s email + {%- endtrans -%} +

+ {{ wtforms_util.render_divs(form, True) }} + {{ csrf_token }} +
+ +
+
+
+{% endblock %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit_account.html b/mediagoblin/templates/mediagoblin/edit/edit_account.html index 51293acb..04f9230f 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_account.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_account.html @@ -48,6 +48,11 @@

{% endif %} +

+ + {% trans %}Change your email.{% endtrans %} + +

{% template_hook("edit_link") %} {{ wtforms_util.render_divs(form, True) }}
From 5a6e4e13076afddeeec31259eaee7c5af0defb2d Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Fri, 12 Jul 2013 12:27:41 -0700 Subject: [PATCH 2/4] check for form.password in the off chance that a user is logged in and the server switches the authentication method from basic_auth to openid. --- mediagoblin/edit/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py index 82cec8da..53a63cd0 100644 --- a/mediagoblin/edit/views.py +++ b/mediagoblin/edit/views.py @@ -444,7 +444,7 @@ def change_email(request): _('Sorry, a user with that email address' ' already exists.')) - if user.pw_hash and not auth.check_password( + if form.password and user.pw_hash and not auth.check_password( form.password.data, user.pw_hash): form.password.errors.append( _('Wrong password')) From 4710097b27a21d146a4ca8df80a5350146b9d30e Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Fri, 12 Jul 2013 12:34:35 -0700 Subject: [PATCH 3/4] fix tests to use new change_email view --- mediagoblin/tests/test_edit.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mediagoblin/tests/test_edit.py b/mediagoblin/tests/test_edit.py index d70d0478..c43a3a42 100644 --- a/mediagoblin/tests/test_edit.py +++ b/mediagoblin/tests/test_edit.py @@ -147,26 +147,26 @@ class TestUserEdit(object): # Test email already in db template.clear_test_template_context() test_app.post( - '/edit/account/', { + '/edit/email/', { 'new_email': 'chris@example.com', 'password': 'toast'}) # Check form errors context = template.TEMPLATE_TEST_CONTEXT[ - 'mediagoblin/edit/edit_account.html'] + 'mediagoblin/edit/change_email.html'] assert context['form'].new_email.errors == [ u'Sorry, a user with that email address already exists.'] # Test successful email change template.clear_test_template_context() res = test_app.post( - '/edit/account/', { + '/edit/email/', { 'new_email': 'new@example.com', 'password': 'toast'}) res.follow() # Correct redirect? - assert urlparse.urlsplit(res.location)[2] == '/u/chris/' + assert urlparse.urlsplit(res.location)[2] == '/edit/account/' # Make sure we get email verification and try verifying assert len(mail.EMAIL_TEST_INBOX) == 1 From c9f9536cdf32ef597216af0ca7ba25adee799dbb Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Fri, 12 Jul 2013 13:07:36 -0700 Subject: [PATCH 4/4] move links to the bottom of the page until we have a tabbed UI --- .../mediagoblin/plugins/openid/edit_link.html | 9 ++++--- .../mediagoblin/edit/edit_account.html | 24 +++++++++---------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html index 2e63e1f8..88b232f8 100644 --- a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html @@ -17,9 +17,8 @@ #} {% block openid_edit_link %} -

- - {% trans %}Edit your OpenID's{% endtrans %} - -

+ + {% trans %}OpenID's{% endtrans %} + + · {% endblock %} diff --git a/mediagoblin/templates/mediagoblin/edit/edit_account.html b/mediagoblin/templates/mediagoblin/edit/edit_account.html index 04f9230f..14011daa 100644 --- a/mediagoblin/templates/mediagoblin/edit/edit_account.html +++ b/mediagoblin/templates/mediagoblin/edit/edit_account.html @@ -41,19 +41,6 @@ Changing {{ username }}'s account settings {%- endtrans -%} - {% if pass_auth is defined %} -

- - {% trans %}Change your password.{% endtrans %} - -

- {% endif %} -

- - {% trans %}Change your email.{% endtrans %} - -

- {% template_hook("edit_link") %} {{ wtforms_util.render_divs(form, True) }}
@@ -65,5 +52,16 @@ {%- trans %}Delete my account{% endtrans -%} + · + {% template_hook("edit_link") %} + + {% trans %}Email{% endtrans %} + + {% if pass_auth is defined %} + · + + {% trans %}Password{% endtrans %} + + {% endif %}
{% endblock %}