2 import sys
, os
, re
, zlib
, hashlib
, base64
, datetime
, random
3 from db
import Query
, Model
, safe
, FastQuery
4 from model
import LimoModel
5 from template
import urldecode
8 from settings
import Settings
11 def __init__(self
, request
, response
):
13 sha
= request
.cookies
.get('sha','').value
14 if len(sha
) == 40 and sha
== safe(sha
):
18 assert self
.sha
is not None
19 response
.cookies
['sha'] = self
.sha
20 # response.cookies['sha'].expires = datetime.datetime.utcnow()+datetime.timedelta(minutes=Settings.sessionTimeout)
21 response
.cookies
['sha'].max_age
= Settings
.sessionTimeout
*60
22 response
.cookies
['sha'].path
= "/"
24 visit
= self
.logVisit(url
=request
['REQUEST_URI'], remote
=request
["REMOTE_ADDR"]+":"+request
.get("REMOTE_PORT","-1"))
29 sha
.update(str(datetime
.datetime
.now()))
30 sha
.update(str(os
.urandom(8192)))
32 FastQuery("begin work; insert into sessions (sha, data) values ('%s', '{}'); commit;" % sha
)
33 if not self
._loadsha
(sha
):
34 raise Exception("Critical Error: I ran an insert/commit, and then couldnt find the data I committed. Database corruption?")
35 assert self
.sha
is not None
39 def _loadsha(self
, sha
):
40 for row
in FastQuery("select sid,sha,uid,data from sessions where sha = '%s'" % sha
):
42 assert row
[3][:4] == 'eJyr', "Session data does not start with zlib magic bytes: %s" % row
[3][:4]
43 self
.data
= eval(zlib
.decompress(base64
.b64decode(row
[3])))
47 self
.sid
= int(row
[0])
48 self
.sha
= str(row
[1])
52 self
.user
= User(row
[2])
56 def logVisit(self
, url
='', remote
=''):
57 if Settings
.detectSessionHijack
:
58 for row
in FastQuery("select remote from visits where sid = %d order by entered desc limit 1" % self
.sid
):
59 if row
[0].split(':')[0] != remote
.split(':')[0]:
60 raise HTTPStatusError(500, "Session Hijack detected, session token '%s' was used on '%s' originally and now on '%s'"
61 % (self
.sha
, row
[0], remote
))
62 FastQuery("begin work; insert into visits (sid, url, remote) values (%d, '%s', '%s'); commit"
63 % (self
.sid
, safe(url
), safe(remote
)))
65 def login(self
, login
, passwd
, save
=False):
66 assert len(login
) > 0, "Login required"
67 assert len(passwd
) > 0, "Password required"
68 for row
in FastQuery("select uid from users where login = '%s' or email = '%s' and passwd = '%s'" % (login
, login
, passwd
)):
74 raise Exception("User not found")
76 def logout(self
, save
=False):
88 data
= base64
.b64encode(zlib
.compress(str(self
.data
)))
89 FastQuery("begin work; update sessions set data = '%s', uid = %d where sid = %d; commit" % (data
, uid
, self
.sid
))
92 def hasRole(self
, name
):
95 return self
.user
.hasRole(name
)
97 def getMessages(self
):
98 return self
.get('messages','')
99 def addMessage(self
, msg
):
100 self
['messages'] = self
.getMessages() + msg
101 def clearMessages(self
):
104 # Session objects behave like a hash table
105 def get(self
, key
, default
):
106 return self
.data
.get(key
, default
)
107 def __getitem__(self
, key
):
108 return self
.data
.__getitem
__(key
)
109 def __setitem__(self
, key
, val
):
110 self
.data
.__setitem
__(key
, val
)
112 def __delitem__(self
, key
):
113 self
.data
.__delitem
__(key
)
117 return "{sid: %s, sha: %s, user: %s, data: %s}" % (self
.sid
, self
.sha
, str(self
.user
), str(self
.data
))
118 def __unicode__(self
):
119 return unicode(self
.__str
__())
122 def __init__(self
, uid
):
124 select u.*, r1.name as ur_name, r2.name as gr_name from users u
125 left join user_roles ur on ur.uid = u.uid
126 left join roles r1 on r1.rid = ur.rid
127 left join group_users ug on ug.uid = u.uid
128 left join group_roles gr on gr.gid = ug.gid
129 left join roles r2 on r2.rid = gr.rid
133 self
.uid
= int(getuser
['uid'][0])
134 (self
.name
, self
.login
, self
.email
, self
.theme
)\
135 = [urldecode(x
) for x
in getuser
['name, login, email, theme'][0]]
137 = [str(r
.role_name
) for r
in getuser
.Query("""
138 select distinct role_name from (
139 select ur_name as role_name from __self__
141 select gr_name as role_name from __self__
142 ) where role_name <> 'None'
145 raise Exception("No such user id: %d" % int(uid
))
147 def setPassword(self
, passwd
):
148 sha
= Model
.uid(passwd
)
149 Query("update users set passwd = '%s' where uid = %d" % (passwd
, self
.uid
))
151 def setTheme(self
, theme
):
153 Query("update users set theme = '%s' where uid = %d" % (theme
, self
.uid
))
155 def hasRole(self
, role
):
163 return "{uid: %s, name: %s, login: %s, email: %s, roles: %s}" % (self
.uid
, self
.name
, self
.login
, self
.email
, str(self
.roles
))
166 def getUser(login
, password
):
167 password
= Model
.uid(password
)
168 q
= Query("select uid from users where login = '%s' and passwd = '%s'" % (login
, password
))
170 return User(q
[0].uid
)
175 def createUser(name
, login
, passwd
, email
, active
=1):
177 .defaultUser(safe(name
), safe(login
), safe(passwd
), safe(email
), int(active
))\
178 .assignUserToGroup(login
, 'users')\
180 for row
in Query("select uid from users where name = '%s' and login = '%s'" % (name
, login
)):