Mercurial > traipse_dev
comparison plugins/cherrypy/lib/csauthenticate.py @ 0:4385a7d0efd1 grumpy-goblin
Deleted and repushed it with the 'grumpy-goblin' branch. I forgot a y
author | sirebral |
---|---|
date | Tue, 14 Jul 2009 16:41:58 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4385a7d0efd1 |
---|---|
1 """ | |
2 Copyright (c) 2004, CherryPy Team (team@cherrypy.org) | |
3 All rights reserved. | |
4 | |
5 Redistribution and use in source and binary forms, with or without modification, | |
6 are permitted provided that the following conditions are met: | |
7 | |
8 * Redistributions of source code must retain the above copyright notice, | |
9 this list of conditions and the following disclaimer. | |
10 * Redistributions in binary form must reproduce the above copyright notice, | |
11 this list of conditions and the following disclaimer in the documentation | |
12 and/or other materials provided with the distribution. | |
13 * Neither the name of the CherryPy Team nor the names of its contributors | |
14 may be used to endorse or promote products derived from this software | |
15 without specific prior written permission. | |
16 | |
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE | |
21 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
23 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
24 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
25 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
26 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 """ | |
28 | |
29 import time, whrandom | |
30 from cherrypy import cpg | |
31 | |
32 from aspect import Aspect, STOP, CONTINUE | |
33 | |
34 class CSAuthenticate(Aspect): | |
35 timeoutMessage = "Session timed out" | |
36 wrongLoginPasswordMessage = "Wrong login/password" | |
37 noCookieMessage = "No cookie" | |
38 logoutMessage = "You have been logged out" | |
39 sessionIdCookieName = "CherrySessionId" | |
40 timeout = 60 # in minutes | |
41 | |
42 def _before(self, methodName, method): | |
43 # If the method is not exposed, don't do anything | |
44 if not getattr(method, 'exposed', None): | |
45 return CONTINUE, None | |
46 | |
47 cpg.request.login = '' | |
48 # If the method is one of these 4, do not try to find out who is logged in | |
49 if methodName in ["loginScreen", "logoutScreen", "doLogin", "doLogout"]: | |
50 return CONTINUE, None | |
51 | |
52 # Check if a user is logged in: | |
53 # - If they are, set request.login with the right value | |
54 # - If not, return the login screen | |
55 if not cpg.request.simpleCookie.has_key(self.sessionIdCookieName): | |
56 return STOP, self.loginScreen(self.noCookieMessage, cpg.request.browserUrl) | |
57 sessionId = cpg.request.simpleCookie[self.sessionIdCookieName].value | |
58 now=time.time() | |
59 | |
60 # Check that session exists and hasn't timed out | |
61 timeout=0 | |
62 if not cpg.request.sessionMap.has_key(sessionId): | |
63 return STOP, self.loginScreen(self.noCookieMessage, cpg.request.browserUrl) | |
64 else: | |
65 login, expire = cpg.request.sessionMap[sessionId] | |
66 if expire < now: timeout=1 | |
67 else: | |
68 expire = now + self.timeout*60 | |
69 cpg.request.sessionMap[sessionId] = login, expire | |
70 | |
71 if timeout: | |
72 return STOP, self.loginScreen(self.timeoutMessage, cpg.request.browserUrl) | |
73 | |
74 cpg.request.login = login | |
75 return CONTINUE, None | |
76 | |
77 def checkLoginAndPassword(self, login, password): | |
78 if (login,password) == ('login','password'): return '' | |
79 return 'Wrong login/password' | |
80 | |
81 def generateSessionId(self, sessionIdList): | |
82 choice="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
83 while 1: | |
84 sessionId="" | |
85 for dummy in range(20): sessionId += whrandom.choice(choice) | |
86 if sessionId not in sessionIdList: return sessionId | |
87 | |
88 def doLogin(self, login, password, fromPage): | |
89 # Check that login/password match | |
90 errorMsg = self.checkLoginAndPassword(login, password) | |
91 if errorMsg: | |
92 cpg.request.login = '' | |
93 return self.loginScreen(errorMsg, fromPage, login) | |
94 cpg.request.login = login | |
95 # Set session | |
96 newSessionId = self.generateSessionId(cpg.request.sessionMap.keys()) | |
97 cpg.request.sessionMap[newSessionId] = login, time.time()+self.timeout*60 | |
98 | |
99 cpg.response.simpleCookie[self.sessionIdCookieName] = newSessionId | |
100 cpg.response.simpleCookie[self.sessionIdCookieName]['path'] = '/' | |
101 cpg.response.simpleCookie[self.sessionIdCookieName]['max-age'] = 31536000 | |
102 cpg.response.simpleCookie[self.sessionIdCookieName]['version'] = 1 | |
103 cpg.response.headerMap['Status'] = 302 | |
104 cpg.response.headerMap['Location'] = fromPage | |
105 return "" | |
106 doLogin.exposed = True | |
107 | |
108 def doLogout(self): | |
109 try: | |
110 sessionId = request.simpleCookie[self.sessionIdCookieName].value | |
111 del request.sessionMap[sessionId] | |
112 except: pass | |
113 | |
114 cpg.response.simpleCookie[self.sessionIdCookieName] = "" | |
115 cpg.response.simpleCookie[self.sessionIdCookieName]['path'] = '/' | |
116 cpg.response.simpleCookie[self.sessionIdCookieName]['max-age'] = 0 | |
117 cpg.response.simpleCookie[self.sessionIdCookieName]['version'] = 1 | |
118 cpg.request.login = '' | |
119 cpg.response.headerMap['Status'] = 302 | |
120 cpg.response.headerMap['Location'] = 'logoutScreen' # TBCTBC: may not be the right URL | |
121 return "" | |
122 doLogout.exposed = True | |
123 | |
124 def logoutScreen(self): | |
125 return self.loginScreen(self.logoutMessage, '/index') # TBC | |
126 logoutScreen.exposed = True | |
127 | |
128 def loginScreen(self, message, fromPage, login=''): | |
129 return """ | |
130 <html><body> | |
131 Message: %s | |
132 <form method="post" action="doLogin"> | |
133 Login: <input type=text name=login value="%s" size=10><br /> | |
134 Password: <input type=password name=password size=10><br /> | |
135 <input type=hidden name=fromPage value="%s"><br /> | |
136 <input type=submit> | |
137 </form> | |
138 </body></html> | |
139 """ % (message, login, fromPage) | |
140 loginScreen.exposed = True |