diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py
--- a/rhodecode/lib/auth.py
+++ b/rhodecode/lib/auth.py
@@ -571,8 +571,14 @@ class PermissionCalculator(object):
# on given user group
for perm in self.default_user_group_perms:
u_k = perm.UserUserGroupToPerm.user_group.users_group_name
- p = perm.Permission.permission_name
o = PermOrigin.USERGROUP_DEFAULT
+ if perm.UserGroup.user_id == self.user_id:
+ # set admin if owner
+ p = 'usergroup.admin'
+ o = PermOrigin.USERGROUP_OWNER
+ else:
+ p = perm.Permission.permission_name
+
# if we decide this user isn't inheriting permissions from default
# user we set him to .none so only explicit permissions work
if not user_inherit_object_permissions:
@@ -651,7 +657,7 @@ class PermissionCalculator(object):
multiple_counter[g_k] += 1
p = perm.Permission.permission_name
if perm.RepoGroup.user_id == self.user_id:
- # set admin if owner
+ # set admin if owner, even for member of other user group
p = 'group.admin'
o = PermOrigin.REPOGROUP_OWNER
else:
@@ -687,7 +693,7 @@ class PermissionCalculator(object):
# user group for user group permissions
user_group_from_user_group = Permission\
.get_default_user_group_perms_from_user_group(
- self.user_id, self.scope_repo_group_id)
+ self.user_id, self.scope_user_group_id)
multiple_counter = collections.defaultdict(int)
for perm in user_group_from_user_group:
@@ -698,9 +704,15 @@ class PermissionCalculator(object):
o = PermOrigin.USERGROUP_USERGROUP % u_k
multiple_counter[g_k] += 1
p = perm.Permission.permission_name
- if multiple_counter[g_k] > 1:
- cur_perm = self.permissions_user_groups[g_k]
- p = self._choose_permission(p, cur_perm)
+
+ if perm.UserGroup.user_id == self.user_id:
+ # set admin if owner, even for member of other user group
+ p = 'usergroup.admin'
+ o = PermOrigin.USERGROUP_OWNER
+ else:
+ if multiple_counter[g_k] > 1:
+ cur_perm = self.permissions_user_groups[g_k]
+ p = self._choose_permission(p, cur_perm)
self.permissions_user_groups[g_k] = p, o
# user explicit permission for user groups
@@ -709,12 +721,18 @@ class PermissionCalculator(object):
for perm in user_user_groups_perms:
ug_k = perm.UserUserGroupToPerm.user_group.users_group_name
u_k = perm.UserUserGroupToPerm.user.username
- p = perm.Permission.permission_name
o = PermOrigin.USERGROUP_USER % u_k
- if not self.explicit:
- cur_perm = self.permissions_user_groups.get(
- ug_k, 'usergroup.none')
- p = self._choose_permission(p, cur_perm)
+
+ if perm.UserGroup.user_id == self.user_id:
+ # set admin if owner
+ p = 'usergroup.admin'
+ o = PermOrigin.USERGROUP_OWNER
+ else:
+ p = perm.Permission.permission_name
+ if not self.explicit:
+ cur_perm = self.permissions_user_groups.get(
+ ug_k, 'usergroup.none')
+ p = self._choose_permission(p, cur_perm)
self.permissions_user_groups[ug_k] = p, o
def _choose_permission(self, new_perm, cur_perm):
@@ -942,25 +960,27 @@ class AuthUser(object):
"""
Returns list of repositories you're an admin of
"""
- return [x[0] for x in self.permissions['repositories'].iteritems()
- if x[1] == 'repository.admin']
+ return [
+ x[0] for x in self.permissions['repositories'].iteritems()
+ if x[1] == 'repository.admin']
@property
def repository_groups_admin(self):
"""
Returns list of repository groups you're an admin of
"""
- return [x[0]
- for x in self.permissions['repositories_groups'].iteritems()
- if x[1] == 'group.admin']
+ return [
+ x[0] for x in self.permissions['repositories_groups'].iteritems()
+ if x[1] == 'group.admin']
@property
def user_groups_admin(self):
"""
Returns list of user groups you're an admin of
"""
- return [x[0] for x in self.permissions['user_groups'].iteritems()
- if x[1] == 'usergroup.admin']
+ return [
+ x[0] for x in self.permissions['user_groups'].iteritems()
+ if x[1] == 'usergroup.admin']
@property
def ip_allowed(self):
diff --git a/rhodecode/templates/base/base.mako b/rhodecode/templates/base/base.mako
--- a/rhodecode/templates/base/base.mako
+++ b/rhodecode/templates/base/base.mako
@@ -142,13 +142,13 @@
<%def name="admin_menu_simple(repositories=None, repository_groups=None, user_groups=None)">
%def>
diff --git a/rhodecode/tests/functional/test_admin_repo_groups.py b/rhodecode/tests/functional/test_admin_repo_groups.py
--- a/rhodecode/tests/functional/test_admin_repo_groups.py
+++ b/rhodecode/tests/functional/test_admin_repo_groups.py
@@ -137,8 +137,7 @@ class _BaseTest(TestController):
assert new_repo_group.group_name == repo_group_name_unicode
assert new_repo_group.group_description == description
- #
- # # test if the repository is visible in the list ?
+ # test if the repository is visible in the list ?
response = self.app.get(
url('repo_group_home', group_name=repo_group_name))
response.mustcontain(repo_group_name)
diff --git a/rhodecode/tests/functional/test_delegated_admin.py b/rhodecode/tests/functional/test_delegated_admin.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/tests/functional/test_delegated_admin.py
@@ -0,0 +1,128 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2016-2017 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 .
+#
+# 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 pytest
+
+from rhodecode.tests import (
+ TestController, url, assert_session_flash, link_to)
+from rhodecode.model.db import User, UserGroup
+from rhodecode.model.meta import Session
+from rhodecode.tests.fixture import Fixture
+
+
+fixture = Fixture()
+
+
+class TestAdminUsersGroupsController(TestController):
+
+ def test_regular_user_cannot_see_admin_interfaces(self, user_util):
+ user = user_util.create_user(password='qweqwe')
+ self.log_user(user.username, 'qweqwe')
+
+ # check if in home view, such user doesn't see the "admin" menus
+ response = self.app.get(url('home'))
+
+ assert_response = response.assert_response()
+
+ assert_response.no_element_exists('li.local-admin-repos')
+ assert_response.no_element_exists('li.local-admin-repo-groups')
+ assert_response.no_element_exists('li.local-admin-user-groups')
+
+ response = self.app.get(url('repos'), status=200)
+ response.mustcontain('data: []')
+
+ response = self.app.get(url('repo_groups'), status=200)
+ response.mustcontain('data: []')
+
+ response = self.app.get(url('users_groups'), status=200)
+ response.mustcontain('data: []')
+
+ def test_regular_user_can_see_admin_interfaces_if_owner(self, user_util):
+ user = user_util.create_user(password='qweqwe')
+ username = user.username
+
+ repo = user_util.create_repo(owner=username)
+ repo_name = repo.repo_name
+
+ repo_group = user_util.create_repo_group(owner=username)
+ repo_group_name = repo_group.group_name
+
+ user_group = user_util.create_user_group(owner=username)
+ user_group_name = user_group.users_group_name
+
+ self.log_user(username, 'qweqwe')
+ # check if in home view, such user doesn't see the "admin" menus
+ response = self.app.get(url('home'))
+
+ assert_response = response.assert_response()
+
+ assert_response.one_element_exists('li.local-admin-repos')
+ assert_response.one_element_exists('li.local-admin-repo-groups')
+ assert_response.one_element_exists('li.local-admin-user-groups')
+
+ # admin interfaces have visible elements
+ response = self.app.get(url('repos'), status=200)
+ response.mustcontain('"name_raw": "{}"'.format(repo_name))
+
+ response = self.app.get(url('repo_groups'), status=200)
+ response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
+
+ response = self.app.get(url('users_groups'), status=200)
+ response.mustcontain('"group_name_raw": "{}"'.format(user_group_name))
+
+ def test_regular_user_can_see_admin_interfaces_if_admin_perm(self, user_util):
+ user = user_util.create_user(password='qweqwe')
+ username = user.username
+
+ repo = user_util.create_repo()
+ repo_name = repo.repo_name
+
+ repo_group = user_util.create_repo_group()
+ repo_group_name = repo_group.group_name
+
+ user_group = user_util.create_user_group()
+ user_group_name = user_group.users_group_name
+
+ user_util.grant_user_permission_to_repo(
+ repo, user, 'repository.admin')
+ user_util.grant_user_permission_to_repo_group(
+ repo_group, user, 'group.admin')
+ user_util.grant_user_permission_to_user_group(
+ user_group, user, 'usergroup.admin')
+
+ self.log_user(username, 'qweqwe')
+ # check if in home view, such user doesn't see the "admin" menus
+ response = self.app.get(url('home'))
+
+ assert_response = response.assert_response()
+
+ assert_response.one_element_exists('li.local-admin-repos')
+ assert_response.one_element_exists('li.local-admin-repo-groups')
+ assert_response.one_element_exists('li.local-admin-user-groups')
+
+ # admin interfaces have visible elements
+ response = self.app.get(url('repos'), status=200)
+ response.mustcontain('"name_raw": "{}"'.format(repo_name))
+
+ response = self.app.get(url('repo_groups'), status=200)
+ response.mustcontain('"name_raw": "{}"'.format(repo_group_name))
+
+ response = self.app.get(url('users_groups'), status=200)
+ response.mustcontain('"group_name_raw": "{}"'.format(user_group_name))
diff --git a/rhodecode/tests/models/test_permissions.py b/rhodecode/tests/models/test_permissions.py
--- a/rhodecode/tests/models/test_permissions.py
+++ b/rhodecode/tests/models/test_permissions.py
@@ -130,14 +130,36 @@ class TestPermissions(object):
assert group_perms(self.a1) == {
'test1': 'group.admin', 'test2': 'group.admin'}
- def test_default_owner_group_perms(self):
- # "u1" shall be owner without any special permission assigned
- self.g1 = fixture.create_repo_group('test1')
- assert group_perms(self.u1) == {'test1': 'group.read'}
+ def test_default_owner_repo_perms(self, backend, user_util, test_repo):
+ user = user_util.create_user()
+ repo = test_repo('minimal', backend.alias)
+ org_owner = repo.user
+ assert repo_perms(user)[repo.repo_name] == 'repository.read'
+
+ repo.user = user
+ assert repo_perms(user)[repo.repo_name] == 'repository.admin'
+ repo.user = org_owner
+
+ def test_default_owner_repo_group_perms(self, user_util, test_repo_group):
+ user = user_util.create_user()
+ org_owner = test_repo_group.user
- # Make him owner, but do not add any special permissions
- self.g1.user = self.u1
- assert group_perms(self.u1) == {'test1': 'group.admin'}
+ assert group_perms(user)[test_repo_group.group_name] == 'group.read'
+
+ test_repo_group.user = user
+ assert group_perms(user)[test_repo_group.group_name] == 'group.admin'
+ test_repo_group.user = org_owner
+
+ def test_default_owner_user_group_perms(self, user_util, test_user_group):
+ user = user_util.create_user()
+ org_owner = test_user_group.user
+
+ assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.read'
+
+ test_user_group.user = user
+ assert user_group_perms(user)[test_user_group.users_group_name] == 'usergroup.admin'
+
+ test_user_group.user = org_owner
def test_propagated_permission_from_users_group_by_explicit_perms_exist(
self, repo_name):