]> git.ipfire.org Git - ipfire.org.git/blame - src/web/auth.py
people: Add account activation handler
[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
MT
22 # User has logged in, create a session
23 session_id, session_expires = self.backend.accounts.create_session(
24 account, self.request.host)
25
26 # Check if a new session was created
27 if not session_id:
28 raise tornado.web.HTTPError(500, "Could not create session")
29
30 # Send session cookie to the client
31 self.set_cookie("session_id", session_id,
32 domain=self.request.host, expires=session_expires)
33
34 def logout(self):
35 session_id = self.get_cookie("session_id")
36 if not session_id:
37 return
38
39 success = self.backend.accounts.destroy_session(session_id, self.request.host)
40 if success:
41 self.clear_cookie("session_id")
42
43
08df6527 44class LoginHandler(AuthenticationMixin, base.BaseHandler):
cfe7d74c 45 @base.blacklisted
08df6527
MT
46 def get(self):
47 next = self.get_argument("next", None)
48
49 self.render("auth/login.html", next=next)
50
cfe7d74c 51 @base.blacklisted
08df6527
MT
52 def post(self):
53 username = self.get_argument("username")
54 password = self.get_argument("password")
55
56 with self.db.transaction():
d8a15b2e 57 self.authenticate(username, password)
08df6527
MT
58
59 # Determine the page we should redirect to
60 next = self.get_argument("next", None)
61
62 return self.redirect(next or "/")
63
64
65class LogoutHandler(AuthenticationMixin, base.BaseHandler):
66 def get(self):
67 with self.db.transaction():
68 self.logout()
69
70 # Get back to the start page
71 self.redirect("/")
9b8ff27d
MT
72
73
f32dd17f
MT
74class RegisterHandler(base.BaseHandler):
75 @base.blacklisted
76 def get(self):
77 self.render("auth/register.html")
78
79 @base.blacklisted
80 def post(self):
81 uid = self.get_argument("uid")
82 email = self.get_argument("email")
83
84 first_name = self.get_argument("first_name")
85 last_name = self.get_argument("last_name")
86
87 # Register account
88 with self.db.transaction():
89 self.backend.accounts.create(uid, email,
90 first_name=first_name, last_name=last_name)
91
92 self.render("auth/register-success.html")
93
94
d8a15b2e
MT
95class ActivateHandler(AuthenticationMixin, base.BaseHandler):
96 def get(self, uid, activation_code):
97 # Fetch the account
98 account = self.backend.accounts.get_by_uid(uid)
99 if not account:
100 raise tornado.web.HTTPError(400, "Account not found: %s" % uid)
101
102 # Validate activation code
103 if not account.check_password(activation_code):
104 raise tornado.web.HTTPError(400, "Activation code did not match: %s" % activation_code)
105
106 self.render("auth/activate.html", account=account)
107
108 def post(self, uid, activation_code):
109 password = self.get_argument("password1")
110
111 # Fetch the account
112 account = self.backend.accounts.get_by_uid(uid)
113 if not account:
114 raise tornado.web.HTTPError(404, "Account not found: %s" % uid)
115
116 # Validate activation code
117 if not account.check_password(activation_code):
118 raise tornado.web.HTTPError(403, "Activation code did not match: %s" % activation_code)
119
120 # Set the new password
121 account.passwd(password)
122
123 # Create session
124 self.login(account)
125
126 # Redirect to main page
127 self.redirect("/")
128
129
9b8ff27d
MT
130class CacheMixin(object):
131 def prepare(self):
132 # Mark this as private when someone is logged in
133 if self.current_user:
134 self.add_header("Cache-Control", "private")
135
136 self.add_header("Vary", "Cookie")