Switch to unified view

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) + '/'