|
a/Allura/allura/model/auth.py |
|
b/Allura/allura/model/auth.py |
|
... |
|
... |
12 |
import iso8601
|
12 |
import iso8601
|
13 |
import pymongo
|
13 |
import pymongo
|
14 |
from pylons import c, g, request
|
14 |
from pylons import c, g, request
|
15 |
|
15 |
|
16 |
from ming import schema as S
|
16 |
from ming import schema as S
|
17 |
from ming.orm.ormsession import ThreadLocalORMSession
|
|
|
18 |
from ming.orm import session, state, MappedClass
|
17 |
from ming.orm import session, state, MappedClass
|
19 |
from ming.orm import FieldProperty, RelationProperty, ForeignIdProperty
|
18 |
from ming.orm import FieldProperty, RelationProperty, ForeignIdProperty
|
20 |
|
19 |
|
21 |
from allura.lib import helpers as h
|
20 |
from allura.lib import helpers as h
|
22 |
from allura.lib import plugin
|
21 |
from allura.lib import plugin
|
|
|
22 |
from allura.lib import security
|
|
|
23 |
from .session import main_orm_session
|
23 |
from .session import ProjectSession
|
24 |
from .session import project_orm_session
|
24 |
from .session import main_doc_session, main_orm_session
|
|
|
25 |
from .session import project_doc_session, project_orm_session
|
|
|
26 |
|
25 |
|
27 |
log = logging.getLogger(__name__)
|
26 |
log = logging.getLogger(__name__)
|
28 |
|
27 |
|
29 |
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
|
28 |
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
|
30 |
"""
|
29 |
"""
|
|
... |
|
... |
293 |
@property
|
292 |
@property
|
294 |
def script_name(self):
|
293 |
def script_name(self):
|
295 |
return '/u/' + self.username + '/'
|
294 |
return '/u/' + self.username + '/'
|
296 |
|
295 |
|
297 |
def my_projects(self):
|
296 |
def my_projects(self):
|
|
|
297 |
'''Find the projects for which this user has a named role.'''
|
|
|
298 |
reaching_role_ids = g.credentials.user_roles(user_id=self._id).reaching_ids_set
|
|
|
299 |
reaching_roles = [ ProjectRole.query.get(_id=i) for i in reaching_role_ids ]
|
|
|
300 |
named_roles = [ r for r in reaching_roles if r.name ]
|
298 |
seen_project_ids = set()
|
301 |
seen_project_ids = set()
|
299 |
seen_role_ids = set()
|
302 |
for r in named_roles:
|
300 |
candidates = ProjectRole.query.find(dict(user_id=self._id)).all()
|
|
|
301 |
user_project = 'u/' + self.username
|
|
|
302 |
while candidates:
|
|
|
303 |
r = candidates.pop(0)
|
|
|
304 |
if r._id in seen_role_ids: continue
|
303 |
if r.project_id in seen_project_ids: continue
|
305 |
seen_role_ids.add(r._id)
|
|
|
306 |
if r.name and r.project_id not in seen_project_ids:
|
|
|
307 |
seen_project_ids.add(r.project_id)
|
304 |
seen_project_ids.add(r.project_id)
|
308 |
if r.project.shortname != user_project:
|
|
|
309 |
yield r.project
|
305 |
yield r.project
|
310 |
candidates += ProjectRole.query.find(dict(
|
|
|
311 |
_id={'$in':r.roles}))
|
|
|
312 |
|
|
|
313 |
def role_iter(self):
|
|
|
314 |
anon_role = ProjectRole.anonymous()
|
|
|
315 |
auth_role = ProjectRole.authenticated()
|
|
|
316 |
if anon_role:
|
|
|
317 |
yield anon_role
|
|
|
318 |
if self._id and auth_role:
|
|
|
319 |
yield auth_role
|
|
|
320 |
if self._id:
|
|
|
321 |
pr = self.project_role()
|
|
|
322 |
for role in pr.role_iter():
|
|
|
323 |
yield role
|
|
|
324 |
|
306 |
|
325 |
def project_role(self, project=None):
|
307 |
def project_role(self, project=None):
|
|
|
308 |
if project is None: project = c.project
|
326 |
if self._id is None:
|
309 |
if self._id is None:
|
327 |
return ProjectRole.anonymous(project)
|
310 |
return ProjectRole.anonymous(project)
|
328 |
pr = ProjectRole.by_user(self, project)
|
311 |
else:
|
329 |
if pr is not None: return pr
|
|
|
330 |
if project is None: project = c.project
|
|
|
331 |
return ProjectRole.upsert(user_id=self._id, project_id=project.root_project._id)
|
312 |
return ProjectRole.upsert(user_id=self._id, project_id=project.root_project._id)
|
332 |
|
313 |
|
333 |
def set_password(self, new_password):
|
314 |
def set_password(self, new_password):
|
334 |
return plugin.AuthenticationProvider.get(request).set_password(
|
315 |
return plugin.AuthenticationProvider.get(request).set_password(
|
335 |
self, self.password, new_password)
|
316 |
self, self.password, new_password)
|
336 |
|
317 |
|
|
... |
|
... |
383 |
return '*user-%s' % uname
|
364 |
return '*user-%s' % uname
|
384 |
return '**unknown name role: %s' % self._id # pragma no cover
|
365 |
return '**unknown name role: %s' % self._id # pragma no cover
|
385 |
|
366 |
|
386 |
@classmethod
|
367 |
@classmethod
|
387 |
def by_user(cls, user=None, project=None):
|
368 |
def by_user(cls, user=None, project=None):
|
|
|
369 |
if user is None and project is None:
|
|
|
370 |
return c.user.current_project_role
|
388 |
if user is None: user = c.user
|
371 |
if user is None: user = c.user
|
389 |
if project is None: project = c.project
|
372 |
if project is None: project = c.project
|
390 |
pr = cls.query.get(
|
373 |
pr = cls.query.get(
|
391 |
user_id=user._id,
|
374 |
user_id=user._id,
|
392 |
project_id={'$in':[project.root_project._id, None]})
|
375 |
project_id=project.root_project._id)
|
393 |
if pr is None:
|
376 |
if pr is None:
|
394 |
pr = cls.query.get(
|
377 |
pr = cls.query.get(
|
395 |
user_id=user._id,
|
378 |
user_id=user._id,
|
396 |
project_id={'$exists':False})
|
379 |
project_id={'$exists':False})
|
397 |
return pr
|
380 |
return pr
|
|
... |
|
... |
399 |
@classmethod
|
382 |
@classmethod
|
400 |
def by_name(cls, name, project=None):
|
383 |
def by_name(cls, name, project=None):
|
401 |
if project is None: project = c.project
|
384 |
if project is None: project = c.project
|
402 |
role = cls.query.get(
|
385 |
role = cls.query.get(
|
403 |
name=name,
|
386 |
name=name,
|
404 |
project_id={'$in':[project.root_project._id, None]})
|
387 |
project_id=project.root_project._id)
|
405 |
if role is None:
|
388 |
if role is None:
|
406 |
role = cls.query.get(
|
389 |
role = cls.query.get(
|
407 |
name=name,
|
390 |
name=name,
|
408 |
project_id={'$exists':False})
|
391 |
project_id={'$exists':False})
|
409 |
return role
|
392 |
return role
|
|
... |
|
... |
439 |
@property
|
422 |
@property
|
440 |
def user(self):
|
423 |
def user(self):
|
441 |
if self.user_id is None: return None
|
424 |
if self.user_id is None: return None
|
442 |
return User.query.get(_id=self.user_id)
|
425 |
return User.query.get(_id=self.user_id)
|
443 |
|
426 |
|
444 |
@classmethod
|
|
|
445 |
def roles_reachable_from(cls, *roots):
|
|
|
446 |
to_visit = list(roots)
|
|
|
447 |
visited = set()
|
|
|
448 |
while to_visit:
|
|
|
449 |
pr = to_visit.pop(0)
|
|
|
450 |
if pr in visited: continue
|
|
|
451 |
visited.add(pr)
|
|
|
452 |
yield pr
|
|
|
453 |
to_visit += cls.query.find(dict(_id={'$in':pr.roles})).all()
|
|
|
454 |
|
|
|
455 |
@classmethod
|
|
|
456 |
def roles_that_reach(cls, *roots):
|
|
|
457 |
to_visit = list(roots)
|
|
|
458 |
visited = set()
|
|
|
459 |
while to_visit:
|
|
|
460 |
pr = to_visit.pop(0)
|
|
|
461 |
if pr in visited: continue
|
|
|
462 |
visited.add(pr)
|
|
|
463 |
yield pr
|
|
|
464 |
to_visit += cls.query.find(dict(roles=pr._id)).all()
|
|
|
465 |
|
|
|
466 |
def users_with_role(self):
|
|
|
467 |
return [
|
|
|
468 |
role.user for role in self.roles_that_reach(self) if role.user_id ]
|
|
|
469 |
|
|
|
470 |
def users_with_role_directly(self):
|
|
|
471 |
return [
|
|
|
472 |
role.user for role in self.query.find(dict(roles=self._id))
|
|
|
473 |
if role.user_id ]
|
|
|
474 |
|
|
|
475 |
def role_iter(self):
|
|
|
476 |
return self.roles_reachable_from(self)
|
|
|
477 |
|
|
|
478 |
@property
|
427 |
@property
|
479 |
def settings_href(self):
|
428 |
def settings_href(self):
|
480 |
if self.name in ('Admin', 'Developer', 'Member'):
|
429 |
if self.name in ('Admin', 'Developer', 'Member'):
|
481 |
return None
|
430 |
return None
|
482 |
return self.project.url() + 'admin/groups/' + str(self._id) + '/'
|
431 |
return self.project.url() + 'admin/groups/' + str(self._id) + '/'
|