| 145 | | _login_screen = """<html><body> |
|---|
| | 145 | class SessionAuth(object): |
|---|
| | 146 | """Assert that the user is logged in.""" |
|---|
| | 147 | |
|---|
| | 148 | session_key = "username" |
|---|
| | 149 | |
|---|
| | 150 | def check_login_and_password(self, login, password): |
|---|
| | 151 | pass |
|---|
| | 152 | |
|---|
| | 153 | def anonymous(self): |
|---|
| | 154 | """Provide a temporary user name for anonymous users.""" |
|---|
| | 155 | pass |
|---|
| | 156 | |
|---|
| | 157 | def load_user_by_username(self, username): |
|---|
| | 158 | pass |
|---|
| | 159 | |
|---|
| | 160 | def on_login(self, login): |
|---|
| | 161 | pass |
|---|
| | 162 | |
|---|
| | 163 | def on_logout(self, login): |
|---|
| | 164 | pass |
|---|
| | 165 | |
|---|
| | 166 | def login_screen(self, from_page='..', login='', error_msg=''): |
|---|
| | 167 | return """<html><body> |
|---|
| 153 | | </body></html>""" |
|---|
| 154 | | |
|---|
| 155 | | def session_auth(check_login_and_password=None, not_logged_in=None, |
|---|
| 156 | | load_user_by_username=None, session_key='username', |
|---|
| 157 | | on_login=None, on_logout=None, login_screen=None): |
|---|
| 158 | | """Assert that the user is logged in.""" |
|---|
| 159 | | |
|---|
| 160 | | if login_screen is None: |
|---|
| 161 | | login_screen = _login_screen |
|---|
| 162 | | |
|---|
| 163 | | request = cherrypy.request |
|---|
| 164 | | tdata = cherrypy.thread_data |
|---|
| 165 | | sess = cherrypy.session |
|---|
| 166 | | request.user = None |
|---|
| 167 | | tdata.user = None |
|---|
| 168 | | |
|---|
| 169 | | if request.path.endswith('login_screen'): |
|---|
| 170 | | return False |
|---|
| 171 | | elif request.path.endswith('do_logout'): |
|---|
| 172 | | login = sess.get(session_key) |
|---|
| 173 | | sess[session_key] = None |
|---|
| | 175 | </body></html>""" % {'from_page': from_page, 'login': login, |
|---|
| | 176 | 'error_msg': error_msg} |
|---|
| | 177 | |
|---|
| | 178 | def do_login(self, login, password, from_page='..'): |
|---|
| | 179 | """Login. May raise redirect, or return True if request handled.""" |
|---|
| | 180 | error_msg = self.check_login_and_password(login, password) |
|---|
| | 181 | if error_msg: |
|---|
| | 182 | body = self.login_screen(from_page, login, error_msg) |
|---|
| | 183 | cherrypy.response.body = body |
|---|
| | 184 | return True |
|---|
| | 185 | else: |
|---|
| | 186 | cherrypy.session[self.session_key] = login |
|---|
| | 187 | self.on_login(login) |
|---|
| | 188 | raise cherrypy.HTTPRedirect(from_page or "/") |
|---|
| | 189 | |
|---|
| | 190 | def do_logout(self, from_page='..'): |
|---|
| | 191 | """Logout. May raise redirect, or return True if request handled.""" |
|---|
| | 192 | sess = cherrypy.session |
|---|
| | 193 | login = sess.get(self.session_key) |
|---|
| | 194 | sess[self.session_key] = None |
|---|
| | 195 | if login: |
|---|
| | 196 | self.on_logout(login) |
|---|
| | 197 | raise cherrypy.HTTPRedirect(from_page) |
|---|
| | 198 | |
|---|
| | 199 | def check_user(self): |
|---|
| | 200 | """Assert username. May raise redirect, or return True if request handled.""" |
|---|
| | 201 | sess = cherrypy.session |
|---|
| | 202 | request = cherrypy.request |
|---|
| | 203 | |
|---|
| | 204 | username = sess.get(self.session_key) |
|---|
| | 205 | if not username: |
|---|
| | 206 | username = self.anonymous() |
|---|
| | 207 | if not username: |
|---|
| | 208 | cherrypy.response.body = self.login_screen(request.browser_url) |
|---|
| | 209 | return True |
|---|
| | 210 | |
|---|
| | 211 | # Everything is OK: user is logged in |
|---|
| | 212 | tdata = cherrypy.thread_data |
|---|
| | 213 | if not tdata.user: |
|---|
| | 214 | tdata.user = request.user = self.load_user_by_username(username) |
|---|
| | 215 | |
|---|
| | 216 | def run(self): |
|---|
| | 217 | request = cherrypy.request |
|---|
| 175 | | tdata.user = None |
|---|
| 176 | | if login and on_logout: |
|---|
| 177 | | on_logout(login) |
|---|
| 178 | | from_page = request.params.get('from_page', '..') |
|---|
| 179 | | raise cherrypy.HTTPRedirect(from_page) |
|---|
| 180 | | elif request.path.endswith('do_login'): |
|---|
| 181 | | from_page = request.params.get('from_page', '..') |
|---|
| 182 | | login = request.params['login'] |
|---|
| 183 | | password = request.params['password'] |
|---|
| 184 | | error_msg = check_login_and_password(login, password) |
|---|
| 185 | | if error_msg: |
|---|
| 186 | | kw = {"from_page": from_page, |
|---|
| 187 | | "login": login, "error_msg": error_msg} |
|---|
| 188 | | cherrypy.response.body = login_screen % kw |
|---|
| 189 | | return True |
|---|
| 190 | | |
|---|
| 191 | | sess[session_key] = login |
|---|
| 192 | | if on_login: |
|---|
| 193 | | on_login(login) |
|---|
| 194 | | raise cherrypy.HTTPRedirect(from_page or "/") |
|---|
| 195 | | |
|---|
| 196 | | # Check if user is logged in |
|---|
| 197 | | temp_user = None |
|---|
| 198 | | if (not sess.get(session_key)) and not_logged_in: |
|---|
| 199 | | # Call not_logged_in so that applications where anonymous user |
|---|
| 200 | | # is OK can handle it |
|---|
| 201 | | temp_user = not_logged_in() |
|---|
| 202 | | if (not sess.get(session_key)) and not temp_user: |
|---|
| 203 | | kw = {"from_page": request.browser_url, "login": "", "error_msg": ""} |
|---|
| 204 | | cherrypy.response.body = login_screen % kw |
|---|
| 205 | | return True |
|---|
| 206 | | |
|---|
| 207 | | # Everything is OK: user is logged in |
|---|
| 208 | | if load_user_by_username and not tdata.user: |
|---|
| 209 | | username = temp_user or sess[session_key] |
|---|
| 210 | | request.user = load_user_by_username(username) |
|---|
| 211 | | tdata.user = request.user |
|---|
| 212 | | |
|---|
| 213 | | return False |
|---|
| | 219 | cherrypy.thread_data.user = None |
|---|
| | 220 | |
|---|
| | 221 | path = request.path |
|---|
| | 222 | if path.endswith('login_screen'): |
|---|
| | 223 | # pass and let the normal handler work |
|---|
| | 224 | return self.login_screen() |
|---|
| | 225 | elif path.endswith('do_login'): |
|---|
| | 226 | return self.do_login(**request.params) |
|---|
| | 227 | elif path.endswith('do_logout'): |
|---|
| | 228 | return self.do_logout(**request.params) |
|---|
| | 229 | else: |
|---|
| | 230 | return self.check_user() |
|---|
| | 231 | |
|---|
| | 232 | |
|---|
| | 233 | def session_auth(**kwargs): |
|---|
| | 234 | sa = SessionAuth() |
|---|
| | 235 | for k, v in kwargs.iteritems(): |
|---|
| | 236 | setattr(sa, k, v) |
|---|
| | 237 | return sa.run() |
|---|
| | 238 | |
|---|