]>
git.ipfire.org Git - ipfire.org.git/blob - src/web/auth.py
8 class CacheMixin(object):
10 # Mark this as private when someone is logged in
12 self
.add_header("Cache-Control", "private")
14 self
.add_header("Cache-Control", "no-store")
17 class AuthenticationMixin(CacheMixin
):
18 def login(self
, account
):
19 # User has logged in, create a session
20 session_id
, session_expires
= self
.backend
.accounts
.create_session(
21 account
, self
.request
.host
)
23 # Check if a new session was created
25 raise tornado
.web
.HTTPError(500, "Could not create session")
27 # Send session cookie to the client
28 self
.set_cookie("session_id", session_id
,
29 domain
=self
.request
.host
, expires
=session_expires
)
32 session_id
= self
.get_cookie("session_id")
36 success
= self
.backend
.accounts
.destroy_session(session_id
, self
.request
.host
)
38 self
.clear_cookie("session_id")
41 class LoginHandler(AuthenticationMixin
, base
.BaseHandler
):
43 next
= self
.get_argument("next", None)
45 self
.render("auth/login.html", next
=next
,
46 incorrect
=False, username
=None)
48 @base.ratelimit(minutes
=15, requests
=10)
50 username
= self
.get_argument("username")
51 password
= self
.get_argument("password")
52 next
= self
.get_argument("next", "/")
55 account
= self
.backend
.accounts
.auth(username
, password
)
57 logging
.error("Unknown user or invalid password: %s" % username
)
62 # Render login page again
63 return self
.render("auth/login.html",
64 incorrect
=True, username
=username
, next
=next
,
68 with self
.db
.transaction():
72 return self
.redirect(next
)
75 class LogoutHandler(AuthenticationMixin
, base
.BaseHandler
):
77 with self
.db
.transaction():
80 # Get back to the start page
84 class RegisterHandler(CacheMixin
, base
.BaseHandler
):
86 # Redirect logged in users away
91 self
.render("auth/register.html")
93 @base.ratelimit(minutes
=15, requests
=5)
95 uid
= self
.get_argument("uid")
96 email
= self
.get_argument("email")
98 first_name
= self
.get_argument("first_name")
99 last_name
= self
.get_argument("last_name")
101 # Check if this is a spam account
102 is_spam
= await self
.backend
.accounts
.check_spam(email
,
103 address
=self
.get_remote_ip())
106 self
.render("auth/register-spam.html")
111 with self
.db
.transaction():
112 self
.backend
.accounts
.register(uid
, email
,
113 first_name
=first_name
, last_name
=last_name
,
114 country_code
=self
.current_country_code
)
115 except ValueError as e
:
116 raise tornado
.web
.HTTPError(400, "%s" % e
) from e
118 self
.render("auth/register-success.html")
121 class ActivateHandler(AuthenticationMixin
, base
.BaseHandler
):
122 def get(self
, uid
, activation_code
):
123 self
.render("auth/activate.html")
125 def post(self
, uid
, activation_code
):
126 password1
= self
.get_argument("password1")
127 password2
= self
.get_argument("password2")
129 if not password1
== password2
:
130 raise tornado
.web
.HTTPError(400, "Passwords do not match")
132 with self
.db
.transaction():
133 account
= self
.backend
.accounts
.activate(uid
, activation_code
)
135 raise tornado
.web
.HTTPError(400, "Account not found: %s" % uid
)
137 # Set the new password
138 account
.passwd(password1
)
143 # Redirect to success page
144 self
.render("auth/activated.html", account
=account
)
147 class PasswordResetInitiationHandler(CacheMixin
, base
.BaseHandler
):
149 username
= self
.get_argument("username", None)
151 self
.render("auth/password-reset-initiation.html", username
=username
)
153 @base.ratelimit(minutes
=15, requests
=10)
155 username
= self
.get_argument("username")
157 # Fetch account and submit password reset
158 account
= self
.backend
.accounts
.get_by_uid(username
)
160 with self
.db
.transaction():
161 account
.request_password_reset()
163 self
.render("auth/password-reset-successful.html")
166 class PasswordResetHandler(AuthenticationMixin
, base
.BaseHandler
):
167 def get(self
, uid
, reset_code
):
168 account
= self
.backend
.accounts
.get_by_uid(uid
)
170 raise tornado
.web
.HTTPError(404, "Could not find account: %s" % uid
)
172 self
.render("auth/password-reset.html", account
=account
)
174 def post(self
, uid
, reset_code
):
175 account
= self
.backend
.accounts
.get_by_uid(uid
)
177 raise tornado
.web
.HTTPError(404, "Could not find account: %s" % uid
)
179 password1
= self
.get_argument("password1")
180 password2
= self
.get_argument("password2")
182 if not password1
== password2
:
183 raise tornado
.web
.HTTPError(400, "Passwords do not match")
185 # Try to perform password reset
186 with self
.db
.transaction():
187 account
.reset_password(reset_code
, password1
)
189 # Login the user straight away after reset was successful
196 class APICheckUID(base
.APIHandler
):
197 @base.ratelimit(minutes
=1, requests
=100)
199 uid
= self
.get_argument("uid")
205 # Check if the username is syntactically valid
206 elif not self
.backend
.accounts
.uid_is_valid(uid
):
209 # Check if the username is already taken
210 elif self
.backend
.accounts
.uid_exists(uid
):
213 # Username seems to be okay
214 self
.finish({ "result" : result
or "ok" })
217 class APICheckEmail(base
.APIHandler
):
218 @base.ratelimit(minutes
=1, requests
=100)
220 email
= self
.get_argument("email")
226 elif not self
.backend
.accounts
.mail_is_valid(email
):
229 # Check if this email address is blacklisted
230 elif self
.backend
.accounts
.mail_is_blacklisted(email
):
231 result
= "blacklisted"
233 # Check if this email address is already useed
234 elif self
.backend
.accounts
.get_by_mail(email
):
237 self
.finish({ "result" : result
or "ok" })