]>
Commit | Line | Data |
---|---|---|
08df6527 MT |
1 | #!/usr/bin/python |
2 | ||
3 | import logging | |
4 | import tornado.web | |
5 | ||
124a8404 | 6 | from . import base |
08df6527 MT |
7 | |
8 | class AuthenticationMixin(object): | |
d8a15b2e | 9 | def authenticate(self, username, password): |
08df6527 MT |
10 | # Find account |
11 | account = self.backend.accounts.find_account(username) | |
12 | if not account: | |
13 | raise tornado.web.HTTPError(401, "Unknown user: %s" % username) | |
14 | ||
15 | # Check credentials | |
16 | if not account.check_password(password): | |
17 | raise tornado.web.HTTPError(401, "Invalid password for %s" % account) | |
18 | ||
d8a15b2e MT |
19 | return self.login(account) |
20 | ||
21 | def login(self, account): | |
08df6527 | 22 | # User has logged in, create a session |
32d0ee1c MT |
23 | with self.db.transaction(): |
24 | session_id, session_expires = self.backend.accounts.create_session( | |
25 | account, self.request.host) | |
08df6527 MT |
26 | |
27 | # Check if a new session was created | |
28 | if not session_id: | |
29 | raise tornado.web.HTTPError(500, "Could not create session") | |
30 | ||
31 | # Send session cookie to the client | |
32 | self.set_cookie("session_id", session_id, | |
33 | domain=self.request.host, expires=session_expires) | |
34 | ||
35 | def logout(self): | |
36 | session_id = self.get_cookie("session_id") | |
37 | if not session_id: | |
38 | return | |
39 | ||
32d0ee1c MT |
40 | # Destroy session |
41 | with self.db.transaction(): | |
42 | success = self.backend.accounts.destroy_session(session_id, self.request.host) | |
43 | ||
08df6527 MT |
44 | if success: |
45 | self.clear_cookie("session_id") | |
46 | ||
47 | ||
08df6527 | 48 | class LoginHandler(AuthenticationMixin, base.BaseHandler): |
cfe7d74c | 49 | @base.blacklisted |
08df6527 MT |
50 | def get(self): |
51 | next = self.get_argument("next", None) | |
52 | ||
53 | self.render("auth/login.html", next=next) | |
54 | ||
cfe7d74c | 55 | @base.blacklisted |
08df6527 MT |
56 | def post(self): |
57 | username = self.get_argument("username") | |
58 | password = self.get_argument("password") | |
59 | ||
60 | with self.db.transaction(): | |
d8a15b2e | 61 | self.authenticate(username, password) |
08df6527 MT |
62 | |
63 | # Determine the page we should redirect to | |
64 | next = self.get_argument("next", None) | |
65 | ||
66 | return self.redirect(next or "/") | |
67 | ||
68 | ||
69 | class LogoutHandler(AuthenticationMixin, base.BaseHandler): | |
70 | def get(self): | |
71 | with self.db.transaction(): | |
72 | self.logout() | |
73 | ||
74 | # Get back to the start page | |
75 | self.redirect("/") | |
9b8ff27d MT |
76 | |
77 | ||
f32dd17f MT |
78 | class RegisterHandler(base.BaseHandler): |
79 | @base.blacklisted | |
80 | def get(self): | |
d521c9df MT |
81 | # Redirect logged in users away |
82 | if self.current_user: | |
83 | self.redirect("/") | |
84 | ||
f32dd17f MT |
85 | self.render("auth/register.html") |
86 | ||
87 | @base.blacklisted | |
88 | def post(self): | |
89 | uid = self.get_argument("uid") | |
90 | email = self.get_argument("email") | |
91 | ||
92 | first_name = self.get_argument("first_name") | |
93 | last_name = self.get_argument("last_name") | |
94 | ||
95 | # Register account | |
96 | with self.db.transaction(): | |
97 | self.backend.accounts.create(uid, email, | |
98 | first_name=first_name, last_name=last_name) | |
99 | ||
100 | self.render("auth/register-success.html") | |
101 | ||
102 | ||
d8a15b2e MT |
103 | class ActivateHandler(AuthenticationMixin, base.BaseHandler): |
104 | def get(self, uid, activation_code): | |
105 | # Fetch the account | |
106 | account = self.backend.accounts.get_by_uid(uid) | |
107 | if not account: | |
108 | raise tornado.web.HTTPError(400, "Account not found: %s" % uid) | |
109 | ||
110 | # Validate activation code | |
111 | if not account.check_password(activation_code): | |
112 | raise tornado.web.HTTPError(400, "Activation code did not match: %s" % activation_code) | |
113 | ||
114 | self.render("auth/activate.html", account=account) | |
115 | ||
116 | def post(self, uid, activation_code): | |
117 | password = self.get_argument("password1") | |
118 | ||
119 | # Fetch the account | |
120 | account = self.backend.accounts.get_by_uid(uid) | |
121 | if not account: | |
122 | raise tornado.web.HTTPError(404, "Account not found: %s" % uid) | |
123 | ||
124 | # Validate activation code | |
125 | if not account.check_password(activation_code): | |
126 | raise tornado.web.HTTPError(403, "Activation code did not match: %s" % activation_code) | |
127 | ||
128 | # Set the new password | |
129 | account.passwd(password) | |
130 | ||
131 | # Create session | |
132 | self.login(account) | |
133 | ||
134 | # Redirect to main page | |
135 | self.redirect("/") | |
136 | ||
137 | ||
9b8ff27d MT |
138 | class CacheMixin(object): |
139 | def prepare(self): | |
140 | # Mark this as private when someone is logged in | |
141 | if self.current_user: | |
142 | self.add_header("Cache-Control", "private") | |
143 | ||
144 | self.add_header("Vary", "Cookie") |