Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,45 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2011-2018 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import logging | |||
|
22 | ||||
|
23 | from pyramid.view import view_config | |||
|
24 | ||||
|
25 | from rhodecode.apps._base import RepoAppView | |||
|
26 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | |||
|
27 | ||||
|
28 | log = logging.getLogger(__name__) | |||
|
29 | ||||
|
30 | ||||
|
31 | class RepoSettingsBranchPermissionsView(RepoAppView): | |||
|
32 | ||||
|
33 | def load_default_context(self): | |||
|
34 | c = self._get_local_tmpl_context() | |||
|
35 | return c | |||
|
36 | ||||
|
37 | @LoginRequired() | |||
|
38 | @HasRepoPermissionAnyDecorator('repository.admin') | |||
|
39 | @view_config( | |||
|
40 | route_name='edit_repo_perms_branch', request_method='GET', | |||
|
41 | renderer='rhodecode:templates/admin/repos/repo_edit.mako') | |||
|
42 | def branch_permissions(self): | |||
|
43 | c = self.load_default_context() | |||
|
44 | c.active = 'permissions_branch' | |||
|
45 | return self._get_template_context(c) |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
@@ -0,0 +1,46 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from sqlalchemy import * | |||
|
4 | from sqlalchemy.engine import reflection | |||
|
5 | from sqlalchemy.dialects.mysql import LONGTEXT | |||
|
6 | ||||
|
7 | from alembic.migration import MigrationContext | |||
|
8 | from alembic.operations import Operations | |||
|
9 | ||||
|
10 | from rhodecode.lib.dbmigrate.utils import create_default_permissions, \ | |||
|
11 | create_default_object_permission | |||
|
12 | from rhodecode.model import meta | |||
|
13 | from rhodecode.lib.dbmigrate.versions import _reset_base, notify | |||
|
14 | ||||
|
15 | log = logging.getLogger(__name__) | |||
|
16 | ||||
|
17 | ||||
|
18 | def upgrade(migrate_engine): | |||
|
19 | """ | |||
|
20 | Upgrade operations go here. | |||
|
21 | Don't create your own engine; bind migrate_engine to your metadata | |||
|
22 | """ | |||
|
23 | _reset_base(migrate_engine) | |||
|
24 | from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db | |||
|
25 | ||||
|
26 | # issue fixups | |||
|
27 | fixups(db, meta.Session) | |||
|
28 | ||||
|
29 | ||||
|
30 | def downgrade(migrate_engine): | |||
|
31 | meta = MetaData() | |||
|
32 | meta.bind = migrate_engine | |||
|
33 | ||||
|
34 | ||||
|
35 | def fixups(models, _SESSION): | |||
|
36 | # create default permissions | |||
|
37 | create_default_permissions(_SESSION, models) | |||
|
38 | log.info('created default global permissions definitions') | |||
|
39 | _SESSION().commit() | |||
|
40 | ||||
|
41 | # # fix default object permissions | |||
|
42 | # create_default_object_permission(_SESSION, models) | |||
|
43 | ||||
|
44 | log.info('created default permission') | |||
|
45 | _SESSION().commit() | |||
|
46 |
@@ -0,0 +1,39 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from sqlalchemy import * | |||
|
4 | from sqlalchemy.engine import reflection | |||
|
5 | from sqlalchemy.dialects.mysql import LONGTEXT | |||
|
6 | ||||
|
7 | from alembic.migration import MigrationContext | |||
|
8 | from alembic.operations import Operations | |||
|
9 | ||||
|
10 | from rhodecode.model import meta | |||
|
11 | from rhodecode.lib.dbmigrate.versions import _reset_base, notify | |||
|
12 | ||||
|
13 | log = logging.getLogger(__name__) | |||
|
14 | ||||
|
15 | ||||
|
16 | def upgrade(migrate_engine): | |||
|
17 | """ | |||
|
18 | Upgrade operations go here. | |||
|
19 | Don't create your own engine; bind migrate_engine to your metadata | |||
|
20 | """ | |||
|
21 | _reset_base(migrate_engine) | |||
|
22 | from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db | |||
|
23 | ||||
|
24 | db.UserToRepoBranchPermission.__table__.create() | |||
|
25 | db.UserGroupToRepoBranchPermission.__table__.create() | |||
|
26 | ||||
|
27 | # issue fixups | |||
|
28 | fixups(db, meta.Session) | |||
|
29 | ||||
|
30 | ||||
|
31 | def downgrade(migrate_engine): | |||
|
32 | meta = MetaData() | |||
|
33 | meta.bind = migrate_engine | |||
|
34 | ||||
|
35 | ||||
|
36 | def fixups(models, _SESSION): | |||
|
37 | pass | |||
|
38 | ||||
|
39 |
@@ -0,0 +1,43 b'' | |||||
|
1 | import logging | |||
|
2 | ||||
|
3 | from sqlalchemy import * | |||
|
4 | ||||
|
5 | from rhodecode.lib.dbmigrate.utils import ( | |||
|
6 | create_default_object_permission, create_default_permissions) | |||
|
7 | ||||
|
8 | from rhodecode.model import meta | |||
|
9 | from rhodecode.lib.dbmigrate.versions import _reset_base, notify | |||
|
10 | ||||
|
11 | log = logging.getLogger(__name__) | |||
|
12 | ||||
|
13 | ||||
|
14 | def upgrade(migrate_engine): | |||
|
15 | """ | |||
|
16 | Upgrade operations go here. | |||
|
17 | Don't create your own engine; bind migrate_engine to your metadata | |||
|
18 | """ | |||
|
19 | _reset_base(migrate_engine) | |||
|
20 | from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db | |||
|
21 | ||||
|
22 | # issue fixups | |||
|
23 | fixups(db, meta.Session) | |||
|
24 | ||||
|
25 | ||||
|
26 | def downgrade(migrate_engine): | |||
|
27 | meta = MetaData() | |||
|
28 | meta.bind = migrate_engine | |||
|
29 | ||||
|
30 | ||||
|
31 | def fixups(models, _SESSION): | |||
|
32 | # create default permissions | |||
|
33 | create_default_permissions(_SESSION, models) | |||
|
34 | log.info('created default global permissions definitions') | |||
|
35 | _SESSION().commit() | |||
|
36 | ||||
|
37 | # fix default object permissions | |||
|
38 | create_default_object_permission(_SESSION, models) | |||
|
39 | ||||
|
40 | log.info('created default permission') | |||
|
41 | _SESSION().commit() | |||
|
42 | ||||
|
43 |
@@ -0,0 +1,9 b'' | |||||
|
1 | <div class="panel panel-default"> | |||
|
2 | <div class="panel-heading"> | |||
|
3 | <h3 class="panel-title">${_('Default Permissions for Branches.')}</h3> | |||
|
4 | </div> | |||
|
5 | <div class="panel-body"> | |||
|
6 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |||
|
7 | <img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_branch_permissions.png')}"/> | |||
|
8 | </div> | |||
|
9 | </div> |
@@ -0,0 +1,9 b'' | |||||
|
1 | <div class="panel panel-default"> | |||
|
2 | <div class="panel-heading"> | |||
|
3 | <h3 class="panel-title">${_('Repository Branch Permissions.')}</h3> | |||
|
4 | </div> | |||
|
5 | <div class="panel-body"> | |||
|
6 | <h4>${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='<a href="mailto:sales@rhodecode.com">sales@rhodecode.com</a>')|n}</h4> | |||
|
7 | <img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/repo_branch_permissions.png')}"/> | |||
|
8 | </div> | |||
|
9 | </div> |
@@ -51,7 +51,7 b' PYRAMID_SETTINGS = {}' | |||||
51 | EXTENSIONS = {} |
|
51 | EXTENSIONS = {} | |
52 |
|
52 | |||
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) |
|
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) | |
54 |
__dbversion__ = |
|
54 | __dbversion__ = 90 # defines current db version for migrations | |
55 | __platform__ = platform.system() |
|
55 | __platform__ = platform.system() | |
56 | __license__ = 'AGPLv3, and Commercial License' |
|
56 | __license__ = 'AGPLv3, and Commercial License' | |
57 | __author__ = 'RhodeCode GmbH' |
|
57 | __author__ = 'RhodeCode GmbH' |
@@ -210,6 +210,11 b' def admin_routes(config):' | |||||
210 | name='admin_permissions_object_update', |
|
210 | name='admin_permissions_object_update', | |
211 | pattern='/permissions/object/update') |
|
211 | pattern='/permissions/object/update') | |
212 |
|
212 | |||
|
213 | # Branch perms EE feature | |||
|
214 | config.add_route( | |||
|
215 | name='admin_permissions_branch', | |||
|
216 | pattern='/permissions/branch') | |||
|
217 | ||||
213 | config.add_route( |
|
218 | config.add_route( | |
214 | name='admin_permissions_ips', |
|
219 | name='admin_permissions_ips', | |
215 | pattern='/permissions/ips') |
|
220 | pattern='/permissions/ips') |
@@ -182,7 +182,8 b' class AdminPermissionsView(BaseAppView, ' | |||||
182 | self.request.translate, |
|
182 | self.request.translate, | |
183 | [x[0] for x in c.repo_perms_choices], |
|
183 | [x[0] for x in c.repo_perms_choices], | |
184 | [x[0] for x in c.group_perms_choices], |
|
184 | [x[0] for x in c.group_perms_choices], | |
185 |
[x[0] for x in c.user_group_perms_choices] |
|
185 | [x[0] for x in c.user_group_perms_choices], | |
|
186 | )() | |||
186 |
|
187 | |||
187 | try: |
|
188 | try: | |
188 | form_result = _form.to_python(dict(self.request.POST)) |
|
189 | form_result = _form.to_python(dict(self.request.POST)) | |
@@ -218,6 +219,30 b' class AdminPermissionsView(BaseAppView, ' | |||||
218 | @LoginRequired() |
|
219 | @LoginRequired() | |
219 | @HasPermissionAllDecorator('hg.admin') |
|
220 | @HasPermissionAllDecorator('hg.admin') | |
220 | @view_config( |
|
221 | @view_config( | |
|
222 | route_name='admin_permissions_branch', request_method='GET', | |||
|
223 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |||
|
224 | def permissions_branch(self): | |||
|
225 | c = self.load_default_context() | |||
|
226 | c.active = 'branch' | |||
|
227 | ||||
|
228 | c.user = User.get_default_user(refresh=True) | |||
|
229 | defaults = {} | |||
|
230 | defaults.update(c.user.get_default_perms()) | |||
|
231 | ||||
|
232 | data = render( | |||
|
233 | 'rhodecode:templates/admin/permissions/permissions.mako', | |||
|
234 | self._get_template_context(c), self.request) | |||
|
235 | html = formencode.htmlfill.render( | |||
|
236 | data, | |||
|
237 | defaults=defaults, | |||
|
238 | encoding="UTF-8", | |||
|
239 | force_defaults=False | |||
|
240 | ) | |||
|
241 | return Response(html) | |||
|
242 | ||||
|
243 | @LoginRequired() | |||
|
244 | @HasPermissionAllDecorator('hg.admin') | |||
|
245 | @view_config( | |||
221 | route_name='admin_permissions_global', request_method='GET', |
|
246 | route_name='admin_permissions_global', request_method='GET', | |
222 | renderer='rhodecode:templates/admin/permissions/permissions.mako') |
|
247 | renderer='rhodecode:templates/admin/permissions/permissions.mako') | |
223 | def permissions_global(self): |
|
248 | def permissions_global(self): |
@@ -345,6 +345,15 b' def includeme(config):' | |||||
345 | name='edit_repo_perms', |
|
345 | name='edit_repo_perms', | |
346 | pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True) |
|
346 | pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True) | |
347 |
|
347 | |||
|
348 | # Permissions Branch (EE feature) | |||
|
349 | config.add_route( | |||
|
350 | name='edit_repo_perms_branch', | |||
|
351 | pattern='/{repo_name:.*?[^/]}/settings/branch_permissions', repo_route=True) | |||
|
352 | config.add_route( | |||
|
353 | name='edit_repo_perms_branch_delete', | |||
|
354 | pattern='/{repo_name:.*?[^/]}/settings/branch_permissions/{rule_id}/delete', | |||
|
355 | repo_route=True) | |||
|
356 | ||||
348 | # Maintenance |
|
357 | # Maintenance | |
349 | config.add_route( |
|
358 | config.add_route( | |
350 | name='edit_repo_maintenance', |
|
359 | name='edit_repo_maintenance', |
@@ -367,10 +367,38 b' class PermOriginDict(dict):' | |||||
367 | self.perm_origin_stack = collections.OrderedDict() |
|
367 | self.perm_origin_stack = collections.OrderedDict() | |
368 |
|
368 | |||
369 | def __setitem__(self, key, (perm, origin)): |
|
369 | def __setitem__(self, key, (perm, origin)): | |
370 |
self.perm_origin_stack.setdefault(key, []).append( |
|
370 | self.perm_origin_stack.setdefault(key, []).append( | |
|
371 | (perm, origin)) | |||
371 | dict.__setitem__(self, key, perm) |
|
372 | dict.__setitem__(self, key, perm) | |
372 |
|
373 | |||
373 |
|
374 | |||
|
375 | class BranchPermOriginDict(PermOriginDict): | |||
|
376 | """ | |||
|
377 | Dedicated branch permissions dict, with tracking of patterns and origins. | |||
|
378 | ||||
|
379 | >>> perms = BranchPermOriginDict() | |||
|
380 | >>> perms['resource'] = '*pattern', 'read', 'default' | |||
|
381 | >>> perms['resource'] | |||
|
382 | {'*pattern': 'read'} | |||
|
383 | >>> perms['resource'] = '*pattern', 'write', 'admin' | |||
|
384 | >>> perms['resource'] | |||
|
385 | {'*pattern': 'write'} | |||
|
386 | >>> perms.perm_origin_stack | |||
|
387 | {'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}} | |||
|
388 | """ | |||
|
389 | def __setitem__(self, key, (pattern, perm, origin)): | |||
|
390 | ||||
|
391 | self.perm_origin_stack.setdefault(key, {}) \ | |||
|
392 | .setdefault(pattern, []).append((perm, origin)) | |||
|
393 | ||||
|
394 | if key in self: | |||
|
395 | self[key].__setitem__(pattern, perm) | |||
|
396 | else: | |||
|
397 | patterns = collections.OrderedDict() | |||
|
398 | patterns[pattern] = perm | |||
|
399 | dict.__setitem__(self, key, patterns) | |||
|
400 | ||||
|
401 | ||||
374 | class PermissionCalculator(object): |
|
402 | class PermissionCalculator(object): | |
375 |
|
403 | |||
376 | def __init__( |
|
404 | def __init__( | |
@@ -395,6 +423,7 b' class PermissionCalculator(object):' | |||||
395 | self.permissions_repositories = PermOriginDict() |
|
423 | self.permissions_repositories = PermOriginDict() | |
396 | self.permissions_repository_groups = PermOriginDict() |
|
424 | self.permissions_repository_groups = PermOriginDict() | |
397 | self.permissions_user_groups = PermOriginDict() |
|
425 | self.permissions_user_groups = PermOriginDict() | |
|
426 | self.permissions_repository_branches = BranchPermOriginDict() | |||
398 | self.permissions_global = set() |
|
427 | self.permissions_global = set() | |
399 |
|
428 | |||
400 | self.default_repo_perms = Permission.get_default_repo_perms( |
|
429 | self.default_repo_perms = Permission.get_default_repo_perms( | |
@@ -405,6 +434,11 b' class PermissionCalculator(object):' | |||||
405 | Permission.get_default_user_group_perms( |
|
434 | Permission.get_default_user_group_perms( | |
406 | self.default_user_id, self.scope_user_group_id) |
|
435 | self.default_user_id, self.scope_user_group_id) | |
407 |
|
436 | |||
|
437 | # default branch perms | |||
|
438 | self.default_branch_repo_perms = \ | |||
|
439 | Permission.get_default_repo_branch_perms( | |||
|
440 | self.default_user_id, self.scope_repo_id) | |||
|
441 | ||||
408 | def calculate(self): |
|
442 | def calculate(self): | |
409 | if self.user_is_admin and not self.calculate_super_admin: |
|
443 | if self.user_is_admin and not self.calculate_super_admin: | |
410 | return self._admin_permissions() |
|
444 | return self._admin_permissions() | |
@@ -413,6 +447,7 b' class PermissionCalculator(object):' | |||||
413 | self._calculate_global_permissions() |
|
447 | self._calculate_global_permissions() | |
414 | self._calculate_default_permissions() |
|
448 | self._calculate_default_permissions() | |
415 | self._calculate_repository_permissions() |
|
449 | self._calculate_repository_permissions() | |
|
450 | self._calculate_repository_branch_permissions() | |||
416 | self._calculate_repository_group_permissions() |
|
451 | self._calculate_repository_group_permissions() | |
417 | self._calculate_user_group_permissions() |
|
452 | self._calculate_user_group_permissions() | |
418 | return self._permission_structure() |
|
453 | return self._permission_structure() | |
@@ -443,6 +478,15 b' class PermissionCalculator(object):' | |||||
443 | p = 'usergroup.admin' |
|
478 | p = 'usergroup.admin' | |
444 | self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN |
|
479 | self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN | |
445 |
|
480 | |||
|
481 | # branch permissions | |||
|
482 | # TODO(marcink): validate this, especially | |||
|
483 | # how this should work using multiple patterns specified ?? | |||
|
484 | # looks ok, but still needs double check !! | |||
|
485 | for perm in self.default_branch_repo_perms: | |||
|
486 | r_k = perm.UserRepoToPerm.repository.repo_name | |||
|
487 | p = 'branch.push_force' | |||
|
488 | self.permissions_repository_branches[r_k] = '*', p, PermOrigin.SUPER_ADMIN | |||
|
489 | ||||
446 | return self._permission_structure() |
|
490 | return self._permission_structure() | |
447 |
|
491 | |||
448 | def _calculate_global_default_permissions(self): |
|
492 | def _calculate_global_default_permissions(self): | |
@@ -472,18 +516,14 b' class PermissionCalculator(object):' | |||||
472 | # now we read the defined permissions and overwrite what we have set |
|
516 | # now we read the defined permissions and overwrite what we have set | |
473 | # before those can be configured from groups or users explicitly. |
|
517 | # before those can be configured from groups or users explicitly. | |
474 |
|
518 | |||
475 | # TODO: johbo: This seems to be out of sync, find out the reason |
|
519 | # In case we want to extend this list we should make sure | |
476 | # for the comment below and update it. |
|
520 | # this is in sync with User.DEFAULT_USER_PERMISSIONS definitions | |
477 |
|
||||
478 | # In case we want to extend this list we should be always in sync with |
|
|||
479 | # User.DEFAULT_USER_PERMISSIONS definitions |
|
|||
480 | _configurable = frozenset([ |
|
521 | _configurable = frozenset([ | |
481 | 'hg.fork.none', 'hg.fork.repository', |
|
522 | 'hg.fork.none', 'hg.fork.repository', | |
482 | 'hg.create.none', 'hg.create.repository', |
|
523 | 'hg.create.none', 'hg.create.repository', | |
483 | 'hg.usergroup.create.false', 'hg.usergroup.create.true', |
|
524 | 'hg.usergroup.create.false', 'hg.usergroup.create.true', | |
484 | 'hg.repogroup.create.false', 'hg.repogroup.create.true', |
|
525 | 'hg.repogroup.create.false', 'hg.repogroup.create.true', | |
485 | 'hg.create.write_on_repogroup.false', |
|
526 | 'hg.create.write_on_repogroup.false', 'hg.create.write_on_repogroup.true', | |
486 | 'hg.create.write_on_repogroup.true', |
|
|||
487 | 'hg.inherit_default_perms.false', 'hg.inherit_default_perms.true' |
|
527 | 'hg.inherit_default_perms.false', 'hg.inherit_default_perms.true' | |
488 | ]) |
|
528 | ]) | |
489 |
|
529 | |||
@@ -506,7 +546,7 b' class PermissionCalculator(object):' | |||||
506 | for gr, perms in _explicit_grouped_perms: |
|
546 | for gr, perms in _explicit_grouped_perms: | |
507 | # since user can be in multiple groups iterate over them and |
|
547 | # since user can be in multiple groups iterate over them and | |
508 | # select the lowest permissions first (more explicit) |
|
548 | # select the lowest permissions first (more explicit) | |
509 |
# TODO |
|
549 | # TODO(marcink): do this^^ | |
510 |
|
550 | |||
511 | # group doesn't inherit default permissions so we actually set them |
|
551 | # group doesn't inherit default permissions so we actually set them | |
512 | if not gr.inherit_default_permissions: |
|
552 | if not gr.inherit_default_permissions: | |
@@ -533,8 +573,8 b' class PermissionCalculator(object):' | |||||
533 |
|
573 | |||
534 | def _calculate_default_permissions(self): |
|
574 | def _calculate_default_permissions(self): | |
535 | """ |
|
575 | """ | |
536 |
Set default user permissions for repositories, repository |
|
576 | Set default user permissions for repositories, repository branches, | |
537 | taken from the default user. |
|
577 | repository groups, user groups taken from the default user. | |
538 |
|
578 | |||
539 | Calculate inheritance of object permissions based on what we have now |
|
579 | Calculate inheritance of object permissions based on what we have now | |
540 | in GLOBAL permissions. We check if .false is in GLOBAL since this is |
|
580 | in GLOBAL permissions. We check if .false is in GLOBAL since this is | |
@@ -551,8 +591,7 b' class PermissionCalculator(object):' | |||||
551 | user_inherit_object_permissions = not ('hg.inherit_default_perms.false' |
|
591 | user_inherit_object_permissions = not ('hg.inherit_default_perms.false' | |
552 | in self.permissions_global) |
|
592 | in self.permissions_global) | |
553 |
|
593 | |||
554 | # defaults for repositories, taken from `default` user permissions |
|
594 | # default permissions for repositories, taken from `default` user permissions | |
555 | # on given repo |
|
|||
556 | for perm in self.default_repo_perms: |
|
595 | for perm in self.default_repo_perms: | |
557 | r_k = perm.UserRepoToPerm.repository.repo_name |
|
596 | r_k = perm.UserRepoToPerm.repository.repo_name | |
558 | p = perm.Permission.permission_name |
|
597 | p = perm.Permission.permission_name | |
@@ -585,8 +624,24 b' class PermissionCalculator(object):' | |||||
585 | o = PermOrigin.SUPER_ADMIN |
|
624 | o = PermOrigin.SUPER_ADMIN | |
586 | self.permissions_repositories[r_k] = p, o |
|
625 | self.permissions_repositories[r_k] = p, o | |
587 |
|
626 | |||
588 |
# defaults for repositor |
|
627 | # default permissions branch for repositories, taken from `default` user permissions | |
589 | # on given group |
|
628 | for perm in self.default_branch_repo_perms: | |
|
629 | ||||
|
630 | r_k = perm.UserRepoToPerm.repository.repo_name | |||
|
631 | p = perm.Permission.permission_name | |||
|
632 | pattern = perm.UserToRepoBranchPermission.branch_pattern | |||
|
633 | o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username | |||
|
634 | ||||
|
635 | if not self.explicit: | |||
|
636 | # TODO(marcink): fix this for multiple entries | |||
|
637 | cur_perm = self.permissions_repository_branches.get(r_k) or 'branch.none' | |||
|
638 | p = self._choose_permission(p, cur_perm) | |||
|
639 | ||||
|
640 | # NOTE(marcink): register all pattern/perm instances in this | |||
|
641 | # special dict that aggregates entries | |||
|
642 | self.permissions_repository_branches[r_k] = pattern, p, o | |||
|
643 | ||||
|
644 | # default permissions for repository groups taken from `default` user permission | |||
590 | for perm in self.default_repo_groups_perms: |
|
645 | for perm in self.default_repo_groups_perms: | |
591 | rg_k = perm.UserRepoGroupToPerm.group.group_name |
|
646 | rg_k = perm.UserRepoGroupToPerm.group.group_name | |
592 | p = perm.Permission.permission_name |
|
647 | p = perm.Permission.permission_name | |
@@ -611,8 +666,7 b' class PermissionCalculator(object):' | |||||
611 | o = PermOrigin.SUPER_ADMIN |
|
666 | o = PermOrigin.SUPER_ADMIN | |
612 | self.permissions_repository_groups[rg_k] = p, o |
|
667 | self.permissions_repository_groups[rg_k] = p, o | |
613 |
|
668 | |||
614 | # defaults for user groups taken from `default` user permission |
|
669 | # default permissions for user groups taken from `default` user permission | |
615 | # on given user group |
|
|||
616 | for perm in self.default_user_group_perms: |
|
670 | for perm in self.default_user_group_perms: | |
617 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name |
|
671 | u_k = perm.UserUserGroupToPerm.user_group.users_group_name | |
618 | p = perm.Permission.permission_name |
|
672 | p = perm.Permission.permission_name | |
@@ -703,6 +757,49 b' class PermissionCalculator(object):' | |||||
703 | o = PermOrigin.SUPER_ADMIN |
|
757 | o = PermOrigin.SUPER_ADMIN | |
704 | self.permissions_repositories[r_k] = p, o |
|
758 | self.permissions_repositories[r_k] = p, o | |
705 |
|
759 | |||
|
760 | def _calculate_repository_branch_permissions(self): | |||
|
761 | # user group for repositories permissions | |||
|
762 | user_repo_branch_perms_from_user_group = Permission\ | |||
|
763 | .get_default_repo_branch_perms_from_user_group( | |||
|
764 | self.user_id, self.scope_repo_id) | |||
|
765 | ||||
|
766 | multiple_counter = collections.defaultdict(int) | |||
|
767 | for perm in user_repo_branch_perms_from_user_group: | |||
|
768 | r_k = perm.UserGroupRepoToPerm.repository.repo_name | |||
|
769 | p = perm.Permission.permission_name | |||
|
770 | pattern = perm.UserGroupToRepoBranchPermission.branch_pattern | |||
|
771 | o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\ | |||
|
772 | .users_group.users_group_name | |||
|
773 | ||||
|
774 | multiple_counter[r_k] += 1 | |||
|
775 | if multiple_counter[r_k] > 1: | |||
|
776 | # TODO(marcink): fix this for multi branch support, and multiple entries | |||
|
777 | cur_perm = self.permissions_repository_branches[r_k] | |||
|
778 | p = self._choose_permission(p, cur_perm) | |||
|
779 | ||||
|
780 | self.permissions_repository_branches[r_k] = pattern, p, o | |||
|
781 | ||||
|
782 | # user explicit branch permissions for repositories, overrides | |||
|
783 | # any specified by the group permission | |||
|
784 | user_repo_branch_perms = Permission.get_default_repo_branch_perms( | |||
|
785 | self.user_id, self.scope_repo_id) | |||
|
786 | for perm in user_repo_branch_perms: | |||
|
787 | ||||
|
788 | r_k = perm.UserRepoToPerm.repository.repo_name | |||
|
789 | p = perm.Permission.permission_name | |||
|
790 | pattern = perm.UserToRepoBranchPermission.branch_pattern | |||
|
791 | o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username | |||
|
792 | ||||
|
793 | if not self.explicit: | |||
|
794 | # TODO(marcink): fix this for multiple entries | |||
|
795 | cur_perm = self.permissions_repository_branches.get(r_k) or 'branch.none' | |||
|
796 | p = self._choose_permission(p, cur_perm) | |||
|
797 | ||||
|
798 | # NOTE(marcink): register all pattern/perm instances in this | |||
|
799 | # special dict that aggregates entries | |||
|
800 | self.permissions_repository_branches[r_k] = pattern, p, o | |||
|
801 | ||||
|
802 | ||||
706 | def _calculate_repository_group_permissions(self): |
|
803 | def _calculate_repository_group_permissions(self): | |
707 | """ |
|
804 | """ | |
708 | Repository group permissions for the current user. |
|
805 | Repository group permissions for the current user. | |
@@ -845,6 +942,7 b' class PermissionCalculator(object):' | |||||
845 | return { |
|
942 | return { | |
846 | 'global': self.permissions_global, |
|
943 | 'global': self.permissions_global, | |
847 | 'repositories': self.permissions_repositories, |
|
944 | 'repositories': self.permissions_repositories, | |
|
945 | 'repository_branches': self.permissions_repository_branches, | |||
848 | 'repositories_groups': self.permissions_repository_groups, |
|
946 | 'repositories_groups': self.permissions_repository_groups, | |
849 | 'user_groups': self.permissions_user_groups, |
|
947 | 'user_groups': self.permissions_user_groups, | |
850 | } |
|
948 | } | |
@@ -956,6 +1054,9 b' class AuthUser(object):' | |||||
956 | perms['user_groups'] = { |
|
1054 | perms['user_groups'] = { | |
957 | k: v for k, v in perms['user_groups'].items() |
|
1055 | k: v for k, v in perms['user_groups'].items() | |
958 | if v != 'usergroup.none'} |
|
1056 | if v != 'usergroup.none'} | |
|
1057 | perms['repository_branches'] = { | |||
|
1058 | k: v for k, v in perms['repository_branches'].iteritems() | |||
|
1059 | if v != 'branch.none'} | |||
959 | return perms |
|
1060 | return perms | |
960 |
|
1061 | |||
961 | @LazyProperty |
|
1062 | @LazyProperty | |
@@ -1800,7 +1901,6 b' class PermsFunction(object):' | |||||
1800 | def __call__(self, check_location='', user=None): |
|
1901 | def __call__(self, check_location='', user=None): | |
1801 | if not user: |
|
1902 | if not user: | |
1802 | log.debug('Using user attribute from global request') |
|
1903 | log.debug('Using user attribute from global request') | |
1803 | # TODO: remove this someday,put as user as attribute here |
|
|||
1804 | request = self._get_request() |
|
1904 | request = self._get_request() | |
1805 | user = request.user |
|
1905 | user = request.user | |
1806 |
|
1906 |
@@ -751,6 +751,13 b' class AttributeDict(AttributeDictBase):' | |||||
751 |
|
751 | |||
752 |
|
752 | |||
753 |
|
753 | |||
|
754 | class OrderedDefaultDict(collections.OrderedDict, collections.defaultdict): | |||
|
755 | def __init__(self, default_factory=None, *args, **kwargs): | |||
|
756 | # in python3 you can omit the args to super | |||
|
757 | super(OrderedDefaultDict, self).__init__(*args, **kwargs) | |||
|
758 | self.default_factory = default_factory | |||
|
759 | ||||
|
760 | ||||
754 | def fix_PATH(os_=None): |
|
761 | def fix_PATH(os_=None): | |
755 | """ |
|
762 | """ | |
756 | Get current active python path, and append it to PATH variable to fix |
|
763 | Get current active python path, and append it to PATH variable to fix |
@@ -1913,6 +1913,7 b' class Repository(Base, BaseModel):' | |||||
1913 | for _usr in q.all(): |
|
1913 | for _usr in q.all(): | |
1914 | usr = AttributeDict(_usr.user.get_dict()) |
|
1914 | usr = AttributeDict(_usr.user.get_dict()) | |
1915 | usr.permission = _usr.permission.permission_name |
|
1915 | usr.permission = _usr.permission.permission_name | |
|
1916 | usr.permission_id = _usr.repo_to_perm_id | |||
1916 | perm_rows.append(usr) |
|
1917 | perm_rows.append(usr) | |
1917 |
|
1918 | |||
1918 | # filter the perm rows by 'default' first and then sort them by |
|
1919 | # filter the perm rows by 'default' first and then sort them by | |
@@ -1926,6 +1927,7 b' class Repository(Base, BaseModel):' | |||||
1926 | usr = AttributeDict(self.user.get_dict()) |
|
1927 | usr = AttributeDict(self.user.get_dict()) | |
1927 | usr.owner_row = True |
|
1928 | usr.owner_row = True | |
1928 | usr.permission = _admin_perm |
|
1929 | usr.permission = _admin_perm | |
|
1930 | usr.permission_id = None | |||
1929 | owner_row.append(usr) |
|
1931 | owner_row.append(usr) | |
1930 |
|
1932 | |||
1931 | super_admin_rows = [] |
|
1933 | super_admin_rows = [] | |
@@ -1938,6 +1940,7 b' class Repository(Base, BaseModel):' | |||||
1938 | usr = AttributeDict(usr.get_dict()) |
|
1940 | usr = AttributeDict(usr.get_dict()) | |
1939 | usr.admin_row = True |
|
1941 | usr.admin_row = True | |
1940 | usr.permission = _admin_perm |
|
1942 | usr.permission = _admin_perm | |
|
1943 | usr.permission_id = None | |||
1941 | super_admin_rows.append(usr) |
|
1944 | super_admin_rows.append(usr) | |
1942 |
|
1945 | |||
1943 | return super_admin_rows + owner_row + perm_rows |
|
1946 | return super_admin_rows + owner_row + perm_rows | |
@@ -2694,6 +2697,11 b' class Permission(Base, BaseModel):' | |||||
2694 | ('usergroup.write', _('User group write access')), |
|
2697 | ('usergroup.write', _('User group write access')), | |
2695 | ('usergroup.admin', _('User group admin access')), |
|
2698 | ('usergroup.admin', _('User group admin access')), | |
2696 |
|
2699 | |||
|
2700 | ('branch.none', _('Branch no permissions')), | |||
|
2701 | ('branch.merge', _('Branch access by web merge')), | |||
|
2702 | ('branch.push', _('Branch access by push')), | |||
|
2703 | ('branch.push_force', _('Branch access by push with force')), | |||
|
2704 | ||||
2697 | ('hg.repogroup.create.false', _('Repository Group creation disabled')), |
|
2705 | ('hg.repogroup.create.false', _('Repository Group creation disabled')), | |
2698 | ('hg.repogroup.create.true', _('Repository Group creation enabled')), |
|
2706 | ('hg.repogroup.create.true', _('Repository Group creation enabled')), | |
2699 |
|
2707 | |||
@@ -2723,11 +2731,16 b' class Permission(Base, BaseModel):' | |||||
2723 | ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), |
|
2731 | ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), | |
2724 | ] |
|
2732 | ] | |
2725 |
|
2733 | |||
2726 | # definition of system default permissions for DEFAULT user |
|
2734 | # definition of system default permissions for DEFAULT user, created on | |
|
2735 | # system setup | |||
2727 | DEFAULT_USER_PERMISSIONS = [ |
|
2736 | DEFAULT_USER_PERMISSIONS = [ | |
|
2737 | # object perms | |||
2728 | 'repository.read', |
|
2738 | 'repository.read', | |
2729 | 'group.read', |
|
2739 | 'group.read', | |
2730 | 'usergroup.read', |
|
2740 | 'usergroup.read', | |
|
2741 | # branch, for backward compat we need same value as before so forced pushed | |||
|
2742 | 'branch.push_force', | |||
|
2743 | # global | |||
2731 | 'hg.create.repository', |
|
2744 | 'hg.create.repository', | |
2732 | 'hg.repogroup.create.false', |
|
2745 | 'hg.repogroup.create.false', | |
2733 | 'hg.usergroup.create.false', |
|
2746 | 'hg.usergroup.create.false', | |
@@ -2758,6 +2771,11 b' class Permission(Base, BaseModel):' | |||||
2758 | 'usergroup.write': 3, |
|
2771 | 'usergroup.write': 3, | |
2759 | 'usergroup.admin': 4, |
|
2772 | 'usergroup.admin': 4, | |
2760 |
|
2773 | |||
|
2774 | 'branch.none': 0, | |||
|
2775 | 'branch.merge': 1, | |||
|
2776 | 'branch.push': 3, | |||
|
2777 | 'branch.push_force': 4, | |||
|
2778 | ||||
2761 | 'hg.repogroup.create.false': 0, |
|
2779 | 'hg.repogroup.create.false': 0, | |
2762 | 'hg.repogroup.create.true': 1, |
|
2780 | 'hg.repogroup.create.true': 1, | |
2763 |
|
2781 | |||
@@ -2794,6 +2812,21 b' class Permission(Base, BaseModel):' | |||||
2794 | return q.all() |
|
2812 | return q.all() | |
2795 |
|
2813 | |||
2796 | @classmethod |
|
2814 | @classmethod | |
|
2815 | def get_default_repo_branch_perms(cls, user_id, repo_id=None): | |||
|
2816 | q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ | |||
|
2817 | .join( | |||
|
2818 | Permission, | |||
|
2819 | UserToRepoBranchPermission.permission_id == Permission.permission_id) \ | |||
|
2820 | .join( | |||
|
2821 | UserRepoToPerm, | |||
|
2822 | UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ | |||
|
2823 | .filter(UserRepoToPerm.user_id == user_id) | |||
|
2824 | ||||
|
2825 | if repo_id: | |||
|
2826 | q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) | |||
|
2827 | return q.order_by(UserToRepoBranchPermission.rule_order).all() | |||
|
2828 | ||||
|
2829 | @classmethod | |||
2797 | def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): |
|
2830 | def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): | |
2798 | q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ |
|
2831 | q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ | |
2799 | .join( |
|
2832 | .join( | |
@@ -2818,10 +2851,37 b' class Permission(Base, BaseModel):' | |||||
2818 | return q.all() |
|
2851 | return q.all() | |
2819 |
|
2852 | |||
2820 | @classmethod |
|
2853 | @classmethod | |
|
2854 | def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): | |||
|
2855 | q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ | |||
|
2856 | .join( | |||
|
2857 | Permission, | |||
|
2858 | UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ | |||
|
2859 | .join( | |||
|
2860 | UserGroupRepoToPerm, | |||
|
2861 | UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ | |||
|
2862 | .join( | |||
|
2863 | UserGroup, | |||
|
2864 | UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ | |||
|
2865 | .join( | |||
|
2866 | UserGroupMember, | |||
|
2867 | UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ | |||
|
2868 | .filter( | |||
|
2869 | UserGroupMember.user_id == user_id, | |||
|
2870 | UserGroup.users_group_active == true()) | |||
|
2871 | ||||
|
2872 | if repo_id: | |||
|
2873 | q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) | |||
|
2874 | return q.order_by(UserGroupToRepoBranchPermission.rule_order).all() | |||
|
2875 | ||||
|
2876 | @classmethod | |||
2821 | def get_default_group_perms(cls, user_id, repo_group_id=None): |
|
2877 | def get_default_group_perms(cls, user_id, repo_group_id=None): | |
2822 | q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ |
|
2878 | q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ | |
2823 | .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ |
|
2879 | .join( | |
2824 | .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ |
|
2880 | Permission, | |
|
2881 | UserRepoGroupToPerm.permission_id == Permission.permission_id)\ | |||
|
2882 | .join( | |||
|
2883 | RepoGroup, | |||
|
2884 | UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ | |||
2825 | .filter(UserRepoGroupToPerm.user_id == user_id) |
|
2885 | .filter(UserRepoGroupToPerm.user_id == user_id) | |
2826 | if repo_group_id: |
|
2886 | if repo_group_id: | |
2827 | q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) |
|
2887 | q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) | |
@@ -2910,6 +2970,8 b' class UserRepoToPerm(Base, BaseModel):' | |||||
2910 | repository = relationship('Repository') |
|
2970 | repository = relationship('Repository') | |
2911 | permission = relationship('Permission') |
|
2971 | permission = relationship('Permission') | |
2912 |
|
2972 | |||
|
2973 | branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined') | |||
|
2974 | ||||
2913 | @classmethod |
|
2975 | @classmethod | |
2914 | def create(cls, user, repository, permission): |
|
2976 | def create(cls, user, repository, permission): | |
2915 | n = cls() |
|
2977 | n = cls() | |
@@ -4470,6 +4532,100 b' def set_task_uid(mapper, connection, tar' | |||||
4470 | target.task_uid = ScheduleEntry.get_uid(target) |
|
4532 | target.task_uid = ScheduleEntry.get_uid(target) | |
4471 |
|
4533 | |||
4472 |
|
4534 | |||
|
4535 | class _BaseBranchPerms(BaseModel): | |||
|
4536 | @classmethod | |||
|
4537 | def compute_hash(cls, value): | |||
|
4538 | return sha1_safe(value) | |||
|
4539 | ||||
|
4540 | @hybrid_property | |||
|
4541 | def branch_pattern(self): | |||
|
4542 | return self._branch_pattern or '*' | |||
|
4543 | ||||
|
4544 | @hybrid_property | |||
|
4545 | def branch_hash(self): | |||
|
4546 | return self._branch_hash | |||
|
4547 | ||||
|
4548 | def _validate_glob(self, value): | |||
|
4549 | re.compile('^' + glob2re(value) + '$') | |||
|
4550 | ||||
|
4551 | @branch_pattern.setter | |||
|
4552 | def branch_pattern(self, value): | |||
|
4553 | self._validate_glob(value) | |||
|
4554 | self._branch_pattern = value or '*' | |||
|
4555 | # set the Hash when setting the branch pattern | |||
|
4556 | self._branch_hash = self.compute_hash(self._branch_pattern) | |||
|
4557 | ||||
|
4558 | def matches(self, branch): | |||
|
4559 | """ | |||
|
4560 | Check if this the branch matches entry | |||
|
4561 | ||||
|
4562 | :param branch: branch name for the commit | |||
|
4563 | """ | |||
|
4564 | ||||
|
4565 | branch = branch or '' | |||
|
4566 | ||||
|
4567 | branch_matches = True | |||
|
4568 | if branch: | |||
|
4569 | branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') | |||
|
4570 | branch_matches = bool(branch_regex.search(branch)) | |||
|
4571 | ||||
|
4572 | return branch_matches | |||
|
4573 | ||||
|
4574 | ||||
|
4575 | class UserToRepoBranchPermission(Base, _BaseBranchPerms): | |||
|
4576 | __tablename__ = 'user_to_repo_branch_permissions' | |||
|
4577 | __table_args__ = ( | |||
|
4578 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |||
|
4579 | 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} | |||
|
4580 | ) | |||
|
4581 | ||||
|
4582 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) | |||
|
4583 | ||||
|
4584 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |||
|
4585 | repo = relationship('Repository', backref='user_branch_perms') | |||
|
4586 | ||||
|
4587 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |||
|
4588 | permission = relationship('Permission') | |||
|
4589 | ||||
|
4590 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) | |||
|
4591 | user_repo_to_perm = relationship('UserRepoToPerm') | |||
|
4592 | ||||
|
4593 | rule_order = Column('rule_order', Integer(), nullable=False) | |||
|
4594 | _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob | |||
|
4595 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) | |||
|
4596 | ||||
|
4597 | def __unicode__(self): | |||
|
4598 | return u'<UserBranchPermission(%s => %r)>' % ( | |||
|
4599 | self.user_repo_to_perm, self.branch_pattern) | |||
|
4600 | ||||
|
4601 | ||||
|
4602 | class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): | |||
|
4603 | __tablename__ = 'user_group_to_repo_branch_permissions' | |||
|
4604 | __table_args__ = ( | |||
|
4605 | {'extend_existing': True, 'mysql_engine': 'InnoDB', | |||
|
4606 | 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} | |||
|
4607 | ) | |||
|
4608 | ||||
|
4609 | branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) | |||
|
4610 | ||||
|
4611 | repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) | |||
|
4612 | repo = relationship('Repository', backref='user_group_branch_perms') | |||
|
4613 | ||||
|
4614 | permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) | |||
|
4615 | permission = relationship('Permission') | |||
|
4616 | ||||
|
4617 | rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) | |||
|
4618 | user_group_repo_to_perm = relationship('UserGroupRepoToPerm') | |||
|
4619 | ||||
|
4620 | rule_order = Column('rule_order', Integer(), nullable=False) | |||
|
4621 | _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob | |||
|
4622 | _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) | |||
|
4623 | ||||
|
4624 | def __unicode__(self): | |||
|
4625 | return u'<UserBranchPermission(%s => %r)>' % ( | |||
|
4626 | self.user_group_repo_to_perm, self.branch_pattern) | |||
|
4627 | ||||
|
4628 | ||||
4473 | class DbMigrateVersion(Base, BaseModel): |
|
4629 | class DbMigrateVersion(Base, BaseModel): | |
4474 | __tablename__ = 'db_migrate_version' |
|
4630 | __tablename__ = 'db_migrate_version' | |
4475 | __table_args__ = ( |
|
4631 | __table_args__ = ( |
@@ -504,12 +504,26 b' def ObjectPermissionsForm(localizer, rep' | |||||
504 | overwrite_default_repo = v.StringBoolean(if_missing=False) |
|
504 | overwrite_default_repo = v.StringBoolean(if_missing=False) | |
505 | overwrite_default_group = v.StringBoolean(if_missing=False) |
|
505 | overwrite_default_group = v.StringBoolean(if_missing=False) | |
506 | overwrite_default_user_group = v.StringBoolean(if_missing=False) |
|
506 | overwrite_default_user_group = v.StringBoolean(if_missing=False) | |
|
507 | ||||
507 | default_repo_perm = v.OneOf(repo_perms_choices) |
|
508 | default_repo_perm = v.OneOf(repo_perms_choices) | |
508 | default_group_perm = v.OneOf(group_perms_choices) |
|
509 | default_group_perm = v.OneOf(group_perms_choices) | |
509 | default_user_group_perm = v.OneOf(user_group_perms_choices) |
|
510 | default_user_group_perm = v.OneOf(user_group_perms_choices) | |
|
511 | ||||
510 | return _ObjectPermissionsForm |
|
512 | return _ObjectPermissionsForm | |
511 |
|
513 | |||
512 |
|
514 | |||
|
515 | def BranchPermissionsForm(localizer, branch_perms_choices): | |||
|
516 | _ = localizer | |||
|
517 | ||||
|
518 | class _BranchPermissionsForm(formencode.Schema): | |||
|
519 | allow_extra_fields = True | |||
|
520 | filter_extra_fields = True | |||
|
521 | overwrite_default_branch = v.StringBoolean(if_missing=False) | |||
|
522 | default_branch_perm = v.OneOf(branch_perms_choices) | |||
|
523 | ||||
|
524 | return _BranchPermissionsForm | |||
|
525 | ||||
|
526 | ||||
513 | def UserPermissionsForm(localizer, create_choices, create_on_write_choices, |
|
527 | def UserPermissionsForm(localizer, create_choices, create_on_write_choices, | |
514 | repo_group_create_choices, user_group_create_choices, |
|
528 | repo_group_create_choices, user_group_create_choices, | |
515 | fork_choices, inherit_default_permissions_choices): |
|
529 | fork_choices, inherit_default_permissions_choices): |
@@ -31,7 +31,7 b' from sqlalchemy.exc import DatabaseError' | |||||
31 | from rhodecode.model import BaseModel |
|
31 | from rhodecode.model import BaseModel | |
32 | from rhodecode.model.db import ( |
|
32 | from rhodecode.model.db import ( | |
33 | User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm, |
|
33 | User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm, | |
34 | UserUserGroupToPerm, UserGroup, UserGroupToPerm) |
|
34 | UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission) | |
35 | from rhodecode.lib.utils2 import str2bool, safe_int |
|
35 | from rhodecode.lib.utils2 import str2bool, safe_int | |
36 |
|
36 | |||
37 | log = logging.getLogger(__name__) |
|
37 | log = logging.getLogger(__name__) | |
@@ -59,6 +59,9 b' class PermissionModel(BaseModel):' | |||||
59 | 'default_repo_perm': None, |
|
59 | 'default_repo_perm': None, | |
60 | 'default_group_perm': None, |
|
60 | 'default_group_perm': None, | |
61 | 'default_user_group_perm': None, |
|
61 | 'default_user_group_perm': None, | |
|
62 | ||||
|
63 | # branch | |||
|
64 | 'default_branch_perm': None, | |||
62 | } |
|
65 | } | |
63 |
|
66 | |||
64 | def set_global_permission_choices(self, c_obj, gettext_translator): |
|
67 | def set_global_permission_choices(self, c_obj, gettext_translator): | |
@@ -82,6 +85,12 b' class PermissionModel(BaseModel):' | |||||
82 | ('usergroup.write', _('Write'),), |
|
85 | ('usergroup.write', _('Write'),), | |
83 | ('usergroup.admin', _('Admin'),)] |
|
86 | ('usergroup.admin', _('Admin'),)] | |
84 |
|
87 | |||
|
88 | c_obj.branch_perms_choices = [ | |||
|
89 | ('branch.none', _('Protected/No Access'),), | |||
|
90 | ('branch.merge', _('Web merge'),), | |||
|
91 | ('branch.push', _('Push'),), | |||
|
92 | ('branch.push_force', _('Force Push'),)] | |||
|
93 | ||||
85 | c_obj.register_choices = [ |
|
94 | c_obj.register_choices = [ | |
86 | ('hg.register.none', _('Disabled')), |
|
95 | ('hg.register.none', _('Disabled')), | |
87 | ('hg.register.manual_activate', _('Allowed with manual account activation')), |
|
96 | ('hg.register.manual_activate', _('Allowed with manual account activation')), | |
@@ -133,6 +142,10 b' class PermissionModel(BaseModel):' | |||||
133 | if perm.permission.permission_name.startswith('usergroup.'): |
|
142 | if perm.permission.permission_name.startswith('usergroup.'): | |
134 | defaults['default_user_group_perm' + suffix] = perm.permission.permission_name |
|
143 | defaults['default_user_group_perm' + suffix] = perm.permission.permission_name | |
135 |
|
144 | |||
|
145 | # branch | |||
|
146 | if perm.permission.permission_name.startswith('branch.'): | |||
|
147 | defaults['default_branch_perm' + suffix] = perm.permission.permission_name | |||
|
148 | ||||
136 | # creation of objects |
|
149 | # creation of objects | |
137 | if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'): |
|
150 | if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'): | |
138 | defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name |
|
151 | defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name | |
@@ -199,6 +212,9 b' class PermissionModel(BaseModel):' | |||||
199 | 'default_repo_perm': 'repository.', |
|
212 | 'default_repo_perm': 'repository.', | |
200 | 'default_group_perm': 'group.', |
|
213 | 'default_group_perm': 'group.', | |
201 | 'default_user_group_perm': 'usergroup.', |
|
214 | 'default_user_group_perm': 'usergroup.', | |
|
215 | # branch | |||
|
216 | 'default_branch_perm': 'branch.', | |||
|
217 | ||||
202 | }[field_name] |
|
218 | }[field_name] | |
203 | for field in keep_fields: |
|
219 | for field in keep_fields: | |
204 | pat = get_pat(field) |
|
220 | pat = get_pat(field) | |
@@ -236,8 +252,12 b' class PermissionModel(BaseModel):' | |||||
236 | _global_perms = self.global_perms.copy() |
|
252 | _global_perms = self.global_perms.copy() | |
237 | if obj_type not in ['user', 'user_group']: |
|
253 | if obj_type not in ['user', 'user_group']: | |
238 | raise ValueError("obj_type must be on of 'user' or 'user_group'") |
|
254 | raise ValueError("obj_type must be on of 'user' or 'user_group'") | |
239 | if len(_global_perms) != len(Permission.DEFAULT_USER_PERMISSIONS): |
|
255 | global_perms = len(_global_perms) | |
240 | raise Exception('Inconsistent permissions definition') |
|
256 | default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS) | |
|
257 | if global_perms != default_user_perms: | |||
|
258 | raise Exception( | |||
|
259 | 'Inconsistent permissions definition. Got {} vs {}'.format( | |||
|
260 | global_perms, default_user_perms)) | |||
241 |
|
261 | |||
242 | if obj_type == 'user': |
|
262 | if obj_type == 'user': | |
243 | self._clear_user_perms(object.user_id, preserve) |
|
263 | self._clear_user_perms(object.user_id, preserve) | |
@@ -337,8 +357,8 b' class PermissionModel(BaseModel):' | |||||
337 |
|
357 | |||
338 | def create_default_user_group_permissions(self, user_group, force=False): |
|
358 | def create_default_user_group_permissions(self, user_group, force=False): | |
339 | """ |
|
359 | """ | |
340 |
Creates only missing default permissions for user group, if force is |
|
360 | Creates only missing default permissions for user group, if force is | |
341 | resets the default permissions for that user group |
|
361 | set it resets the default permissions for that user group | |
342 |
|
362 | |||
343 | :param user_group: |
|
363 | :param user_group: | |
344 | :param force: |
|
364 | :param force: | |
@@ -366,6 +386,7 b' class PermissionModel(BaseModel):' | |||||
366 | 'default_repo_perm', |
|
386 | 'default_repo_perm', | |
367 | 'default_group_perm', |
|
387 | 'default_group_perm', | |
368 | 'default_user_group_perm', |
|
388 | 'default_user_group_perm', | |
|
389 | 'default_branch_perm', | |||
369 |
|
390 | |||
370 | 'default_repo_group_create', |
|
391 | 'default_repo_group_create', | |
371 | 'default_user_group_create', |
|
392 | 'default_user_group_create', | |
@@ -392,6 +413,7 b' class PermissionModel(BaseModel):' | |||||
392 | 'default_repo_perm', |
|
413 | 'default_repo_perm', | |
393 | 'default_group_perm', |
|
414 | 'default_group_perm', | |
394 | 'default_user_group_perm', |
|
415 | 'default_user_group_perm', | |
|
416 | 'default_branch_perm', | |||
395 |
|
417 | |||
396 | 'default_register', |
|
418 | 'default_register', | |
397 | 'default_password_reset', |
|
419 | 'default_password_reset', | |
@@ -414,6 +436,7 b' class PermissionModel(BaseModel):' | |||||
414 | 'default_repo_perm', |
|
436 | 'default_repo_perm', | |
415 | 'default_group_perm', |
|
437 | 'default_group_perm', | |
416 | 'default_user_group_perm', |
|
438 | 'default_user_group_perm', | |
|
439 | 'default_branch_perm', | |||
417 |
|
440 | |||
418 | 'default_register', |
|
441 | 'default_register', | |
419 | 'default_password_reset', |
|
442 | 'default_password_reset', | |
@@ -440,6 +463,7 b' class PermissionModel(BaseModel):' | |||||
440 | 'default_repo_create', |
|
463 | 'default_repo_create', | |
441 | 'default_fork_create', |
|
464 | 'default_fork_create', | |
442 | 'default_inherit_default_permissions', |
|
465 | 'default_inherit_default_permissions', | |
|
466 | 'default_branch_perm', | |||
443 |
|
467 | |||
444 | 'default_register', |
|
468 | 'default_register', | |
445 | 'default_password_reset', |
|
469 | 'default_password_reset', | |
@@ -477,8 +501,57 b' class PermissionModel(BaseModel):' | |||||
477 | .all(): |
|
501 | .all(): | |
478 | g2p.permission = _def |
|
502 | g2p.permission = _def | |
479 | self.sa.add(g2p) |
|
503 | self.sa.add(g2p) | |
|
504 | ||||
|
505 | # COMMIT | |||
480 | self.sa.commit() |
|
506 | self.sa.commit() | |
481 | except (DatabaseError,): |
|
507 | except (DatabaseError,): | |
482 | log.exception('Failed to set default object permissions') |
|
508 | log.exception('Failed to set default object permissions') | |
483 | self.sa.rollback() |
|
509 | self.sa.rollback() | |
484 | raise |
|
510 | raise | |
|
511 | ||||
|
512 | def update_branch_permissions(self, form_result): | |||
|
513 | if 'perm_user_id' in form_result: | |||
|
514 | perm_user = User.get(safe_int(form_result['perm_user_id'])) | |||
|
515 | else: | |||
|
516 | # used mostly to do lookup for default user | |||
|
517 | perm_user = User.get_by_username(form_result['perm_user_name']) | |||
|
518 | try: | |||
|
519 | ||||
|
520 | # stage 2 reset defaults and set them from form data | |||
|
521 | self._set_new_user_perms(perm_user, form_result, preserve=[ | |||
|
522 | 'default_repo_perm', | |||
|
523 | 'default_group_perm', | |||
|
524 | 'default_user_group_perm', | |||
|
525 | ||||
|
526 | 'default_repo_group_create', | |||
|
527 | 'default_user_group_create', | |||
|
528 | 'default_repo_create_on_write', | |||
|
529 | 'default_repo_create', | |||
|
530 | 'default_fork_create', | |||
|
531 | 'default_inherit_default_permissions', | |||
|
532 | ||||
|
533 | 'default_register', | |||
|
534 | 'default_password_reset', | |||
|
535 | 'default_extern_activate']) | |||
|
536 | ||||
|
537 | # overwrite default branch permissions | |||
|
538 | if form_result['overwrite_default_branch']: | |||
|
539 | _def_name = \ | |||
|
540 | form_result['default_branch_perm'].split('branch.')[-1] | |||
|
541 | ||||
|
542 | _def = Permission.get_by_key('branch.' + _def_name) | |||
|
543 | ||||
|
544 | # TODO(marcink): those are bind to repo, perms, we need to unfold user somehow from this | |||
|
545 | for g2p in self.sa.query(UserToRepoBranchPermission) \ | |||
|
546 | .filter(UserToRepoBranchPermission.user == perm_user) \ | |||
|
547 | .all(): | |||
|
548 | g2p.permission = _def | |||
|
549 | self.sa.add(g2p) | |||
|
550 | ||||
|
551 | # COMMIT | |||
|
552 | self.sa.commit() | |||
|
553 | except (DatabaseError,): | |||
|
554 | log.exception('Failed to set default branch permissions') | |||
|
555 | self.sa.rollback() | |||
|
556 | raise | |||
|
557 |
@@ -116,6 +116,11 b'' | |||||
116 | .label; |
|
116 | .label; | |
117 | padding-top: 5px; |
|
117 | padding-top: 5px; | |
118 | } |
|
118 | } | |
|
119 | .label-branch-perm { | |||
|
120 | .label; | |||
|
121 | width: 20px; | |||
|
122 | } | |||
|
123 | ||||
119 | // Used to position content on the right side of a .label |
|
124 | // Used to position content on the right side of a .label | |
120 | .content, |
|
125 | .content, | |
121 | .side-by-side-selector { |
|
126 | .side-by-side-selector { | |
@@ -135,6 +140,15 b'' | |||||
135 | } |
|
140 | } | |
136 | } |
|
141 | } | |
137 |
|
142 | |||
|
143 | .input-branch-perm { | |||
|
144 | .input; | |||
|
145 | margin-left: 90px; | |||
|
146 | } | |||
|
147 | ||||
|
148 | .input-branch-perm-order { | |||
|
149 | width: 40px; | |||
|
150 | } | |||
|
151 | ||||
138 | .checkboxes, |
|
152 | .checkboxes, | |
139 | .input, |
|
153 | .input, | |
140 | .select { |
|
154 | .select { | |
@@ -169,6 +183,9 b'' | |||||
169 | } |
|
183 | } | |
170 |
|
184 | |||
171 | .input { |
|
185 | .input { | |
|
186 | .branch-perm { | |||
|
187 | width: 80px; | |||
|
188 | } | |||
172 | .medium { |
|
189 | .medium { | |
173 | width: @fields-input-m; |
|
190 | width: @fields-input-m; | |
174 | } |
|
191 | } |
@@ -462,7 +462,7 b' ul.auth_plugins {' | |||||
462 |
|
462 | |||
463 | .radios { |
|
463 | .radios { | |
464 | position: relative; |
|
464 | position: relative; | |
465 |
width: |
|
465 | width: 505px; | |
466 | } |
|
466 | } | |
467 | } |
|
467 | } | |
468 |
|
468 |
@@ -159,3 +159,9 b'' | |||||
159 | &:extend(.icon-svn-transparent:before); |
|
159 | &:extend(.icon-svn-transparent:before); | |
160 | } |
|
160 | } | |
161 | } |
|
161 | } | |
|
162 | ||||
|
163 | .icon-user-group:before { | |||
|
164 | &:extend(.icon-group:before); | |||
|
165 | margin: 0; | |||
|
166 | font-size: 16px; | |||
|
167 | } |
@@ -109,13 +109,21 b'' | |||||
109 | &.read { |
|
109 | &.read { | |
110 | &:extend(.tag1); |
|
110 | &:extend(.tag1); | |
111 | } |
|
111 | } | |
112 |
|
||||
113 | &.write { |
|
112 | &.write { | |
114 | &:extend(.tag4); |
|
113 | &:extend(.tag4); | |
115 | } |
|
114 | } | |
116 | &.admin { |
|
115 | &.admin { | |
117 | &:extend(.tag5); |
|
116 | &:extend(.tag5); | |
118 | } |
|
117 | } | |
|
118 | &.merge { | |||
|
119 | &:extend(.tag1); | |||
|
120 | } | |||
|
121 | &.push { | |||
|
122 | &:extend(.tag4); | |||
|
123 | } | |||
|
124 | &.push_force { | |||
|
125 | &:extend(.tag5); | |||
|
126 | } | |||
119 | } |
|
127 | } | |
120 |
|
128 | |||
121 | .phase-draft { |
|
129 | .phase-draft { |
@@ -87,6 +87,7 b' function registerRCRoutes() {' | |||||
87 | pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []); |
|
87 | pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []); | |
88 | pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []); |
|
88 | pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []); | |
89 | pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []); |
|
89 | pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []); | |
|
90 | pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []); | |||
90 | pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); |
|
91 | pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []); | |
91 | pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []); |
|
92 | pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []); | |
92 | pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []); |
|
93 | pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []); | |
@@ -233,6 +234,8 b' function registerRCRoutes() {' | |||||
233 | pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']); |
|
234 | pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']); | |
234 | pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']); |
|
235 | pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']); | |
235 | pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']); |
|
236 | pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']); | |
|
237 | pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']); | |||
|
238 | pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']); | |||
236 | pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']); |
|
239 | pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']); | |
237 | pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']); |
|
240 | pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']); | |
238 | pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']); |
|
241 | pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']); |
@@ -38,7 +38,7 b' var api;' | |||||
38 | { data: {"_": "group_name", |
|
38 | { data: {"_": "group_name", | |
39 | "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," , |
|
39 | "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," , | |
40 | render: function (data,type,full,meta) |
|
40 | render: function (data,type,full,meta) | |
41 | {return '<div><i class="icon-group" title="User group">'+data+'</i></div>'}}, |
|
41 | {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}}, | |
42 |
|
42 | |||
43 | { data: {"_": "group_description", |
|
43 | { data: {"_": "group_description", | |
44 | "sort": "group_description"}, title: "${_('Description')}", className: "td-description" }, |
|
44 | "sort": "group_description"}, title: "${_('Description')}", className: "td-description" }, |
@@ -38,6 +38,9 b'' | |||||
38 | <li class="${'active' if c.active=='objects' else ''}"> |
|
38 | <li class="${'active' if c.active=='objects' else ''}"> | |
39 | <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a> |
|
39 | <a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a> | |
40 | </li> |
|
40 | </li> | |
|
41 | <li class="${'active' if c.active=='branch' else ''}"> | |||
|
42 | <a href="${h.route_path('admin_permissions_branch')}">${_('Branch')}</a> | |||
|
43 | </li> | |||
41 | <li class="${'active' if c.active=='ips' else ''}"> |
|
44 | <li class="${'active' if c.active=='ips' else ''}"> | |
42 | <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a> |
|
45 | <a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a> | |
43 | </li> |
|
46 | </li> |
@@ -3,7 +3,10 b'' | |||||
3 | <h3 class="panel-title">${_('Default Permissions for Repositories, User Groups and Repository Groups.')}</h3> |
|
3 | <h3 class="panel-title">${_('Default Permissions for Repositories, User Groups and Repository Groups.')}</h3> | |
4 | </div> |
|
4 | </div> | |
5 | <div class="panel-body"> |
|
5 | <div class="panel-body"> | |
6 | <p>${_('Default system permissions. Each permissions management entity will be created with the following default settings. Check the overwrite checkbox to force any permission changes on already existing settings.')} |
|
6 | <p> | |
|
7 | ${_('Default access permissions. This defines permissions for the `default` user from which other users inherit permissions.')} | |||
|
8 | <br/> | |||
|
9 | ${_('Check the overwrite checkbox to force change all previously defined permissions for `default` user to the new selected value.')} | |||
7 | </p> |
|
10 | </p> | |
8 | ${h.secure_form(h.route_path('admin_permissions_object_update'), request=request)} |
|
11 | ${h.secure_form(h.route_path('admin_permissions_object_update'), request=request)} | |
9 | <div class="form"> |
|
12 | <div class="form"> | |
@@ -45,7 +48,7 b'' | |||||
45 | ${h.select('default_user_group_perm','',c.user_group_perms_choices)} |
|
48 | ${h.select('default_user_group_perm','',c.user_group_perms_choices)} | |
46 | ${h.checkbox('overwrite_default_user_group','true')} |
|
49 | ${h.checkbox('overwrite_default_user_group','true')} | |
47 | <label for="overwrite_default_user_group"> |
|
50 | <label for="overwrite_default_user_group"> | |
48 |
<span class="tooltip" title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on |
|
51 | <span class="tooltip" title="${h.tooltip(_('All default permissions on each user group will be reset to chosen permission, note that all custom default permission on user groups will be lost'))}"> | |
49 | ${_('Overwrite Existing Settings')} |
|
52 | ${_('Overwrite Existing Settings')} | |
50 | </span> |
|
53 | </span> | |
51 | </label> |
|
54 | </label> |
@@ -57,7 +57,7 b'' | |||||
57 | %if _user.username != h.DEFAULT_USER: |
|
57 | %if _user.username != h.DEFAULT_USER: | |
58 | <span class="btn btn-link btn-danger revoke_perm" |
|
58 | <span class="btn btn-link btn-danger revoke_perm" | |
59 | member="${_user.user_id}" member_type="user"> |
|
59 | member="${_user.user_id}" member_type="user"> | |
60 |
|
|
60 | ${_('Revoke')} | |
61 | </span> |
|
61 | </span> | |
62 | %endif |
|
62 | %endif | |
63 | </td> |
|
63 | </td> | |
@@ -92,7 +92,7 b'' | |||||
92 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.write', checked=_user_group.permission=='group.write')}</td> |
|
92 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.write', checked=_user_group.permission=='group.write')}</td> | |
93 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin', checked=_user_group.permission=='group.admin')}</td> |
|
93 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin', checked=_user_group.permission=='group.admin')}</td> | |
94 | <td class="td-componentname"> |
|
94 | <td class="td-componentname"> | |
95 |
<i class="icon-group" |
|
95 | <i class="icon-user-group"></i> | |
96 | %if h.HasPermissionAny('hg.admin')(): |
|
96 | %if h.HasPermissionAny('hg.admin')(): | |
97 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> |
|
97 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> | |
98 | ${_user_group.users_group_name} |
|
98 | ${_user_group.users_group_name} | |
@@ -104,17 +104,27 b'' | |||||
104 | <td class="td-action"> |
|
104 | <td class="td-action"> | |
105 | <span class="btn btn-link btn-danger revoke_perm" |
|
105 | <span class="btn btn-link btn-danger revoke_perm" | |
106 | member="${_user_group.users_group_id}" member_type="user_group"> |
|
106 | member="${_user_group.users_group_id}" member_type="user_group"> | |
107 |
|
|
107 | ${_('Revoke')} | |
108 | </span> |
|
108 | </span> | |
109 | </td> |
|
109 | </td> | |
110 | </tr> |
|
110 | </tr> | |
111 | %endfor |
|
111 | %endfor | |
112 |
|
112 | |||
113 | <tr class="new_members" id="add_perm_input"></tr> |
|
113 | <tr class="new_members" id="add_perm_input"></tr> | |
|
114 | <tr> | |||
|
115 | <td></td> | |||
|
116 | <td></td> | |||
|
117 | <td></td> | |||
|
118 | <td></td> | |||
|
119 | <td></td> | |||
|
120 | <td> | |||
|
121 | <span id="add_perm" class="link"> | |||
|
122 | ${_('Add user/user group')} | |||
|
123 | </span> | |||
|
124 | </td> | |||
|
125 | </tr> | |||
114 | </table> |
|
126 | </table> | |
115 | <div id="add_perm" class="link"> |
|
127 | ||
116 | ${_('Add new')} |
|
|||
117 | </div> |
|
|||
118 | <div class="fields"> |
|
128 | <div class="fields"> | |
119 | <div class="field"> |
|
129 | <div class="field"> | |
120 | <div class="label label-radio"> |
|
130 | <div class="label label-radio"> |
@@ -48,6 +48,9 b'' | |||||
48 | <li class="${'active' if c.active=='permissions' else ''}"> |
|
48 | <li class="${'active' if c.active=='permissions' else ''}"> | |
49 | <a href="${h.route_path('edit_repo_perms', repo_name=c.repo_name)}">${_('Permissions')}</a> |
|
49 | <a href="${h.route_path('edit_repo_perms', repo_name=c.repo_name)}">${_('Permissions')}</a> | |
50 | </li> |
|
50 | </li> | |
|
51 | <li class="${'active' if c.active=='permissions_branch' else ''}"> | |||
|
52 | <a href="${h.route_path('edit_repo_perms_branch', repo_name=c.repo_name)}">${_('Branch Permissions')}</a> | |||
|
53 | </li> | |||
51 | <li class="${'active' if c.active=='advanced' else ''}"> |
|
54 | <li class="${'active' if c.active=='advanced' else ''}"> | |
52 | <a href="${h.route_path('edit_repo_advanced', repo_name=c.repo_name)}">${_('Advanced')}</a> |
|
55 | <a href="${h.route_path('edit_repo_advanced', repo_name=c.repo_name)}">${_('Advanced')}</a> | |
53 | </li> |
|
56 | </li> |
@@ -67,7 +67,7 b'' | |||||
67 | %if _user.username != h.DEFAULT_USER: |
|
67 | %if _user.username != h.DEFAULT_USER: | |
68 | <span class="btn btn-link btn-danger revoke_perm" |
|
68 | <span class="btn btn-link btn-danger revoke_perm" | |
69 | member="${_user.user_id}" member_type="user"> |
|
69 | member="${_user.user_id}" member_type="user"> | |
70 |
|
|
70 | ${_('Revoke')} | |
71 | </span> |
|
71 | </span> | |
72 | %endif |
|
72 | %endif | |
73 | </td> |
|
73 | </td> | |
@@ -83,7 +83,7 b'' | |||||
83 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.write', checked=_user_group.permission=='repository.write')}</td> |
|
83 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.write', checked=_user_group.permission=='repository.write')}</td> | |
84 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td> |
|
84 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td> | |
85 | <td class="td-componentname"> |
|
85 | <td class="td-componentname"> | |
86 |
<i class="icon-group" |
|
86 | <i class="icon-user-group"></i> | |
87 | %if h.HasPermissionAny('hg.admin')(): |
|
87 | %if h.HasPermissionAny('hg.admin')(): | |
88 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> |
|
88 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> | |
89 | ${_user_group.users_group_name} |
|
89 | ${_user_group.users_group_name} | |
@@ -95,16 +95,28 b'' | |||||
95 | <td class="td-action"> |
|
95 | <td class="td-action"> | |
96 | <span class="btn btn-link btn-danger revoke_perm" |
|
96 | <span class="btn btn-link btn-danger revoke_perm" | |
97 | member="${_user_group.users_group_id}" member_type="user_group"> |
|
97 | member="${_user_group.users_group_id}" member_type="user_group"> | |
98 |
|
|
98 | ${_('Revoke')} | |
99 | </span> |
|
99 | </span> | |
100 | </td> |
|
100 | </td> | |
101 | </tr> |
|
101 | </tr> | |
102 | %endfor |
|
102 | %endfor | |
103 | <tr class="new_members" id="add_perm_input"></tr> |
|
103 | <tr class="new_members" id="add_perm_input"></tr> | |
|
104 | ||||
|
105 | <tr> | |||
|
106 | <td></td> | |||
|
107 | <td></td> | |||
|
108 | <td></td> | |||
|
109 | <td></td> | |||
|
110 | <td></td> | |||
|
111 | <td> | |||
|
112 | <span id="add_perm" class="link"> | |||
|
113 | ${_('Add user/user group')} | |||
|
114 | </span> | |||
|
115 | </td> | |||
|
116 | </tr> | |||
|
117 | ||||
104 | </table> |
|
118 | </table> | |
105 | <div id="add_perm" class="link"> |
|
119 | ||
106 | ${_('Add new')} |
|
|||
107 | </div> |
|
|||
108 | <div class="buttons"> |
|
120 | <div class="buttons"> | |
109 | ${h.submit('save',_('Save'),class_="btn btn-primary")} |
|
121 | ${h.submit('save',_('Save'),class_="btn btn-primary")} | |
110 | ${h.reset('reset',_('Reset'),class_="btn btn-danger")} |
|
122 | ${h.reset('reset',_('Reset'),class_="btn btn-danger")} |
@@ -59,7 +59,7 b'' | |||||
59 | %if _user.username != h.DEFAULT_USER: |
|
59 | %if _user.username != h.DEFAULT_USER: | |
60 | <span class="btn btn-link btn-danger revoke_perm" |
|
60 | <span class="btn btn-link btn-danger revoke_perm" | |
61 | member="${_user.user_id}" member_type="user"> |
|
61 | member="${_user.user_id}" member_type="user"> | |
62 |
|
|
62 | ${_('Revoke')} | |
63 | </span> |
|
63 | </span> | |
64 | %endif |
|
64 | %endif | |
65 | </td> |
|
65 | </td> | |
@@ -94,7 +94,7 b'' | |||||
94 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td> |
|
94 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td> | |
95 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td> |
|
95 | <td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td> | |
96 | <td class="td-user"> |
|
96 | <td class="td-user"> | |
97 |
<i class="icon-group" |
|
97 | <i class="icon-user-group"></i> | |
98 | %if h.HasPermissionAny('hg.admin')(): |
|
98 | %if h.HasPermissionAny('hg.admin')(): | |
99 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> |
|
99 | <a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}"> | |
100 | ${_user_group.users_group_name} |
|
100 | ${_user_group.users_group_name} | |
@@ -106,16 +106,26 b'' | |||||
106 | <td class="td-action"> |
|
106 | <td class="td-action"> | |
107 | <span class="btn btn-link btn-danger revoke_perm" |
|
107 | <span class="btn btn-link btn-danger revoke_perm" | |
108 | member="${_user_group.users_group_id}" member_type="user_group"> |
|
108 | member="${_user_group.users_group_id}" member_type="user_group"> | |
109 |
|
|
109 | ${_('Revoke')} | |
110 | </span> |
|
110 | </span> | |
111 | </td> |
|
111 | </td> | |
112 | </tr> |
|
112 | </tr> | |
113 | %endfor |
|
113 | %endfor | |
114 | <tr class="new_members" id="add_perm_input"></tr> |
|
114 | <tr class="new_members" id="add_perm_input"></tr> | |
|
115 | <tr> | |||
|
116 | <td></td> | |||
|
117 | <td></td> | |||
|
118 | <td></td> | |||
|
119 | <td></td> | |||
|
120 | <td></td> | |||
|
121 | <td> | |||
|
122 | <span id="add_perm" class="link"> | |||
|
123 | ${_('Add user/user group')} | |||
|
124 | </span> | |||
|
125 | </td> | |||
|
126 | </tr> | |||
115 | </table> |
|
127 | </table> | |
116 | <div id="add_perm" class="link"> |
|
128 | ||
117 | ${_('Add new')} |
|
|||
118 | </div> |
|
|||
119 | <div class="buttons"> |
|
129 | <div class="buttons"> | |
120 | ${h.submit('save',_('Save'),class_="btn btn-primary")} |
|
130 | ${h.submit('save',_('Save'),class_="btn btn-primary")} | |
121 | ${h.reset('reset',_('Reset'),class_="btn btn-danger")} |
|
131 | ${h.reset('reset',_('Reset'),class_="btn btn-danger")} |
@@ -53,7 +53,7 b' var api;' | |||||
53 | { data: {"_": "group_name", |
|
53 | { data: {"_": "group_name", | |
54 | "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," , |
|
54 | "sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," , | |
55 | render: function (data,type,full,meta) |
|
55 | render: function (data,type,full,meta) | |
56 | {return '<div><i class="icon-group" title="User group">'+data+'</i></div>'}}, |
|
56 | {return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}}, | |
57 |
|
57 | |||
58 | { data: {"_": "group_description", |
|
58 | { data: {"_": "group_description", | |
59 | "sort": "group_description"}, title: "${_('Description')}", className: "td-description" }, |
|
59 | "sort": "group_description"}, title: "${_('Description')}", className: "td-description" }, |
@@ -4,11 +4,20 b'' | |||||
4 | ## ${p.perms_summary(c.perm_user.permissions)} |
|
4 | ## ${p.perms_summary(c.perm_user.permissions)} | |
5 |
|
5 | |||
6 | <%def name="perms_summary(permissions, show_all=False, actions=True, side_link=None)"> |
|
6 | <%def name="perms_summary(permissions, show_all=False, actions=True, side_link=None)"> | |
|
7 | <% section_to_label = { | |||
|
8 | 'global': 'Global Permissions', | |||
|
9 | 'repository_branches': 'Repository Branch Rules', | |||
|
10 | 'repositories': 'Repository Permissions', | |||
|
11 | 'user_groups': 'User Group Permissions', | |||
|
12 | 'repositories_groups': 'Repository Group Permissions', | |||
|
13 | } %> | |||
7 | <div id="perms" class="table fields"> |
|
14 | <div id="perms" class="table fields"> | |
8 | %for section in sorted(permissions.keys()): |
|
15 | %for section in sorted(permissions.keys(), key=lambda item: {'global': 0, 'repository_branches': 1}.get(item, 1000)): | |
9 | <div class="panel panel-default"> |
|
16 | <div class="panel panel-default"> | |
10 | <div class="panel-heading"> |
|
17 | <div class="panel-heading" id="${section.replace("_","-")}-permissions"> | |
11 | <h3 class="panel-title">${section.replace("_"," ").capitalize()}</h3> |
|
18 | <h3 class="panel-title">${section_to_label.get(section, section)} - ${len(permissions[section])} | |
|
19 | <a class="permalink" href="#${section.replace("_","-")}-permissions"> ΒΆ</a> | |||
|
20 | </h3> | |||
12 | % if side_link: |
|
21 | % if side_link: | |
13 | <div class="pull-right"> |
|
22 | <div class="pull-right"> | |
14 | <a href="${side_link}">${_('in JSON format')}</a> |
|
23 | <a href="${side_link}">${_('in JSON format')}</a> | |
@@ -18,15 +27,24 b'' | |||||
18 | <div class="panel-body"> |
|
27 | <div class="panel-body"> | |
19 | <div class="perms_section_head field"> |
|
28 | <div class="perms_section_head field"> | |
20 | <div class="radios"> |
|
29 | <div class="radios"> | |
21 |
%if section |
|
30 | % if section == 'repository_branches': | |
22 | <span class="permissions_boxes"> |
|
31 | <span class="permissions_boxes"> | |
23 | <span class="desc">${_('show')}: </span> |
|
32 | <span class="desc">${_('show')}: </span> | |
24 |
${h.checkbox('perms_filter_none_%s' % section, 'none', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='none')} <label for="${'perms_filter_none_ |
|
33 | ${h.checkbox('perms_filter_none_%s' % section, 'none', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='none')} <label for="${'perms_filter_none_{}'.format(section)}"><span class="perm_tag none">${_('none')}</span></label> | |
25 |
${h.checkbox('perms_filter_re |
|
34 | ${h.checkbox('perms_filter_merge_%s' % section, 'merge', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='merge')} <label for="${'perms_filter_merge_{}'.format(section)}"><span class="perm_tag merge">${_('merge')}</span></label> | |
26 |
${h.checkbox('perms_filter_ |
|
35 | ${h.checkbox('perms_filter_push_%s' % section, 'push', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='push')} <label for="${'perms_filter_push_{}'.format(section)}"> <span class="perm_tag push">${_('push')}</span></label> | |
27 | ${h.checkbox('perms_filter_admin_%s' % section, 'admin', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='admin')} <label for="${'perms_filter_admin_%s' % section}"><span class="perm_tag admin">${_('admin')}</span></label> |
|
36 | ${h.checkbox('perms_filter_push_force_%s' % section, 'push_force', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='push_force')} <label for="${'perms_filter_push_force_{}'.format(section)}"><span class="perm_tag push_force">${_('push force')}</span></label> | |
28 | </span> |
|
37 | </span> | |
29 | %endif |
|
38 | % elif section != 'global': | |
|
39 | <span class="permissions_boxes"> | |||
|
40 | <span class="desc">${_('show')}: </span> | |||
|
41 | ${h.checkbox('perms_filter_none_%s' % section, 'none', '', class_='perm_filter filter_%s' % section, section=section, perm_type='none')} <label for="${'perms_filter_none_{}'.format(section)}"><span class="perm_tag none">${_('none')}</span></label> | |||
|
42 | ${h.checkbox('perms_filter_read_%s' % section, 'read', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='read')} <label for="${'perms_filter_read_{}'.format(section)}"><span class="perm_tag read">${_('read')}</span></label> | |||
|
43 | ${h.checkbox('perms_filter_write_%s' % section, 'write', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='write')} <label for="${'perms_filter_write_{}'.format(section)}"> <span class="perm_tag write">${_('write')}</span></label> | |||
|
44 | ${h.checkbox('perms_filter_admin_%s' % section, 'admin', 'checked', class_='perm_filter filter_%s' % section, section=section, perm_type='admin')} <label for="${'perms_filter_admin_{}'.format(section)}"><span class="perm_tag admin">${_('admin')}</span></label> | |||
|
45 | </span> | |||
|
46 | % endif | |||
|
47 | ||||
30 | </div> |
|
48 | </div> | |
31 | </div> |
|
49 | </div> | |
32 | <div class="field"> |
|
50 | <div class="field"> | |
@@ -72,12 +90,10 b'' | |||||
72 | %endif |
|
90 | %endif | |
73 | %else: |
|
91 | %else: | |
74 | %if not val_lbl: |
|
92 | %if not val_lbl: | |
75 | ${ |
|
93 | ${{'false': False, | |
76 | {'false': False, |
|
|||
77 | 'true': True, |
|
94 | 'true': True, | |
78 | 'none': False, |
|
95 | 'none': False, | |
79 | 'repository': True}.get(val[1][0] if 0 < len(val[1]) else 'false') |
|
96 | 'repository': True}.get(val[1][0] if 0 < len(val[1]) else 'false')} | |
80 | } |
|
|||
81 | %else: |
|
97 | %else: | |
82 | <span class="perm_tag ${val[1][0]}">${val_lbl}.${val[1][0]}</span> |
|
98 | <span class="perm_tag ${val[1][0]}">${val_lbl}.${val[1][0]}</span> | |
83 | %endif |
|
99 | %endif | |
@@ -142,7 +158,72 b'' | |||||
142 | edit_url=h.route_path('user_edit_global_perms', user_id=c.user.user_id), edit_global_url=h.route_path('admin_permissions_object'))} |
|
158 | edit_url=h.route_path('user_edit_global_perms', user_id=c.user.user_id), edit_global_url=h.route_path('admin_permissions_object'))} | |
143 |
|
159 | |||
144 | </tbody> |
|
160 | </tbody> | |
|
161 | ## Branch perms | |||
|
162 | %elif section == 'repository_branches': | |||
|
163 | <thead> | |||
|
164 | <tr> | |||
|
165 | <th>${_('Name')}</th> | |||
|
166 | <th>${_('Pattern')}</th> | |||
|
167 | <th>${_('Permission')}</th> | |||
|
168 | %if actions: | |||
|
169 | <th>${_('Edit Branch Permission')}</th> | |||
|
170 | %endif | |||
|
171 | </thead> | |||
|
172 | <tbody class="section_${section}"> | |||
|
173 | <% | |||
|
174 | def name_sorter(permissions): | |||
|
175 | def custom_sorter(item): | |||
|
176 | return item[0] | |||
|
177 | return sorted(permissions, key=custom_sorter) | |||
|
178 | ||||
|
179 | def branch_sorter(permissions): | |||
|
180 | def custom_sorter(item): | |||
|
181 | ## none, merge, push, push_force | |||
|
182 | section = item[1].split('.')[-1] | |||
|
183 | section_importance = {'none': u'0', | |||
|
184 | 'merge': u'1', | |||
|
185 | 'push': u'2', | |||
|
186 | 'push_force': u'3'}.get(section) | |||
|
187 | ## sort by importance + name | |||
|
188 | return section_importance + item[0] | |||
|
189 | return sorted(permissions, key=custom_sorter) | |||
|
190 | %> | |||
|
191 | %for k, section_perms in name_sorter(permissions[section].items()): | |||
|
192 | % for pattern, perm in branch_sorter(section_perms.items()): | |||
|
193 | <tr class="perm_row ${'{}_{}'.format(section, perm.split('.')[-1])}"> | |||
|
194 | <td class="td-name"> | |||
|
195 | <a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a> | |||
|
196 | </td> | |||
|
197 | <td>${pattern}</td> | |||
|
198 | <td class="td-tags"> | |||
|
199 | ## TODO: calculate origin somehow | |||
|
200 | ## % for i, ((_pat, perm), origin) in enumerate((permissions[section].perm_origin_stack[k])): | |||
|
201 | ||||
|
202 | <div> | |||
|
203 | <% i = 0 %> | |||
|
204 | <% origin = 'unknown' %> | |||
|
205 | <% _css_class = i > 0 and 'perm_overriden' or '' %> | |||
|
206 | ||||
|
207 | <span class="${_css_class} perm_tag ${perm.split('.')[-1]}"> | |||
|
208 | ${perm} | |||
|
209 | ##(${origin}) | |||
|
210 | </span> | |||
|
211 | </div> | |||
|
212 | ## % endfor | |||
|
213 | </td> | |||
|
214 | %if actions: | |||
|
215 | <td class="td-action"> | |||
|
216 | <a href="${h.route_path('edit_repo_perms_branch',repo_name=k)}">${_('edit')}</a> | |||
|
217 | </td> | |||
|
218 | %endif | |||
|
219 | </tr> | |||
|
220 | % endfor | |||
|
221 | %endfor | |||
|
222 | </tbody> | |||
|
223 | ||||
|
224 | ## Repos/Repo Groups/users groups perms | |||
145 | %else: |
|
225 | %else: | |
|
226 | ||||
146 |
|
|
227 | ## none/read/write/admin permissions on groups/repos etc | |
147 | <thead> |
|
228 | <thead> | |
148 | <tr> |
|
229 | <tr> | |
@@ -167,8 +248,11 b'' | |||||
167 | return sorted(permissions, key=custom_sorter) |
|
248 | return sorted(permissions, key=custom_sorter) | |
168 | %> |
|
249 | %> | |
169 | %for k, section_perm in sorter(permissions[section].items()): |
|
250 | %for k, section_perm in sorter(permissions[section].items()): | |
170 |
|
|
251 | <% perm_value = section_perm.split('.')[-1] %> | |
171 | <tr class="perm_row ${'%s_%s' % (section, section_perm.split('.')[-1])}"> |
|
252 | <% _css_class = 'display:none' if perm_value in ['none'] else '' %> | |
|
253 | ||||
|
254 | %if perm_value != 'none' or show_all: | |||
|
255 | <tr class="perm_row ${'{}_{}'.format(section, section_perm.split('.')[-1])}" style="${_css_class}"> | |||
172 | <td class="td-name"> |
|
256 | <td class="td-name"> | |
173 | %if section == 'repositories': |
|
257 | %if section == 'repositories': | |
174 | <a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a> |
|
258 | <a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a> | |
@@ -183,7 +267,7 b'' | |||||
183 | %if hasattr(permissions[section], 'perm_origin_stack'): |
|
267 | %if hasattr(permissions[section], 'perm_origin_stack'): | |
184 | <div> |
|
268 | <div> | |
185 | %for i, (perm, origin) in enumerate(reversed(permissions[section].perm_origin_stack[k])): |
|
269 | %for i, (perm, origin) in enumerate(reversed(permissions[section].perm_origin_stack[k])): | |
186 |
|
270 | <% _css_class = i > 0 and 'perm_overriden' or '' %> | ||
187 | % if i > 0: |
|
271 | % if i > 0: | |
188 | <div style="color: #979797"> |
|
272 | <div style="color: #979797"> | |
189 | <i class="icon-arrow_up"></i> |
|
273 | <i class="icon-arrow_up"></i> | |
@@ -193,7 +277,7 b'' | |||||
193 | % endif |
|
277 | % endif | |
194 |
|
278 | |||
195 | <div> |
|
279 | <div> | |
196 |
<span class="${ |
|
280 | <span class="${_css_class} perm_tag ${perm.split('.')[-1]}"> | |
197 | ${perm} (${origin}) |
|
281 | ${perm} (${origin}) | |
198 | </span> |
|
282 | </span> | |
199 | </div> |
|
283 | </div> | |
@@ -220,7 +304,7 b'' | |||||
220 | %endfor |
|
304 | %endfor | |
221 |
|
305 | |||
222 | <tr id="empty_${section}" class="noborder" style="display:none;"> |
|
306 | <tr id="empty_${section}" class="noborder" style="display:none;"> | |
223 | <td colspan="6">${_('No permission defined')}</td> |
|
307 | <td colspan="6">${_('No matching permission defined')}</td> | |
224 | </tr> |
|
308 | </tr> | |
225 |
|
309 | |||
226 | </tbody> |
|
310 | </tbody> | |
@@ -236,15 +320,16 b'' | |||||
236 |
|
320 | |||
237 | <script> |
|
321 | <script> | |
238 | $(document).ready(function(){ |
|
322 | $(document).ready(function(){ | |
239 |
var show |
|
323 | var showEmpty = function(section){ | |
240 | var visible = $('.section_{0} tr.perm_row:visible'.format(section)).length; |
|
324 | var visible = $('.section_{0} tr.perm_row:visible'.format(section)).length; | |
241 | if(visible == 0){ |
|
325 | if(visible === 0){ | |
242 | $('#empty_{0}'.format(section)).show(); |
|
326 | $('#empty_{0}'.format(section)).show(); | |
243 | } |
|
327 | } | |
244 | else{ |
|
328 | else{ | |
245 | $('#empty_{0}'.format(section)).hide(); |
|
329 | $('#empty_{0}'.format(section)).hide(); | |
246 | } |
|
330 | } | |
247 | }; |
|
331 | }; | |
|
332 | ||||
248 | $('.perm_filter').on('change', function(e){ |
|
333 | $('.perm_filter').on('change', function(e){ | |
249 | var self = this; |
|
334 | var self = this; | |
250 | var section = $(this).attr('section'); |
|
335 | var section = $(this).attr('section'); | |
@@ -261,7 +346,7 b'' | |||||
261 | $('.'+section+'_'+perm_type).hide(); |
|
346 | $('.'+section+'_'+perm_type).hide(); | |
262 | } |
|
347 | } | |
263 | }); |
|
348 | }); | |
264 |
show |
|
349 | showEmpty(section); | |
265 | }) |
|
350 | }) | |
266 | }) |
|
351 | }) | |
267 | </script> |
|
352 | </script> |
@@ -284,7 +284,7 b'' | |||||
284 |
|
284 | |||
285 | <%def name="user_group_name(user_group_name)"> |
|
285 | <%def name="user_group_name(user_group_name)"> | |
286 | <div> |
|
286 | <div> | |
287 | <i class="icon-group" title="${_('User group')}"></i> |
|
287 | <i class="icon-user-group" title="${_('User group')}"></i> | |
288 | ${h.link_to_group(user_group_name)} |
|
288 | ${h.link_to_group(user_group_name)} | |
289 | </div> |
|
289 | </div> | |
290 | </%def> |
|
290 | </%def> |
@@ -534,7 +534,7 b'' | |||||
534 | </tbody> |
|
534 | </tbody> | |
535 | </table> |
|
535 | </table> | |
536 | <div class="link" id="add_perm"> |
|
536 | <div class="link" id="add_perm"> | |
537 |
Add |
|
537 | Add user/user group | |
538 | </div> |
|
538 | </div> | |
539 |
|
539 | |||
540 |
|
540 |
@@ -8,12 +8,11 b'' | |||||
8 | <div class="panel-heading">${title}</div> |
|
8 | <div class="panel-heading">${title}</div> | |
9 | <div class="panel-body"> |
|
9 | <div class="panel-body"> | |
10 |
|
10 | |||
11 | <div tal:condition="errormsg" |
|
11 | <div tal:condition="errormsg" class="clearfix alert alert-error"> | |
12 | class="clearfix alert alert-danger"> |
|
12 | <span i18n:translate=""> | |
13 | <p i18n:translate=""> |
|
|||
14 | There was a problem with this section |
|
13 | There was a problem with this section | |
15 | </p> |
|
14 | </span> | |
16 |
< |
|
15 | <div>${errormsg}</div> | |
17 | </div> |
|
16 | </div> | |
18 |
|
17 | |||
19 | <div tal:condition="description"> |
|
18 | <div tal:condition="description"> |
@@ -140,6 +140,10 b' class TestPermissions(object):' | |||||
140 | assert repo_perms(user)[repo.repo_name] == 'repository.admin' |
|
140 | assert repo_perms(user)[repo.repo_name] == 'repository.admin' | |
141 | repo.user = org_owner |
|
141 | repo.user = org_owner | |
142 |
|
142 | |||
|
143 | def test_default_owner_branch_perms(self, user_util, test_user_group): | |||
|
144 | user = user_util.create_user() | |||
|
145 | assert branch_perms(user) == {} | |||
|
146 | ||||
143 | def test_default_owner_repo_group_perms(self, user_util, test_repo_group): |
|
147 | def test_default_owner_repo_group_perms(self, user_util, test_repo_group): | |
144 | user = user_util.create_user() |
|
148 | user = user_util.create_user() | |
145 | org_owner = test_repo_group.user |
|
149 | org_owner = test_repo_group.user | |
@@ -360,13 +364,15 b' class TestPermissions(object):' | |||||
360 | user_model.revoke_perm(self.u1, 'hg.fork.repository') |
|
364 | user_model.revoke_perm(self.u1, 'hg.fork.repository') | |
361 | user_model.grant_perm(self.u1, 'hg.fork.none') |
|
365 | user_model.grant_perm(self.u1, 'hg.fork.none') | |
362 |
|
366 | |||
|
367 | # TODO(marcink): check branch permissions now ? | |||
|
368 | ||||
363 | # make sure inherit flag is turned off |
|
369 | # make sure inherit flag is turned off | |
364 | self.u1.inherit_default_permissions = False |
|
370 | self.u1.inherit_default_permissions = False | |
365 | Session().commit() |
|
371 | Session().commit() | |
366 |
|
372 | |||
367 | # this user will have non inherited permissions from he's |
|
373 | # this user will have non inherited permissions from he's | |
368 | # explicitly set permissions |
|
374 | # explicitly set permissions | |
369 |
assert global_perms(self.u1) == |
|
375 | assert global_perms(self.u1) == { | |
370 | 'hg.create.none', |
|
376 | 'hg.create.none', | |
371 | 'hg.fork.none', |
|
377 | 'hg.fork.none', | |
372 | 'hg.register.manual_activate', |
|
378 | 'hg.register.manual_activate', | |
@@ -375,7 +381,8 b' class TestPermissions(object):' | |||||
375 | 'repository.read', |
|
381 | 'repository.read', | |
376 | 'group.read', |
|
382 | 'group.read', | |
377 | 'usergroup.read', |
|
383 | 'usergroup.read', | |
378 | ]) |
|
384 | 'branch.push_force', | |
|
385 | } | |||
379 |
|
386 | |||
380 | def test_non_inherited_permissions_from_default_on_user_disabled(self): |
|
387 | def test_non_inherited_permissions_from_default_on_user_disabled(self): | |
381 | user_model = UserModel() |
|
388 | user_model = UserModel() | |
@@ -396,9 +403,11 b' class TestPermissions(object):' | |||||
396 | self.u1.inherit_default_permissions = False |
|
403 | self.u1.inherit_default_permissions = False | |
397 | Session().commit() |
|
404 | Session().commit() | |
398 |
|
405 | |||
|
406 | # TODO(marcink): check branch perms | |||
|
407 | ||||
399 | # this user will have non inherited permissions from he's |
|
408 | # this user will have non inherited permissions from he's | |
400 | # explicitly set permissions |
|
409 | # explicitly set permissions | |
401 |
assert global_perms(self.u1) == |
|
410 | assert global_perms(self.u1) == { | |
402 | 'hg.create.repository', |
|
411 | 'hg.create.repository', | |
403 | 'hg.fork.repository', |
|
412 | 'hg.fork.repository', | |
404 | 'hg.register.manual_activate', |
|
413 | 'hg.register.manual_activate', | |
@@ -407,7 +416,8 b' class TestPermissions(object):' | |||||
407 | 'repository.read', |
|
416 | 'repository.read', | |
408 | 'group.read', |
|
417 | 'group.read', | |
409 | 'usergroup.read', |
|
418 | 'usergroup.read', | |
410 | ]) |
|
419 | 'branch.push_force', | |
|
420 | } | |||
411 |
|
421 | |||
412 | @pytest.mark.parametrize('perm, expected_perm', [ |
|
422 | @pytest.mark.parametrize('perm, expected_perm', [ | |
413 | ('hg.inherit_default_perms.false', 'repository.none', ), |
|
423 | ('hg.inherit_default_perms.false', 'repository.none', ), | |
@@ -425,8 +435,10 b' class TestPermissions(object):' | |||||
425 | self.u1.inherit_default_permissions = True |
|
435 | self.u1.inherit_default_permissions = True | |
426 | Session().commit() |
|
436 | Session().commit() | |
427 |
|
437 | |||
|
438 | # TODO(marcink): check branch perms | |||
|
439 | ||||
428 | # this user will have inherited permissions from default user |
|
440 | # this user will have inherited permissions from default user | |
429 |
assert global_perms(self.u1) == |
|
441 | assert global_perms(self.u1) == { | |
430 | 'hg.create.none', |
|
442 | 'hg.create.none', | |
431 | 'hg.fork.none', |
|
443 | 'hg.fork.none', | |
432 | 'hg.register.manual_activate', |
|
444 | 'hg.register.manual_activate', | |
@@ -435,11 +447,12 b' class TestPermissions(object):' | |||||
435 | 'repository.read', |
|
447 | 'repository.read', | |
436 | 'group.read', |
|
448 | 'group.read', | |
437 | 'usergroup.read', |
|
449 | 'usergroup.read', | |
|
450 | 'branch.push_force', | |||
438 | 'hg.create.write_on_repogroup.true', |
|
451 | 'hg.create.write_on_repogroup.true', | |
439 | 'hg.usergroup.create.false', |
|
452 | 'hg.usergroup.create.false', | |
440 | 'hg.repogroup.create.false', |
|
453 | 'hg.repogroup.create.false', | |
441 |
perm |
|
454 | perm | |
442 |
|
|
455 | } | |
443 |
|
456 | |||
444 | assert set(repo_perms(self.u1).values()) == set([expected_perm]) |
|
457 | assert set(repo_perms(self.u1).values()) == set([expected_perm]) | |
445 |
|
458 | |||
@@ -693,6 +706,11 b' def repo_perms(user):' | |||||
693 | return auth_user.permissions['repositories'] |
|
706 | return auth_user.permissions['repositories'] | |
694 |
|
707 | |||
695 |
|
708 | |||
|
709 | def branch_perms(user): | |||
|
710 | auth_user = AuthUser(user_id=user.user_id) | |||
|
711 | return auth_user.permissions['repository_branches'] | |||
|
712 | ||||
|
713 | ||||
696 | def group_perms(user): |
|
714 | def group_perms(user): | |
697 | auth_user = AuthUser(user_id=user.user_id) |
|
715 | auth_user = AuthUser(user_id=user.user_id) | |
698 | return auth_user.permissions['repositories_groups'] |
|
716 | return auth_user.permissions['repositories_groups'] |
@@ -66,5 +66,5 b' class TestTags(BackendTestMixin):' | |||||
66 | def test_name_with_slash(self): |
|
66 | def test_name_with_slash(self): | |
67 | self.repo.tag('19/10/11', 'joe') |
|
67 | self.repo.tag('19/10/11', 'joe') | |
68 | assert '19/10/11' in self.repo.tags |
|
68 | assert '19/10/11' in self.repo.tags | |
69 | self.repo.tag('11', 'joe') |
|
69 | self.repo.tag('rel.11', 'joe') | |
70 | assert '11' in self.repo.tags |
|
70 | assert 'rel.11' in self.repo.tags |
General Comments 0
You need to be logged in to leave comments.
Login now