]>
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 | |
f2ba8a1f MT |
96 | try: |
97 | with self.db.transaction(): | |
98 | self.backend.accounts.register(uid, email, | |
99 | first_name=first_name, last_name=last_name) | |
100 | except ValueError as e: | |
101 | raise tornado.web.HTTPError(400) from e | |
f32dd17f MT |
102 | |
103 | self.render("auth/register-success.html") | |
104 | ||
105 | ||
d8a15b2e MT |
106 | class ActivateHandler(AuthenticationMixin, base.BaseHandler): |
107 | def get(self, uid, activation_code): | |
b4d72c76 | 108 | self.render("auth/activate.html") |
d8a15b2e MT |
109 | |
110 | def post(self, uid, activation_code): | |
b4d72c76 MT |
111 | password1 = self.get_argument("password1") |
112 | password2 = self.get_argument("password2") | |
d8a15b2e | 113 | |
b4d72c76 MT |
114 | if not password1 == password2: |
115 | raise tornado.web.HTTPError(400, "Passwords do not match") | |
d8a15b2e | 116 | |
b4d72c76 MT |
117 | with self.db.transaction(): |
118 | account = self.backend.accounts.activate(uid, activation_code) | |
119 | if not account: | |
120 | raise tornado.web.HTTPError(400, "Account not found: %s" % uid) | |
d8a15b2e | 121 | |
b4d72c76 MT |
122 | # Set the new password |
123 | account.passwd(password1) | |
d8a15b2e | 124 | |
b4d72c76 MT |
125 | # Create session |
126 | self.login(account) | |
d8a15b2e MT |
127 | |
128 | # Redirect to main page | |
129 | self.redirect("/") | |
130 | ||
131 | ||
9b8ff27d MT |
132 | class CacheMixin(object): |
133 | def prepare(self): | |
134 | # Mark this as private when someone is logged in | |
135 | if self.current_user: | |
136 | self.add_header("Cache-Control", "private") | |
137 | ||
138 | self.add_header("Vary", "Cookie") |