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