aboutsummaryrefslogtreecommitdiffstats
path: root/mediagoblin/auth
diff options
context:
space:
mode:
authorRodney Ewing <ewing.rj@gmail.com>2013-05-28 10:46:46 -0700
committerRodney Ewing <ewing.rj@gmail.com>2013-05-28 10:46:46 -0700
commit8087f56b07b11a8abc1f6d5108a70765712cc63d (patch)
tree7002a38f819f8ccfc505494c9eb6d6d0ed388f33 /mediagoblin/auth
parent377db0e7ffdca6ce56041d28eba536ecd3b2a58a (diff)
parentf9e032212dff4d54de644cb5537bc0bef6d24c7f (diff)
downloadmediagoblin-8087f56b07b11a8abc1f6d5108a70765712cc63d.tar.lz
mediagoblin-8087f56b07b11a8abc1f6d5108a70765712cc63d.tar.xz
mediagoblin-8087f56b07b11a8abc1f6d5108a70765712cc63d.zip
Merge remote-tracking branch 'upstream/master' into change_email
Conflicts: mediagoblin/auth/lib.py
Diffstat (limited to 'mediagoblin/auth')
-rw-r--r--mediagoblin/auth/forms.py1
-rw-r--r--mediagoblin/auth/lib.py40
-rw-r--r--mediagoblin/auth/tools.py116
-rw-r--r--mediagoblin/auth/views.py67
4 files changed, 124 insertions, 100 deletions
diff --git a/mediagoblin/auth/forms.py b/mediagoblin/auth/forms.py
index 599b2576..0a391d67 100644
--- a/mediagoblin/auth/forms.py
+++ b/mediagoblin/auth/forms.py
@@ -16,7 +16,6 @@
import wtforms
-from mediagoblin.tools.mail import normalize_email
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
from mediagoblin.auth.tools import normalize_user_or_email_field
diff --git a/mediagoblin/auth/lib.py b/mediagoblin/auth/lib.py
index 8bba8484..bfc36b28 100644
--- a/mediagoblin/auth/lib.py
+++ b/mediagoblin/auth/lib.py
@@ -90,46 +90,6 @@ def fake_login_attempt():
randplus_stored_hash == randplus_hashed_pass
-EMAIL_VERIFICATION_TEMPLATE = (
- u"http://{host}{uri}?"
- u"userid={userid}&token={verification_key}")
-
-
-def send_verification_email(user, request, email=None,
- rendered_email=None):
- """
- Send the verification email to users to activate their accounts.
-
- Args:
- - user: a user object
- - request: the request
- """
- if not email:
- email = user.email
-
- if not rendered_email:
- rendered_email = render_template(
- request, 'mediagoblin/auth/verification_email.txt',
- {'username': user.username,
- 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format(
- host=request.host,
- uri=request.urlgen('mediagoblin.auth.verify_email'),
- userid=unicode(user.id),
- verification_key=user.verification_key)})
-
- # TODO: There is no error handling in place
- send_email(
- mg_globals.app_config['email_sender_address'],
- [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 your email!',
- rendered_email)
-
-
EMAIL_FP_VERIFICATION_TEMPLATE = (
u"http://{host}{uri}?"
u"userid={userid}&token={fp_verification_key}")
diff --git a/mediagoblin/auth/tools.py b/mediagoblin/auth/tools.py
index 1b30a7d9..d86235b1 100644
--- a/mediagoblin/auth/tools.py
+++ b/mediagoblin/auth/tools.py
@@ -14,11 +14,22 @@
# 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 uuid
+import logging
+
import wtforms
+from sqlalchemy import or_
-from mediagoblin.tools.mail import normalize_email
+from mediagoblin import mg_globals
+from mediagoblin.auth import lib as auth_lib
+from mediagoblin.db.models import User
+from mediagoblin.tools.mail import (normalize_email, send_email,
+ email_debug_message)
+from mediagoblin.tools.template import render_template
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
+_log = logging.getLogger(__name__)
+
def normalize_user_or_email_field(allow_email=True, allow_user=True):
"""
@@ -48,3 +59,106 @@ def normalize_user_or_email_field(allow_email=True, allow_user=True):
if field.data is None: # should not happen, but be cautious anyway
raise wtforms.ValidationError(message)
return _normalize_field
+
+
+EMAIL_VERIFICATION_TEMPLATE = (
+ u"http://{host}{uri}?"
+ u"userid={userid}&token={verification_key}")
+
+
+def send_verification_email(user, request, email=None,
+ rendered_email=None):
+ """
+ Send the verification email to users to activate their accounts.
+
+ Args:
+ - user: a user object
+ - request: the request
+ """
+ if not email:
+ email = user.email
+
+ if not rendered_email:
+ rendered_email = render_template(
+ request, 'mediagoblin/auth/verification_email.txt',
+ {'username': user.username,
+ 'verification_url': EMAIL_VERIFICATION_TEMPLATE.format(
+ host=request.host,
+ uri=request.urlgen('mediagoblin.auth.verify_email'),
+ userid=unicode(user.id),
+ verification_key=user.verification_key)})
+
+ # TODO: There is no error handling in place
+ send_email(
+ mg_globals.app_config['email_sender_address'],
+ [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 your email!',
+ rendered_email)
+
+
+def basic_extra_validation(register_form, *args):
+ users_with_username = User.query.filter_by(
+ username=register_form.data['username']).count()
+ users_with_email = User.query.filter_by(
+ email=register_form.data['email']).count()
+
+ extra_validation_passes = True
+
+ if users_with_username:
+ register_form.username.errors.append(
+ _(u'Sorry, a user with that name already exists.'))
+ extra_validation_passes = False
+ if users_with_email:
+ register_form.email.errors.append(
+ _(u'Sorry, a user with that email address already exists.'))
+ extra_validation_passes = False
+
+ return extra_validation_passes
+
+
+def register_user(request, register_form):
+ """ Handle user registration """
+ extra_validation_passes = basic_extra_validation(register_form)
+
+ if extra_validation_passes:
+ # Create the user
+ user = User()
+ user.username = register_form.data['username']
+ user.email = register_form.data['email']
+ user.pw_hash = auth_lib.bcrypt_gen_password_hash(
+ register_form.password.data)
+ user.verification_key = unicode(uuid.uuid4())
+ user.save()
+
+ # log the user in
+ request.session['user_id'] = unicode(user.id)
+ request.session.save()
+
+ # send verification email
+ email_debug_message(request)
+ send_verification_email(user, request)
+
+ return user
+
+ return None
+
+
+def check_login_simple(username, password, username_might_be_email=False):
+ search = (User.username == username)
+ if username_might_be_email and ('@' in username):
+ search = or_(search, User.email == username)
+ user = User.query.filter(search).first()
+ if not user:
+ _log.info("User %r not found", username)
+ auth_lib.fake_login_attempt()
+ return None
+ if not auth_lib.bcrypt_check_password(password, user.pw_hash):
+ _log.warn("Wrong password for %r", username)
+ return None
+ _log.info("Logging %r in", username)
+ return user
diff --git a/mediagoblin/auth/views.py b/mediagoblin/auth/views.py
index dc408911..bb7bda77 100644
--- a/mediagoblin/auth/views.py
+++ b/mediagoblin/auth/views.py
@@ -21,23 +21,12 @@ from mediagoblin import messages, mg_globals
from mediagoblin.db.models import User
from mediagoblin.tools.response import render_to_response, redirect, render_404
from mediagoblin.tools.translate import pass_to_ugettext as _
+from mediagoblin.tools.mail import email_debug_message
from mediagoblin.auth import lib as auth_lib
from mediagoblin.auth import forms as auth_forms
-from mediagoblin.auth.lib import send_verification_email, \
- send_fp_verification_email
-from sqlalchemy import or_
-
-def email_debug_message(request):
- """
- If the server is running in email debug mode (which is
- the current default), give a debug message to the user
- so that they have an idea where to find their email.
- """
- if mg_globals.app_config['email_debug_mode']:
- # DEBUG message, no need to translate
- messages.add_message(request, messages.DEBUG,
- u"This instance is running in email debug mode. "
- u"The email will be on the console of the server process.")
+from mediagoblin.auth.lib import send_fp_verification_email
+from mediagoblin.auth.tools import (send_verification_email, register_user,
+ check_login_simple)
def register(request):
@@ -58,38 +47,9 @@ def register(request):
if request.method == 'POST' and register_form.validate():
# TODO: Make sure the user doesn't exist already
- users_with_username = User.query.filter_by(username=register_form.data['username']).count()
- users_with_email = User.query.filter_by(email=register_form.data['email']).count()
-
- extra_validation_passes = True
-
- if users_with_username:
- register_form.username.errors.append(
- _(u'Sorry, a user with that name already exists.'))
- extra_validation_passes = False
- if users_with_email:
- register_form.email.errors.append(
- _(u'Sorry, a user with that email address already exists.'))
- extra_validation_passes = False
-
- if extra_validation_passes:
- # Create the user
- user = User()
- user.username = register_form.data['username']
- user.email = register_form.data['email']
- user.pw_hash = auth_lib.bcrypt_gen_password_hash(
- register_form.password.data)
- user.verification_key = unicode(uuid.uuid4())
- user.save()
-
- # log the user in
- request.session['user_id'] = unicode(user.id)
- request.session.save()
-
- # send verification email
- email_debug_message(request)
- send_verification_email(user, request)
+ user = register_user(request, register_form)
+ if user:
# redirect the user to their homepage... there will be a
# message waiting for them to verify their email
return redirect(
@@ -113,18 +73,13 @@ def login(request):
login_failed = False
if request.method == 'POST':
-
+
username = login_form.data['username']
if login_form.validate():
- user = User.query.filter(
- or_(
- User.username == username,
- User.email == username,
-
- )).first()
+ user = check_login_simple(username, login_form.password.data, True)
- if user and user.check_login(login_form.password.data):
+ if user:
# set up login in session
request.session['user_id'] = unicode(user.id)
request.session.save()
@@ -134,10 +89,6 @@ def login(request):
else:
return redirect(request, "index")
- # Some failure during login occured if we are here!
- # Prevent detecting who's on this system by testing login
- # attempt timings
- auth_lib.fake_login_attempt()
login_failed = True
return render_to_response(