Mercurial > kallithea
comparison rhodecode/lib/auth.py @ 1016:3790279d2538 beta
#56 added propagation of permission from group
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Wed, 09 Feb 2011 18:54:20 +0100 |
parents | b232a36cc51f |
children | 405b80e4ccd5 |
comparison
equal
deleted
inserted
replaced
1015:65129c332d37 | 1016:3790279d2538 |
---|---|
39 from rhodecode.lib.auth_ldap import AuthLdap | 39 from rhodecode.lib.auth_ldap import AuthLdap |
40 | 40 |
41 from rhodecode.model import meta | 41 from rhodecode.model import meta |
42 from rhodecode.model.user import UserModel | 42 from rhodecode.model.user import UserModel |
43 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \ | 43 from rhodecode.model.db import User, RepoToPerm, Repository, Permission, \ |
44 UserToPerm | 44 UserToPerm, UsersGroupToPerm, UsersGroupMember |
45 | 45 |
46 | 46 |
47 log = logging.getLogger(__name__) | 47 log = logging.getLogger(__name__) |
48 | |
49 | |
50 PERM_WEIGHTS = {'repository.none':0, | |
51 'repository.read':1, | |
52 'repository.write':3, | |
53 'repository.admin':3} | |
54 | |
48 | 55 |
49 class PasswordGenerator(object): | 56 class PasswordGenerator(object): |
50 """This is a simple class for generating password from | 57 """This is a simple class for generating password from |
51 different sets of characters | 58 different sets of characters |
52 usage: | 59 usage: |
71 self.passwd = ''.join([random.choice(type) for _ in xrange(len)]) | 78 self.passwd = ''.join([random.choice(type) for _ in xrange(len)]) |
72 return self.passwd | 79 return self.passwd |
73 | 80 |
74 | 81 |
75 def get_crypt_password(password): | 82 def get_crypt_password(password): |
76 """Cryptographic function used for password hashing based on sha1 | 83 """Cryptographic function used for password hashing based on pybcrypt |
84 | |
77 :param password: password to hash | 85 :param password: password to hash |
78 """ | 86 """ |
79 return bcrypt.hashpw(password, bcrypt.gensalt(10)) | 87 return bcrypt.hashpw(password, bcrypt.gensalt(10)) |
80 | 88 |
81 def check_password(password, hashed): | 89 def check_password(password, hashed): |
82 return bcrypt.hashpw(password, hashed) == hashed | 90 return bcrypt.hashpw(password, hashed) == hashed |
83 | 91 |
84 def authfunc(environ, username, password): | 92 def authfunc(environ, username, password): |
85 """ | 93 """Dummy authentication function used in Mercurial/Git/ and access control, |
86 Dummy authentication function used in Mercurial/Git/ and access control, | |
87 | 94 |
88 :param environ: needed only for using in Basic auth | 95 :param environ: needed only for using in Basic auth |
89 """ | 96 """ |
90 return authenticate(username, password) | 97 return authenticate(username, password) |
91 | 98 |
92 | 99 |
93 def authenticate(username, password): | 100 def authenticate(username, password): |
94 """ | 101 """Authentication function used for access control, |
95 Authentication function used for access control, | |
96 firstly checks for db authentication then if ldap is enabled for ldap | 102 firstly checks for db authentication then if ldap is enabled for ldap |
97 authentication, also creates ldap user if not in database | 103 authentication, also creates ldap user if not in database |
98 | 104 |
99 :param username: username | 105 :param username: username |
100 :param password: password | 106 :param password: password |
128 | 134 |
129 from rhodecode.model.settings import SettingsModel | 135 from rhodecode.model.settings import SettingsModel |
130 ldap_settings = SettingsModel().get_ldap_settings() | 136 ldap_settings = SettingsModel().get_ldap_settings() |
131 | 137 |
132 #====================================================================== | 138 #====================================================================== |
133 # FALLBACK TO LDAP AUTH IN ENABLE | 139 # FALLBACK TO LDAP AUTH IF ENABLE |
134 #====================================================================== | 140 #====================================================================== |
135 if ldap_settings.get('ldap_active', False): | 141 if ldap_settings.get('ldap_active', False): |
136 log.debug("Authenticating user using ldap") | 142 log.debug("Authenticating user using ldap") |
137 kwargs = { | 143 kwargs = { |
138 'server':ldap_settings.get('ldap_host', ''), | 144 'server':ldap_settings.get('ldap_host', ''), |
158 'lastname' : ldap_attrs[ldap_settings.get('ldap_attr_lastname')][0], | 164 'lastname' : ldap_attrs[ldap_settings.get('ldap_attr_lastname')][0], |
159 'email' : ldap_attrs[ldap_settings.get('ldap_attr_email')][0], | 165 'email' : ldap_attrs[ldap_settings.get('ldap_attr_email')][0], |
160 } | 166 } |
161 | 167 |
162 if user_model.create_ldap(username, password, user_dn, user_attrs): | 168 if user_model.create_ldap(username, password, user_dn, user_attrs): |
163 log.info('created new ldap user') | 169 log.info('created new ldap user %s', username) |
164 | 170 |
165 return True | 171 return True |
166 except (LdapUsernameError, LdapPasswordError,): | 172 except (LdapUsernameError, LdapPasswordError,): |
167 pass | 173 pass |
168 except (Exception,): | 174 except (Exception,): |
169 log.error(traceback.format_exc()) | 175 log.error(traceback.format_exc()) |
170 pass | 176 pass |
171 return False | 177 return False |
172 | 178 |
173 class AuthUser(object): | 179 class AuthUser(object): |
174 """ | 180 """A simple object that handles a mercurial username for authentication |
175 A simple object that handles a mercurial username for authentication | 181 """ |
176 """ | 182 |
177 def __init__(self): | 183 def __init__(self): |
178 self.username = 'None' | 184 self.username = 'None' |
179 self.name = '' | 185 self.name = '' |
180 self.lastname = '' | 186 self.lastname = '' |
181 self.email = '' | 187 self.email = '' |
187 def __repr__(self): | 193 def __repr__(self): |
188 return "<AuthUser('id:%s:%s')>" % (self.user_id, self.username) | 194 return "<AuthUser('id:%s:%s')>" % (self.user_id, self.username) |
189 | 195 |
190 def set_available_permissions(config): | 196 def set_available_permissions(config): |
191 """This function will propagate pylons globals with all available defined | 197 """This function will propagate pylons globals with all available defined |
192 permission given in db. We don't wannt to check each time from db for new | 198 permission given in db. We don't want to check each time from db for new |
193 permissions since adding a new permission also requires application restart | 199 permissions since adding a new permission also requires application restart |
194 ie. to decorate new views with the newly created permission | 200 ie. to decorate new views with the newly created permission |
195 | 201 |
196 :param config: current pylons config instance | 202 :param config: current pylons config instance |
197 | 203 |
211 config['base_path'] = config['pylons.app_globals'].base_path | 217 config['base_path'] = config['pylons.app_globals'].base_path |
212 | 218 |
213 | 219 |
214 def fill_perms(user): | 220 def fill_perms(user): |
215 """Fills user permission attribute with permissions taken from database | 221 """Fills user permission attribute with permissions taken from database |
216 | 222 works for permissions given for repositories, and for permissions that |
217 :param user: | 223 as part of beeing group member |
218 | 224 |
225 :param user: user instance to fill his perms | |
219 """ | 226 """ |
220 | 227 |
221 sa = meta.Session() | 228 sa = meta.Session() |
222 user.permissions['repositories'] = {} | 229 user.permissions['repositories'] = {} |
223 user.permissions['global'] = set() | 230 user.permissions['global'] = set() |
253 .filter(User.username == 'default').one()) | 260 .filter(User.username == 'default').one()) |
254 | 261 |
255 for perm in default_global_perms: | 262 for perm in default_global_perms: |
256 user.permissions['global'].add(perm.permission.permission_name) | 263 user.permissions['global'].add(perm.permission.permission_name) |
257 | 264 |
258 #default repositories | 265 #default for repositories |
259 for perm in default_perms: | 266 for perm in default_perms: |
260 if perm.Repository.private and not perm.Repository.user_id == user.user_id: | 267 if perm.Repository.private and not perm.Repository.user_id == user.user_id: |
261 #disable defaults for private repos, | 268 #disable defaults for private repos, |
262 p = 'repository.none' | 269 p = 'repository.none' |
263 elif perm.Repository.user_id == user.user_id: | 270 elif perm.Repository.user_id == user.user_id: |
267 p = perm.Permission.permission_name | 274 p = perm.Permission.permission_name |
268 | 275 |
269 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p | 276 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p |
270 | 277 |
271 #======================================================================= | 278 #======================================================================= |
272 # #overwrite default with user permissions if any | 279 # overwrite default with user permissions if any |
273 #======================================================================= | 280 #======================================================================= |
274 user_perms = sa.query(RepoToPerm, Permission, Repository)\ | 281 user_perms = sa.query(RepoToPerm, Permission, Repository)\ |
275 .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\ | 282 .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\ |
276 .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\ | 283 .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\ |
277 .filter(RepoToPerm.user_id == user.user_id).all() | 284 .filter(RepoToPerm.user_id == user.user_id).all() |
280 if perm.Repository.user_id == user.user_id:#set admin if owner | 287 if perm.Repository.user_id == user.user_id:#set admin if owner |
281 p = 'repository.admin' | 288 p = 'repository.admin' |
282 else: | 289 else: |
283 p = perm.Permission.permission_name | 290 p = perm.Permission.permission_name |
284 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p | 291 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p |
292 | |
293 | |
294 #======================================================================= | |
295 # check if user is part of groups for this repository and fill in | |
296 # (or replace with higher) permissions | |
297 #======================================================================= | |
298 user_perms_from_users_groups = sa.query(UsersGroupToPerm, Permission, Repository,)\ | |
299 .join((Repository, UsersGroupToPerm.repository_id == Repository.repo_id))\ | |
300 .join((Permission, UsersGroupToPerm.permission_id == Permission.permission_id))\ | |
301 .join((UsersGroupMember, UsersGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\ | |
302 .filter(UsersGroupMember.user_id == user.user_id).all() | |
303 | |
304 for perm in user_perms_from_users_groups: | |
305 p = perm.Permission.permission_name | |
306 cur_perm = user.permissions['repositories'][perm.UsersGroupToPerm.repository.repo_name] | |
307 #overwrite permission only if it's greater than permission given from other sources | |
308 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]: | |
309 user.permissions['repositories'][perm.UsersGroupToPerm.repository.repo_name] = p | |
310 | |
285 meta.Session.remove() | 311 meta.Session.remove() |
286 return user | 312 return user |
287 | 313 |
288 def get_user(session): | 314 def get_user(session): |
289 """ | 315 """Gets user from session, and wraps permissions into user |
290 Gets user from session, and wraps permissions into user | 316 |
291 :param session: | 317 :param session: |
292 """ | 318 """ |
293 user = session.get('rhodecode_user', AuthUser()) | 319 user = session.get('rhodecode_user', AuthUser()) |
294 #if the user is not logged in we check for anonymous access | 320 #if the user is not logged in we check for anonymous access |
295 #if user is logged and it's a default user check if we still have anonymous | 321 #if user is logged and it's a default user check if we still have anonymous |