|
a/Allura/allura/model/project.py |
|
b/Allura/allura/model/project.py |
|
... |
|
... |
16 |
|
16 |
|
17 |
from allura.lib import helpers as h
|
17 |
from allura.lib import helpers as h
|
18 |
from allura.lib import plugin
|
18 |
from allura.lib import plugin
|
19 |
from allura.lib import exceptions
|
19 |
from allura.lib import exceptions
|
20 |
from allura.lib import security
|
20 |
from allura.lib import security
|
|
|
21 |
from allura.lib.security import has_access
|
|
|
22 |
|
|
|
23 |
try:
|
|
|
24 |
from forgewiki import ForgeWikiApp
|
|
|
25 |
except ImportError:
|
|
|
26 |
ForgeWikiApp = None
|
21 |
|
27 |
|
22 |
from .session import main_orm_session
|
28 |
from .session import main_orm_session
|
23 |
from .session import project_doc_session, project_orm_session
|
29 |
from .session import project_doc_session, project_orm_session
|
24 |
from .neighborhood import Neighborhood
|
30 |
from .neighborhood import Neighborhood
|
25 |
from .auth import ProjectRole
|
31 |
from .auth import ProjectRole
|
|
... |
|
... |
93 |
_id=FieldProperty(S.ObjectId)
|
99 |
_id=FieldProperty(S.ObjectId)
|
94 |
parent_id = FieldProperty(S.ObjectId, if_missing=None)
|
100 |
parent_id = FieldProperty(S.ObjectId, if_missing=None)
|
95 |
neighborhood_id = ForeignIdProperty(Neighborhood)
|
101 |
neighborhood_id = ForeignIdProperty(Neighborhood)
|
96 |
shortname = FieldProperty(str)
|
102 |
shortname = FieldProperty(str)
|
97 |
name=FieldProperty(str)
|
103 |
name=FieldProperty(str)
|
|
|
104 |
notifications_disabled = FieldProperty(bool)
|
98 |
show_download_button=FieldProperty(bool, if_missing=True)
|
105 |
show_download_button=FieldProperty(bool, if_missing=True)
|
99 |
short_description=FieldProperty(str, if_missing='')
|
106 |
short_description=FieldProperty(str, if_missing='')
|
100 |
description=FieldProperty(str, if_missing='')
|
107 |
description=FieldProperty(str, if_missing='')
|
101 |
homepage_title=FieldProperty(str, if_missing='')
|
108 |
homepage_title=FieldProperty(str, if_missing='')
|
102 |
external_homepage=FieldProperty(str, if_missing='')
|
109 |
external_homepage=FieldProperty(str, if_missing='')
|
|
... |
|
... |
436 |
if not h.re_path_portion.match(name):
|
443 |
if not h.re_path_portion.match(name):
|
437 |
raise exceptions.ToolError, 'Mount point "%s" is invalid' % name
|
444 |
raise exceptions.ToolError, 'Mount point "%s" is invalid' % name
|
438 |
provider = plugin.ProjectRegistrationProvider.get()
|
445 |
provider = plugin.ProjectRegistrationProvider.get()
|
439 |
return provider.register_subproject(self, name, user or c.user, install_apps)
|
446 |
return provider.register_subproject(self, name, user or c.user, install_apps)
|
440 |
|
447 |
|
|
|
448 |
def ordered_mounts(self, include_search=False):
|
|
|
449 |
'''Returns an array of a projects mounts (tools and sub-projects) in
|
|
|
450 |
toolbar order.'''
|
|
|
451 |
result = []
|
|
|
452 |
for sub in self.direct_subprojects:
|
|
|
453 |
result.append({'ordinal':sub.ordinal, 'sub':sub})
|
|
|
454 |
for ac in self.app_configs:
|
|
|
455 |
if include_search or ac.tool_name != 'search':
|
|
|
456 |
ordinal = ac.options.get('ordinal', 0)
|
|
|
457 |
result.append({'ordinal':ordinal, 'ac':ac})
|
|
|
458 |
return sorted(result, key=lambda e: e['ordinal'])
|
|
|
459 |
|
|
|
460 |
def first_mount(self, required_access=None):
|
|
|
461 |
'''Returns the first (toolbar order) mount, or the first mount to
|
|
|
462 |
which the user has the required access.'''
|
|
|
463 |
mounts = self.ordered_mounts()
|
|
|
464 |
if mounts and required_access is None:
|
|
|
465 |
return mounts[0]
|
|
|
466 |
for mount in mounts:
|
|
|
467 |
if 'sub' in mount:
|
|
|
468 |
obj = mount['sub']
|
|
|
469 |
elif 'ac' in mount:
|
|
|
470 |
obj = self.app_instance(mount['ac'])
|
|
|
471 |
else:
|
|
|
472 |
continue
|
|
|
473 |
if has_access(obj, required_access):
|
|
|
474 |
return mount
|
|
|
475 |
return None
|
|
|
476 |
|
441 |
def delete(self):
|
477 |
def delete(self):
|
442 |
# Cascade to subprojects
|
478 |
# Cascade to subprojects
|
443 |
for sp in self.direct_subprojects:
|
479 |
for sp in self.direct_subprojects:
|
444 |
sp.delete()
|
480 |
sp.delete()
|
445 |
# Cascade to app configs
|
481 |
# Cascade to app configs
|
|
... |
|
... |
481 |
is_private_project=False):
|
517 |
is_private_project=False):
|
482 |
from allura import model as M
|
518 |
from allura import model as M
|
483 |
if users is None: users = [ c.user ]
|
519 |
if users is None: users = [ c.user ]
|
484 |
if apps is None:
|
520 |
if apps is None:
|
485 |
if is_user_project:
|
521 |
if is_user_project:
|
486 |
apps = [('profile', 'profile'),
|
522 |
apps = [('profile', 'profile', 'Profile'),
|
487 |
('admin', 'admin'),
|
523 |
('admin', 'admin', 'Admin'),
|
488 |
('search', 'search')]
|
524 |
('search', 'search', 'Search')]
|
489 |
else:
|
525 |
else:
|
490 |
apps = [('home', 'home'),
|
526 |
apps = [('Wiki', 'home', 'Home'),
|
491 |
('admin', 'admin'),
|
527 |
('admin', 'admin', 'Admin'),
|
492 |
('search', 'search')]
|
528 |
('search', 'search', 'Search')]
|
493 |
with h.push_config(c, project=self, user=users[0]):
|
529 |
with h.push_config(c, project=self, user=users[0]):
|
494 |
# Install default named roles (#78)
|
530 |
# Install default named roles (#78)
|
495 |
root_project_id=self.root_project._id
|
531 |
root_project_id=self.root_project._id
|
496 |
role_admin = M.ProjectRole.upsert(name='Admin', project_id=root_project_id)
|
532 |
role_admin = M.ProjectRole.upsert(name='Admin', project_id=root_project_id)
|
497 |
role_developer = M.ProjectRole.upsert(name='Developer', project_id=root_project_id)
|
533 |
role_developer = M.ProjectRole.upsert(name='Developer', project_id=root_project_id)
|
|
... |
|
... |
511 |
for perm in self.permissions ]
|
547 |
for perm in self.permissions ]
|
512 |
for user in users:
|
548 |
for user in users:
|
513 |
pr = user.project_role()
|
549 |
pr = user.project_role()
|
514 |
pr.roles = [ role_admin._id, role_developer._id, role_member._id ]
|
550 |
pr.roles = [ role_admin._id, role_developer._id, role_member._id ]
|
515 |
# Setup apps
|
551 |
# Setup apps
|
516 |
for ep_name, mount_point in apps:
|
552 |
for i, (ep_name, mount_point, label) in enumerate(apps):
|
517 |
self.install_app(ep_name, mount_point)
|
553 |
self.install_app(ep_name, mount_point, label, ordinal=i)
|
|
|
554 |
if ForgeWikiApp is not None:
|
|
|
555 |
home_app = self.app_instance('home')
|
|
|
556 |
if isinstance(home_app, ForgeWikiApp):
|
|
|
557 |
home_app.show_discussion = False
|
|
|
558 |
home_app.show_left_bar = False
|
518 |
self.database_configured = True
|
559 |
self.database_configured = True
|
519 |
ThreadLocalORMSession.flush_all()
|
560 |
ThreadLocalORMSession.flush_all()
|
520 |
|
561 |
|
521 |
def add_user(self, user, role_names):
|
562 |
def add_user(self, user, role_names):
|
522 |
'Convenience method to add member with the given role(s).'
|
563 |
'Convenience method to add member with the given role(s).'
|