+ messages.add_message(
+ request,
+ messages.INFO,
+ _('Resent your verification email.'))
+ return redirect(
+ request, 'mediagoblin.user_pages.user_home',
+ user=request.user.username)
+
+
+def forgot_password(request):
+ """
+ Forgot password view
+
+ Sends an email with an url to renew forgotten password
+ """
+ fp_form = auth_forms.ForgotPassForm(request.POST)
+
+ if request.method == 'POST' and fp_form.validate():
+
+ # '$or' not available till mongodb 1.5.3
+ user = request.db.User.find_one(
+ {'username': request.POST['username']})
+ if not user:
+ user = request.db.User.find_one(
+ {'email': request.POST['username']})
+
+ if user:
+ if user.email_verified and user.status == 'active':
+ user.fp_verification_key = unicode(uuid.uuid4())
+ user.fp_token_expire = datetime.datetime.now() + \
+ datetime.timedelta(days=10)
+ user.save()
+
+ send_fp_verification_email(user, request)
+
+ messages.add_message(
+ request,
+ messages.INFO,
+ _("An email has been sent with instructions on how to "
+ "change your password."))
+ email_debug_message(request)
+
+ else:
+ # special case... we can't send the email because the
+ # username is inactive / hasn't verified their email
+ messages.add_message(
+ request,
+ messages.WARNING,
+ _("Could not send password recovery email as "
+ "your username is inactive or your account's "
+ "email address has not been verified."))
+
+ return redirect(
+ request, 'mediagoblin.user_pages.user_home',
+ user=user.username)
+ return redirect(request, 'mediagoblin.auth.login')
+ else:
+ messages.add_message(
+ request,
+ messages.WARNING,
+ _("Couldn't find someone with that username or email."))
+ return redirect(request, 'mediagoblin.auth.forgot_password')
+
+ return render_to_response(
+ request,
+ 'mediagoblin/auth/forgot_password.html',
+ {'fp_form': fp_form})
+
+
+def verify_forgot_password(request):
+ """
+ Check the forgot-password verification and possibly let the user
+ change their password because of it.
+ """
+ # get form data variables, and specifically check for presence of token
+ formdata = _process_for_token(request)
+ if not formdata['has_userid_and_token']:
+ return render_404(request)
+
+ formdata_token = formdata['vars']['token']
+ formdata_userid = formdata['vars']['userid']
+ formdata_vars = formdata['vars']
+
+ # check if it's a valid Id
+ try:
+ user = request.db.User.find_one(
+ {'_id': ObjectId(unicode(formdata_userid))})
+ except InvalidId:
+ return render_404(request)
+
+ # check if we have a real user and correct token
+ if ((user and user.fp_verification_key and
+ user.fp_verification_key == unicode(formdata_token) and
+ datetime.datetime.now() < user.fp_token_expire
+ and user.email_verified and user.status == 'active')):
+
+ cp_form = auth_forms.ChangePassForm(formdata_vars)
+
+ if request.method == 'POST' and cp_form.validate():
+ user.pw_hash = auth_lib.bcrypt_gen_password_hash(
+ request.POST['password'])
+ user.fp_verification_key = None
+ user.fp_token_expire = None
+ user.save()
+
+ return redirect(request, 'mediagoblin.auth.fp_changed_success')
+ else:
+ return render_to_response(
+ request,
+ 'mediagoblin/auth/change_fp.html',
+ {'cp_form': cp_form})
+
+ # in case there is a valid id but no user whit that id in the db
+ # or the token expired
+ else:
+ return render_404(request)
+
+
+def _process_for_token(request):
+ """
+ Checks for tokens in formdata without prior knowledge of request method
+
+ For now, returns whether the userid and token formdata variables exist, and
+ the formdata variables in a hash. Perhaps an object is warranted?
+ """
+ # retrieve the formdata variables
+ if request.method == 'GET':
+ formdata_vars = request.GET
+ else:
+ formdata_vars = request.POST
+
+ formdata = {
+ 'vars': formdata_vars,
+ 'has_userid_and_token':
+ 'userid' in formdata_vars and 'token' in formdata_vars}
+
+ return formdata