diff options
author | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-05-07 20:05:28 -0500 |
---|---|---|
committer | Christopher Allan Webber <cwebber@dustycloud.org> | 2011-05-07 20:05:28 -0500 |
commit | 9fa51f07af5981a7d119aa6b5ea52ea6bba600cf (patch) | |
tree | 585c68bc02645659d70aeb146608e3dca97ffef0 | |
parent | 7a5ddb45dcf55c6d651b4a32dc1924e54b77c0f0 (diff) | |
parent | 8a6a81bcaa557f1d7ceebea8b372be7cc3423ca2 (diff) | |
download | mediagoblin-9fa51f07af5981a7d119aa6b5ea52ea6bba600cf.tar.lz mediagoblin-9fa51f07af5981a7d119aa6b5ea52ea6bba600cf.tar.xz mediagoblin-9fa51f07af5981a7d119aa6b5ea52ea6bba600cf.zip |
Merge remote branch 'refs/remotes/jwandborg/master'
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | mediagoblin.ini | 1 | ||||
-rw-r--r-- | mediagoblin/app.py | 4 | ||||
-rw-r--r-- | mediagoblin/auth/routing.py | 4 | ||||
-rw-r--r-- | mediagoblin/auth/views.py | 56 | ||||
-rw-r--r-- | mediagoblin/celery_setup/from_celery.py | 4 | ||||
-rw-r--r-- | mediagoblin/models.py | 7 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/auth/verification_email.txt | 22 | ||||
-rw-r--r-- | mediagoblin/templates/mediagoblin/auth/verify_email.html | 28 |
9 files changed, 120 insertions, 7 deletions
@@ -10,3 +10,4 @@ mediagoblin.egg-info *.pyo docs/_build/ user_dev/ +server-log.txt
\ No newline at end of file diff --git a/mediagoblin.ini b/mediagoblin.ini index c6dd4f76..951971a9 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -14,6 +14,7 @@ queuestore_base_dir = %(here)s/user_dev/media/queue publicstore_base_dir = %(here)s/user_dev/media/public publicstore_base_url = /mgoblin_media/ direct_remote_path = /mgoblin_static/ +email_sender_address = "notice@mediagoblin.example.org" ## Uncomment this to put some user-overriding templates here #local_templates = %(here)s/user_dev/templates/ diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 59b943dd..ad9e77df 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -36,6 +36,7 @@ class MediaGoblinApp(object): def __init__(self, connection, database_path, public_store, queue_store, staticdirector, + email_sender_address, user_template_path=None): # Get the template environment self.template_env = util.get_jinja_env(user_template_path) @@ -59,6 +60,7 @@ class MediaGoblinApp(object): # validators, etc, which might not access to the request # object. setup_globals( + email_sender_address=email_sender_address, db_connection=connection, database=self.db, public_store=self.public_store, @@ -139,6 +141,8 @@ def paste_app_factory(global_config, **app_config): connection, app_config.get('db_name', 'mediagoblin'), public_store=public_store, queue_store=queue_store, staticdirector=staticdirector, + email_sender_address=app_config.get('email_sender_address', + 'notice@mediagoblin.example.org'), user_template_path=app_config.get('local_templates')) return mgoblin_app diff --git a/mediagoblin/auth/routing.py b/mediagoblin/auth/routing.py index 92f19371..59762840 100644 --- a/mediagoblin/auth/routing.py +++ b/mediagoblin/auth/routing.py @@ -24,4 +24,6 @@ auth_routes = [ Route('mediagoblin.auth.login', '/login/', controller='mediagoblin.auth.views:login'), Route('mediagoblin.auth.logout', '/logout/', - controller='mediagoblin.auth.views:logout')] + controller='mediagoblin.auth.views:logout'), + Route('mediagoblin.auth.verify_email', '/verify_email/', + controller='mediagoblin.auth.views:verify_email')] diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py index 15e33e17..3ef1e75f 100644 --- a/mediagoblin/auth/views.py +++ b/mediagoblin/auth/views.py @@ -19,6 +19,8 @@ from webob import Response, exc from mediagoblin.auth import lib as auth_lib from mediagoblin.auth import forms as auth_forms +from mediagoblin.util import send_email +from mediagoblin import globals as mgoblin_globals def register(request): @@ -44,9 +46,28 @@ def register(request): entry['pw_hash'] = auth_lib.bcrypt_gen_password_hash( request.POST['password']) entry.save(validate=True) - - # TODO: Send email authentication request - + + email_template = request.template_env.get_template( + 'mediagoblin/auth/verification_email.txt') + + # TODO: There is no error handling in place + send_email( + mgoblin_globals.email_sender_address, + list(entry['email']), + # TODO + # Due to the distributed nature of GNU MediaGoblin, we should + # find a way to send some additional information about the + # specific GNU MediaGoblin instance in the subject line. For + # example "GNU MediaGoblin @ Wandborg - [...]". + 'GNU MediaGoblin - Verify email', + email_template.render( + username=entry['username'], + verification_url='http://{host}{uri}?userid={userid}&token={verification_key}'.format( + host=request.host, + uri=request.urlgen('mediagoblin.auth.verify_email'), + userid=unicode(entry['_id']), + verification_key=entry['verification_key']))) + # Redirect to register_success return exc.HTTPFound( location=request.urlgen("mediagoblin.auth.register_success")) @@ -116,3 +137,32 @@ def logout(request): return exc.HTTPFound( location=request.urlgen("index")) + +def verify_email(request): + """ + Email verification view + + validates GET parameters against database and unlocks the user account, if + you are lucky :) + """ + import bson.objectid + user = request.db.User.find_one( + {'_id': bson.objectid.ObjectId(unicode(request.GET.get('userid')))}) + + verification_successful = bool + + if user and user['verification_key'] == unicode(request.GET.get('token')): + user['status'] = u'active' + user['email_verified'] = True + verification_successful = True + user.save() + else: + verification_successful = False + + template = request.template_env.get_template( + 'mediagoblin/auth/verify_email.html') + return Response( + template.render( + {'request': request, + 'user': user, + 'verification_successful': verification_successful})) diff --git a/mediagoblin/celery_setup/from_celery.py b/mediagoblin/celery_setup/from_celery.py index 9bd7fe07..218ebfeb 100644 --- a/mediagoblin/celery_setup/from_celery.py +++ b/mediagoblin/celery_setup/from_celery.py @@ -22,6 +22,7 @@ from paste.deploy.loadwsgi import NicerConfigParser from mediagoblin import storage, models from mediagoblin.celery_setup import setup_celery_from_config from mediagoblin.globals import setup_globals +from mediagoblin import globals as mgoblin_globals OUR_MODULENAME = 'mediagoblin.celery_setup.from_celery' @@ -81,6 +82,9 @@ def setup_self(setup_globals_func=setup_globals): db_connection=connection, database=db, public_store=public_store, + email_sender_address=mgoblin_section.get( + 'email_sender_address', + 'notice@mediagoblin.example.org'), queue_store=queue_store) diff --git a/mediagoblin/models.py b/mediagoblin/models.py index cd6a28cc..69b1f4f0 100644 --- a/mediagoblin/models.py +++ b/mediagoblin/models.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -import datetime +import datetime, uuid from mongokit import Document, Set @@ -41,6 +41,7 @@ class User(Document): 'pw_hash': unicode, 'email_verified': bool, 'status': unicode, + 'verification_key': unicode } required_fields = ['username', 'created', 'pw_hash', 'email'] @@ -48,8 +49,8 @@ class User(Document): default_values = { 'created': datetime.datetime.utcnow, 'email_verified': False, - # TODO: shouldn't be active by default, must have email registration - 'status': u'active'} + 'status': u'needs_email_verification', + 'verification_key': lambda: unicode( uuid.uuid4() ) } def check_login(self, password): """ diff --git a/mediagoblin/templates/mediagoblin/auth/verification_email.txt b/mediagoblin/templates/mediagoblin/auth/verification_email.txt new file mode 100644 index 00000000..ce0629eb --- /dev/null +++ b/mediagoblin/templates/mediagoblin/auth/verification_email.txt @@ -0,0 +1,22 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 <http://www.gnu.org/licenses/>. +#} +Hi {{ username }}, + +to activate your GNU MediaGoblin account, open the following URL in your web browser + +{{ verification_url }} diff --git a/mediagoblin/templates/mediagoblin/auth/verify_email.html b/mediagoblin/templates/mediagoblin/auth/verify_email.html new file mode 100644 index 00000000..b6e6d1f8 --- /dev/null +++ b/mediagoblin/templates/mediagoblin/auth/verify_email.html @@ -0,0 +1,28 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011 Free Software Foundation, Inc +# +# 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 <http://www.gnu.org/licenses/>. +#} +{% extends "mediagoblin/base.html" %} + +{% block mediagoblin_content %} +<p> + {% if verification_successful %} + Your email address has been verified! + {% else %} + The verification key or user id is incorrect + {% endif %} +</p> +{% endblock %} |