]> git.ipfire.org Git - ipfire.org.git/blame - src/web/auth.py
auth: Do not allow logged-in users to register again
[ipfire.org.git] / src / web / auth.py
CommitLineData
08df6527
MT
1#!/usr/bin/python
2
3import logging
4import tornado.web
5
124a8404 6from . import base
08df6527
MT
7
8class 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 48class 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
69class 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
78class 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
103class 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
138class 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")