Switch to unified view

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