Switch to unified view

a/Allura/allura/model/project.py b/Allura/allura/model/project.py
...
...
21
21
22
from .session import main_orm_session
22
from .session import main_orm_session
23
from .session import project_doc_session, project_orm_session
23
from .session import project_doc_session, project_orm_session
24
from .neighborhood import Neighborhood
24
from .neighborhood import Neighborhood
25
from .auth import ProjectRole
25
from .auth import ProjectRole
26
from .types import ACL, ACE
26
27
27
from filesystem import File
28
from filesystem import File
28
29
29
log = logging.getLogger(__name__)
30
log = logging.getLogger(__name__)
30
31
...
...
76
    description=FieldProperty(str, if_missing='')
77
    description=FieldProperty(str, if_missing='')
77
    homepage_title=FieldProperty(str, if_missing='')
78
    homepage_title=FieldProperty(str, if_missing='')
78
    database=FieldProperty(S.Deprecated)
79
    database=FieldProperty(S.Deprecated)
79
    database_uri=FieldProperty(str)
80
    database_uri=FieldProperty(str)
80
    is_root=FieldProperty(bool)
81
    is_root=FieldProperty(bool)
81
    acl = FieldProperty({
82
    acl = FieldProperty(ACL(permissions=[
82
            'create':[S.ObjectId],    # create subproject
83
                'read', 'update', 'admin', 'create']))
83
            'read':[S.ObjectId],      # read project
84
            'update':[S.ObjectId],    # update project metadata
85
            'delete':[S.ObjectId],    # delete project, subprojects
86
            'tool':[S.ObjectId],    # install/delete/configure tools
87
            'security':[S.ObjectId],  # update ACL, roles
88
            })
89
    neighborhood_invitations=FieldProperty([S.ObjectId])
84
    neighborhood_invitations=FieldProperty([S.ObjectId])
90
    neighborhood = RelationProperty(Neighborhood)
85
    neighborhood = RelationProperty(Neighborhood)
91
    app_configs = RelationProperty('AppConfig')
86
    app_configs = RelationProperty('AppConfig')
92
    category_id = FieldProperty(S.ObjectId, if_missing=None)
87
    category_id = FieldProperty(S.ObjectId, if_missing=None)
93
    deleted = FieldProperty(bool, if_missing=False)
88
    deleted = FieldProperty(bool, if_missing=False)
...
...
95
    last_updated = FieldProperty(datetime, if_missing=None)
90
    last_updated = FieldProperty(datetime, if_missing=None)
96
    tool_data = FieldProperty({str:{str:None}}) # entry point: prefs dict
91
    tool_data = FieldProperty({str:{str:None}}) # entry point: prefs dict
97
    ordinal = FieldProperty(int, if_missing=0)
92
    ordinal = FieldProperty(int, if_missing=0)
98
    database_configured = FieldProperty(bool, if_missing=True)
93
    database_configured = FieldProperty(bool, if_missing=True)
99
    _extra_tool_status = FieldProperty([str])
94
    _extra_tool_status = FieldProperty([str])
95
96
    def parent_security_context(self):
97
        return self.parent_project
100
98
101
    @classmethod
99
    @classmethod
102
    def default_database_uri(cls, shortname):
100
    def default_database_uri(cls, shortname):
103
        base = config.get('ming.project.master')
101
        base = config.get('ming.project.master')
104
        db = config.get('ming.project.database')
102
        db = config.get('ming.project.database')
...
...
211
    @property
209
    @property
212
    def category(self):
210
    def category(self):
213
        return ProjectCategory.query.find(dict(_id=self.category_id)).first()
211
        return ProjectCategory.query.find(dict(_id=self.category_id)).first()
214
212
215
    def roleids_with_permission(self, name):
213
    def roleids_with_permission(self, name):
216
        roles = []
214
        roles = set()
217
        for p in self.parent_iter():
215
        for p in self.parent_iter():
218
            for roleid in p.acl[name]:
216
            for ace in p.acl:
217
                if ace.permission == name and ace.access == ACE.alllow:
219
                roles.append(roleid)
218
                    roles.add(ace.role_id)
220
        for roleid in self.acl[name]:
221
            if roleid not in roles:
222
                roles.append(roleid)
223
        return roles
219
        return list(roles)
224
220
225
    def sitemap(self):
221
    def sitemap(self):
226
        from allura.app import SitemapEntry
222
        from allura.app import SitemapEntry
227
        sitemap = SitemapEntry('root')
223
        sitemap = SitemapEntry('root')
228
        entries = []
224
        entries = []
...
...
307
            'install tool %s', ep_name,
303
            'install tool %s', ep_name,
308
            meta=dict(tool_type=ep_name, mount_point=options['mount_point'], mount_label=options['mount_label']))
304
            meta=dict(tool_type=ep_name, mount_point=options['mount_point'], mount_label=options['mount_label']))
309
        cfg = AppConfig(
305
        cfg = AppConfig(
310
            project_id=self._id,
306
            project_id=self._id,
311
            tool_name=ep.name,
307
            tool_name=ep.name,
312
            options=options,
308
            options=options)
313
            acl=dict((p,[]) for p in App.permissions))
314
        app = App(self, cfg)
309
        app = App(self, cfg)
315
        with h.push_config(c, project=self, app=app):
310
        with h.push_config(c, project=self, app=app):
316
            session(cfg).flush()
311
            session(cfg).flush()
317
            app.install(self)
312
            app.install(self)
318
        return app
313
        return app
...
...
406
            role_auth = M.ProjectRole.upsert(name='*authenticated', project_id=root_project_id)
401
            role_auth = M.ProjectRole.upsert(name='*authenticated', project_id=root_project_id)
407
            role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=root_project_id)
402
            role_anon = M.ProjectRole.upsert(name='*anonymous', project_id=root_project_id)
408
            # Setup subroles
403
            # Setup subroles
409
            role_admin.roles = [ role_developer._id ]
404
            role_admin.roles = [ role_developer._id ]
410
            role_developer.roles = [ role_member._id ]
405
            role_developer.roles = [ role_member._id ]
411
            self.acl['create'] = [ role_admin._id ]
406
            self.acl = [
412
            self.acl['read'] = [ role_admin._id, role_developer._id, role_member._id,
407
                ACE.allow(role_admin._id, 'create'),
413
                              role_anon._id ]
408
                ACE.allow(role_admin._id, 'update'),
414
            self.acl['update'] = [ role_admin._id ]
409
                ACE.allow(role_admin._id, 'admin'),
415
            self.acl['delete'] = [ role_admin._id ]
410
                ACE.allow(role_admin._id, 'read'),
416
            self.acl['tool'] = [ role_admin._id ]
411
                ACE.allow(role_developer._id, 'read'),
417
            self.acl['security'] = [ role_admin._id ]
412
                ACE.allow(role_member._id, 'read'),
413
                ACE.allow(role_anon._id, 'read')]
418
            for user in users:
414
            for user in users:
419
                pr = user.project_role()
415
                pr = user.project_role()
420
                pr.roles = [ role_admin._id, role_developer._id, role_member._id ]
416
                pr.roles = [ role_admin._id, role_developer._id, role_member._id ]
421
            # Setup apps
417
            # Setup apps
422
            for ep_name, mount_point in apps:
418
            for ep_name, mount_point in apps:
...
...
452
    version=FieldProperty(str)
448
    version=FieldProperty(str)
453
    options=FieldProperty(None)
449
    options=FieldProperty(None)
454
    project = RelationProperty(Project, via='project_id')
450
    project = RelationProperty(Project, via='project_id')
455
    discussion = RelationProperty('Discussion', via='discussion_id')
451
    discussion = RelationProperty('Discussion', via='discussion_id')
456
452
457
    # acl[permission] = [ role1, role2, ... ]
453
    acl = FieldProperty(ACL())
458
    acl = FieldProperty({str:[S.ObjectId]})
454
455
    def parent_security_context(self):
456
        return None
459
457
460
    def load(self):
458
    def load(self):
461
        """
459
        """
462
        :returns: the related :class:`Application <allura.app.Application>` class
460
        :returns: the related :class:`Application <allura.app.Application>` class
463
        """
461
        """
...
...
479
        return self.project.url() + self.options.mount_point + '/'
477
        return self.project.url() + self.options.mount_point + '/'
480
478
481
    def breadcrumbs(self):
479
    def breadcrumbs(self):
482
        return self.project.breadcrumbs() + [
480
        return self.project.breadcrumbs() + [
483
            (self.options.mount_point, self.url()) ]
481
            (self.options.mount_point, self.url()) ]
484
485
    def grant_permission(self, permission, role=None):
486
        from . import auth
487
        if role is None: role = c.user
488
        if not isinstance(role, auth.ProjectRole):
489
            role = role.project_role()
490
        if role._id not in self.acl[permission]:
491
            self.acl[permission].append(role._id)
492
493
    def revoke_permission(self, permission, role=None):
494
        from . import auth
495
        if role is None: role = c.user
496
        if not isinstance(role, auth.ProjectRole):
497
            role = role.project_role()
498
        if role._id in self.acl[permission]:
499
            self.acl[permission].remove(role._id)