branch permissions: added logic to define in UI branch permissions.
- db models - new permissions pages placeholders
This commit is contained in:
parent
8676434a71
commit
e41725c078
35 changed files with 5433 additions and 89 deletions
|
|
@ -51,7 +51,7 @@ PYRAMID_SETTINGS = {}
|
|||
EXTENSIONS = {}
|
||||
|
||||
__version__ = ('.'.join((str(each) for each in VERSION[:3])))
|
||||
__dbversion__ = 87 # defines current db version for migrations
|
||||
__dbversion__ = 90 # defines current db version for migrations
|
||||
__platform__ = platform.system()
|
||||
__license__ = 'AGPLv3, and Commercial License'
|
||||
__author__ = 'RhodeCode GmbH'
|
||||
|
|
|
|||
|
|
@ -210,6 +210,11 @@ def admin_routes(config):
|
|||
name='admin_permissions_object_update',
|
||||
pattern='/permissions/object/update')
|
||||
|
||||
# Branch perms EE feature
|
||||
config.add_route(
|
||||
name='admin_permissions_branch',
|
||||
pattern='/permissions/branch')
|
||||
|
||||
config.add_route(
|
||||
name='admin_permissions_ips',
|
||||
pattern='/permissions/ips')
|
||||
|
|
|
|||
|
|
@ -182,7 +182,8 @@ class AdminPermissionsView(BaseAppView, DataGridAppView):
|
|||
self.request.translate,
|
||||
[x[0] for x in c.repo_perms_choices],
|
||||
[x[0] for x in c.group_perms_choices],
|
||||
[x[0] for x in c.user_group_perms_choices])()
|
||||
[x[0] for x in c.user_group_perms_choices],
|
||||
)()
|
||||
|
||||
try:
|
||||
form_result = _form.to_python(dict(self.request.POST))
|
||||
|
|
@ -215,6 +216,30 @@ class AdminPermissionsView(BaseAppView, DataGridAppView):
|
|||
|
||||
raise HTTPFound(h.route_path('admin_permissions_object'))
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAllDecorator('hg.admin')
|
||||
@view_config(
|
||||
route_name='admin_permissions_branch', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/permissions/permissions.mako')
|
||||
def permissions_branch(self):
|
||||
c = self.load_default_context()
|
||||
c.active = 'branch'
|
||||
|
||||
c.user = User.get_default_user(refresh=True)
|
||||
defaults = {}
|
||||
defaults.update(c.user.get_default_perms())
|
||||
|
||||
data = render(
|
||||
'rhodecode:templates/admin/permissions/permissions.mako',
|
||||
self._get_template_context(c), self.request)
|
||||
html = formencode.htmlfill.render(
|
||||
data,
|
||||
defaults=defaults,
|
||||
encoding="UTF-8",
|
||||
force_defaults=False
|
||||
)
|
||||
return Response(html)
|
||||
|
||||
@LoginRequired()
|
||||
@HasPermissionAllDecorator('hg.admin')
|
||||
@view_config(
|
||||
|
|
|
|||
|
|
@ -345,6 +345,15 @@ def includeme(config):
|
|||
name='edit_repo_perms',
|
||||
pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True)
|
||||
|
||||
# Permissions Branch (EE feature)
|
||||
config.add_route(
|
||||
name='edit_repo_perms_branch',
|
||||
pattern='/{repo_name:.*?[^/]}/settings/branch_permissions', repo_route=True)
|
||||
config.add_route(
|
||||
name='edit_repo_perms_branch_delete',
|
||||
pattern='/{repo_name:.*?[^/]}/settings/branch_permissions/{rule_id}/delete',
|
||||
repo_route=True)
|
||||
|
||||
# Maintenance
|
||||
config.add_route(
|
||||
name='edit_repo_maintenance',
|
||||
|
|
|
|||
45
rhodecode/apps/repository/views/repo_branch_permissions.py
Normal file
45
rhodecode/apps/repository/views/repo_branch_permissions.py
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2011-2018 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
# (only), as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import logging
|
||||
|
||||
from pyramid.view import view_config
|
||||
|
||||
from rhodecode.apps._base import RepoAppView
|
||||
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RepoSettingsBranchPermissionsView(RepoAppView):
|
||||
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context()
|
||||
return c
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.admin')
|
||||
@view_config(
|
||||
route_name='edit_repo_perms_branch', request_method='GET',
|
||||
renderer='rhodecode:templates/admin/repos/repo_edit.mako')
|
||||
def branch_permissions(self):
|
||||
c = self.load_default_context()
|
||||
c.active = 'permissions_branch'
|
||||
return self._get_template_context(c)
|
||||
|
|
@ -367,10 +367,38 @@ class PermOriginDict(dict):
|
|||
self.perm_origin_stack = collections.OrderedDict()
|
||||
|
||||
def __setitem__(self, key, (perm, origin)):
|
||||
self.perm_origin_stack.setdefault(key, []).append((perm, origin))
|
||||
self.perm_origin_stack.setdefault(key, []).append(
|
||||
(perm, origin))
|
||||
dict.__setitem__(self, key, perm)
|
||||
|
||||
|
||||
class BranchPermOriginDict(PermOriginDict):
|
||||
"""
|
||||
Dedicated branch permissions dict, with tracking of patterns and origins.
|
||||
|
||||
>>> perms = BranchPermOriginDict()
|
||||
>>> perms['resource'] = '*pattern', 'read', 'default'
|
||||
>>> perms['resource']
|
||||
{'*pattern': 'read'}
|
||||
>>> perms['resource'] = '*pattern', 'write', 'admin'
|
||||
>>> perms['resource']
|
||||
{'*pattern': 'write'}
|
||||
>>> perms.perm_origin_stack
|
||||
{'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}}
|
||||
"""
|
||||
def __setitem__(self, key, (pattern, perm, origin)):
|
||||
|
||||
self.perm_origin_stack.setdefault(key, {}) \
|
||||
.setdefault(pattern, []).append((perm, origin))
|
||||
|
||||
if key in self:
|
||||
self[key].__setitem__(pattern, perm)
|
||||
else:
|
||||
patterns = collections.OrderedDict()
|
||||
patterns[pattern] = perm
|
||||
dict.__setitem__(self, key, patterns)
|
||||
|
||||
|
||||
class PermissionCalculator(object):
|
||||
|
||||
def __init__(
|
||||
|
|
@ -395,6 +423,7 @@ class PermissionCalculator(object):
|
|||
self.permissions_repositories = PermOriginDict()
|
||||
self.permissions_repository_groups = PermOriginDict()
|
||||
self.permissions_user_groups = PermOriginDict()
|
||||
self.permissions_repository_branches = BranchPermOriginDict()
|
||||
self.permissions_global = set()
|
||||
|
||||
self.default_repo_perms = Permission.get_default_repo_perms(
|
||||
|
|
@ -405,6 +434,11 @@ class PermissionCalculator(object):
|
|||
Permission.get_default_user_group_perms(
|
||||
self.default_user_id, self.scope_user_group_id)
|
||||
|
||||
# default branch perms
|
||||
self.default_branch_repo_perms = \
|
||||
Permission.get_default_repo_branch_perms(
|
||||
self.default_user_id, self.scope_repo_id)
|
||||
|
||||
def calculate(self):
|
||||
if self.user_is_admin and not self.calculate_super_admin:
|
||||
return self._admin_permissions()
|
||||
|
|
@ -413,6 +447,7 @@ class PermissionCalculator(object):
|
|||
self._calculate_global_permissions()
|
||||
self._calculate_default_permissions()
|
||||
self._calculate_repository_permissions()
|
||||
self._calculate_repository_branch_permissions()
|
||||
self._calculate_repository_group_permissions()
|
||||
self._calculate_user_group_permissions()
|
||||
return self._permission_structure()
|
||||
|
|
@ -443,6 +478,15 @@ class PermissionCalculator(object):
|
|||
p = 'usergroup.admin'
|
||||
self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN
|
||||
|
||||
# branch permissions
|
||||
# TODO(marcink): validate this, especially
|
||||
# how this should work using multiple patterns specified ??
|
||||
# looks ok, but still needs double check !!
|
||||
for perm in self.default_branch_repo_perms:
|
||||
r_k = perm.UserRepoToPerm.repository.repo_name
|
||||
p = 'branch.push_force'
|
||||
self.permissions_repository_branches[r_k] = '*', p, PermOrigin.SUPER_ADMIN
|
||||
|
||||
return self._permission_structure()
|
||||
|
||||
def _calculate_global_default_permissions(self):
|
||||
|
|
@ -472,18 +516,14 @@ class PermissionCalculator(object):
|
|||
# now we read the defined permissions and overwrite what we have set
|
||||
# before those can be configured from groups or users explicitly.
|
||||
|
||||
# TODO: johbo: This seems to be out of sync, find out the reason
|
||||
# for the comment below and update it.
|
||||
|
||||
# In case we want to extend this list we should be always in sync with
|
||||
# User.DEFAULT_USER_PERMISSIONS definitions
|
||||
# In case we want to extend this list we should make sure
|
||||
# this is in sync with User.DEFAULT_USER_PERMISSIONS definitions
|
||||
_configurable = frozenset([
|
||||
'hg.fork.none', 'hg.fork.repository',
|
||||
'hg.create.none', 'hg.create.repository',
|
||||
'hg.usergroup.create.false', 'hg.usergroup.create.true',
|
||||
'hg.repogroup.create.false', 'hg.repogroup.create.true',
|
||||
'hg.create.write_on_repogroup.false',
|
||||
'hg.create.write_on_repogroup.true',
|
||||
'hg.create.write_on_repogroup.false', 'hg.create.write_on_repogroup.true',
|
||||
'hg.inherit_default_perms.false', 'hg.inherit_default_perms.true'
|
||||
])
|
||||
|
||||
|
|
@ -506,7 +546,7 @@ class PermissionCalculator(object):
|
|||
for gr, perms in _explicit_grouped_perms:
|
||||
# since user can be in multiple groups iterate over them and
|
||||
# select the lowest permissions first (more explicit)
|
||||
# TODO: marcink: do this^^
|
||||
# TODO(marcink): do this^^
|
||||
|
||||
# group doesn't inherit default permissions so we actually set them
|
||||
if not gr.inherit_default_permissions:
|
||||
|
|
@ -533,8 +573,8 @@ class PermissionCalculator(object):
|
|||
|
||||
def _calculate_default_permissions(self):
|
||||
"""
|
||||
Set default user permissions for repositories, repository groups
|
||||
taken from the default user.
|
||||
Set default user permissions for repositories, repository branches,
|
||||
repository groups, user groups taken from the default user.
|
||||
|
||||
Calculate inheritance of object permissions based on what we have now
|
||||
in GLOBAL permissions. We check if .false is in GLOBAL since this is
|
||||
|
|
@ -551,8 +591,7 @@ class PermissionCalculator(object):
|
|||
user_inherit_object_permissions = not ('hg.inherit_default_perms.false'
|
||||
in self.permissions_global)
|
||||
|
||||
# defaults for repositories, taken from `default` user permissions
|
||||
# on given repo
|
||||
# default permissions for repositories, taken from `default` user permissions
|
||||
for perm in self.default_repo_perms:
|
||||
r_k = perm.UserRepoToPerm.repository.repo_name
|
||||
p = perm.Permission.permission_name
|
||||
|
|
@ -585,8 +624,24 @@ class PermissionCalculator(object):
|
|||
o = PermOrigin.SUPER_ADMIN
|
||||
self.permissions_repositories[r_k] = p, o
|
||||
|
||||
# defaults for repository groups taken from `default` user permission
|
||||
# on given group
|
||||
# default permissions branch for repositories, taken from `default` user permissions
|
||||
for perm in self.default_branch_repo_perms:
|
||||
|
||||
r_k = perm.UserRepoToPerm.repository.repo_name
|
||||
p = perm.Permission.permission_name
|
||||
pattern = perm.UserToRepoBranchPermission.branch_pattern
|
||||
o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username
|
||||
|
||||
if not self.explicit:
|
||||
# TODO(marcink): fix this for multiple entries
|
||||
cur_perm = self.permissions_repository_branches.get(r_k) or 'branch.none'
|
||||
p = self._choose_permission(p, cur_perm)
|
||||
|
||||
# NOTE(marcink): register all pattern/perm instances in this
|
||||
# special dict that aggregates entries
|
||||
self.permissions_repository_branches[r_k] = pattern, p, o
|
||||
|
||||
# default permissions for repository groups taken from `default` user permission
|
||||
for perm in self.default_repo_groups_perms:
|
||||
rg_k = perm.UserRepoGroupToPerm.group.group_name
|
||||
p = perm.Permission.permission_name
|
||||
|
|
@ -611,8 +666,7 @@ class PermissionCalculator(object):
|
|||
o = PermOrigin.SUPER_ADMIN
|
||||
self.permissions_repository_groups[rg_k] = p, o
|
||||
|
||||
# defaults for user groups taken from `default` user permission
|
||||
# on given user group
|
||||
# default permissions for user groups taken from `default` user permission
|
||||
for perm in self.default_user_group_perms:
|
||||
u_k = perm.UserUserGroupToPerm.user_group.users_group_name
|
||||
p = perm.Permission.permission_name
|
||||
|
|
@ -703,6 +757,49 @@ class PermissionCalculator(object):
|
|||
o = PermOrigin.SUPER_ADMIN
|
||||
self.permissions_repositories[r_k] = p, o
|
||||
|
||||
def _calculate_repository_branch_permissions(self):
|
||||
# user group for repositories permissions
|
||||
user_repo_branch_perms_from_user_group = Permission\
|
||||
.get_default_repo_branch_perms_from_user_group(
|
||||
self.user_id, self.scope_repo_id)
|
||||
|
||||
multiple_counter = collections.defaultdict(int)
|
||||
for perm in user_repo_branch_perms_from_user_group:
|
||||
r_k = perm.UserGroupRepoToPerm.repository.repo_name
|
||||
p = perm.Permission.permission_name
|
||||
pattern = perm.UserGroupToRepoBranchPermission.branch_pattern
|
||||
o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\
|
||||
.users_group.users_group_name
|
||||
|
||||
multiple_counter[r_k] += 1
|
||||
if multiple_counter[r_k] > 1:
|
||||
# TODO(marcink): fix this for multi branch support, and multiple entries
|
||||
cur_perm = self.permissions_repository_branches[r_k]
|
||||
p = self._choose_permission(p, cur_perm)
|
||||
|
||||
self.permissions_repository_branches[r_k] = pattern, p, o
|
||||
|
||||
# user explicit branch permissions for repositories, overrides
|
||||
# any specified by the group permission
|
||||
user_repo_branch_perms = Permission.get_default_repo_branch_perms(
|
||||
self.user_id, self.scope_repo_id)
|
||||
for perm in user_repo_branch_perms:
|
||||
|
||||
r_k = perm.UserRepoToPerm.repository.repo_name
|
||||
p = perm.Permission.permission_name
|
||||
pattern = perm.UserToRepoBranchPermission.branch_pattern
|
||||
o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username
|
||||
|
||||
if not self.explicit:
|
||||
# TODO(marcink): fix this for multiple entries
|
||||
cur_perm = self.permissions_repository_branches.get(r_k) or 'branch.none'
|
||||
p = self._choose_permission(p, cur_perm)
|
||||
|
||||
# NOTE(marcink): register all pattern/perm instances in this
|
||||
# special dict that aggregates entries
|
||||
self.permissions_repository_branches[r_k] = pattern, p, o
|
||||
|
||||
|
||||
def _calculate_repository_group_permissions(self):
|
||||
"""
|
||||
Repository group permissions for the current user.
|
||||
|
|
@ -845,6 +942,7 @@ class PermissionCalculator(object):
|
|||
return {
|
||||
'global': self.permissions_global,
|
||||
'repositories': self.permissions_repositories,
|
||||
'repository_branches': self.permissions_repository_branches,
|
||||
'repositories_groups': self.permissions_repository_groups,
|
||||
'user_groups': self.permissions_user_groups,
|
||||
}
|
||||
|
|
@ -956,6 +1054,9 @@ class AuthUser(object):
|
|||
perms['user_groups'] = {
|
||||
k: v for k, v in perms['user_groups'].items()
|
||||
if v != 'usergroup.none'}
|
||||
perms['repository_branches'] = {
|
||||
k: v for k, v in perms['repository_branches'].iteritems()
|
||||
if v != 'branch.none'}
|
||||
return perms
|
||||
|
||||
@LazyProperty
|
||||
|
|
@ -1800,7 +1901,6 @@ class PermsFunction(object):
|
|||
def __call__(self, check_location='', user=None):
|
||||
if not user:
|
||||
log.debug('Using user attribute from global request')
|
||||
# TODO: remove this someday,put as user as attribute here
|
||||
request = self._get_request()
|
||||
user = request.user
|
||||
|
||||
|
|
|
|||
4587
rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py
Normal file
4587
rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py
Normal file
File diff suppressed because it is too large
Load diff
46
rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py
Normal file
46
rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import logging
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.engine import reflection
|
||||
from sqlalchemy.dialects.mysql import LONGTEXT
|
||||
|
||||
from alembic.migration import MigrationContext
|
||||
from alembic.operations import Operations
|
||||
|
||||
from rhodecode.lib.dbmigrate.utils import create_default_permissions, \
|
||||
create_default_object_permission
|
||||
from rhodecode.model import meta
|
||||
from rhodecode.lib.dbmigrate.versions import _reset_base, notify
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""
|
||||
Upgrade operations go here.
|
||||
Don't create your own engine; bind migrate_engine to your metadata
|
||||
"""
|
||||
_reset_base(migrate_engine)
|
||||
from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db
|
||||
|
||||
# issue fixups
|
||||
fixups(db, meta.Session)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
|
||||
def fixups(models, _SESSION):
|
||||
# create default permissions
|
||||
create_default_permissions(_SESSION, models)
|
||||
log.info('created default global permissions definitions')
|
||||
_SESSION().commit()
|
||||
|
||||
# # fix default object permissions
|
||||
# create_default_object_permission(_SESSION, models)
|
||||
|
||||
log.info('created default permission')
|
||||
_SESSION().commit()
|
||||
|
||||
39
rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py
Normal file
39
rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import logging
|
||||
|
||||
from sqlalchemy import *
|
||||
from sqlalchemy.engine import reflection
|
||||
from sqlalchemy.dialects.mysql import LONGTEXT
|
||||
|
||||
from alembic.migration import MigrationContext
|
||||
from alembic.operations import Operations
|
||||
|
||||
from rhodecode.model import meta
|
||||
from rhodecode.lib.dbmigrate.versions import _reset_base, notify
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""
|
||||
Upgrade operations go here.
|
||||
Don't create your own engine; bind migrate_engine to your metadata
|
||||
"""
|
||||
_reset_base(migrate_engine)
|
||||
from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db
|
||||
|
||||
db.UserToRepoBranchPermission.__table__.create()
|
||||
db.UserGroupToRepoBranchPermission.__table__.create()
|
||||
|
||||
# issue fixups
|
||||
fixups(db, meta.Session)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
|
||||
def fixups(models, _SESSION):
|
||||
pass
|
||||
|
||||
|
||||
43
rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py
Normal file
43
rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
import logging
|
||||
|
||||
from sqlalchemy import *
|
||||
|
||||
from rhodecode.lib.dbmigrate.utils import (
|
||||
create_default_object_permission, create_default_permissions)
|
||||
|
||||
from rhodecode.model import meta
|
||||
from rhodecode.lib.dbmigrate.versions import _reset_base, notify
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def upgrade(migrate_engine):
|
||||
"""
|
||||
Upgrade operations go here.
|
||||
Don't create your own engine; bind migrate_engine to your metadata
|
||||
"""
|
||||
_reset_base(migrate_engine)
|
||||
from rhodecode.lib.dbmigrate.schema import db_4_13_0_0 as db
|
||||
|
||||
# issue fixups
|
||||
fixups(db, meta.Session)
|
||||
|
||||
|
||||
def downgrade(migrate_engine):
|
||||
meta = MetaData()
|
||||
meta.bind = migrate_engine
|
||||
|
||||
|
||||
def fixups(models, _SESSION):
|
||||
# create default permissions
|
||||
create_default_permissions(_SESSION, models)
|
||||
log.info('created default global permissions definitions')
|
||||
_SESSION().commit()
|
||||
|
||||
# fix default object permissions
|
||||
create_default_object_permission(_SESSION, models)
|
||||
|
||||
log.info('created default permission')
|
||||
_SESSION().commit()
|
||||
|
||||
|
||||
|
|
@ -751,6 +751,13 @@ class AttributeDict(AttributeDictBase):
|
|||
|
||||
|
||||
|
||||
class OrderedDefaultDict(collections.OrderedDict, collections.defaultdict):
|
||||
def __init__(self, default_factory=None, *args, **kwargs):
|
||||
# in python3 you can omit the args to super
|
||||
super(OrderedDefaultDict, self).__init__(*args, **kwargs)
|
||||
self.default_factory = default_factory
|
||||
|
||||
|
||||
def fix_PATH(os_=None):
|
||||
"""
|
||||
Get current active python path, and append it to PATH variable to fix
|
||||
|
|
|
|||
|
|
@ -1913,6 +1913,7 @@ class Repository(Base, BaseModel):
|
|||
for _usr in q.all():
|
||||
usr = AttributeDict(_usr.user.get_dict())
|
||||
usr.permission = _usr.permission.permission_name
|
||||
usr.permission_id = _usr.repo_to_perm_id
|
||||
perm_rows.append(usr)
|
||||
|
||||
# filter the perm rows by 'default' first and then sort them by
|
||||
|
|
@ -1926,6 +1927,7 @@ class Repository(Base, BaseModel):
|
|||
usr = AttributeDict(self.user.get_dict())
|
||||
usr.owner_row = True
|
||||
usr.permission = _admin_perm
|
||||
usr.permission_id = None
|
||||
owner_row.append(usr)
|
||||
|
||||
super_admin_rows = []
|
||||
|
|
@ -1938,6 +1940,7 @@ class Repository(Base, BaseModel):
|
|||
usr = AttributeDict(usr.get_dict())
|
||||
usr.admin_row = True
|
||||
usr.permission = _admin_perm
|
||||
usr.permission_id = None
|
||||
super_admin_rows.append(usr)
|
||||
|
||||
return super_admin_rows + owner_row + perm_rows
|
||||
|
|
@ -2694,6 +2697,11 @@ class Permission(Base, BaseModel):
|
|||
('usergroup.write', _('User group write access')),
|
||||
('usergroup.admin', _('User group admin access')),
|
||||
|
||||
('branch.none', _('Branch no permissions')),
|
||||
('branch.merge', _('Branch access by web merge')),
|
||||
('branch.push', _('Branch access by push')),
|
||||
('branch.push_force', _('Branch access by push with force')),
|
||||
|
||||
('hg.repogroup.create.false', _('Repository Group creation disabled')),
|
||||
('hg.repogroup.create.true', _('Repository Group creation enabled')),
|
||||
|
||||
|
|
@ -2723,11 +2731,16 @@ class Permission(Base, BaseModel):
|
|||
('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')),
|
||||
]
|
||||
|
||||
# definition of system default permissions for DEFAULT user
|
||||
# definition of system default permissions for DEFAULT user, created on
|
||||
# system setup
|
||||
DEFAULT_USER_PERMISSIONS = [
|
||||
# object perms
|
||||
'repository.read',
|
||||
'group.read',
|
||||
'usergroup.read',
|
||||
# branch, for backward compat we need same value as before so forced pushed
|
||||
'branch.push_force',
|
||||
# global
|
||||
'hg.create.repository',
|
||||
'hg.repogroup.create.false',
|
||||
'hg.usergroup.create.false',
|
||||
|
|
@ -2758,6 +2771,11 @@ class Permission(Base, BaseModel):
|
|||
'usergroup.write': 3,
|
||||
'usergroup.admin': 4,
|
||||
|
||||
'branch.none': 0,
|
||||
'branch.merge': 1,
|
||||
'branch.push': 3,
|
||||
'branch.push_force': 4,
|
||||
|
||||
'hg.repogroup.create.false': 0,
|
||||
'hg.repogroup.create.true': 1,
|
||||
|
||||
|
|
@ -2793,6 +2811,21 @@ class Permission(Base, BaseModel):
|
|||
q = q.filter(UserRepoToPerm.repository_id == repo_id)
|
||||
return q.all()
|
||||
|
||||
@classmethod
|
||||
def get_default_repo_branch_perms(cls, user_id, repo_id=None):
|
||||
q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \
|
||||
.join(
|
||||
Permission,
|
||||
UserToRepoBranchPermission.permission_id == Permission.permission_id) \
|
||||
.join(
|
||||
UserRepoToPerm,
|
||||
UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \
|
||||
.filter(UserRepoToPerm.user_id == user_id)
|
||||
|
||||
if repo_id:
|
||||
q = q.filter(UserToRepoBranchPermission.repository_id == repo_id)
|
||||
return q.order_by(UserToRepoBranchPermission.rule_order).all()
|
||||
|
||||
@classmethod
|
||||
def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None):
|
||||
q = Session().query(UserGroupRepoToPerm, Repository, Permission)\
|
||||
|
|
@ -2817,11 +2850,38 @@ class Permission(Base, BaseModel):
|
|||
q = q.filter(UserGroupRepoToPerm.repository_id == repo_id)
|
||||
return q.all()
|
||||
|
||||
@classmethod
|
||||
def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None):
|
||||
q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \
|
||||
.join(
|
||||
Permission,
|
||||
UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \
|
||||
.join(
|
||||
UserGroupRepoToPerm,
|
||||
UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \
|
||||
.join(
|
||||
UserGroup,
|
||||
UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \
|
||||
.join(
|
||||
UserGroupMember,
|
||||
UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \
|
||||
.filter(
|
||||
UserGroupMember.user_id == user_id,
|
||||
UserGroup.users_group_active == true())
|
||||
|
||||
if repo_id:
|
||||
q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id)
|
||||
return q.order_by(UserGroupToRepoBranchPermission.rule_order).all()
|
||||
|
||||
@classmethod
|
||||
def get_default_group_perms(cls, user_id, repo_group_id=None):
|
||||
q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\
|
||||
.join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\
|
||||
.join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
|
||||
.join(
|
||||
Permission,
|
||||
UserRepoGroupToPerm.permission_id == Permission.permission_id)\
|
||||
.join(
|
||||
RepoGroup,
|
||||
UserRepoGroupToPerm.group_id == RepoGroup.group_id)\
|
||||
.filter(UserRepoGroupToPerm.user_id == user_id)
|
||||
if repo_group_id:
|
||||
q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id)
|
||||
|
|
@ -2910,6 +2970,8 @@ class UserRepoToPerm(Base, BaseModel):
|
|||
repository = relationship('Repository')
|
||||
permission = relationship('Permission')
|
||||
|
||||
branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined')
|
||||
|
||||
@classmethod
|
||||
def create(cls, user, repository, permission):
|
||||
n = cls()
|
||||
|
|
@ -4470,6 +4532,100 @@ def set_task_uid(mapper, connection, target):
|
|||
target.task_uid = ScheduleEntry.get_uid(target)
|
||||
|
||||
|
||||
class _BaseBranchPerms(BaseModel):
|
||||
@classmethod
|
||||
def compute_hash(cls, value):
|
||||
return sha1_safe(value)
|
||||
|
||||
@hybrid_property
|
||||
def branch_pattern(self):
|
||||
return self._branch_pattern or '*'
|
||||
|
||||
@hybrid_property
|
||||
def branch_hash(self):
|
||||
return self._branch_hash
|
||||
|
||||
def _validate_glob(self, value):
|
||||
re.compile('^' + glob2re(value) + '$')
|
||||
|
||||
@branch_pattern.setter
|
||||
def branch_pattern(self, value):
|
||||
self._validate_glob(value)
|
||||
self._branch_pattern = value or '*'
|
||||
# set the Hash when setting the branch pattern
|
||||
self._branch_hash = self.compute_hash(self._branch_pattern)
|
||||
|
||||
def matches(self, branch):
|
||||
"""
|
||||
Check if this the branch matches entry
|
||||
|
||||
:param branch: branch name for the commit
|
||||
"""
|
||||
|
||||
branch = branch or ''
|
||||
|
||||
branch_matches = True
|
||||
if branch:
|
||||
branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$')
|
||||
branch_matches = bool(branch_regex.search(branch))
|
||||
|
||||
return branch_matches
|
||||
|
||||
|
||||
class UserToRepoBranchPermission(Base, _BaseBranchPerms):
|
||||
__tablename__ = 'user_to_repo_branch_permissions'
|
||||
__table_args__ = (
|
||||
{'extend_existing': True, 'mysql_engine': 'InnoDB',
|
||||
'mysql_charset': 'utf8', 'sqlite_autoincrement': True,}
|
||||
)
|
||||
|
||||
branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True)
|
||||
|
||||
repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
|
||||
repo = relationship('Repository', backref='user_branch_perms')
|
||||
|
||||
permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
|
||||
permission = relationship('Permission')
|
||||
|
||||
rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None)
|
||||
user_repo_to_perm = relationship('UserRepoToPerm')
|
||||
|
||||
rule_order = Column('rule_order', Integer(), nullable=False)
|
||||
_branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob
|
||||
_branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql'))
|
||||
|
||||
def __unicode__(self):
|
||||
return u'<UserBranchPermission(%s => %r)>' % (
|
||||
self.user_repo_to_perm, self.branch_pattern)
|
||||
|
||||
|
||||
class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms):
|
||||
__tablename__ = 'user_group_to_repo_branch_permissions'
|
||||
__table_args__ = (
|
||||
{'extend_existing': True, 'mysql_engine': 'InnoDB',
|
||||
'mysql_charset': 'utf8', 'sqlite_autoincrement': True,}
|
||||
)
|
||||
|
||||
branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True)
|
||||
|
||||
repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
|
||||
repo = relationship('Repository', backref='user_group_branch_perms')
|
||||
|
||||
permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
|
||||
permission = relationship('Permission')
|
||||
|
||||
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)
|
||||
user_group_repo_to_perm = relationship('UserGroupRepoToPerm')
|
||||
|
||||
rule_order = Column('rule_order', Integer(), nullable=False)
|
||||
_branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob
|
||||
_branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql'))
|
||||
|
||||
def __unicode__(self):
|
||||
return u'<UserBranchPermission(%s => %r)>' % (
|
||||
self.user_group_repo_to_perm, self.branch_pattern)
|
||||
|
||||
|
||||
class DbMigrateVersion(Base, BaseModel):
|
||||
__tablename__ = 'db_migrate_version'
|
||||
__table_args__ = (
|
||||
|
|
|
|||
|
|
@ -504,12 +504,26 @@ def ObjectPermissionsForm(localizer, repo_perms_choices, group_perms_choices,
|
|||
overwrite_default_repo = v.StringBoolean(if_missing=False)
|
||||
overwrite_default_group = v.StringBoolean(if_missing=False)
|
||||
overwrite_default_user_group = v.StringBoolean(if_missing=False)
|
||||
|
||||
default_repo_perm = v.OneOf(repo_perms_choices)
|
||||
default_group_perm = v.OneOf(group_perms_choices)
|
||||
default_user_group_perm = v.OneOf(user_group_perms_choices)
|
||||
|
||||
return _ObjectPermissionsForm
|
||||
|
||||
|
||||
def BranchPermissionsForm(localizer, branch_perms_choices):
|
||||
_ = localizer
|
||||
|
||||
class _BranchPermissionsForm(formencode.Schema):
|
||||
allow_extra_fields = True
|
||||
filter_extra_fields = True
|
||||
overwrite_default_branch = v.StringBoolean(if_missing=False)
|
||||
default_branch_perm = v.OneOf(branch_perms_choices)
|
||||
|
||||
return _BranchPermissionsForm
|
||||
|
||||
|
||||
def UserPermissionsForm(localizer, create_choices, create_on_write_choices,
|
||||
repo_group_create_choices, user_group_create_choices,
|
||||
fork_choices, inherit_default_permissions_choices):
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ from sqlalchemy.exc import DatabaseError
|
|||
from rhodecode.model import BaseModel
|
||||
from rhodecode.model.db import (
|
||||
User, Permission, UserToPerm, UserRepoToPerm, UserRepoGroupToPerm,
|
||||
UserUserGroupToPerm, UserGroup, UserGroupToPerm)
|
||||
UserUserGroupToPerm, UserGroup, UserGroupToPerm, UserToRepoBranchPermission)
|
||||
from rhodecode.lib.utils2 import str2bool, safe_int
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
|
@ -59,6 +59,9 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_perm': None,
|
||||
'default_group_perm': None,
|
||||
'default_user_group_perm': None,
|
||||
|
||||
# branch
|
||||
'default_branch_perm': None,
|
||||
}
|
||||
|
||||
def set_global_permission_choices(self, c_obj, gettext_translator):
|
||||
|
|
@ -82,6 +85,12 @@ class PermissionModel(BaseModel):
|
|||
('usergroup.write', _('Write'),),
|
||||
('usergroup.admin', _('Admin'),)]
|
||||
|
||||
c_obj.branch_perms_choices = [
|
||||
('branch.none', _('Protected/No Access'),),
|
||||
('branch.merge', _('Web merge'),),
|
||||
('branch.push', _('Push'),),
|
||||
('branch.push_force', _('Force Push'),)]
|
||||
|
||||
c_obj.register_choices = [
|
||||
('hg.register.none', _('Disabled')),
|
||||
('hg.register.manual_activate', _('Allowed with manual account activation')),
|
||||
|
|
@ -133,6 +142,10 @@ class PermissionModel(BaseModel):
|
|||
if perm.permission.permission_name.startswith('usergroup.'):
|
||||
defaults['default_user_group_perm' + suffix] = perm.permission.permission_name
|
||||
|
||||
# branch
|
||||
if perm.permission.permission_name.startswith('branch.'):
|
||||
defaults['default_branch_perm' + suffix] = perm.permission.permission_name
|
||||
|
||||
# creation of objects
|
||||
if perm.permission.permission_name.startswith('hg.create.write_on_repogroup'):
|
||||
defaults['default_repo_create_on_write' + suffix] = perm.permission.permission_name
|
||||
|
|
@ -199,6 +212,9 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_perm': 'repository.',
|
||||
'default_group_perm': 'group.',
|
||||
'default_user_group_perm': 'usergroup.',
|
||||
# branch
|
||||
'default_branch_perm': 'branch.',
|
||||
|
||||
}[field_name]
|
||||
for field in keep_fields:
|
||||
pat = get_pat(field)
|
||||
|
|
@ -236,8 +252,12 @@ class PermissionModel(BaseModel):
|
|||
_global_perms = self.global_perms.copy()
|
||||
if obj_type not in ['user', 'user_group']:
|
||||
raise ValueError("obj_type must be on of 'user' or 'user_group'")
|
||||
if len(_global_perms) != len(Permission.DEFAULT_USER_PERMISSIONS):
|
||||
raise Exception('Inconsistent permissions definition')
|
||||
global_perms = len(_global_perms)
|
||||
default_user_perms = len(Permission.DEFAULT_USER_PERMISSIONS)
|
||||
if global_perms != default_user_perms:
|
||||
raise Exception(
|
||||
'Inconsistent permissions definition. Got {} vs {}'.format(
|
||||
global_perms, default_user_perms))
|
||||
|
||||
if obj_type == 'user':
|
||||
self._clear_user_perms(object.user_id, preserve)
|
||||
|
|
@ -337,8 +357,8 @@ class PermissionModel(BaseModel):
|
|||
|
||||
def create_default_user_group_permissions(self, user_group, force=False):
|
||||
"""
|
||||
Creates only missing default permissions for user group, if force is set it
|
||||
resets the default permissions for that user group
|
||||
Creates only missing default permissions for user group, if force is
|
||||
set it resets the default permissions for that user group
|
||||
|
||||
:param user_group:
|
||||
:param force:
|
||||
|
|
@ -366,6 +386,7 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_perm',
|
||||
'default_group_perm',
|
||||
'default_user_group_perm',
|
||||
'default_branch_perm',
|
||||
|
||||
'default_repo_group_create',
|
||||
'default_user_group_create',
|
||||
|
|
@ -392,6 +413,7 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_perm',
|
||||
'default_group_perm',
|
||||
'default_user_group_perm',
|
||||
'default_branch_perm',
|
||||
|
||||
'default_register',
|
||||
'default_password_reset',
|
||||
|
|
@ -414,6 +436,7 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_perm',
|
||||
'default_group_perm',
|
||||
'default_user_group_perm',
|
||||
'default_branch_perm',
|
||||
|
||||
'default_register',
|
||||
'default_password_reset',
|
||||
|
|
@ -440,6 +463,7 @@ class PermissionModel(BaseModel):
|
|||
'default_repo_create',
|
||||
'default_fork_create',
|
||||
'default_inherit_default_permissions',
|
||||
'default_branch_perm',
|
||||
|
||||
'default_register',
|
||||
'default_password_reset',
|
||||
|
|
@ -477,8 +501,57 @@ class PermissionModel(BaseModel):
|
|||
.all():
|
||||
g2p.permission = _def
|
||||
self.sa.add(g2p)
|
||||
|
||||
# COMMIT
|
||||
self.sa.commit()
|
||||
except (DatabaseError,):
|
||||
log.exception('Failed to set default object permissions')
|
||||
self.sa.rollback()
|
||||
raise
|
||||
|
||||
def update_branch_permissions(self, form_result):
|
||||
if 'perm_user_id' in form_result:
|
||||
perm_user = User.get(safe_int(form_result['perm_user_id']))
|
||||
else:
|
||||
# used mostly to do lookup for default user
|
||||
perm_user = User.get_by_username(form_result['perm_user_name'])
|
||||
try:
|
||||
|
||||
# stage 2 reset defaults and set them from form data
|
||||
self._set_new_user_perms(perm_user, form_result, preserve=[
|
||||
'default_repo_perm',
|
||||
'default_group_perm',
|
||||
'default_user_group_perm',
|
||||
|
||||
'default_repo_group_create',
|
||||
'default_user_group_create',
|
||||
'default_repo_create_on_write',
|
||||
'default_repo_create',
|
||||
'default_fork_create',
|
||||
'default_inherit_default_permissions',
|
||||
|
||||
'default_register',
|
||||
'default_password_reset',
|
||||
'default_extern_activate'])
|
||||
|
||||
# overwrite default branch permissions
|
||||
if form_result['overwrite_default_branch']:
|
||||
_def_name = \
|
||||
form_result['default_branch_perm'].split('branch.')[-1]
|
||||
|
||||
_def = Permission.get_by_key('branch.' + _def_name)
|
||||
|
||||
# TODO(marcink): those are bind to repo, perms, we need to unfold user somehow from this
|
||||
for g2p in self.sa.query(UserToRepoBranchPermission) \
|
||||
.filter(UserToRepoBranchPermission.user == perm_user) \
|
||||
.all():
|
||||
g2p.permission = _def
|
||||
self.sa.add(g2p)
|
||||
|
||||
# COMMIT
|
||||
self.sa.commit()
|
||||
except (DatabaseError,):
|
||||
log.exception('Failed to set default branch permissions')
|
||||
self.sa.rollback()
|
||||
raise
|
||||
|
||||
|
|
|
|||
|
|
@ -116,6 +116,11 @@
|
|||
.label;
|
||||
padding-top: 5px;
|
||||
}
|
||||
.label-branch-perm {
|
||||
.label;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
// Used to position content on the right side of a .label
|
||||
.content,
|
||||
.side-by-side-selector {
|
||||
|
|
@ -135,6 +140,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.input-branch-perm {
|
||||
.input;
|
||||
margin-left: 90px;
|
||||
}
|
||||
|
||||
.input-branch-perm-order {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.checkboxes,
|
||||
.input,
|
||||
.select {
|
||||
|
|
@ -169,6 +183,9 @@
|
|||
}
|
||||
|
||||
.input {
|
||||
.branch-perm {
|
||||
width: 80px;
|
||||
}
|
||||
.medium {
|
||||
width: @fields-input-m;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -462,7 +462,7 @@ ul.auth_plugins {
|
|||
|
||||
.radios {
|
||||
position: relative;
|
||||
width: 405px;
|
||||
width: 505px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -159,3 +159,9 @@
|
|||
&:extend(.icon-svn-transparent:before);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-user-group:before {
|
||||
&:extend(.icon-group:before);
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -109,13 +109,21 @@
|
|||
&.read {
|
||||
&:extend(.tag1);
|
||||
}
|
||||
|
||||
&.write {
|
||||
&:extend(.tag4);
|
||||
}
|
||||
&.admin {
|
||||
&:extend(.tag5);
|
||||
}
|
||||
&.merge {
|
||||
&:extend(.tag1);
|
||||
}
|
||||
&.push {
|
||||
&:extend(.tag4);
|
||||
}
|
||||
&.push_force {
|
||||
&:extend(.tag5);
|
||||
}
|
||||
}
|
||||
|
||||
.phase-draft {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ function registerRCRoutes() {
|
|||
pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
|
||||
pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
|
||||
pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
|
||||
pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []);
|
||||
pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
|
||||
pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
|
||||
pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
|
||||
|
|
@ -233,6 +234,8 @@ function registerRCRoutes() {
|
|||
pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']);
|
||||
pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
|
||||
pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
|
||||
pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']);
|
||||
pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']);
|
||||
pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
|
||||
pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
|
||||
pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ $(document).ready(function() {
|
|||
{ data: {"_": "group_name",
|
||||
"sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
|
||||
render: function (data,type,full,meta)
|
||||
{return '<div><i class="icon-group" title="User group">'+data+'</i></div>'}},
|
||||
{return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
|
||||
|
||||
{ data: {"_": "group_description",
|
||||
"sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
|
||||
|
|
|
|||
|
|
@ -38,6 +38,9 @@
|
|||
<li class="${'active' if c.active=='objects' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_object')}">${_('Object')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='branch' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_branch')}">${_('Branch')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='ips' else ''}">
|
||||
<a href="${h.route_path('admin_permissions_ips')}">${_('IP Whitelist')}</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('Default Permissions for Branches.')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<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>
|
||||
<img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/admin_branch_permissions.png')}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -3,7 +3,10 @@
|
|||
<h3 class="panel-title">${_('Default Permissions for Repositories, User Groups and Repository Groups.')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<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.')}
|
||||
<p>
|
||||
${_('Default access permissions. This defines permissions for the `default` user from which other users inherit permissions.')}
|
||||
<br/>
|
||||
${_('Check the overwrite checkbox to force change all previously defined permissions for `default` user to the new selected value.')}
|
||||
</p>
|
||||
${h.secure_form(h.route_path('admin_permissions_object_update'), request=request)}
|
||||
<div class="form">
|
||||
|
|
@ -45,7 +48,7 @@
|
|||
${h.select('default_user_group_perm','',c.user_group_perms_choices)}
|
||||
${h.checkbox('overwrite_default_user_group','true')}
|
||||
<label for="overwrite_default_user_group">
|
||||
<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 repository groups will be lost'))}">
|
||||
<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'))}">
|
||||
${_('Overwrite Existing Settings')}
|
||||
</span>
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
%if _user.username != h.DEFAULT_USER:
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user.user_id}" member_type="user">
|
||||
<i class="icon-remove"></i> ${_('Revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
%endif
|
||||
</td>
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.write', checked=_user_group.permission=='group.write')}</td>
|
||||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'group.admin', checked=_user_group.permission=='group.admin')}</td>
|
||||
<td class="td-componentname">
|
||||
<i class="icon-group" ></i>
|
||||
<i class="icon-user-group"></i>
|
||||
%if h.HasPermissionAny('hg.admin')():
|
||||
<a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
|
||||
${_user_group.users_group_name}
|
||||
|
|
@ -104,17 +104,27 @@
|
|||
<td class="td-action">
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user_group.users_group_id}" member_type="user_group">
|
||||
<i class="icon-remove"></i> ${_('Revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
|
||||
<tr class="new_members" id="add_perm_input"></tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<span id="add_perm" class="link">
|
||||
${_('Add user/user group')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="add_perm" class="link">
|
||||
${_('Add new')}
|
||||
</div>
|
||||
|
||||
<div class="fields">
|
||||
<div class="field">
|
||||
<div class="label label-radio">
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@
|
|||
<li class="${'active' if c.active=='permissions' else ''}">
|
||||
<a href="${h.route_path('edit_repo_perms', repo_name=c.repo_name)}">${_('Permissions')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='permissions_branch' else ''}">
|
||||
<a href="${h.route_path('edit_repo_perms_branch', repo_name=c.repo_name)}">${_('Branch Permissions')}</a>
|
||||
</li>
|
||||
<li class="${'active' if c.active=='advanced' else ''}">
|
||||
<a href="${h.route_path('edit_repo_advanced', repo_name=c.repo_name)}">${_('Advanced')}</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@
|
|||
%if _user.username != h.DEFAULT_USER:
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user.user_id}" member_type="user">
|
||||
<i class="icon-remove"></i> ${_('Revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
%endif
|
||||
</td>
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.write', checked=_user_group.permission=='repository.write')}</td>
|
||||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'repository.admin', checked=_user_group.permission=='repository.admin')}</td>
|
||||
<td class="td-componentname">
|
||||
<i class="icon-group" ></i>
|
||||
<i class="icon-user-group"></i>
|
||||
%if h.HasPermissionAny('hg.admin')():
|
||||
<a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
|
||||
${_user_group.users_group_name}
|
||||
|
|
@ -95,16 +95,28 @@
|
|||
<td class="td-action">
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user_group.users_group_id}" member_type="user_group">
|
||||
<i class="icon-remove"></i> ${_('Revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
<tr class="new_members" id="add_perm_input"></tr>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<span id="add_perm" class="link">
|
||||
${_('Add user/user group')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<div id="add_perm" class="link">
|
||||
${_('Add new')}
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
${h.submit('save',_('Save'),class_="btn btn-primary")}
|
||||
${h.reset('reset',_('Reset'),class_="btn btn-danger")}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${_('Repository Branch Permissions.')}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<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>
|
||||
<img style="width: 100%; height: 100%" src="${h.asset('images/ee_features/repo_branch_permissions.png')}"/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
%if _user.username != h.DEFAULT_USER:
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user.user_id}" member_type="user">
|
||||
<i class="icon-remove"></i> ${_('revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
%endif
|
||||
</td>
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.write')}</td>
|
||||
<td class="td-radio">${h.radio('g_perm_%s' % _user_group.users_group_id,'usergroup.admin')}</td>
|
||||
<td class="td-user">
|
||||
<i class="icon-group" ></i>
|
||||
<i class="icon-user-group"></i>
|
||||
%if h.HasPermissionAny('hg.admin')():
|
||||
<a href="${h.route_path('edit_user_group',user_group_id=_user_group.users_group_id)}">
|
||||
${_user_group.users_group_name}
|
||||
|
|
@ -106,16 +106,26 @@
|
|||
<td class="td-action">
|
||||
<span class="btn btn-link btn-danger revoke_perm"
|
||||
member="${_user_group.users_group_id}" member_type="user_group">
|
||||
<i class="icon-remove"></i> ${_('revoke')}
|
||||
${_('Revoke')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
%endfor
|
||||
<tr class="new_members" id="add_perm_input"></tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<span id="add_perm" class="link">
|
||||
${_('Add user/user group')}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="add_perm" class="link">
|
||||
${_('Add new')}
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
${h.submit('save',_('Save'),class_="btn btn-primary")}
|
||||
${h.reset('reset',_('Reset'),class_="btn btn-danger")}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ $(document).ready(function() {
|
|||
{ data: {"_": "group_name",
|
||||
"sort": "group_name"}, title: "${_('Name')}", className: "td-componentname," ,
|
||||
render: function (data,type,full,meta)
|
||||
{return '<div><i class="icon-group" title="User group">'+data+'</i></div>'}},
|
||||
{return '<div><i class="icon-user-group" title="User group">'+data+'</i></div>'}},
|
||||
|
||||
{ data: {"_": "group_description",
|
||||
"sort": "group_description"}, title: "${_('Description')}", className: "td-description" },
|
||||
|
|
|
|||
|
|
@ -4,11 +4,20 @@
|
|||
## ${p.perms_summary(c.perm_user.permissions)}
|
||||
|
||||
<%def name="perms_summary(permissions, show_all=False, actions=True, side_link=None)">
|
||||
<% section_to_label = {
|
||||
'global': 'Global Permissions',
|
||||
'repository_branches': 'Repository Branch Rules',
|
||||
'repositories': 'Repository Permissions',
|
||||
'user_groups': 'User Group Permissions',
|
||||
'repositories_groups': 'Repository Group Permissions',
|
||||
} %>
|
||||
<div id="perms" class="table fields">
|
||||
%for section in sorted(permissions.keys()):
|
||||
%for section in sorted(permissions.keys(), key=lambda item: {'global': 0, 'repository_branches': 1}.get(item, 1000)):
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">${section.replace("_"," ").capitalize()}</h3>
|
||||
<div class="panel-heading" id="${section.replace("_","-")}-permissions">
|
||||
<h3 class="panel-title">${section_to_label.get(section, section)} - ${len(permissions[section])}
|
||||
<a class="permalink" href="#${section.replace("_","-")}-permissions"> ¶</a>
|
||||
</h3>
|
||||
% if side_link:
|
||||
<div class="pull-right">
|
||||
<a href="${side_link}">${_('in JSON format')}</a>
|
||||
|
|
@ -18,15 +27,24 @@
|
|||
<div class="panel-body">
|
||||
<div class="perms_section_head field">
|
||||
<div class="radios">
|
||||
%if section != 'global':
|
||||
% if section == 'repository_branches':
|
||||
<span class="permissions_boxes">
|
||||
<span class="desc">${_('show')}: </span>
|
||||
${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_%s' % section}"><span class="perm_tag none">${_('none')}</span></label>
|
||||
${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_%s' % section}"><span class="perm_tag read">${_('read')}</span></label>
|
||||
${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_%s' % section}"> <span class="perm_tag write">${_('write')}</span></label>
|
||||
${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>
|
||||
${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>
|
||||
${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>
|
||||
${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>
|
||||
${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>
|
||||
</span>
|
||||
%endif
|
||||
% elif section != 'global':
|
||||
<span class="permissions_boxes">
|
||||
<span class="desc">${_('show')}: </span>
|
||||
${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>
|
||||
${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>
|
||||
${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>
|
||||
${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>
|
||||
</span>
|
||||
% endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
|
|
@ -72,12 +90,10 @@
|
|||
%endif
|
||||
%else:
|
||||
%if not val_lbl:
|
||||
${
|
||||
{'false': False,
|
||||
${{'false': False,
|
||||
'true': True,
|
||||
'none': False,
|
||||
'repository': True}.get(val[1][0] if 0 < len(val[1]) else 'false')
|
||||
}
|
||||
'repository': True}.get(val[1][0] if 0 < len(val[1]) else 'false')}
|
||||
%else:
|
||||
<span class="perm_tag ${val[1][0]}">${val_lbl}.${val[1][0]}</span>
|
||||
%endif
|
||||
|
|
@ -142,7 +158,72 @@
|
|||
edit_url=h.route_path('user_edit_global_perms', user_id=c.user.user_id), edit_global_url=h.route_path('admin_permissions_object'))}
|
||||
|
||||
</tbody>
|
||||
## Branch perms
|
||||
%elif section == 'repository_branches':
|
||||
<thead>
|
||||
<tr>
|
||||
<th>${_('Name')}</th>
|
||||
<th>${_('Pattern')}</th>
|
||||
<th>${_('Permission')}</th>
|
||||
%if actions:
|
||||
<th>${_('Edit Branch Permission')}</th>
|
||||
%endif
|
||||
</thead>
|
||||
<tbody class="section_${section}">
|
||||
<%
|
||||
def name_sorter(permissions):
|
||||
def custom_sorter(item):
|
||||
return item[0]
|
||||
return sorted(permissions, key=custom_sorter)
|
||||
|
||||
def branch_sorter(permissions):
|
||||
def custom_sorter(item):
|
||||
## none, merge, push, push_force
|
||||
section = item[1].split('.')[-1]
|
||||
section_importance = {'none': u'0',
|
||||
'merge': u'1',
|
||||
'push': u'2',
|
||||
'push_force': u'3'}.get(section)
|
||||
## sort by importance + name
|
||||
return section_importance + item[0]
|
||||
return sorted(permissions, key=custom_sorter)
|
||||
%>
|
||||
%for k, section_perms in name_sorter(permissions[section].items()):
|
||||
% for pattern, perm in branch_sorter(section_perms.items()):
|
||||
<tr class="perm_row ${'{}_{}'.format(section, perm.split('.')[-1])}">
|
||||
<td class="td-name">
|
||||
<a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a>
|
||||
</td>
|
||||
<td>${pattern}</td>
|
||||
<td class="td-tags">
|
||||
## TODO: calculate origin somehow
|
||||
## % for i, ((_pat, perm), origin) in enumerate((permissions[section].perm_origin_stack[k])):
|
||||
|
||||
<div>
|
||||
<% i = 0 %>
|
||||
<% origin = 'unknown' %>
|
||||
<% _css_class = i > 0 and 'perm_overriden' or '' %>
|
||||
|
||||
<span class="${_css_class} perm_tag ${perm.split('.')[-1]}">
|
||||
${perm}
|
||||
##(${origin})
|
||||
</span>
|
||||
</div>
|
||||
## % endfor
|
||||
</td>
|
||||
%if actions:
|
||||
<td class="td-action">
|
||||
<a href="${h.route_path('edit_repo_perms_branch',repo_name=k)}">${_('edit')}</a>
|
||||
</td>
|
||||
%endif
|
||||
</tr>
|
||||
% endfor
|
||||
%endfor
|
||||
</tbody>
|
||||
|
||||
## Repos/Repo Groups/users groups perms
|
||||
%else:
|
||||
|
||||
## none/read/write/admin permissions on groups/repos etc
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
@ -167,8 +248,11 @@
|
|||
return sorted(permissions, key=custom_sorter)
|
||||
%>
|
||||
%for k, section_perm in sorter(permissions[section].items()):
|
||||
%if section_perm.split('.')[-1] != 'none' or show_all:
|
||||
<tr class="perm_row ${'%s_%s' % (section, section_perm.split('.')[-1])}">
|
||||
<% perm_value = section_perm.split('.')[-1] %>
|
||||
<% _css_class = 'display:none' if perm_value in ['none'] else '' %>
|
||||
|
||||
%if perm_value != 'none' or show_all:
|
||||
<tr class="perm_row ${'{}_{}'.format(section, section_perm.split('.')[-1])}" style="${_css_class}">
|
||||
<td class="td-name">
|
||||
%if section == 'repositories':
|
||||
<a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a>
|
||||
|
|
@ -183,7 +267,7 @@
|
|||
%if hasattr(permissions[section], 'perm_origin_stack'):
|
||||
<div>
|
||||
%for i, (perm, origin) in enumerate(reversed(permissions[section].perm_origin_stack[k])):
|
||||
|
||||
<% _css_class = i > 0 and 'perm_overriden' or '' %>
|
||||
% if i > 0:
|
||||
<div style="color: #979797">
|
||||
<i class="icon-arrow_up"></i>
|
||||
|
|
@ -193,7 +277,7 @@
|
|||
% endif
|
||||
|
||||
<div>
|
||||
<span class="${i > 0 and 'perm_overriden' or ''} perm_tag ${perm.split('.')[-1]}">
|
||||
<span class="${_css_class} perm_tag ${perm.split('.')[-1]}">
|
||||
${perm} (${origin})
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -220,7 +304,7 @@
|
|||
%endfor
|
||||
|
||||
<tr id="empty_${section}" class="noborder" style="display:none;">
|
||||
<td colspan="6">${_('No permission defined')}</td>
|
||||
<td colspan="6">${_('No matching permission defined')}</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
|
|
@ -236,15 +320,16 @@
|
|||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var show_empty = function(section){
|
||||
var showEmpty = function(section){
|
||||
var visible = $('.section_{0} tr.perm_row:visible'.format(section)).length;
|
||||
if(visible == 0){
|
||||
if(visible === 0){
|
||||
$('#empty_{0}'.format(section)).show();
|
||||
}
|
||||
else{
|
||||
$('#empty_{0}'.format(section)).hide();
|
||||
}
|
||||
};
|
||||
|
||||
$('.perm_filter').on('change', function(e){
|
||||
var self = this;
|
||||
var section = $(this).attr('section');
|
||||
|
|
@ -261,7 +346,7 @@
|
|||
$('.'+section+'_'+perm_type).hide();
|
||||
}
|
||||
});
|
||||
show_empty(section);
|
||||
showEmpty(section);
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -284,7 +284,7 @@
|
|||
|
||||
<%def name="user_group_name(user_group_name)">
|
||||
<div>
|
||||
<i class="icon-group" title="${_('User group')}"></i>
|
||||
<i class="icon-user-group" title="${_('User group')}"></i>
|
||||
${h.link_to_group(user_group_name)}
|
||||
</div>
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -534,7 +534,7 @@
|
|||
</tbody>
|
||||
</table>
|
||||
<div class="link" id="add_perm">
|
||||
Add new
|
||||
Add user/user group
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@
|
|||
<div class="panel-heading">${title}</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div tal:condition="errormsg"
|
||||
class="clearfix alert alert-danger">
|
||||
<p i18n:translate="">
|
||||
<div tal:condition="errormsg" class="clearfix alert alert-error">
|
||||
<span i18n:translate="">
|
||||
There was a problem with this section
|
||||
</p>
|
||||
<p>${errormsg}</p>
|
||||
</span>
|
||||
<div>${errormsg}</div>
|
||||
</div>
|
||||
|
||||
<div tal:condition="description">
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ class TestPermissions(object):
|
|||
assert repo_perms(user)[repo.repo_name] == 'repository.admin'
|
||||
repo.user = org_owner
|
||||
|
||||
def test_default_owner_branch_perms(self, user_util, test_user_group):
|
||||
user = user_util.create_user()
|
||||
assert branch_perms(user) == {}
|
||||
|
||||
def test_default_owner_repo_group_perms(self, user_util, test_repo_group):
|
||||
user = user_util.create_user()
|
||||
org_owner = test_repo_group.user
|
||||
|
|
@ -360,13 +364,15 @@ class TestPermissions(object):
|
|||
user_model.revoke_perm(self.u1, 'hg.fork.repository')
|
||||
user_model.grant_perm(self.u1, 'hg.fork.none')
|
||||
|
||||
# TODO(marcink): check branch permissions now ?
|
||||
|
||||
# make sure inherit flag is turned off
|
||||
self.u1.inherit_default_permissions = False
|
||||
Session().commit()
|
||||
|
||||
# this user will have non inherited permissions from he's
|
||||
# explicitly set permissions
|
||||
assert global_perms(self.u1) == set([
|
||||
assert global_perms(self.u1) == {
|
||||
'hg.create.none',
|
||||
'hg.fork.none',
|
||||
'hg.register.manual_activate',
|
||||
|
|
@ -375,7 +381,8 @@ class TestPermissions(object):
|
|||
'repository.read',
|
||||
'group.read',
|
||||
'usergroup.read',
|
||||
])
|
||||
'branch.push_force',
|
||||
}
|
||||
|
||||
def test_non_inherited_permissions_from_default_on_user_disabled(self):
|
||||
user_model = UserModel()
|
||||
|
|
@ -396,9 +403,11 @@ class TestPermissions(object):
|
|||
self.u1.inherit_default_permissions = False
|
||||
Session().commit()
|
||||
|
||||
# TODO(marcink): check branch perms
|
||||
|
||||
# this user will have non inherited permissions from he's
|
||||
# explicitly set permissions
|
||||
assert global_perms(self.u1) == set([
|
||||
assert global_perms(self.u1) == {
|
||||
'hg.create.repository',
|
||||
'hg.fork.repository',
|
||||
'hg.register.manual_activate',
|
||||
|
|
@ -407,7 +416,8 @@ class TestPermissions(object):
|
|||
'repository.read',
|
||||
'group.read',
|
||||
'usergroup.read',
|
||||
])
|
||||
'branch.push_force',
|
||||
}
|
||||
|
||||
@pytest.mark.parametrize('perm, expected_perm', [
|
||||
('hg.inherit_default_perms.false', 'repository.none', ),
|
||||
|
|
@ -425,8 +435,10 @@ class TestPermissions(object):
|
|||
self.u1.inherit_default_permissions = True
|
||||
Session().commit()
|
||||
|
||||
# TODO(marcink): check branch perms
|
||||
|
||||
# this user will have inherited permissions from default user
|
||||
assert global_perms(self.u1) == set([
|
||||
assert global_perms(self.u1) == {
|
||||
'hg.create.none',
|
||||
'hg.fork.none',
|
||||
'hg.register.manual_activate',
|
||||
|
|
@ -435,11 +447,12 @@ class TestPermissions(object):
|
|||
'repository.read',
|
||||
'group.read',
|
||||
'usergroup.read',
|
||||
'branch.push_force',
|
||||
'hg.create.write_on_repogroup.true',
|
||||
'hg.usergroup.create.false',
|
||||
'hg.repogroup.create.false',
|
||||
perm,
|
||||
])
|
||||
perm
|
||||
}
|
||||
|
||||
assert set(repo_perms(self.u1).values()) == set([expected_perm])
|
||||
|
||||
|
|
@ -693,6 +706,11 @@ def repo_perms(user):
|
|||
return auth_user.permissions['repositories']
|
||||
|
||||
|
||||
def branch_perms(user):
|
||||
auth_user = AuthUser(user_id=user.user_id)
|
||||
return auth_user.permissions['repository_branches']
|
||||
|
||||
|
||||
def group_perms(user):
|
||||
auth_user = AuthUser(user_id=user.user_id)
|
||||
return auth_user.permissions['repositories_groups']
|
||||
|
|
|
|||
|
|
@ -66,5 +66,5 @@ class TestTags(BackendTestMixin):
|
|||
def test_name_with_slash(self):
|
||||
self.repo.tag('19/10/11', 'joe')
|
||||
assert '19/10/11' in self.repo.tags
|
||||
self.repo.tag('11', 'joe')
|
||||
assert '11' in self.repo.tags
|
||||
self.repo.tag('rel.11', 'joe')
|
||||
assert 'rel.11' in self.repo.tags
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue