1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
import os
import simplejson as json
import cherrypy
import cfg
from model import User
from plugin_mount import UserStoreModule
from withsqlite.withsqlite import sqlite_db
class UserStore(UserStoreModule, sqlite_db):
def __init__(self):
self.data_dir = cfg.users_dir
self.db_file = cfg.user_db
sqlite_db.__init__(self, self.db_file, autocommit=True)
self.__enter__()
def close(self):
self.__exit__(None,None,None)
def expert(self, username=None):
groups = self.attr(username,"groups")
if not groups:
return False
return 'expert' in groups
def attr(self, username=None, field=None):
return self.get(username)[field]
def get(self,username=None):
return User(sqlite_db.get(self,username))
def exists(self, username=None):
try:
user = self.get(username)
if not user:
return False
elif user["username"]=='':
return False
return True
except TypeError:
return False
def remove(self,username=None):
self.__delitem__(username)
self.commit()
def get_all(self):
return self.items()
def set(self,username=None,user=None):
sqlite_db.__setitem__(self,username, user)
class UserStoreOld():
#class UserStore(UserStoreModule):
"""The user storage is on disk. Rather than slurp the entire
thing, we read from the disk as needed. Writes are immediate,
though.
TODO: file locking"""
def __init__(self):
self.data_dir = cfg.users_dir
self.users = {}
def sanitize(username):
"""Return username with nonalphanumeric/underscore chars
removed.
TODO: allow international chars in usernames."""
pass
def attr(self, key, username):
"""Return field from username's record. If key does not
exist, don't raise attribute error, just return None.
User defaults to current. If no current user and none
specified, return none."""
try:
return self.get(username)[key]
except AttributeError:
return None
def current(self, name=False):
"""Return current user, if there is one, else None.
If name = True, return the username instead of the user."""
try:
username = cherrypy.session.get(cfg.session_key)
if name:
return username
else:
return self.get(username)
except AttributeError:
return None
def expert(self, username=None):
"""Return True if user username is an expert, else False.
If username is None, use the current user. If no such user exists, return False."""
user = self.get(username)
if not user:
return False
return 'expert' in user['groups']
def get(self, username=None, reload=False):
"""Returns a user instance with the user's info or else None if the user couldn't be found.
If reload is true, reload from disk, regardless of dict's contents
If username is None, try current user. If no current user, return None.
TODO: implement user_store.get reload"""
if not username:
username = self.current(name=True)
try:
return self.users[username]
except KeyError:
try:
IF = open(os.path.join(self.data_dir, username), "r")
except IOError:
return None
data = IF.read()
IF.close()
# We cache the result, and since we assume a system with
# relatively few users and small user data files, we never
# expire those results. If we revisit that assumption, we
# might need some cache expiry.
self.users[username] = User(json.loads(data))
return self.users[username]
def exists(self, username):
"""Return True if username exists, else False."""
return username in self.users or os.path.exists(os.path.join(cfg.users_dir, username))
def get_all(self):
"Returns a list of all the user objects"
usernames = os.listdir(self.data_dir)
for name in usernames:
self.get(name)
return self.users
def set(self, user):
"""Set the user data, both in memory and as needed in storage."""
OF = open(os.path.join(self.data_dir, user['username']), 'w')
OF.write(json.dumps(user))
OF.close()
def remove(self, user):
"""Delete the user from storage and RAM. User can be a user instance or a username."""
try:
name = user['name']
except TypeError:
if isinstance(user, basestring):
name = user
else:
raise TypeError
os.unlink(os.path.join(cfg.users_dir, name))
try:
del self.users[name]
except KeyError:
pass
cfg.log.info("%s deleted %s" % (cherrypy.session.get(cfg.session_key), name))
|