[973924]: / qiita_pet / handlers / auth_handlers.py

Download this file

180 lines (156 with data), 7.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The Qiita Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------
from tornado.escape import url_escape, json_encode
from qiita_pet.handlers.base_handlers import BaseHandler
from qiita_core.qiita_settings import qiita_config, r_client
from qiita_core.util import execute_as_transaction
from qiita_core.exceptions import (IncorrectPasswordError, IncorrectEmailError,
UnverifiedEmailError)
from qiita_db.util import send_email
from qiita_db.user import User
from qiita_db.exceptions import (QiitaDBUnknownIDError, QiitaDBDuplicateError,
QiitaDBError)
# login code modified from https://gist.github.com/guillaumevincent/4771570
class AuthCreateHandler(BaseHandler):
"""User Creation"""
def get(self):
try:
error_message = self.get_argument("error")
# Tornado can raise an Exception directly, not a defined type
except Exception:
error_message = ""
self.render("create_user.html", error=error_message)
@execute_as_transaction
def post(self):
username = self.get_argument("email", "").strip().lower()
password = self.get_argument("newpass", "")
info = {}
for info_column in ("name", "affiliation", "address", "phone"):
hold = self.get_argument(info_column, None)
if hold:
info[info_column] = hold
created = False
try:
created = User.create(username, password, info)
except QiitaDBDuplicateError:
msg = "Email already registered as a user"
if created:
info = created.info
try:
# qiita_config.base_url doesn't have a / at the end, but the
# qiita_config.portal_dir has it at the beginning but not at
# the end. This constructs the correct URL
url = qiita_config.base_url + qiita_config.portal_dir
send_email(username, "QIITA: Verify Email Address", "Please "
"click the following link to verify email address: "
"%s/auth/verify/%s?email=%s\n\nBy clicking you are "
"accepting our term and conditions: "
"%s/iframe/?iframe=qiita-terms"
% (url, info['user_verify_code'],
url_escape(username), url))
except Exception:
msg = ("Unable to send verification email. Please contact the "
"qiita developers at <a href='mailto:%s'>%s</a>") % (
qiita_config.help_email, qiita_config.help_email)
self.redirect(u"%s/?level=danger&message=%s"
% (qiita_config.portal_dir, url_escape(msg)))
return
msg = ("<h3>User Successfully Created</h3><p>Your Qiita account "
"has been successfully created. An email has been sent to "
"the email address you provided. This email contains "
"instructions on how to activate your account.</p>"
"<p>If you don't receive your activation email within a "
"couple of minutes, check your spam folder. If you still "
"don't see it, send us an email at <a "
"href=\"mailto:%s\">%s"
"</a>.</p>") % (qiita_config.help_email,
qiita_config.help_email)
self.redirect(u"%s/?level=success&message=%s" %
(qiita_config.portal_dir, url_escape(msg)))
else:
error_msg = u"?error=" + url_escape(msg)
self.redirect(u"%s/auth/create/%s"
% (qiita_config.portal_dir, error_msg))
class AuthVerifyHandler(BaseHandler):
def get(self, code):
email = self.get_argument("email").strip().lower()
code_is_valid = False
msg = "This code is not valid."
# an exception is raised if the 'code type' is not available, otherwise
# the method determines the validity of the code
try:
code_is_valid = User.verify_code(email, code, "create")
except QiitaDBError:
msg = "This user has already created an account."
if code_is_valid:
msg = "Successfully verified user. You are now free to log in."
color = "black"
r_client.zadd('qiita-usernames', {email: 0})
else:
color = "red"
self.render("user_verified.html", msg=msg, color=color,
email=self.get_argument("email").strip())
class AuthLoginHandler(BaseHandler):
"""user login, no page necessary"""
def get(self):
self.redirect("%s/" % qiita_config.portal_dir)
@execute_as_transaction
def post(self):
username = self.get_argument("username", "").strip().lower()
passwd = self.get_argument("password", "")
nextpage = self.get_argument("next", None)
if nextpage is None:
if "auth/" not in self.request.headers['Referer']:
nextpage = self.request.headers['Referer']
else:
nextpage = "%s/" % qiita_config.portal_dir
msg = ""
# check the user level
try:
if User(username).level == "unverified":
# email not verified so dont log in
msg = ("Email not verified. Please check your email and click "
"the verify link. You may need to check your spam "
"folder to find the email.<br/>If a verification email"
" has not arrived in 15 minutes, please email <a href='"
"mailto:%s'>%s</a>") % (qiita_config.help_email,
qiita_config.help_email)
except QiitaDBUnknownIDError:
msg = "Unknown user"
except RuntimeError:
# means DB not available, so set maintenance mode and failover
r_client.set("maintenance", "Database connection unavailable, "
"please try again later.")
self.redirect("%s/" % qiita_config.portal_dir)
return
# Check the login information
login = None
try:
login = User.login(username, passwd)
except IncorrectEmailError:
msg = "Unknown user"
except IncorrectPasswordError:
msg = "Incorrect password"
except UnverifiedEmailError:
msg = "You have not verified your email address"
if login:
# everything good so log in
self.set_current_user(username)
self.redirect(nextpage)
else:
self.render("index.html", message=msg, level='danger')
def set_current_user(self, user):
if user:
self.set_secure_cookie("user", json_encode(user))
else:
self.clear_cookie("user")
class AuthLogoutHandler(BaseHandler):
"""Logout handler, no page necessary"""
def get(self):
self.clear_cookie("user")
self.redirect("%s/" % qiita_config.portal_dir)