##// END OF EJS Templates
api: enable setting sync flag for user groups on create/edit.
marcink -
r2660:499461c1 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,110 +1,125 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2018 RhodeCode GmbH
3 # Copyright (C) 2010-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import mock
21 import mock
22 import pytest
22 import pytest
23
23
24 from rhodecode.model.user import UserModel
24 from rhodecode.model.user import UserModel
25 from rhodecode.model.user_group import UserGroupModel
25 from rhodecode.model.user_group import UserGroupModel
26 from rhodecode.tests import TEST_USER_ADMIN_EMAIL
26 from rhodecode.tests import TEST_USER_ADMIN_EMAIL
27 from rhodecode.api.tests.utils import (
27 from rhodecode.api.tests.utils import (
28 build_data, api_call, assert_error, assert_ok, crash, jsonify)
28 build_data, api_call, assert_error, assert_ok, crash, jsonify)
29
29
30
30
31 @pytest.mark.usefixtures("testuser_api", "app")
31 @pytest.mark.usefixtures("testuser_api", "app")
32 class TestUpdateUserGroup(object):
32 class TestUpdateUserGroup(object):
33 @pytest.mark.parametrize("changing_attr, updates", [
33 @pytest.mark.parametrize("changing_attr, updates", [
34 ('group_name', {'group_name': 'new_group_name'}),
34 ('group_name', {'group_name': 'new_group_name'}),
35 ('group_name', {'group_name': 'test_group_for_update'}),
35 ('group_name', {'group_name': 'test_group_for_update'}),
36 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
36 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
37 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
37 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
38 ('active', {'active': False}),
38 ('active', {'active': False}),
39 ('active', {'active': True})
39 ('active', {'active': True}),
40 ('sync', {'sync': False}),
41 ('sync', {'sync': True})
40 ])
42 ])
41 def test_api_update_user_group(self, changing_attr, updates, user_util):
43 def test_api_update_user_group(self, changing_attr, updates, user_util):
42 user_group = user_util.create_user_group()
44 user_group = user_util.create_user_group()
43 group_name = user_group.users_group_name
45 group_name = user_group.users_group_name
44 expected_api_data = user_group.get_api_data()
46 expected_api_data = user_group.get_api_data()
45 expected_api_data.update(updates)
47 expected_api_data.update(updates)
46
48
47 id_, params = build_data(
49 id_, params = build_data(
48 self.apikey, 'update_user_group', usergroupid=group_name,
50 self.apikey, 'update_user_group', usergroupid=group_name,
49 **updates)
51 **updates)
50 response = api_call(self.app, params)
52 response = api_call(self.app, params)
51
53
54 # special case for sync
55 if changing_attr == 'sync' and updates['sync'] is False:
56 expected_api_data['sync'] = None
57 elif changing_attr == 'sync' and updates['sync'] is True:
58 expected_api_data['sync'] = 'manual_api'
59
52 expected = {
60 expected = {
53 'msg': 'updated user group ID:%s %s' % (
61 'msg': 'updated user group ID:%s %s' % (
54 user_group.users_group_id, user_group.users_group_name),
62 user_group.users_group_id, user_group.users_group_name),
55 'user_group': jsonify(expected_api_data)
63 'user_group': jsonify(expected_api_data)
56 }
64 }
57 assert_ok(id_, expected, given=response.body)
65 assert_ok(id_, expected, given=response.body)
58
66
59 @pytest.mark.parametrize("changing_attr, updates", [
67 @pytest.mark.parametrize("changing_attr, updates", [
60 # TODO: mikhail: decide if we need to test against the commented params
68 # TODO: mikhail: decide if we need to test against the commented params
61 # ('group_name', {'group_name': 'new_group_name'}),
69 # ('group_name', {'group_name': 'new_group_name'}),
62 # ('group_name', {'group_name': 'test_group_for_update'}),
70 # ('group_name', {'group_name': 'test_group_for_update'}),
63 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
71 # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}),
64 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
72 ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}),
65 ('active', {'active': False}),
73 ('active', {'active': False}),
66 ('active', {'active': True})
74 ('active', {'active': True}),
75 ('sync', {'sync': False}),
76 ('sync', {'sync': True})
67 ])
77 ])
68 def test_api_update_user_group_regular_user(
78 def test_api_update_user_group_regular_user(
69 self, changing_attr, updates, user_util):
79 self, changing_attr, updates, user_util):
70 user_group = user_util.create_user_group()
80 user_group = user_util.create_user_group()
71 group_name = user_group.users_group_name
81 group_name = user_group.users_group_name
72 expected_api_data = user_group.get_api_data()
82 expected_api_data = user_group.get_api_data()
73 expected_api_data.update(updates)
83 expected_api_data.update(updates)
74
84
75
76 # grant permission to this user
85 # grant permission to this user
77 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
86 user = UserModel().get_by_username(self.TEST_USER_LOGIN)
78
87
79 user_util.grant_user_permission_to_user_group(
88 user_util.grant_user_permission_to_user_group(
80 user_group, user, 'usergroup.admin')
89 user_group, user, 'usergroup.admin')
81 id_, params = build_data(
90 id_, params = build_data(
82 self.apikey_regular, 'update_user_group',
91 self.apikey_regular, 'update_user_group',
83 usergroupid=group_name, **updates)
92 usergroupid=group_name, **updates)
84 response = api_call(self.app, params)
93 response = api_call(self.app, params)
94 # special case for sync
95 if changing_attr == 'sync' and updates['sync'] is False:
96 expected_api_data['sync'] = None
97 elif changing_attr == 'sync' and updates['sync'] is True:
98 expected_api_data['sync'] = 'manual_api'
99
85 expected = {
100 expected = {
86 'msg': 'updated user group ID:%s %s' % (
101 'msg': 'updated user group ID:%s %s' % (
87 user_group.users_group_id, user_group.users_group_name),
102 user_group.users_group_id, user_group.users_group_name),
88 'user_group': jsonify(expected_api_data)
103 'user_group': jsonify(expected_api_data)
89 }
104 }
90 assert_ok(id_, expected, given=response.body)
105 assert_ok(id_, expected, given=response.body)
91
106
92 def test_api_update_user_group_regular_user_no_permission(self, user_util):
107 def test_api_update_user_group_regular_user_no_permission(self, user_util):
93 user_group = user_util.create_user_group()
108 user_group = user_util.create_user_group()
94 group_name = user_group.users_group_name
109 group_name = user_group.users_group_name
95 id_, params = build_data(
110 id_, params = build_data(
96 self.apikey_regular, 'update_user_group', usergroupid=group_name)
111 self.apikey_regular, 'update_user_group', usergroupid=group_name)
97 response = api_call(self.app, params)
112 response = api_call(self.app, params)
98
113
99 expected = 'user group `%s` does not exist' % (group_name)
114 expected = 'user group `%s` does not exist' % (group_name)
100 assert_error(id_, expected, given=response.body)
115 assert_error(id_, expected, given=response.body)
101
116
102 @mock.patch.object(UserGroupModel, 'update', crash)
117 @mock.patch.object(UserGroupModel, 'update', crash)
103 def test_api_update_user_group_exception_occurred(self, user_util):
118 def test_api_update_user_group_exception_occurred(self, user_util):
104 user_group = user_util.create_user_group()
119 user_group = user_util.create_user_group()
105 group_name = user_group.users_group_name
120 group_name = user_group.users_group_name
106 id_, params = build_data(
121 id_, params = build_data(
107 self.apikey, 'update_user_group', usergroupid=group_name)
122 self.apikey, 'update_user_group', usergroupid=group_name)
108 response = api_call(self.app, params)
123 response = api_call(self.app, params)
109 expected = 'failed to update user group `%s`' % (group_name,)
124 expected = 'failed to update user group `%s`' % (group_name,)
110 assert_error(id_, expected, given=response.body)
125 assert_error(id_, expected, given=response.body)
@@ -1,829 +1,858 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2018 RhodeCode GmbH
3 # Copyright (C) 2011-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 from rhodecode.api import (
23 from rhodecode.api import (
24 jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError)
24 jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError)
25 from rhodecode.api.utils import (
25 from rhodecode.api.utils import (
26 Optional, OAttr, store_update, has_superadmin_permission, get_origin,
26 Optional, OAttr, store_update, has_superadmin_permission, get_origin,
27 get_user_or_error, get_user_group_or_error, get_perm_or_error)
27 get_user_or_error, get_user_group_or_error, get_perm_or_error)
28 from rhodecode.lib import audit_logger
28 from rhodecode.lib import audit_logger
29 from rhodecode.lib.auth import HasUserGroupPermissionAnyApi, HasPermissionAnyApi
29 from rhodecode.lib.auth import HasUserGroupPermissionAnyApi, HasPermissionAnyApi
30 from rhodecode.lib.exceptions import UserGroupAssignedException
30 from rhodecode.lib.exceptions import UserGroupAssignedException
31 from rhodecode.model.db import Session
31 from rhodecode.model.db import Session
32 from rhodecode.model.scm import UserGroupList
32 from rhodecode.model.scm import UserGroupList
33 from rhodecode.model.user_group import UserGroupModel
33 from rhodecode.model.user_group import UserGroupModel
34 from rhodecode.model import validation_schema
34 from rhodecode.model import validation_schema
35 from rhodecode.model.validation_schema.schemas import user_group_schema
35 from rhodecode.model.validation_schema.schemas import user_group_schema
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 @jsonrpc_method()
40 @jsonrpc_method()
41 def get_user_group(request, apiuser, usergroupid):
41 def get_user_group(request, apiuser, usergroupid):
42 """
42 """
43 Returns the data of an existing user group.
43 Returns the data of an existing user group.
44
44
45 This command can only be run using an |authtoken| with admin rights to
45 This command can only be run using an |authtoken| with admin rights to
46 the specified repository.
46 the specified repository.
47
47
48 :param apiuser: This is filled automatically from the |authtoken|.
48 :param apiuser: This is filled automatically from the |authtoken|.
49 :type apiuser: AuthUser
49 :type apiuser: AuthUser
50 :param usergroupid: Set the user group from which to return data.
50 :param usergroupid: Set the user group from which to return data.
51 :type usergroupid: str or int
51 :type usergroupid: str or int
52
52
53 Example error output:
53 Example error output:
54
54
55 .. code-block:: bash
55 .. code-block:: bash
56
56
57 {
57 {
58 "error": null,
58 "error": null,
59 "id": <id>,
59 "id": <id>,
60 "result": {
60 "result": {
61 "active": true,
61 "active": true,
62 "group_description": "group description",
62 "group_description": "group description",
63 "group_name": "group name",
63 "group_name": "group name",
64 "permissions": [
64 "permissions": [
65 {
65 {
66 "name": "owner-name",
66 "name": "owner-name",
67 "origin": "owner",
67 "origin": "owner",
68 "permission": "usergroup.admin",
68 "permission": "usergroup.admin",
69 "type": "user"
69 "type": "user"
70 },
70 },
71 {
71 {
72 {
72 {
73 "name": "user name",
73 "name": "user name",
74 "origin": "permission",
74 "origin": "permission",
75 "permission": "usergroup.admin",
75 "permission": "usergroup.admin",
76 "type": "user"
76 "type": "user"
77 },
77 },
78 {
78 {
79 "name": "user group name",
79 "name": "user group name",
80 "origin": "permission",
80 "origin": "permission",
81 "permission": "usergroup.write",
81 "permission": "usergroup.write",
82 "type": "user_group"
82 "type": "user_group"
83 }
83 }
84 ],
84 ],
85 "permissions_summary": {
85 "permissions_summary": {
86 "repositories": {
86 "repositories": {
87 "aa-root-level-repo-1": "repository.admin"
87 "aa-root-level-repo-1": "repository.admin"
88 },
88 },
89 "repositories_groups": {}
89 "repositories_groups": {}
90 },
90 },
91 "owner": "owner name",
91 "owner": "owner name",
92 "users": [],
92 "users": [],
93 "users_group_id": 2
93 "users_group_id": 2
94 }
94 }
95 }
95 }
96
96
97 """
97 """
98
98
99 user_group = get_user_group_or_error(usergroupid)
99 user_group = get_user_group_or_error(usergroupid)
100 if not has_superadmin_permission(apiuser):
100 if not has_superadmin_permission(apiuser):
101 # check if we have at least read permission for this user group !
101 # check if we have at least read permission for this user group !
102 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
102 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
103 if not HasUserGroupPermissionAnyApi(*_perms)(
103 if not HasUserGroupPermissionAnyApi(*_perms)(
104 user=apiuser, user_group_name=user_group.users_group_name):
104 user=apiuser, user_group_name=user_group.users_group_name):
105 raise JSONRPCError('user group `%s` does not exist' % (
105 raise JSONRPCError('user group `%s` does not exist' % (
106 usergroupid,))
106 usergroupid,))
107
107
108 permissions = []
108 permissions = []
109 for _user in user_group.permissions():
109 for _user in user_group.permissions():
110 user_data = {
110 user_data = {
111 'name': _user.username,
111 'name': _user.username,
112 'permission': _user.permission,
112 'permission': _user.permission,
113 'origin': get_origin(_user),
113 'origin': get_origin(_user),
114 'type': "user",
114 'type': "user",
115 }
115 }
116 permissions.append(user_data)
116 permissions.append(user_data)
117
117
118 for _user_group in user_group.permission_user_groups():
118 for _user_group in user_group.permission_user_groups():
119 user_group_data = {
119 user_group_data = {
120 'name': _user_group.users_group_name,
120 'name': _user_group.users_group_name,
121 'permission': _user_group.permission,
121 'permission': _user_group.permission,
122 'origin': get_origin(_user_group),
122 'origin': get_origin(_user_group),
123 'type': "user_group",
123 'type': "user_group",
124 }
124 }
125 permissions.append(user_group_data)
125 permissions.append(user_group_data)
126
126
127 data = user_group.get_api_data()
127 data = user_group.get_api_data()
128 data["permissions"] = permissions
128 data["permissions"] = permissions
129 data["permissions_summary"] = UserGroupModel().get_perms_summary(
129 data["permissions_summary"] = UserGroupModel().get_perms_summary(
130 user_group.users_group_id)
130 user_group.users_group_id)
131 return data
131 return data
132
132
133
133
134 @jsonrpc_method()
134 @jsonrpc_method()
135 def get_user_groups(request, apiuser):
135 def get_user_groups(request, apiuser):
136 """
136 """
137 Lists all the existing user groups within RhodeCode.
137 Lists all the existing user groups within RhodeCode.
138
138
139 This command can only be run using an |authtoken| with admin rights to
139 This command can only be run using an |authtoken| with admin rights to
140 the specified repository.
140 the specified repository.
141
141
142 This command takes the following options:
142 This command takes the following options:
143
143
144 :param apiuser: This is filled automatically from the |authtoken|.
144 :param apiuser: This is filled automatically from the |authtoken|.
145 :type apiuser: AuthUser
145 :type apiuser: AuthUser
146
146
147 Example error output:
147 Example error output:
148
148
149 .. code-block:: bash
149 .. code-block:: bash
150
150
151 id : <id_given_in_input>
151 id : <id_given_in_input>
152 result : [<user_group_obj>,...]
152 result : [<user_group_obj>,...]
153 error : null
153 error : null
154 """
154 """
155
155
156 include_secrets = has_superadmin_permission(apiuser)
156 include_secrets = has_superadmin_permission(apiuser)
157
157
158 result = []
158 result = []
159 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
159 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
160 extras = {'user': apiuser}
160 extras = {'user': apiuser}
161 for user_group in UserGroupList(UserGroupModel().get_all(),
161 for user_group in UserGroupList(UserGroupModel().get_all(),
162 perm_set=_perms, extra_kwargs=extras):
162 perm_set=_perms, extra_kwargs=extras):
163 result.append(
163 result.append(
164 user_group.get_api_data(include_secrets=include_secrets))
164 user_group.get_api_data(include_secrets=include_secrets))
165 return result
165 return result
166
166
167
167
168 @jsonrpc_method()
168 @jsonrpc_method()
169 def create_user_group(
169 def create_user_group(
170 request, apiuser, group_name, description=Optional(''),
170 request, apiuser, group_name, description=Optional(''),
171 owner=Optional(OAttr('apiuser')), active=Optional(True)):
171 owner=Optional(OAttr('apiuser')), active=Optional(True),
172 sync=Optional(None)):
172 """
173 """
173 Creates a new user group.
174 Creates a new user group.
174
175
175 This command can only be run using an |authtoken| with admin rights to
176 This command can only be run using an |authtoken| with admin rights to
176 the specified repository.
177 the specified repository.
177
178
178 This command takes the following options:
179 This command takes the following options:
179
180
180 :param apiuser: This is filled automatically from the |authtoken|.
181 :param apiuser: This is filled automatically from the |authtoken|.
181 :type apiuser: AuthUser
182 :type apiuser: AuthUser
182 :param group_name: Set the name of the new user group.
183 :param group_name: Set the name of the new user group.
183 :type group_name: str
184 :type group_name: str
184 :param description: Give a description of the new user group.
185 :param description: Give a description of the new user group.
185 :type description: str
186 :type description: str
186 :param owner: Set the owner of the new user group.
187 :param owner: Set the owner of the new user group.
187 If not set, the owner is the |authtoken| user.
188 If not set, the owner is the |authtoken| user.
188 :type owner: Optional(str or int)
189 :type owner: Optional(str or int)
189 :param active: Set this group as active.
190 :param active: Set this group as active.
190 :type active: Optional(``True`` | ``False``)
191 :type active: Optional(``True`` | ``False``)
192 :param sync: Set enabled or disabled the automatically sync from
193 external authentication types like ldap.
194 :type sync: Optional(``True`` | ``False``)
191
195
192 Example output:
196 Example output:
193
197
194 .. code-block:: bash
198 .. code-block:: bash
195
199
196 id : <id_given_in_input>
200 id : <id_given_in_input>
197 result: {
201 result: {
198 "msg": "created new user group `<groupname>`",
202 "msg": "created new user group `<groupname>`",
199 "user_group": <user_group_object>
203 "user_group": <user_group_object>
200 }
204 }
201 error: null
205 error: null
202
206
203 Example error output:
207 Example error output:
204
208
205 .. code-block:: bash
209 .. code-block:: bash
206
210
207 id : <id_given_in_input>
211 id : <id_given_in_input>
208 result : null
212 result : null
209 error : {
213 error : {
210 "user group `<group name>` already exist"
214 "user group `<group name>` already exist"
211 or
215 or
212 "failed to create group `<group name>`"
216 "failed to create group `<group name>`"
213 }
217 }
214
218
215 """
219 """
216
220
217 if not has_superadmin_permission(apiuser):
221 if not has_superadmin_permission(apiuser):
218 if not HasPermissionAnyApi('hg.usergroup.create.true')(user=apiuser):
222 if not HasPermissionAnyApi('hg.usergroup.create.true')(user=apiuser):
219 raise JSONRPCForbidden()
223 raise JSONRPCForbidden()
220
224
221 if UserGroupModel().get_by_name(group_name):
225 if UserGroupModel().get_by_name(group_name):
222 raise JSONRPCError("user group `%s` already exist" % (group_name,))
226 raise JSONRPCError("user group `%s` already exist" % (group_name,))
223
227
224 if isinstance(owner, Optional):
228 if isinstance(owner, Optional):
225 owner = apiuser.user_id
229 owner = apiuser.user_id
226
230
227 owner = get_user_or_error(owner)
231 owner = get_user_or_error(owner)
228 active = Optional.extract(active)
232 active = Optional.extract(active)
229 description = Optional.extract(description)
233 description = Optional.extract(description)
234 sync = Optional.extract(sync)
235
236 # set the sync option based on group_data
237 group_data = None
238 if sync:
239 group_data = {
240 'extern_type': 'manual_api',
241 'extern_type_set_by': apiuser.username
242 }
230
243
231 schema = user_group_schema.UserGroupSchema().bind(
244 schema = user_group_schema.UserGroupSchema().bind(
232 # user caller
245 # user caller
233 user=apiuser)
246 user=apiuser)
234 try:
247 try:
235 schema_data = schema.deserialize(dict(
248 schema_data = schema.deserialize(dict(
236 user_group_name=group_name,
249 user_group_name=group_name,
237 user_group_description=description,
250 user_group_description=description,
238 user_group_owner=owner.username,
251 user_group_owner=owner.username,
239 user_group_active=active,
252 user_group_active=active,
240 ))
253 ))
241 except validation_schema.Invalid as err:
254 except validation_schema.Invalid as err:
242 raise JSONRPCValidationError(colander_exc=err)
255 raise JSONRPCValidationError(colander_exc=err)
243
256
244 try:
257 try:
245 user_group = UserGroupModel().create(
258 user_group = UserGroupModel().create(
246 name=schema_data['user_group_name'],
259 name=schema_data['user_group_name'],
247 description=schema_data['user_group_description'],
260 description=schema_data['user_group_description'],
248 owner=owner,
261 owner=owner,
249 active=schema_data['user_group_active'])
262 active=schema_data['user_group_active'], group_data=group_data)
250 Session().flush()
263 Session().flush()
251 creation_data = user_group.get_api_data()
264 creation_data = user_group.get_api_data()
252 audit_logger.store_api(
265 audit_logger.store_api(
253 'user_group.create', action_data={'data': creation_data},
266 'user_group.create', action_data={'data': creation_data},
254 user=apiuser)
267 user=apiuser)
255 Session().commit()
268 Session().commit()
256 return {
269 return {
257 'msg': 'created new user group `%s`' % group_name,
270 'msg': 'created new user group `%s`' % group_name,
258 'user_group': creation_data
271 'user_group': creation_data
259 }
272 }
260 except Exception:
273 except Exception:
261 log.exception("Error occurred during creation of user group")
274 log.exception("Error occurred during creation of user group")
262 raise JSONRPCError('failed to create group `%s`' % (group_name,))
275 raise JSONRPCError('failed to create group `%s`' % (group_name,))
263
276
264
277
265 @jsonrpc_method()
278 @jsonrpc_method()
266 def update_user_group(request, apiuser, usergroupid, group_name=Optional(''),
279 def update_user_group(request, apiuser, usergroupid, group_name=Optional(''),
267 description=Optional(''), owner=Optional(None),
280 description=Optional(''), owner=Optional(None),
268 active=Optional(True)):
281 active=Optional(True), sync=Optional(None)):
269 """
282 """
270 Updates the specified `user group` with the details provided.
283 Updates the specified `user group` with the details provided.
271
284
272 This command can only be run using an |authtoken| with admin rights to
285 This command can only be run using an |authtoken| with admin rights to
273 the specified repository.
286 the specified repository.
274
287
275 :param apiuser: This is filled automatically from the |authtoken|.
288 :param apiuser: This is filled automatically from the |authtoken|.
276 :type apiuser: AuthUser
289 :type apiuser: AuthUser
277 :param usergroupid: Set the id of the `user group` to update.
290 :param usergroupid: Set the id of the `user group` to update.
278 :type usergroupid: str or int
291 :type usergroupid: str or int
279 :param group_name: Set the new name the `user group`
292 :param group_name: Set the new name the `user group`
280 :type group_name: str
293 :type group_name: str
281 :param description: Give a description for the `user group`
294 :param description: Give a description for the `user group`
282 :type description: str
295 :type description: str
283 :param owner: Set the owner of the `user group`.
296 :param owner: Set the owner of the `user group`.
284 :type owner: Optional(str or int)
297 :type owner: Optional(str or int)
285 :param active: Set the group as active.
298 :param active: Set the group as active.
286 :type active: Optional(``True`` | ``False``)
299 :type active: Optional(``True`` | ``False``)
300 :param sync: Set enabled or disabled the automatically sync from
301 external authentication types like ldap.
302 :type sync: Optional(``True`` | ``False``)
287
303
288 Example output:
304 Example output:
289
305
290 .. code-block:: bash
306 .. code-block:: bash
291
307
292 id : <id_given_in_input>
308 id : <id_given_in_input>
293 result : {
309 result : {
294 "msg": 'updated user group ID:<user group id> <user group name>',
310 "msg": 'updated user group ID:<user group id> <user group name>',
295 "user_group": <user_group_object>
311 "user_group": <user_group_object>
296 }
312 }
297 error : null
313 error : null
298
314
299 Example error output:
315 Example error output:
300
316
301 .. code-block:: bash
317 .. code-block:: bash
302
318
303 id : <id_given_in_input>
319 id : <id_given_in_input>
304 result : null
320 result : null
305 error : {
321 error : {
306 "failed to update user group `<user group name>`"
322 "failed to update user group `<user group name>`"
307 }
323 }
308
324
309 """
325 """
310
326
311 user_group = get_user_group_or_error(usergroupid)
327 user_group = get_user_group_or_error(usergroupid)
312 include_secrets = False
328 include_secrets = False
313 if not has_superadmin_permission(apiuser):
329 if not has_superadmin_permission(apiuser):
314 # check if we have admin permission for this user group !
330 # check if we have admin permission for this user group !
315 _perms = ('usergroup.admin',)
331 _perms = ('usergroup.admin',)
316 if not HasUserGroupPermissionAnyApi(*_perms)(
332 if not HasUserGroupPermissionAnyApi(*_perms)(
317 user=apiuser, user_group_name=user_group.users_group_name):
333 user=apiuser, user_group_name=user_group.users_group_name):
318 raise JSONRPCError(
334 raise JSONRPCError(
319 'user group `%s` does not exist' % (usergroupid,))
335 'user group `%s` does not exist' % (usergroupid,))
320 else:
336 else:
321 include_secrets = True
337 include_secrets = True
322
338
323 if not isinstance(owner, Optional):
339 if not isinstance(owner, Optional):
324 owner = get_user_or_error(owner)
340 owner = get_user_or_error(owner)
325
341
326 old_data = user_group.get_api_data()
342 old_data = user_group.get_api_data()
327 updates = {}
343 updates = {}
328 store_update(updates, group_name, 'users_group_name')
344 store_update(updates, group_name, 'users_group_name')
329 store_update(updates, description, 'user_group_description')
345 store_update(updates, description, 'user_group_description')
330 store_update(updates, owner, 'user')
346 store_update(updates, owner, 'user')
331 store_update(updates, active, 'users_group_active')
347 store_update(updates, active, 'users_group_active')
348
349 sync = Optional.extract(sync)
350 group_data = None
351 if sync is True:
352 group_data = {
353 'extern_type': 'manual_api',
354 'extern_type_set_by': apiuser.username
355 }
356 if sync is False:
357 group_data = user_group.group_data
358 if group_data and "extern_type" in group_data:
359 del group_data["extern_type"]
360
332 try:
361 try:
333 UserGroupModel().update(user_group, updates)
362 UserGroupModel().update(user_group, updates, group_data=group_data)
334 audit_logger.store_api(
363 audit_logger.store_api(
335 'user_group.edit', action_data={'old_data': old_data},
364 'user_group.edit', action_data={'old_data': old_data},
336 user=apiuser)
365 user=apiuser)
337 Session().commit()
366 Session().commit()
338 return {
367 return {
339 'msg': 'updated user group ID:%s %s' % (
368 'msg': 'updated user group ID:%s %s' % (
340 user_group.users_group_id, user_group.users_group_name),
369 user_group.users_group_id, user_group.users_group_name),
341 'user_group': user_group.get_api_data(
370 'user_group': user_group.get_api_data(
342 include_secrets=include_secrets)
371 include_secrets=include_secrets)
343 }
372 }
344 except Exception:
373 except Exception:
345 log.exception("Error occurred during update of user group")
374 log.exception("Error occurred during update of user group")
346 raise JSONRPCError(
375 raise JSONRPCError(
347 'failed to update user group `%s`' % (usergroupid,))
376 'failed to update user group `%s`' % (usergroupid,))
348
377
349
378
350 @jsonrpc_method()
379 @jsonrpc_method()
351 def delete_user_group(request, apiuser, usergroupid):
380 def delete_user_group(request, apiuser, usergroupid):
352 """
381 """
353 Deletes the specified `user group`.
382 Deletes the specified `user group`.
354
383
355 This command can only be run using an |authtoken| with admin rights to
384 This command can only be run using an |authtoken| with admin rights to
356 the specified repository.
385 the specified repository.
357
386
358 This command takes the following options:
387 This command takes the following options:
359
388
360 :param apiuser: filled automatically from apikey
389 :param apiuser: filled automatically from apikey
361 :type apiuser: AuthUser
390 :type apiuser: AuthUser
362 :param usergroupid:
391 :param usergroupid:
363 :type usergroupid: int
392 :type usergroupid: int
364
393
365 Example output:
394 Example output:
366
395
367 .. code-block:: bash
396 .. code-block:: bash
368
397
369 id : <id_given_in_input>
398 id : <id_given_in_input>
370 result : {
399 result : {
371 "msg": "deleted user group ID:<user_group_id> <user_group_name>"
400 "msg": "deleted user group ID:<user_group_id> <user_group_name>"
372 }
401 }
373 error : null
402 error : null
374
403
375 Example error output:
404 Example error output:
376
405
377 .. code-block:: bash
406 .. code-block:: bash
378
407
379 id : <id_given_in_input>
408 id : <id_given_in_input>
380 result : null
409 result : null
381 error : {
410 error : {
382 "failed to delete user group ID:<user_group_id> <user_group_name>"
411 "failed to delete user group ID:<user_group_id> <user_group_name>"
383 or
412 or
384 "RepoGroup assigned to <repo_groups_list>"
413 "RepoGroup assigned to <repo_groups_list>"
385 }
414 }
386
415
387 """
416 """
388
417
389 user_group = get_user_group_or_error(usergroupid)
418 user_group = get_user_group_or_error(usergroupid)
390 if not has_superadmin_permission(apiuser):
419 if not has_superadmin_permission(apiuser):
391 # check if we have admin permission for this user group !
420 # check if we have admin permission for this user group !
392 _perms = ('usergroup.admin',)
421 _perms = ('usergroup.admin',)
393 if not HasUserGroupPermissionAnyApi(*_perms)(
422 if not HasUserGroupPermissionAnyApi(*_perms)(
394 user=apiuser, user_group_name=user_group.users_group_name):
423 user=apiuser, user_group_name=user_group.users_group_name):
395 raise JSONRPCError(
424 raise JSONRPCError(
396 'user group `%s` does not exist' % (usergroupid,))
425 'user group `%s` does not exist' % (usergroupid,))
397
426
398 old_data = user_group.get_api_data()
427 old_data = user_group.get_api_data()
399 try:
428 try:
400 UserGroupModel().delete(user_group)
429 UserGroupModel().delete(user_group)
401 audit_logger.store_api(
430 audit_logger.store_api(
402 'user_group.delete', action_data={'old_data': old_data},
431 'user_group.delete', action_data={'old_data': old_data},
403 user=apiuser)
432 user=apiuser)
404 Session().commit()
433 Session().commit()
405 return {
434 return {
406 'msg': 'deleted user group ID:%s %s' % (
435 'msg': 'deleted user group ID:%s %s' % (
407 user_group.users_group_id, user_group.users_group_name),
436 user_group.users_group_id, user_group.users_group_name),
408 'user_group': None
437 'user_group': None
409 }
438 }
410 except UserGroupAssignedException as e:
439 except UserGroupAssignedException as e:
411 log.exception("UserGroupAssigned error")
440 log.exception("UserGroupAssigned error")
412 raise JSONRPCError(str(e))
441 raise JSONRPCError(str(e))
413 except Exception:
442 except Exception:
414 log.exception("Error occurred during deletion of user group")
443 log.exception("Error occurred during deletion of user group")
415 raise JSONRPCError(
444 raise JSONRPCError(
416 'failed to delete user group ID:%s %s' %(
445 'failed to delete user group ID:%s %s' %(
417 user_group.users_group_id, user_group.users_group_name))
446 user_group.users_group_id, user_group.users_group_name))
418
447
419
448
420 @jsonrpc_method()
449 @jsonrpc_method()
421 def add_user_to_user_group(request, apiuser, usergroupid, userid):
450 def add_user_to_user_group(request, apiuser, usergroupid, userid):
422 """
451 """
423 Adds a user to a `user group`. If the user already exists in the group
452 Adds a user to a `user group`. If the user already exists in the group
424 this command will return false.
453 this command will return false.
425
454
426 This command can only be run using an |authtoken| with admin rights to
455 This command can only be run using an |authtoken| with admin rights to
427 the specified user group.
456 the specified user group.
428
457
429 This command takes the following options:
458 This command takes the following options:
430
459
431 :param apiuser: This is filled automatically from the |authtoken|.
460 :param apiuser: This is filled automatically from the |authtoken|.
432 :type apiuser: AuthUser
461 :type apiuser: AuthUser
433 :param usergroupid: Set the name of the `user group` to which a
462 :param usergroupid: Set the name of the `user group` to which a
434 user will be added.
463 user will be added.
435 :type usergroupid: int
464 :type usergroupid: int
436 :param userid: Set the `user_id` of the user to add to the group.
465 :param userid: Set the `user_id` of the user to add to the group.
437 :type userid: int
466 :type userid: int
438
467
439 Example output:
468 Example output:
440
469
441 .. code-block:: bash
470 .. code-block:: bash
442
471
443 id : <id_given_in_input>
472 id : <id_given_in_input>
444 result : {
473 result : {
445 "success": True|False # depends on if member is in group
474 "success": True|False # depends on if member is in group
446 "msg": "added member `<username>` to user group `<groupname>` |
475 "msg": "added member `<username>` to user group `<groupname>` |
447 User is already in that group"
476 User is already in that group"
448
477
449 }
478 }
450 error : null
479 error : null
451
480
452 Example error output:
481 Example error output:
453
482
454 .. code-block:: bash
483 .. code-block:: bash
455
484
456 id : <id_given_in_input>
485 id : <id_given_in_input>
457 result : null
486 result : null
458 error : {
487 error : {
459 "failed to add member to user group `<user_group_name>`"
488 "failed to add member to user group `<user_group_name>`"
460 }
489 }
461
490
462 """
491 """
463
492
464 user = get_user_or_error(userid)
493 user = get_user_or_error(userid)
465 user_group = get_user_group_or_error(usergroupid)
494 user_group = get_user_group_or_error(usergroupid)
466 if not has_superadmin_permission(apiuser):
495 if not has_superadmin_permission(apiuser):
467 # check if we have admin permission for this user group !
496 # check if we have admin permission for this user group !
468 _perms = ('usergroup.admin',)
497 _perms = ('usergroup.admin',)
469 if not HasUserGroupPermissionAnyApi(*_perms)(
498 if not HasUserGroupPermissionAnyApi(*_perms)(
470 user=apiuser, user_group_name=user_group.users_group_name):
499 user=apiuser, user_group_name=user_group.users_group_name):
471 raise JSONRPCError('user group `%s` does not exist' % (
500 raise JSONRPCError('user group `%s` does not exist' % (
472 usergroupid,))
501 usergroupid,))
473
502
474 old_values = user_group.get_api_data()
503 old_values = user_group.get_api_data()
475 try:
504 try:
476 ugm = UserGroupModel().add_user_to_group(user_group, user)
505 ugm = UserGroupModel().add_user_to_group(user_group, user)
477 success = True if ugm is not True else False
506 success = True if ugm is not True else False
478 msg = 'added member `%s` to user group `%s`' % (
507 msg = 'added member `%s` to user group `%s`' % (
479 user.username, user_group.users_group_name
508 user.username, user_group.users_group_name
480 )
509 )
481 msg = msg if success else 'User is already in that group'
510 msg = msg if success else 'User is already in that group'
482 if success:
511 if success:
483 user_data = user.get_api_data()
512 user_data = user.get_api_data()
484 audit_logger.store_api(
513 audit_logger.store_api(
485 'user_group.edit.member.add',
514 'user_group.edit.member.add',
486 action_data={'user': user_data, 'old_data': old_values},
515 action_data={'user': user_data, 'old_data': old_values},
487 user=apiuser)
516 user=apiuser)
488
517
489 Session().commit()
518 Session().commit()
490
519
491 return {
520 return {
492 'success': success,
521 'success': success,
493 'msg': msg
522 'msg': msg
494 }
523 }
495 except Exception:
524 except Exception:
496 log.exception("Error occurred during adding a member to user group")
525 log.exception("Error occurred during adding a member to user group")
497 raise JSONRPCError(
526 raise JSONRPCError(
498 'failed to add member to user group `%s`' % (
527 'failed to add member to user group `%s`' % (
499 user_group.users_group_name,
528 user_group.users_group_name,
500 )
529 )
501 )
530 )
502
531
503
532
504 @jsonrpc_method()
533 @jsonrpc_method()
505 def remove_user_from_user_group(request, apiuser, usergroupid, userid):
534 def remove_user_from_user_group(request, apiuser, usergroupid, userid):
506 """
535 """
507 Removes a user from a user group.
536 Removes a user from a user group.
508
537
509 * If the specified user is not in the group, this command will return
538 * If the specified user is not in the group, this command will return
510 `false`.
539 `false`.
511
540
512 This command can only be run using an |authtoken| with admin rights to
541 This command can only be run using an |authtoken| with admin rights to
513 the specified user group.
542 the specified user group.
514
543
515 :param apiuser: This is filled automatically from the |authtoken|.
544 :param apiuser: This is filled automatically from the |authtoken|.
516 :type apiuser: AuthUser
545 :type apiuser: AuthUser
517 :param usergroupid: Sets the user group name.
546 :param usergroupid: Sets the user group name.
518 :type usergroupid: str or int
547 :type usergroupid: str or int
519 :param userid: The user you wish to remove from |RCE|.
548 :param userid: The user you wish to remove from |RCE|.
520 :type userid: str or int
549 :type userid: str or int
521
550
522 Example output:
551 Example output:
523
552
524 .. code-block:: bash
553 .. code-block:: bash
525
554
526 id : <id_given_in_input>
555 id : <id_given_in_input>
527 result: {
556 result: {
528 "success": True|False, # depends on if member is in group
557 "success": True|False, # depends on if member is in group
529 "msg": "removed member <username> from user group <groupname> |
558 "msg": "removed member <username> from user group <groupname> |
530 User wasn't in group"
559 User wasn't in group"
531 }
560 }
532 error: null
561 error: null
533
562
534 """
563 """
535
564
536 user = get_user_or_error(userid)
565 user = get_user_or_error(userid)
537 user_group = get_user_group_or_error(usergroupid)
566 user_group = get_user_group_or_error(usergroupid)
538 if not has_superadmin_permission(apiuser):
567 if not has_superadmin_permission(apiuser):
539 # check if we have admin permission for this user group !
568 # check if we have admin permission for this user group !
540 _perms = ('usergroup.admin',)
569 _perms = ('usergroup.admin',)
541 if not HasUserGroupPermissionAnyApi(*_perms)(
570 if not HasUserGroupPermissionAnyApi(*_perms)(
542 user=apiuser, user_group_name=user_group.users_group_name):
571 user=apiuser, user_group_name=user_group.users_group_name):
543 raise JSONRPCError(
572 raise JSONRPCError(
544 'user group `%s` does not exist' % (usergroupid,))
573 'user group `%s` does not exist' % (usergroupid,))
545
574
546 old_values = user_group.get_api_data()
575 old_values = user_group.get_api_data()
547 try:
576 try:
548 success = UserGroupModel().remove_user_from_group(user_group, user)
577 success = UserGroupModel().remove_user_from_group(user_group, user)
549 msg = 'removed member `%s` from user group `%s`' % (
578 msg = 'removed member `%s` from user group `%s`' % (
550 user.username, user_group.users_group_name
579 user.username, user_group.users_group_name
551 )
580 )
552 msg = msg if success else "User wasn't in group"
581 msg = msg if success else "User wasn't in group"
553 if success:
582 if success:
554 user_data = user.get_api_data()
583 user_data = user.get_api_data()
555 audit_logger.store_api(
584 audit_logger.store_api(
556 'user_group.edit.member.delete',
585 'user_group.edit.member.delete',
557 action_data={'user': user_data, 'old_data': old_values},
586 action_data={'user': user_data, 'old_data': old_values},
558 user=apiuser)
587 user=apiuser)
559
588
560 Session().commit()
589 Session().commit()
561 return {'success': success, 'msg': msg}
590 return {'success': success, 'msg': msg}
562 except Exception:
591 except Exception:
563 log.exception("Error occurred during removing an member from user group")
592 log.exception("Error occurred during removing an member from user group")
564 raise JSONRPCError(
593 raise JSONRPCError(
565 'failed to remove member from user group `%s`' % (
594 'failed to remove member from user group `%s`' % (
566 user_group.users_group_name,
595 user_group.users_group_name,
567 )
596 )
568 )
597 )
569
598
570
599
571 @jsonrpc_method()
600 @jsonrpc_method()
572 def grant_user_permission_to_user_group(
601 def grant_user_permission_to_user_group(
573 request, apiuser, usergroupid, userid, perm):
602 request, apiuser, usergroupid, userid, perm):
574 """
603 """
575 Set permissions for a user in a user group.
604 Set permissions for a user in a user group.
576
605
577 :param apiuser: This is filled automatically from the |authtoken|.
606 :param apiuser: This is filled automatically from the |authtoken|.
578 :type apiuser: AuthUser
607 :type apiuser: AuthUser
579 :param usergroupid: Set the user group to edit permissions on.
608 :param usergroupid: Set the user group to edit permissions on.
580 :type usergroupid: str or int
609 :type usergroupid: str or int
581 :param userid: Set the user from whom you wish to set permissions.
610 :param userid: Set the user from whom you wish to set permissions.
582 :type userid: str
611 :type userid: str
583 :param perm: (usergroup.(none|read|write|admin))
612 :param perm: (usergroup.(none|read|write|admin))
584 :type perm: str
613 :type perm: str
585
614
586 Example output:
615 Example output:
587
616
588 .. code-block:: bash
617 .. code-block:: bash
589
618
590 id : <id_given_in_input>
619 id : <id_given_in_input>
591 result : {
620 result : {
592 "msg": "Granted perm: `<perm_name>` for user: `<username>` in user group: `<user_group_name>`",
621 "msg": "Granted perm: `<perm_name>` for user: `<username>` in user group: `<user_group_name>`",
593 "success": true
622 "success": true
594 }
623 }
595 error : null
624 error : null
596 """
625 """
597
626
598 user_group = get_user_group_or_error(usergroupid)
627 user_group = get_user_group_or_error(usergroupid)
599
628
600 if not has_superadmin_permission(apiuser):
629 if not has_superadmin_permission(apiuser):
601 # check if we have admin permission for this user group !
630 # check if we have admin permission for this user group !
602 _perms = ('usergroup.admin',)
631 _perms = ('usergroup.admin',)
603 if not HasUserGroupPermissionAnyApi(*_perms)(
632 if not HasUserGroupPermissionAnyApi(*_perms)(
604 user=apiuser, user_group_name=user_group.users_group_name):
633 user=apiuser, user_group_name=user_group.users_group_name):
605 raise JSONRPCError(
634 raise JSONRPCError(
606 'user group `%s` does not exist' % (usergroupid,))
635 'user group `%s` does not exist' % (usergroupid,))
607
636
608 user = get_user_or_error(userid)
637 user = get_user_or_error(userid)
609 perm = get_perm_or_error(perm, prefix='usergroup.')
638 perm = get_perm_or_error(perm, prefix='usergroup.')
610
639
611 try:
640 try:
612 UserGroupModel().grant_user_permission(
641 UserGroupModel().grant_user_permission(
613 user_group=user_group, user=user, perm=perm)
642 user_group=user_group, user=user, perm=perm)
614 Session().commit()
643 Session().commit()
615 return {
644 return {
616 'msg':
645 'msg':
617 'Granted perm: `%s` for user: `%s` in user group: `%s`' % (
646 'Granted perm: `%s` for user: `%s` in user group: `%s`' % (
618 perm.permission_name, user.username,
647 perm.permission_name, user.username,
619 user_group.users_group_name
648 user_group.users_group_name
620 ),
649 ),
621 'success': True
650 'success': True
622 }
651 }
623 except Exception:
652 except Exception:
624 log.exception("Error occurred during editing permissions "
653 log.exception("Error occurred during editing permissions "
625 "for user in user group")
654 "for user in user group")
626 raise JSONRPCError(
655 raise JSONRPCError(
627 'failed to edit permission for user: '
656 'failed to edit permission for user: '
628 '`%s` in user group: `%s`' % (
657 '`%s` in user group: `%s`' % (
629 userid, user_group.users_group_name))
658 userid, user_group.users_group_name))
630
659
631
660
632 @jsonrpc_method()
661 @jsonrpc_method()
633 def revoke_user_permission_from_user_group(
662 def revoke_user_permission_from_user_group(
634 request, apiuser, usergroupid, userid):
663 request, apiuser, usergroupid, userid):
635 """
664 """
636 Revoke a users permissions in a user group.
665 Revoke a users permissions in a user group.
637
666
638 :param apiuser: This is filled automatically from the |authtoken|.
667 :param apiuser: This is filled automatically from the |authtoken|.
639 :type apiuser: AuthUser
668 :type apiuser: AuthUser
640 :param usergroupid: Set the user group from which to revoke the user
669 :param usergroupid: Set the user group from which to revoke the user
641 permissions.
670 permissions.
642 :type: usergroupid: str or int
671 :type: usergroupid: str or int
643 :param userid: Set the userid of the user whose permissions will be
672 :param userid: Set the userid of the user whose permissions will be
644 revoked.
673 revoked.
645 :type userid: str
674 :type userid: str
646
675
647 Example output:
676 Example output:
648
677
649 .. code-block:: bash
678 .. code-block:: bash
650
679
651 id : <id_given_in_input>
680 id : <id_given_in_input>
652 result : {
681 result : {
653 "msg": "Revoked perm for user: `<username>` in user group: `<user_group_name>`",
682 "msg": "Revoked perm for user: `<username>` in user group: `<user_group_name>`",
654 "success": true
683 "success": true
655 }
684 }
656 error : null
685 error : null
657 """
686 """
658
687
659 user_group = get_user_group_or_error(usergroupid)
688 user_group = get_user_group_or_error(usergroupid)
660
689
661 if not has_superadmin_permission(apiuser):
690 if not has_superadmin_permission(apiuser):
662 # check if we have admin permission for this user group !
691 # check if we have admin permission for this user group !
663 _perms = ('usergroup.admin',)
692 _perms = ('usergroup.admin',)
664 if not HasUserGroupPermissionAnyApi(*_perms)(
693 if not HasUserGroupPermissionAnyApi(*_perms)(
665 user=apiuser, user_group_name=user_group.users_group_name):
694 user=apiuser, user_group_name=user_group.users_group_name):
666 raise JSONRPCError(
695 raise JSONRPCError(
667 'user group `%s` does not exist' % (usergroupid,))
696 'user group `%s` does not exist' % (usergroupid,))
668
697
669 user = get_user_or_error(userid)
698 user = get_user_or_error(userid)
670
699
671 try:
700 try:
672 UserGroupModel().revoke_user_permission(
701 UserGroupModel().revoke_user_permission(
673 user_group=user_group, user=user)
702 user_group=user_group, user=user)
674 Session().commit()
703 Session().commit()
675 return {
704 return {
676 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (
705 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % (
677 user.username, user_group.users_group_name
706 user.username, user_group.users_group_name
678 ),
707 ),
679 'success': True
708 'success': True
680 }
709 }
681 except Exception:
710 except Exception:
682 log.exception("Error occurred during editing permissions "
711 log.exception("Error occurred during editing permissions "
683 "for user in user group")
712 "for user in user group")
684 raise JSONRPCError(
713 raise JSONRPCError(
685 'failed to edit permission for user: `%s` in user group: `%s`'
714 'failed to edit permission for user: `%s` in user group: `%s`'
686 % (userid, user_group.users_group_name))
715 % (userid, user_group.users_group_name))
687
716
688
717
689 @jsonrpc_method()
718 @jsonrpc_method()
690 def grant_user_group_permission_to_user_group(
719 def grant_user_group_permission_to_user_group(
691 request, apiuser, usergroupid, sourceusergroupid, perm):
720 request, apiuser, usergroupid, sourceusergroupid, perm):
692 """
721 """
693 Give one user group permissions to another user group.
722 Give one user group permissions to another user group.
694
723
695 :param apiuser: This is filled automatically from the |authtoken|.
724 :param apiuser: This is filled automatically from the |authtoken|.
696 :type apiuser: AuthUser
725 :type apiuser: AuthUser
697 :param usergroupid: Set the user group on which to edit permissions.
726 :param usergroupid: Set the user group on which to edit permissions.
698 :type usergroupid: str or int
727 :type usergroupid: str or int
699 :param sourceusergroupid: Set the source user group to which
728 :param sourceusergroupid: Set the source user group to which
700 access/permissions will be granted.
729 access/permissions will be granted.
701 :type sourceusergroupid: str or int
730 :type sourceusergroupid: str or int
702 :param perm: (usergroup.(none|read|write|admin))
731 :param perm: (usergroup.(none|read|write|admin))
703 :type perm: str
732 :type perm: str
704
733
705 Example output:
734 Example output:
706
735
707 .. code-block:: bash
736 .. code-block:: bash
708
737
709 id : <id_given_in_input>
738 id : <id_given_in_input>
710 result : {
739 result : {
711 "msg": "Granted perm: `<perm_name>` for user group: `<source_user_group_name>` in user group: `<user_group_name>`",
740 "msg": "Granted perm: `<perm_name>` for user group: `<source_user_group_name>` in user group: `<user_group_name>`",
712 "success": true
741 "success": true
713 }
742 }
714 error : null
743 error : null
715 """
744 """
716
745
717 user_group = get_user_group_or_error(sourceusergroupid)
746 user_group = get_user_group_or_error(sourceusergroupid)
718 target_user_group = get_user_group_or_error(usergroupid)
747 target_user_group = get_user_group_or_error(usergroupid)
719 perm = get_perm_or_error(perm, prefix='usergroup.')
748 perm = get_perm_or_error(perm, prefix='usergroup.')
720
749
721 if not has_superadmin_permission(apiuser):
750 if not has_superadmin_permission(apiuser):
722 # check if we have admin permission for this user group !
751 # check if we have admin permission for this user group !
723 _perms = ('usergroup.admin',)
752 _perms = ('usergroup.admin',)
724 if not HasUserGroupPermissionAnyApi(*_perms)(
753 if not HasUserGroupPermissionAnyApi(*_perms)(
725 user=apiuser,
754 user=apiuser,
726 user_group_name=target_user_group.users_group_name):
755 user_group_name=target_user_group.users_group_name):
727 raise JSONRPCError(
756 raise JSONRPCError(
728 'to user group `%s` does not exist' % (usergroupid,))
757 'to user group `%s` does not exist' % (usergroupid,))
729
758
730 # check if we have at least read permission for source user group !
759 # check if we have at least read permission for source user group !
731 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
760 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
732 if not HasUserGroupPermissionAnyApi(*_perms)(
761 if not HasUserGroupPermissionAnyApi(*_perms)(
733 user=apiuser, user_group_name=user_group.users_group_name):
762 user=apiuser, user_group_name=user_group.users_group_name):
734 raise JSONRPCError(
763 raise JSONRPCError(
735 'user group `%s` does not exist' % (sourceusergroupid,))
764 'user group `%s` does not exist' % (sourceusergroupid,))
736
765
737 try:
766 try:
738 UserGroupModel().grant_user_group_permission(
767 UserGroupModel().grant_user_group_permission(
739 target_user_group=target_user_group,
768 target_user_group=target_user_group,
740 user_group=user_group, perm=perm)
769 user_group=user_group, perm=perm)
741 Session().commit()
770 Session().commit()
742
771
743 return {
772 return {
744 'msg': 'Granted perm: `%s` for user group: `%s` '
773 'msg': 'Granted perm: `%s` for user group: `%s` '
745 'in user group: `%s`' % (
774 'in user group: `%s`' % (
746 perm.permission_name, user_group.users_group_name,
775 perm.permission_name, user_group.users_group_name,
747 target_user_group.users_group_name
776 target_user_group.users_group_name
748 ),
777 ),
749 'success': True
778 'success': True
750 }
779 }
751 except Exception:
780 except Exception:
752 log.exception("Error occurred during editing permissions "
781 log.exception("Error occurred during editing permissions "
753 "for user group in user group")
782 "for user group in user group")
754 raise JSONRPCError(
783 raise JSONRPCError(
755 'failed to edit permission for user group: `%s` in '
784 'failed to edit permission for user group: `%s` in '
756 'user group: `%s`' % (
785 'user group: `%s`' % (
757 sourceusergroupid, target_user_group.users_group_name
786 sourceusergroupid, target_user_group.users_group_name
758 )
787 )
759 )
788 )
760
789
761
790
762 @jsonrpc_method()
791 @jsonrpc_method()
763 def revoke_user_group_permission_from_user_group(
792 def revoke_user_group_permission_from_user_group(
764 request, apiuser, usergroupid, sourceusergroupid):
793 request, apiuser, usergroupid, sourceusergroupid):
765 """
794 """
766 Revoke the permissions that one user group has to another.
795 Revoke the permissions that one user group has to another.
767
796
768 :param apiuser: This is filled automatically from the |authtoken|.
797 :param apiuser: This is filled automatically from the |authtoken|.
769 :type apiuser: AuthUser
798 :type apiuser: AuthUser
770 :param usergroupid: Set the user group on which to edit permissions.
799 :param usergroupid: Set the user group on which to edit permissions.
771 :type usergroupid: str or int
800 :type usergroupid: str or int
772 :param sourceusergroupid: Set the user group from which permissions
801 :param sourceusergroupid: Set the user group from which permissions
773 are revoked.
802 are revoked.
774 :type sourceusergroupid: str or int
803 :type sourceusergroupid: str or int
775
804
776 Example output:
805 Example output:
777
806
778 .. code-block:: bash
807 .. code-block:: bash
779
808
780 id : <id_given_in_input>
809 id : <id_given_in_input>
781 result : {
810 result : {
782 "msg": "Revoked perm for user group: `<user_group_name>` in user group: `<target_user_group_name>`",
811 "msg": "Revoked perm for user group: `<user_group_name>` in user group: `<target_user_group_name>`",
783 "success": true
812 "success": true
784 }
813 }
785 error : null
814 error : null
786 """
815 """
787
816
788 user_group = get_user_group_or_error(sourceusergroupid)
817 user_group = get_user_group_or_error(sourceusergroupid)
789 target_user_group = get_user_group_or_error(usergroupid)
818 target_user_group = get_user_group_or_error(usergroupid)
790
819
791 if not has_superadmin_permission(apiuser):
820 if not has_superadmin_permission(apiuser):
792 # check if we have admin permission for this user group !
821 # check if we have admin permission for this user group !
793 _perms = ('usergroup.admin',)
822 _perms = ('usergroup.admin',)
794 if not HasUserGroupPermissionAnyApi(*_perms)(
823 if not HasUserGroupPermissionAnyApi(*_perms)(
795 user=apiuser,
824 user=apiuser,
796 user_group_name=target_user_group.users_group_name):
825 user_group_name=target_user_group.users_group_name):
797 raise JSONRPCError(
826 raise JSONRPCError(
798 'to user group `%s` does not exist' % (usergroupid,))
827 'to user group `%s` does not exist' % (usergroupid,))
799
828
800 # check if we have at least read permission
829 # check if we have at least read permission
801 # for the source user group !
830 # for the source user group !
802 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
831 _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',)
803 if not HasUserGroupPermissionAnyApi(*_perms)(
832 if not HasUserGroupPermissionAnyApi(*_perms)(
804 user=apiuser, user_group_name=user_group.users_group_name):
833 user=apiuser, user_group_name=user_group.users_group_name):
805 raise JSONRPCError(
834 raise JSONRPCError(
806 'user group `%s` does not exist' % (sourceusergroupid,))
835 'user group `%s` does not exist' % (sourceusergroupid,))
807
836
808 try:
837 try:
809 UserGroupModel().revoke_user_group_permission(
838 UserGroupModel().revoke_user_group_permission(
810 target_user_group=target_user_group, user_group=user_group)
839 target_user_group=target_user_group, user_group=user_group)
811 Session().commit()
840 Session().commit()
812
841
813 return {
842 return {
814 'msg': 'Revoked perm for user group: '
843 'msg': 'Revoked perm for user group: '
815 '`%s` in user group: `%s`' % (
844 '`%s` in user group: `%s`' % (
816 user_group.users_group_name,
845 user_group.users_group_name,
817 target_user_group.users_group_name
846 target_user_group.users_group_name
818 ),
847 ),
819 'success': True
848 'success': True
820 }
849 }
821 except Exception:
850 except Exception:
822 log.exception("Error occurred during editing permissions "
851 log.exception("Error occurred during editing permissions "
823 "for user group in user group")
852 "for user group in user group")
824 raise JSONRPCError(
853 raise JSONRPCError(
825 'failed to edit permission for user group: '
854 'failed to edit permission for user group: '
826 '`%s` in user group: `%s`' % (
855 '`%s` in user group: `%s`' % (
827 sourceusergroupid, target_user_group.users_group_name
856 sourceusergroupid, target_user_group.users_group_name
828 )
857 )
829 )
858 )
@@ -1,246 +1,245 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2018 RhodeCode GmbH
3 # Copyright (C) 2016-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22
22
23 import formencode
23 import formencode
24 import formencode.htmlfill
24 import formencode.htmlfill
25
25
26 from pyramid.httpexceptions import HTTPFound
26 from pyramid.httpexceptions import HTTPFound
27 from pyramid.view import view_config
27 from pyramid.view import view_config
28 from pyramid.response import Response
28 from pyramid.response import Response
29 from pyramid.renderers import render
29 from pyramid.renderers import render
30
30
31 from rhodecode.apps._base import BaseAppView, DataGridAppView
31 from rhodecode.apps._base import BaseAppView, DataGridAppView
32 from rhodecode.lib.auth import (
32 from rhodecode.lib.auth import (
33 LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator)
33 LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator)
34 from rhodecode.lib import helpers as h, audit_logger
34 from rhodecode.lib import helpers as h, audit_logger
35 from rhodecode.lib.utils2 import safe_unicode
35 from rhodecode.lib.utils2 import safe_unicode
36
36
37 from rhodecode.model.forms import UserGroupForm
37 from rhodecode.model.forms import UserGroupForm
38 from rhodecode.model.permission import PermissionModel
38 from rhodecode.model.permission import PermissionModel
39 from rhodecode.model.scm import UserGroupList
39 from rhodecode.model.scm import UserGroupList
40 from rhodecode.model.db import (
40 from rhodecode.model.db import (
41 or_, count, User, UserGroup, UserGroupMember)
41 or_, count, User, UserGroup, UserGroupMember)
42 from rhodecode.model.meta import Session
42 from rhodecode.model.meta import Session
43 from rhodecode.model.user_group import UserGroupModel
43 from rhodecode.model.user_group import UserGroupModel
44
44
45 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
46
46
47
47
48 class AdminUserGroupsView(BaseAppView, DataGridAppView):
48 class AdminUserGroupsView(BaseAppView, DataGridAppView):
49
49
50 def load_default_context(self):
50 def load_default_context(self):
51 c = self._get_local_tmpl_context()
51 c = self._get_local_tmpl_context()
52
52
53 PermissionModel().set_global_permission_choices(
53 PermissionModel().set_global_permission_choices(
54 c, gettext_translator=self.request.translate)
54 c, gettext_translator=self.request.translate)
55
55
56 return c
56 return c
57
57
58 # permission check in data loading of
58 # permission check in data loading of
59 # `user_groups_list_data` via UserGroupList
59 # `user_groups_list_data` via UserGroupList
60 @LoginRequired()
60 @LoginRequired()
61 @NotAnonymous()
61 @NotAnonymous()
62 @view_config(
62 @view_config(
63 route_name='user_groups', request_method='GET',
63 route_name='user_groups', request_method='GET',
64 renderer='rhodecode:templates/admin/user_groups/user_groups.mako')
64 renderer='rhodecode:templates/admin/user_groups/user_groups.mako')
65 def user_groups_list(self):
65 def user_groups_list(self):
66 c = self.load_default_context()
66 c = self.load_default_context()
67 return self._get_template_context(c)
67 return self._get_template_context(c)
68
68
69 # permission check inside
69 # permission check inside
70 @LoginRequired()
70 @LoginRequired()
71 @NotAnonymous()
71 @NotAnonymous()
72 @view_config(
72 @view_config(
73 route_name='user_groups_data', request_method='GET',
73 route_name='user_groups_data', request_method='GET',
74 renderer='json_ext', xhr=True)
74 renderer='json_ext', xhr=True)
75 def user_groups_list_data(self):
75 def user_groups_list_data(self):
76 self.load_default_context()
76 self.load_default_context()
77 column_map = {
77 column_map = {
78 'active': 'users_group_active',
78 'active': 'users_group_active',
79 'description': 'user_group_description',
79 'description': 'user_group_description',
80 'members': 'members_total',
80 'members': 'members_total',
81 'owner': 'user_username',
81 'owner': 'user_username',
82 'sync': 'group_data'
82 'sync': 'group_data'
83 }
83 }
84 draw, start, limit = self._extract_chunk(self.request)
84 draw, start, limit = self._extract_chunk(self.request)
85 search_q, order_by, order_dir = self._extract_ordering(
85 search_q, order_by, order_dir = self._extract_ordering(
86 self.request, column_map=column_map)
86 self.request, column_map=column_map)
87
87
88 _render = self.request.get_partial_renderer(
88 _render = self.request.get_partial_renderer(
89 'rhodecode:templates/data_table/_dt_elements.mako')
89 'rhodecode:templates/data_table/_dt_elements.mako')
90
90
91 def user_group_name(user_group_name):
91 def user_group_name(user_group_name):
92 return _render("user_group_name", user_group_name)
92 return _render("user_group_name", user_group_name)
93
93
94 def user_group_actions(user_group_id, user_group_name):
94 def user_group_actions(user_group_id, user_group_name):
95 return _render("user_group_actions", user_group_id, user_group_name)
95 return _render("user_group_actions", user_group_id, user_group_name)
96
96
97 def user_profile(username):
97 def user_profile(username):
98 return _render('user_profile', username)
98 return _render('user_profile', username)
99
99
100 auth_user_group_list = UserGroupList(
100 auth_user_group_list = UserGroupList(
101 UserGroup.query().all(), perm_set=['usergroup.admin'])
101 UserGroup.query().all(), perm_set=['usergroup.admin'])
102
102
103 allowed_ids = [-1]
103 allowed_ids = [-1]
104 for user_group in auth_user_group_list:
104 for user_group in auth_user_group_list:
105 allowed_ids.append(user_group.users_group_id)
105 allowed_ids.append(user_group.users_group_id)
106
106
107 user_groups_data_total_count = UserGroup.query()\
107 user_groups_data_total_count = UserGroup.query()\
108 .filter(UserGroup.users_group_id.in_(allowed_ids))\
108 .filter(UserGroup.users_group_id.in_(allowed_ids))\
109 .count()
109 .count()
110
110
111 member_count = count(UserGroupMember.user_id)
111 member_count = count(UserGroupMember.user_id)
112 base_q = Session.query(
112 base_q = Session.query(
113 UserGroup.users_group_name,
113 UserGroup.users_group_name,
114 UserGroup.user_group_description,
114 UserGroup.user_group_description,
115 UserGroup.users_group_active,
115 UserGroup.users_group_active,
116 UserGroup.users_group_id,
116 UserGroup.users_group_id,
117 UserGroup.group_data,
117 UserGroup.group_data,
118 User,
118 User,
119 member_count.label('member_count')
119 member_count.label('member_count')
120 ) \
120 ) \
121 .filter(UserGroup.users_group_id.in_(allowed_ids)) \
121 .filter(UserGroup.users_group_id.in_(allowed_ids)) \
122 .outerjoin(UserGroupMember) \
122 .outerjoin(UserGroupMember) \
123 .join(User, User.user_id == UserGroup.user_id) \
123 .join(User, User.user_id == UserGroup.user_id) \
124 .group_by(UserGroup, User)
124 .group_by(UserGroup, User)
125
125
126 if search_q:
126 if search_q:
127 like_expression = u'%{}%'.format(safe_unicode(search_q))
127 like_expression = u'%{}%'.format(safe_unicode(search_q))
128 base_q = base_q.filter(or_(
128 base_q = base_q.filter(or_(
129 UserGroup.users_group_name.ilike(like_expression),
129 UserGroup.users_group_name.ilike(like_expression),
130 ))
130 ))
131
131
132 user_groups_data_total_filtered_count = base_q.count()
132 user_groups_data_total_filtered_count = base_q.count()
133
133
134 if order_by == 'members_total':
134 if order_by == 'members_total':
135 sort_col = member_count
135 sort_col = member_count
136 elif order_by == 'user_username':
136 elif order_by == 'user_username':
137 sort_col = User.username
137 sort_col = User.username
138 else:
138 else:
139 sort_col = getattr(UserGroup, order_by, None)
139 sort_col = getattr(UserGroup, order_by, None)
140
140
141 if isinstance(sort_col, count) or sort_col:
141 if isinstance(sort_col, count) or sort_col:
142 if order_dir == 'asc':
142 if order_dir == 'asc':
143 sort_col = sort_col.asc()
143 sort_col = sort_col.asc()
144 else:
144 else:
145 sort_col = sort_col.desc()
145 sort_col = sort_col.desc()
146
146
147 base_q = base_q.order_by(sort_col)
147 base_q = base_q.order_by(sort_col)
148 base_q = base_q.offset(start).limit(limit)
148 base_q = base_q.offset(start).limit(limit)
149
149
150 # authenticated access to user groups
150 # authenticated access to user groups
151 auth_user_group_list = base_q.all()
151 auth_user_group_list = base_q.all()
152
152
153 user_groups_data = []
153 user_groups_data = []
154 for user_gr in auth_user_group_list:
154 for user_gr in auth_user_group_list:
155 user_groups_data.append({
155 user_groups_data.append({
156 "users_group_name": user_group_name(user_gr.users_group_name),
156 "users_group_name": user_group_name(user_gr.users_group_name),
157 "name_raw": h.escape(user_gr.users_group_name),
157 "name_raw": h.escape(user_gr.users_group_name),
158 "description": h.escape(user_gr.user_group_description),
158 "description": h.escape(user_gr.user_group_description),
159 "members": user_gr.member_count,
159 "members": user_gr.member_count,
160 # NOTE(marcink): because of advanced query we
160 # NOTE(marcink): because of advanced query we
161 # need to load it like that
161 # need to load it like that
162 "sync": UserGroup._load_group_data(
162 "sync": UserGroup._load_sync(user_gr.group_data),
163 user_gr.group_data).get('extern_type'),
164 "active": h.bool2icon(user_gr.users_group_active),
163 "active": h.bool2icon(user_gr.users_group_active),
165 "owner": user_profile(user_gr.User.username),
164 "owner": user_profile(user_gr.User.username),
166 "action": user_group_actions(
165 "action": user_group_actions(
167 user_gr.users_group_id, user_gr.users_group_name)
166 user_gr.users_group_id, user_gr.users_group_name)
168 })
167 })
169
168
170 data = ({
169 data = ({
171 'draw': draw,
170 'draw': draw,
172 'data': user_groups_data,
171 'data': user_groups_data,
173 'recordsTotal': user_groups_data_total_count,
172 'recordsTotal': user_groups_data_total_count,
174 'recordsFiltered': user_groups_data_total_filtered_count,
173 'recordsFiltered': user_groups_data_total_filtered_count,
175 })
174 })
176
175
177 return data
176 return data
178
177
179 @LoginRequired()
178 @LoginRequired()
180 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
179 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
181 @view_config(
180 @view_config(
182 route_name='user_groups_new', request_method='GET',
181 route_name='user_groups_new', request_method='GET',
183 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
182 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
184 def user_groups_new(self):
183 def user_groups_new(self):
185 c = self.load_default_context()
184 c = self.load_default_context()
186 return self._get_template_context(c)
185 return self._get_template_context(c)
187
186
188 @LoginRequired()
187 @LoginRequired()
189 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
188 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
190 @CSRFRequired()
189 @CSRFRequired()
191 @view_config(
190 @view_config(
192 route_name='user_groups_create', request_method='POST',
191 route_name='user_groups_create', request_method='POST',
193 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
192 renderer='rhodecode:templates/admin/user_groups/user_group_add.mako')
194 def user_groups_create(self):
193 def user_groups_create(self):
195 _ = self.request.translate
194 _ = self.request.translate
196 c = self.load_default_context()
195 c = self.load_default_context()
197 users_group_form = UserGroupForm(self.request.translate)()
196 users_group_form = UserGroupForm(self.request.translate)()
198
197
199 user_group_name = self.request.POST.get('users_group_name')
198 user_group_name = self.request.POST.get('users_group_name')
200 try:
199 try:
201 form_result = users_group_form.to_python(dict(self.request.POST))
200 form_result = users_group_form.to_python(dict(self.request.POST))
202 user_group = UserGroupModel().create(
201 user_group = UserGroupModel().create(
203 name=form_result['users_group_name'],
202 name=form_result['users_group_name'],
204 description=form_result['user_group_description'],
203 description=form_result['user_group_description'],
205 owner=self._rhodecode_user.user_id,
204 owner=self._rhodecode_user.user_id,
206 active=form_result['users_group_active'])
205 active=form_result['users_group_active'])
207 Session().flush()
206 Session().flush()
208 creation_data = user_group.get_api_data()
207 creation_data = user_group.get_api_data()
209 user_group_name = form_result['users_group_name']
208 user_group_name = form_result['users_group_name']
210
209
211 audit_logger.store_web(
210 audit_logger.store_web(
212 'user_group.create', action_data={'data': creation_data},
211 'user_group.create', action_data={'data': creation_data},
213 user=self._rhodecode_user)
212 user=self._rhodecode_user)
214
213
215 user_group_link = h.link_to(
214 user_group_link = h.link_to(
216 h.escape(user_group_name),
215 h.escape(user_group_name),
217 h.route_path(
216 h.route_path(
218 'edit_user_group', user_group_id=user_group.users_group_id))
217 'edit_user_group', user_group_id=user_group.users_group_id))
219 h.flash(h.literal(_('Created user group %(user_group_link)s')
218 h.flash(h.literal(_('Created user group %(user_group_link)s')
220 % {'user_group_link': user_group_link}),
219 % {'user_group_link': user_group_link}),
221 category='success')
220 category='success')
222 Session().commit()
221 Session().commit()
223 user_group_id = user_group.users_group_id
222 user_group_id = user_group.users_group_id
224 except formencode.Invalid as errors:
223 except formencode.Invalid as errors:
225
224
226 data = render(
225 data = render(
227 'rhodecode:templates/admin/user_groups/user_group_add.mako',
226 'rhodecode:templates/admin/user_groups/user_group_add.mako',
228 self._get_template_context(c), self.request)
227 self._get_template_context(c), self.request)
229 html = formencode.htmlfill.render(
228 html = formencode.htmlfill.render(
230 data,
229 data,
231 defaults=errors.value,
230 defaults=errors.value,
232 errors=errors.error_dict or {},
231 errors=errors.error_dict or {},
233 prefix_error=False,
232 prefix_error=False,
234 encoding="UTF-8",
233 encoding="UTF-8",
235 force_defaults=False
234 force_defaults=False
236 )
235 )
237 return Response(html)
236 return Response(html)
238
237
239 except Exception:
238 except Exception:
240 log.exception("Exception creating user group")
239 log.exception("Exception creating user group")
241 h.flash(_('Error occurred during creation of user group %s') \
240 h.flash(_('Error occurred during creation of user group %s') \
242 % user_group_name, category='error')
241 % user_group_name, category='error')
243 raise HTTPFound(h.route_path('user_groups_new'))
242 raise HTTPFound(h.route_path('user_groups_new'))
244
243
245 raise HTTPFound(
244 raise HTTPFound(
246 h.route_path('edit_user_group', user_group_id=user_group_id))
245 h.route_path('edit_user_group', user_group_id=user_group_id))
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,673 +1,678 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2018 RhodeCode GmbH
3 # Copyright (C) 2011-2018 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import traceback
22 import traceback
23
23
24 from rhodecode.lib.utils2 import safe_str, safe_unicode
24 from rhodecode.lib.utils2 import safe_str, safe_unicode
25 from rhodecode.lib.exceptions import (
25 from rhodecode.lib.exceptions import (
26 UserGroupAssignedException, RepoGroupAssignmentError)
26 UserGroupAssignedException, RepoGroupAssignmentError)
27 from rhodecode.lib.utils2 import (
27 from rhodecode.lib.utils2 import (
28 get_current_rhodecode_user, action_logger_generic)
28 get_current_rhodecode_user, action_logger_generic)
29 from rhodecode.model import BaseModel
29 from rhodecode.model import BaseModel
30 from rhodecode.model.scm import UserGroupList
30 from rhodecode.model.scm import UserGroupList
31 from rhodecode.model.db import (
31 from rhodecode.model.db import (
32 joinedload, true, func, User, UserGroupMember, UserGroup,
32 joinedload, true, func, User, UserGroupMember, UserGroup,
33 UserGroupRepoToPerm, Permission, UserGroupToPerm, UserUserGroupToPerm,
33 UserGroupRepoToPerm, Permission, UserGroupToPerm, UserUserGroupToPerm,
34 UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm)
34 UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm)
35
35
36
36
37 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
38
38
39
39
40 class UserGroupModel(BaseModel):
40 class UserGroupModel(BaseModel):
41
41
42 cls = UserGroup
42 cls = UserGroup
43
43
44 def _get_user_group(self, user_group):
44 def _get_user_group(self, user_group):
45 return self._get_instance(UserGroup, user_group,
45 return self._get_instance(UserGroup, user_group,
46 callback=UserGroup.get_by_group_name)
46 callback=UserGroup.get_by_group_name)
47
47
48 def _create_default_perms(self, user_group):
48 def _create_default_perms(self, user_group):
49 # create default permission
49 # create default permission
50 default_perm = 'usergroup.read'
50 default_perm = 'usergroup.read'
51 def_user = User.get_default_user()
51 def_user = User.get_default_user()
52 for p in def_user.user_perms:
52 for p in def_user.user_perms:
53 if p.permission.permission_name.startswith('usergroup.'):
53 if p.permission.permission_name.startswith('usergroup.'):
54 default_perm = p.permission.permission_name
54 default_perm = p.permission.permission_name
55 break
55 break
56
56
57 user_group_to_perm = UserUserGroupToPerm()
57 user_group_to_perm = UserUserGroupToPerm()
58 user_group_to_perm.permission = Permission.get_by_key(default_perm)
58 user_group_to_perm.permission = Permission.get_by_key(default_perm)
59
59
60 user_group_to_perm.user_group = user_group
60 user_group_to_perm.user_group = user_group
61 user_group_to_perm.user_id = def_user.user_id
61 user_group_to_perm.user_id = def_user.user_id
62 return user_group_to_perm
62 return user_group_to_perm
63
63
64 def update_permissions(
64 def update_permissions(
65 self, user_group, perm_additions=None, perm_updates=None,
65 self, user_group, perm_additions=None, perm_updates=None,
66 perm_deletions=None, check_perms=True, cur_user=None):
66 perm_deletions=None, check_perms=True, cur_user=None):
67
67
68 from rhodecode.lib.auth import HasUserGroupPermissionAny
68 from rhodecode.lib.auth import HasUserGroupPermissionAny
69 if not perm_additions:
69 if not perm_additions:
70 perm_additions = []
70 perm_additions = []
71 if not perm_updates:
71 if not perm_updates:
72 perm_updates = []
72 perm_updates = []
73 if not perm_deletions:
73 if not perm_deletions:
74 perm_deletions = []
74 perm_deletions = []
75
75
76 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
76 req_perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin')
77
77
78 changes = {
78 changes = {
79 'added': [],
79 'added': [],
80 'updated': [],
80 'updated': [],
81 'deleted': []
81 'deleted': []
82 }
82 }
83 # update permissions
83 # update permissions
84 for member_id, perm, member_type in perm_updates:
84 for member_id, perm, member_type in perm_updates:
85 member_id = int(member_id)
85 member_id = int(member_id)
86 if member_type == 'user':
86 if member_type == 'user':
87 member_name = User.get(member_id).username
87 member_name = User.get(member_id).username
88 # this updates existing one
88 # this updates existing one
89 self.grant_user_permission(
89 self.grant_user_permission(
90 user_group=user_group, user=member_id, perm=perm
90 user_group=user_group, user=member_id, perm=perm
91 )
91 )
92 else:
92 else:
93 # check if we have permissions to alter this usergroup
93 # check if we have permissions to alter this usergroup
94 member_name = UserGroup.get(member_id).users_group_name
94 member_name = UserGroup.get(member_id).users_group_name
95 if not check_perms or HasUserGroupPermissionAny(
95 if not check_perms or HasUserGroupPermissionAny(
96 *req_perms)(member_name, user=cur_user):
96 *req_perms)(member_name, user=cur_user):
97 self.grant_user_group_permission(
97 self.grant_user_group_permission(
98 target_user_group=user_group, user_group=member_id, perm=perm)
98 target_user_group=user_group, user_group=member_id, perm=perm)
99
99
100 changes['updated'].append({'type': member_type, 'id': member_id,
100 changes['updated'].append({'type': member_type, 'id': member_id,
101 'name': member_name, 'new_perm': perm})
101 'name': member_name, 'new_perm': perm})
102
102
103 # set new permissions
103 # set new permissions
104 for member_id, perm, member_type in perm_additions:
104 for member_id, perm, member_type in perm_additions:
105 member_id = int(member_id)
105 member_id = int(member_id)
106 if member_type == 'user':
106 if member_type == 'user':
107 member_name = User.get(member_id).username
107 member_name = User.get(member_id).username
108 self.grant_user_permission(
108 self.grant_user_permission(
109 user_group=user_group, user=member_id, perm=perm)
109 user_group=user_group, user=member_id, perm=perm)
110 else:
110 else:
111 # check if we have permissions to alter this usergroup
111 # check if we have permissions to alter this usergroup
112 member_name = UserGroup.get(member_id).users_group_name
112 member_name = UserGroup.get(member_id).users_group_name
113 if not check_perms or HasUserGroupPermissionAny(
113 if not check_perms or HasUserGroupPermissionAny(
114 *req_perms)(member_name, user=cur_user):
114 *req_perms)(member_name, user=cur_user):
115 self.grant_user_group_permission(
115 self.grant_user_group_permission(
116 target_user_group=user_group, user_group=member_id, perm=perm)
116 target_user_group=user_group, user_group=member_id, perm=perm)
117
117
118 changes['added'].append({'type': member_type, 'id': member_id,
118 changes['added'].append({'type': member_type, 'id': member_id,
119 'name': member_name, 'new_perm': perm})
119 'name': member_name, 'new_perm': perm})
120
120
121 # delete permissions
121 # delete permissions
122 for member_id, perm, member_type in perm_deletions:
122 for member_id, perm, member_type in perm_deletions:
123 member_id = int(member_id)
123 member_id = int(member_id)
124 if member_type == 'user':
124 if member_type == 'user':
125 member_name = User.get(member_id).username
125 member_name = User.get(member_id).username
126 self.revoke_user_permission(user_group=user_group, user=member_id)
126 self.revoke_user_permission(user_group=user_group, user=member_id)
127 else:
127 else:
128 # check if we have permissions to alter this usergroup
128 # check if we have permissions to alter this usergroup
129 member_name = UserGroup.get(member_id).users_group_name
129 member_name = UserGroup.get(member_id).users_group_name
130 if not check_perms or HasUserGroupPermissionAny(
130 if not check_perms or HasUserGroupPermissionAny(
131 *req_perms)(member_name, user=cur_user):
131 *req_perms)(member_name, user=cur_user):
132 self.revoke_user_group_permission(
132 self.revoke_user_group_permission(
133 target_user_group=user_group, user_group=member_id)
133 target_user_group=user_group, user_group=member_id)
134
134
135 changes['deleted'].append({'type': member_type, 'id': member_id,
135 changes['deleted'].append({'type': member_type, 'id': member_id,
136 'name': member_name, 'new_perm': perm})
136 'name': member_name, 'new_perm': perm})
137 return changes
137 return changes
138
138
139 def get(self, user_group_id, cache=False):
139 def get(self, user_group_id, cache=False):
140 return UserGroup.get(user_group_id)
140 return UserGroup.get(user_group_id)
141
141
142 def get_group(self, user_group):
142 def get_group(self, user_group):
143 return self._get_user_group(user_group)
143 return self._get_user_group(user_group)
144
144
145 def get_by_name(self, name, cache=False, case_insensitive=False):
145 def get_by_name(self, name, cache=False, case_insensitive=False):
146 return UserGroup.get_by_group_name(name, cache, case_insensitive)
146 return UserGroup.get_by_group_name(name, cache, case_insensitive)
147
147
148 def create(self, name, description, owner, active=True, group_data=None):
148 def create(self, name, description, owner, active=True, group_data=None):
149 try:
149 try:
150 new_user_group = UserGroup()
150 new_user_group = UserGroup()
151 new_user_group.user = self._get_user(owner)
151 new_user_group.user = self._get_user(owner)
152 new_user_group.users_group_name = name
152 new_user_group.users_group_name = name
153 new_user_group.user_group_description = description
153 new_user_group.user_group_description = description
154 new_user_group.users_group_active = active
154 new_user_group.users_group_active = active
155 if group_data:
155 if group_data:
156 new_user_group.group_data = group_data
156 new_user_group.group_data = group_data
157 self.sa.add(new_user_group)
157 self.sa.add(new_user_group)
158 perm_obj = self._create_default_perms(new_user_group)
158 perm_obj = self._create_default_perms(new_user_group)
159 self.sa.add(perm_obj)
159 self.sa.add(perm_obj)
160
160
161 self.grant_user_permission(user_group=new_user_group,
161 self.grant_user_permission(user_group=new_user_group,
162 user=owner, perm='usergroup.admin')
162 user=owner, perm='usergroup.admin')
163
163
164 return new_user_group
164 return new_user_group
165 except Exception:
165 except Exception:
166 log.error(traceback.format_exc())
166 log.error(traceback.format_exc())
167 raise
167 raise
168
168
169 def _get_memberships_for_user_ids(self, user_group, user_id_list):
169 def _get_memberships_for_user_ids(self, user_group, user_id_list):
170 members = []
170 members = []
171 for user_id in user_id_list:
171 for user_id in user_id_list:
172 member = self._get_membership(user_group.users_group_id, user_id)
172 member = self._get_membership(user_group.users_group_id, user_id)
173 members.append(member)
173 members.append(member)
174 return members
174 return members
175
175
176 def _get_added_and_removed_user_ids(self, user_group, user_id_list):
176 def _get_added_and_removed_user_ids(self, user_group, user_id_list):
177 current_members = user_group.members or []
177 current_members = user_group.members or []
178 current_members_ids = [m.user.user_id for m in current_members]
178 current_members_ids = [m.user.user_id for m in current_members]
179
179
180 added_members = [
180 added_members = [
181 user_id for user_id in user_id_list
181 user_id for user_id in user_id_list
182 if user_id not in current_members_ids]
182 if user_id not in current_members_ids]
183 if user_id_list == []:
183 if user_id_list == []:
184 # all members were deleted
184 # all members were deleted
185 deleted_members = current_members_ids
185 deleted_members = current_members_ids
186 else:
186 else:
187 deleted_members = [
187 deleted_members = [
188 user_id for user_id in current_members_ids
188 user_id for user_id in current_members_ids
189 if user_id not in user_id_list]
189 if user_id not in user_id_list]
190
190
191 return added_members, deleted_members
191 return added_members, deleted_members
192
192
193 def _set_users_as_members(self, user_group, user_ids):
193 def _set_users_as_members(self, user_group, user_ids):
194 user_group.members = []
194 user_group.members = []
195 self.sa.flush()
195 self.sa.flush()
196 members = self._get_memberships_for_user_ids(
196 members = self._get_memberships_for_user_ids(
197 user_group, user_ids)
197 user_group, user_ids)
198 user_group.members = members
198 user_group.members = members
199 self.sa.add(user_group)
199 self.sa.add(user_group)
200
200
201 def _update_members_from_user_ids(self, user_group, user_ids):
201 def _update_members_from_user_ids(self, user_group, user_ids):
202 added, removed = self._get_added_and_removed_user_ids(
202 added, removed = self._get_added_and_removed_user_ids(
203 user_group, user_ids)
203 user_group, user_ids)
204 self._set_users_as_members(user_group, user_ids)
204 self._set_users_as_members(user_group, user_ids)
205 self._log_user_changes('added to', user_group, added)
205 self._log_user_changes('added to', user_group, added)
206 self._log_user_changes('removed from', user_group, removed)
206 self._log_user_changes('removed from', user_group, removed)
207 return added, removed
207 return added, removed
208
208
209 def _clean_members_data(self, members_data):
209 def _clean_members_data(self, members_data):
210 if not members_data:
210 if not members_data:
211 members_data = []
211 members_data = []
212
212
213 members = []
213 members = []
214 for user in members_data:
214 for user in members_data:
215 uid = int(user['member_user_id'])
215 uid = int(user['member_user_id'])
216 if uid not in members and user['type'] in ['new', 'existing']:
216 if uid not in members and user['type'] in ['new', 'existing']:
217 members.append(uid)
217 members.append(uid)
218 return members
218 return members
219
219
220 def update(self, user_group, form_data):
220 def update(self, user_group, form_data, group_data=None):
221 user_group = self._get_user_group(user_group)
221 user_group = self._get_user_group(user_group)
222 if 'users_group_name' in form_data:
222 if 'users_group_name' in form_data:
223 user_group.users_group_name = form_data['users_group_name']
223 user_group.users_group_name = form_data['users_group_name']
224 if 'users_group_active' in form_data:
224 if 'users_group_active' in form_data:
225 user_group.users_group_active = form_data['users_group_active']
225 user_group.users_group_active = form_data['users_group_active']
226 if 'user_group_description' in form_data:
226 if 'user_group_description' in form_data:
227 user_group.user_group_description = form_data[
227 user_group.user_group_description = form_data[
228 'user_group_description']
228 'user_group_description']
229
229
230 # handle owner change
230 # handle owner change
231 if 'user' in form_data:
231 if 'user' in form_data:
232 owner = form_data['user']
232 owner = form_data['user']
233 if isinstance(owner, basestring):
233 if isinstance(owner, basestring):
234 owner = User.get_by_username(form_data['user'])
234 owner = User.get_by_username(form_data['user'])
235
235
236 if not isinstance(owner, User):
236 if not isinstance(owner, User):
237 raise ValueError(
237 raise ValueError(
238 'invalid owner for user group: %s' % form_data['user'])
238 'invalid owner for user group: %s' % form_data['user'])
239
239
240 user_group.user = owner
240 user_group.user = owner
241
241
242 added_user_ids = []
242 added_user_ids = []
243 removed_user_ids = []
243 removed_user_ids = []
244 if 'users_group_members' in form_data:
244 if 'users_group_members' in form_data:
245 members_id_list = self._clean_members_data(
245 members_id_list = self._clean_members_data(
246 form_data['users_group_members'])
246 form_data['users_group_members'])
247 added_user_ids, removed_user_ids = \
247 added_user_ids, removed_user_ids = \
248 self._update_members_from_user_ids(user_group, members_id_list)
248 self._update_members_from_user_ids(user_group, members_id_list)
249
249
250 if group_data:
251 new_group_data = {}
252 new_group_data.update(group_data)
253 user_group.group_data = new_group_data
254
250 self.sa.add(user_group)
255 self.sa.add(user_group)
251 return user_group, added_user_ids, removed_user_ids
256 return user_group, added_user_ids, removed_user_ids
252
257
253 def delete(self, user_group, force=False):
258 def delete(self, user_group, force=False):
254 """
259 """
255 Deletes repository group, unless force flag is used
260 Deletes repository group, unless force flag is used
256 raises exception if there are members in that group, else deletes
261 raises exception if there are members in that group, else deletes
257 group and users
262 group and users
258
263
259 :param user_group:
264 :param user_group:
260 :param force:
265 :param force:
261 """
266 """
262 user_group = self._get_user_group(user_group)
267 user_group = self._get_user_group(user_group)
263 if not user_group:
268 if not user_group:
264 return
269 return
265
270
266 try:
271 try:
267 # check if this group is not assigned to repo
272 # check if this group is not assigned to repo
268 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
273 assigned_to_repo = [x.repository for x in UserGroupRepoToPerm.query()\
269 .filter(UserGroupRepoToPerm.users_group == user_group).all()]
274 .filter(UserGroupRepoToPerm.users_group == user_group).all()]
270 # check if this group is not assigned to repo
275 # check if this group is not assigned to repo
271 assigned_to_repo_group = [x.group for x in UserGroupRepoGroupToPerm.query()\
276 assigned_to_repo_group = [x.group for x in UserGroupRepoGroupToPerm.query()\
272 .filter(UserGroupRepoGroupToPerm.users_group == user_group).all()]
277 .filter(UserGroupRepoGroupToPerm.users_group == user_group).all()]
273
278
274 if (assigned_to_repo or assigned_to_repo_group) and not force:
279 if (assigned_to_repo or assigned_to_repo_group) and not force:
275 assigned = ','.join(map(safe_str,
280 assigned = ','.join(map(safe_str,
276 assigned_to_repo+assigned_to_repo_group))
281 assigned_to_repo+assigned_to_repo_group))
277
282
278 raise UserGroupAssignedException(
283 raise UserGroupAssignedException(
279 'UserGroup assigned to %s' % (assigned,))
284 'UserGroup assigned to %s' % (assigned,))
280 self.sa.delete(user_group)
285 self.sa.delete(user_group)
281 except Exception:
286 except Exception:
282 log.error(traceback.format_exc())
287 log.error(traceback.format_exc())
283 raise
288 raise
284
289
285 def _log_user_changes(self, action, user_group, user_or_users):
290 def _log_user_changes(self, action, user_group, user_or_users):
286 users = user_or_users
291 users = user_or_users
287 if not isinstance(users, (list, tuple)):
292 if not isinstance(users, (list, tuple)):
288 users = [users]
293 users = [users]
289
294
290 group_name = user_group.users_group_name
295 group_name = user_group.users_group_name
291
296
292 for user_or_user_id in users:
297 for user_or_user_id in users:
293 user = self._get_user(user_or_user_id)
298 user = self._get_user(user_or_user_id)
294 log_text = 'User {user} {action} {group}'.format(
299 log_text = 'User {user} {action} {group}'.format(
295 action=action, user=user.username, group=group_name)
300 action=action, user=user.username, group=group_name)
296 action_logger_generic(log_text)
301 action_logger_generic(log_text)
297
302
298 def _find_user_in_group(self, user, user_group):
303 def _find_user_in_group(self, user, user_group):
299 user_group_member = None
304 user_group_member = None
300 for m in user_group.members:
305 for m in user_group.members:
301 if m.user_id == user.user_id:
306 if m.user_id == user.user_id:
302 # Found this user's membership row
307 # Found this user's membership row
303 user_group_member = m
308 user_group_member = m
304 break
309 break
305
310
306 return user_group_member
311 return user_group_member
307
312
308 def _get_membership(self, user_group_id, user_id):
313 def _get_membership(self, user_group_id, user_id):
309 user_group_member = UserGroupMember(user_group_id, user_id)
314 user_group_member = UserGroupMember(user_group_id, user_id)
310 return user_group_member
315 return user_group_member
311
316
312 def add_user_to_group(self, user_group, user):
317 def add_user_to_group(self, user_group, user):
313 user_group = self._get_user_group(user_group)
318 user_group = self._get_user_group(user_group)
314 user = self._get_user(user)
319 user = self._get_user(user)
315 user_member = self._find_user_in_group(user, user_group)
320 user_member = self._find_user_in_group(user, user_group)
316 if user_member:
321 if user_member:
317 # user already in the group, skip
322 # user already in the group, skip
318 return True
323 return True
319
324
320 member = self._get_membership(
325 member = self._get_membership(
321 user_group.users_group_id, user.user_id)
326 user_group.users_group_id, user.user_id)
322 user_group.members.append(member)
327 user_group.members.append(member)
323
328
324 try:
329 try:
325 self.sa.add(member)
330 self.sa.add(member)
326 except Exception:
331 except Exception:
327 # what could go wrong here?
332 # what could go wrong here?
328 log.error(traceback.format_exc())
333 log.error(traceback.format_exc())
329 raise
334 raise
330
335
331 self._log_user_changes('added to', user_group, user)
336 self._log_user_changes('added to', user_group, user)
332 return member
337 return member
333
338
334 def remove_user_from_group(self, user_group, user):
339 def remove_user_from_group(self, user_group, user):
335 user_group = self._get_user_group(user_group)
340 user_group = self._get_user_group(user_group)
336 user = self._get_user(user)
341 user = self._get_user(user)
337 user_group_member = self._find_user_in_group(user, user_group)
342 user_group_member = self._find_user_in_group(user, user_group)
338
343
339 if not user_group_member:
344 if not user_group_member:
340 # User isn't in that group
345 # User isn't in that group
341 return False
346 return False
342
347
343 try:
348 try:
344 self.sa.delete(user_group_member)
349 self.sa.delete(user_group_member)
345 except Exception:
350 except Exception:
346 log.error(traceback.format_exc())
351 log.error(traceback.format_exc())
347 raise
352 raise
348
353
349 self._log_user_changes('removed from', user_group, user)
354 self._log_user_changes('removed from', user_group, user)
350 return True
355 return True
351
356
352 def has_perm(self, user_group, perm):
357 def has_perm(self, user_group, perm):
353 user_group = self._get_user_group(user_group)
358 user_group = self._get_user_group(user_group)
354 perm = self._get_perm(perm)
359 perm = self._get_perm(perm)
355
360
356 return UserGroupToPerm.query()\
361 return UserGroupToPerm.query()\
357 .filter(UserGroupToPerm.users_group == user_group)\
362 .filter(UserGroupToPerm.users_group == user_group)\
358 .filter(UserGroupToPerm.permission == perm).scalar() is not None
363 .filter(UserGroupToPerm.permission == perm).scalar() is not None
359
364
360 def grant_perm(self, user_group, perm):
365 def grant_perm(self, user_group, perm):
361 user_group = self._get_user_group(user_group)
366 user_group = self._get_user_group(user_group)
362 perm = self._get_perm(perm)
367 perm = self._get_perm(perm)
363
368
364 # if this permission is already granted skip it
369 # if this permission is already granted skip it
365 _perm = UserGroupToPerm.query()\
370 _perm = UserGroupToPerm.query()\
366 .filter(UserGroupToPerm.users_group == user_group)\
371 .filter(UserGroupToPerm.users_group == user_group)\
367 .filter(UserGroupToPerm.permission == perm)\
372 .filter(UserGroupToPerm.permission == perm)\
368 .scalar()
373 .scalar()
369 if _perm:
374 if _perm:
370 return
375 return
371
376
372 new = UserGroupToPerm()
377 new = UserGroupToPerm()
373 new.users_group = user_group
378 new.users_group = user_group
374 new.permission = perm
379 new.permission = perm
375 self.sa.add(new)
380 self.sa.add(new)
376 return new
381 return new
377
382
378 def revoke_perm(self, user_group, perm):
383 def revoke_perm(self, user_group, perm):
379 user_group = self._get_user_group(user_group)
384 user_group = self._get_user_group(user_group)
380 perm = self._get_perm(perm)
385 perm = self._get_perm(perm)
381
386
382 obj = UserGroupToPerm.query()\
387 obj = UserGroupToPerm.query()\
383 .filter(UserGroupToPerm.users_group == user_group)\
388 .filter(UserGroupToPerm.users_group == user_group)\
384 .filter(UserGroupToPerm.permission == perm).scalar()
389 .filter(UserGroupToPerm.permission == perm).scalar()
385 if obj:
390 if obj:
386 self.sa.delete(obj)
391 self.sa.delete(obj)
387
392
388 def grant_user_permission(self, user_group, user, perm):
393 def grant_user_permission(self, user_group, user, perm):
389 """
394 """
390 Grant permission for user on given user group, or update
395 Grant permission for user on given user group, or update
391 existing one if found
396 existing one if found
392
397
393 :param user_group: Instance of UserGroup, users_group_id,
398 :param user_group: Instance of UserGroup, users_group_id,
394 or users_group_name
399 or users_group_name
395 :param user: Instance of User, user_id or username
400 :param user: Instance of User, user_id or username
396 :param perm: Instance of Permission, or permission_name
401 :param perm: Instance of Permission, or permission_name
397 """
402 """
398
403
399 user_group = self._get_user_group(user_group)
404 user_group = self._get_user_group(user_group)
400 user = self._get_user(user)
405 user = self._get_user(user)
401 permission = self._get_perm(perm)
406 permission = self._get_perm(perm)
402
407
403 # check if we have that permission already
408 # check if we have that permission already
404 obj = self.sa.query(UserUserGroupToPerm)\
409 obj = self.sa.query(UserUserGroupToPerm)\
405 .filter(UserUserGroupToPerm.user == user)\
410 .filter(UserUserGroupToPerm.user == user)\
406 .filter(UserUserGroupToPerm.user_group == user_group)\
411 .filter(UserUserGroupToPerm.user_group == user_group)\
407 .scalar()
412 .scalar()
408 if obj is None:
413 if obj is None:
409 # create new !
414 # create new !
410 obj = UserUserGroupToPerm()
415 obj = UserUserGroupToPerm()
411 obj.user_group = user_group
416 obj.user_group = user_group
412 obj.user = user
417 obj.user = user
413 obj.permission = permission
418 obj.permission = permission
414 self.sa.add(obj)
419 self.sa.add(obj)
415 log.debug('Granted perm %s to %s on %s', perm, user, user_group)
420 log.debug('Granted perm %s to %s on %s', perm, user, user_group)
416 action_logger_generic(
421 action_logger_generic(
417 'granted permission: {} to user: {} on usergroup: {}'.format(
422 'granted permission: {} to user: {} on usergroup: {}'.format(
418 perm, user, user_group), namespace='security.usergroup')
423 perm, user, user_group), namespace='security.usergroup')
419
424
420 return obj
425 return obj
421
426
422 def revoke_user_permission(self, user_group, user):
427 def revoke_user_permission(self, user_group, user):
423 """
428 """
424 Revoke permission for user on given user group
429 Revoke permission for user on given user group
425
430
426 :param user_group: Instance of UserGroup, users_group_id,
431 :param user_group: Instance of UserGroup, users_group_id,
427 or users_group name
432 or users_group name
428 :param user: Instance of User, user_id or username
433 :param user: Instance of User, user_id or username
429 """
434 """
430
435
431 user_group = self._get_user_group(user_group)
436 user_group = self._get_user_group(user_group)
432 user = self._get_user(user)
437 user = self._get_user(user)
433
438
434 obj = self.sa.query(UserUserGroupToPerm)\
439 obj = self.sa.query(UserUserGroupToPerm)\
435 .filter(UserUserGroupToPerm.user == user)\
440 .filter(UserUserGroupToPerm.user == user)\
436 .filter(UserUserGroupToPerm.user_group == user_group)\
441 .filter(UserUserGroupToPerm.user_group == user_group)\
437 .scalar()
442 .scalar()
438 if obj:
443 if obj:
439 self.sa.delete(obj)
444 self.sa.delete(obj)
440 log.debug('Revoked perm on %s on %s', user_group, user)
445 log.debug('Revoked perm on %s on %s', user_group, user)
441 action_logger_generic(
446 action_logger_generic(
442 'revoked permission from user: {} on usergroup: {}'.format(
447 'revoked permission from user: {} on usergroup: {}'.format(
443 user, user_group), namespace='security.usergroup')
448 user, user_group), namespace='security.usergroup')
444
449
445 def grant_user_group_permission(self, target_user_group, user_group, perm):
450 def grant_user_group_permission(self, target_user_group, user_group, perm):
446 """
451 """
447 Grant user group permission for given target_user_group
452 Grant user group permission for given target_user_group
448
453
449 :param target_user_group:
454 :param target_user_group:
450 :param user_group:
455 :param user_group:
451 :param perm:
456 :param perm:
452 """
457 """
453 target_user_group = self._get_user_group(target_user_group)
458 target_user_group = self._get_user_group(target_user_group)
454 user_group = self._get_user_group(user_group)
459 user_group = self._get_user_group(user_group)
455 permission = self._get_perm(perm)
460 permission = self._get_perm(perm)
456 # forbid assigning same user group to itself
461 # forbid assigning same user group to itself
457 if target_user_group == user_group:
462 if target_user_group == user_group:
458 raise RepoGroupAssignmentError('target repo:%s cannot be '
463 raise RepoGroupAssignmentError('target repo:%s cannot be '
459 'assigned to itself' % target_user_group)
464 'assigned to itself' % target_user_group)
460
465
461 # check if we have that permission already
466 # check if we have that permission already
462 obj = self.sa.query(UserGroupUserGroupToPerm)\
467 obj = self.sa.query(UserGroupUserGroupToPerm)\
463 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
468 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
464 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
469 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
465 .scalar()
470 .scalar()
466 if obj is None:
471 if obj is None:
467 # create new !
472 # create new !
468 obj = UserGroupUserGroupToPerm()
473 obj = UserGroupUserGroupToPerm()
469 obj.user_group = user_group
474 obj.user_group = user_group
470 obj.target_user_group = target_user_group
475 obj.target_user_group = target_user_group
471 obj.permission = permission
476 obj.permission = permission
472 self.sa.add(obj)
477 self.sa.add(obj)
473 log.debug(
478 log.debug(
474 'Granted perm %s to %s on %s', perm, target_user_group, user_group)
479 'Granted perm %s to %s on %s', perm, target_user_group, user_group)
475 action_logger_generic(
480 action_logger_generic(
476 'granted permission: {} to usergroup: {} on usergroup: {}'.format(
481 'granted permission: {} to usergroup: {} on usergroup: {}'.format(
477 perm, user_group, target_user_group),
482 perm, user_group, target_user_group),
478 namespace='security.usergroup')
483 namespace='security.usergroup')
479
484
480 return obj
485 return obj
481
486
482 def revoke_user_group_permission(self, target_user_group, user_group):
487 def revoke_user_group_permission(self, target_user_group, user_group):
483 """
488 """
484 Revoke user group permission for given target_user_group
489 Revoke user group permission for given target_user_group
485
490
486 :param target_user_group:
491 :param target_user_group:
487 :param user_group:
492 :param user_group:
488 """
493 """
489 target_user_group = self._get_user_group(target_user_group)
494 target_user_group = self._get_user_group(target_user_group)
490 user_group = self._get_user_group(user_group)
495 user_group = self._get_user_group(user_group)
491
496
492 obj = self.sa.query(UserGroupUserGroupToPerm)\
497 obj = self.sa.query(UserGroupUserGroupToPerm)\
493 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
498 .filter(UserGroupUserGroupToPerm.target_user_group == target_user_group)\
494 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
499 .filter(UserGroupUserGroupToPerm.user_group == user_group)\
495 .scalar()
500 .scalar()
496 if obj:
501 if obj:
497 self.sa.delete(obj)
502 self.sa.delete(obj)
498 log.debug(
503 log.debug(
499 'Revoked perm on %s on %s', target_user_group, user_group)
504 'Revoked perm on %s on %s', target_user_group, user_group)
500 action_logger_generic(
505 action_logger_generic(
501 'revoked permission from usergroup: {} on usergroup: {}'.format(
506 'revoked permission from usergroup: {} on usergroup: {}'.format(
502 user_group, target_user_group),
507 user_group, target_user_group),
503 namespace='security.repogroup')
508 namespace='security.repogroup')
504
509
505 def get_perms_summary(self, user_group_id):
510 def get_perms_summary(self, user_group_id):
506 permissions = {
511 permissions = {
507 'repositories': {},
512 'repositories': {},
508 'repositories_groups': {},
513 'repositories_groups': {},
509 }
514 }
510 ugroup_repo_perms = UserGroupRepoToPerm.query()\
515 ugroup_repo_perms = UserGroupRepoToPerm.query()\
511 .options(joinedload(UserGroupRepoToPerm.permission))\
516 .options(joinedload(UserGroupRepoToPerm.permission))\
512 .options(joinedload(UserGroupRepoToPerm.repository))\
517 .options(joinedload(UserGroupRepoToPerm.repository))\
513 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
518 .filter(UserGroupRepoToPerm.users_group_id == user_group_id)\
514 .all()
519 .all()
515
520
516 for gr in ugroup_repo_perms:
521 for gr in ugroup_repo_perms:
517 permissions['repositories'][gr.repository.repo_name] \
522 permissions['repositories'][gr.repository.repo_name] \
518 = gr.permission.permission_name
523 = gr.permission.permission_name
519
524
520 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
525 ugroup_group_perms = UserGroupRepoGroupToPerm.query()\
521 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
526 .options(joinedload(UserGroupRepoGroupToPerm.permission))\
522 .options(joinedload(UserGroupRepoGroupToPerm.group))\
527 .options(joinedload(UserGroupRepoGroupToPerm.group))\
523 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
528 .filter(UserGroupRepoGroupToPerm.users_group_id == user_group_id)\
524 .all()
529 .all()
525
530
526 for gr in ugroup_group_perms:
531 for gr in ugroup_group_perms:
527 permissions['repositories_groups'][gr.group.group_name] \
532 permissions['repositories_groups'][gr.group.group_name] \
528 = gr.permission.permission_name
533 = gr.permission.permission_name
529 return permissions
534 return permissions
530
535
531 def enforce_groups(self, user, groups, extern_type=None):
536 def enforce_groups(self, user, groups, extern_type=None):
532 user = self._get_user(user)
537 user = self._get_user(user)
533 current_groups = user.group_member
538 current_groups = user.group_member
534
539
535 # find the external created groups, i.e automatically created
540 # find the external created groups, i.e automatically created
536 log.debug('Enforcing user group set `%s` on user %s', groups, user)
541 log.debug('Enforcing user group set `%s` on user %s', groups, user)
537 # calculate from what groups user should be removed
542 # calculate from what groups user should be removed
538 # external_groups that are not in groups
543 # external_groups that are not in groups
539 for gr in [x.users_group for x in current_groups]:
544 for gr in [x.users_group for x in current_groups]:
540 managed = gr.group_data.get('extern_type')
545 managed = gr.group_data.get('extern_type')
541 if managed:
546 if managed:
542 if gr.users_group_name not in groups:
547 if gr.users_group_name not in groups:
543 log.debug('Removing user %s from user group %s. '
548 log.debug('Removing user %s from user group %s. '
544 'Group sync managed by: %s', user, gr, managed)
549 'Group sync managed by: %s', user, gr, managed)
545 self.remove_user_from_group(gr, user)
550 self.remove_user_from_group(gr, user)
546 else:
551 else:
547 log.debug('Skipping removal from group %s since it is '
552 log.debug('Skipping removal from group %s since it is '
548 'not set to be automatically synchronized' % gr)
553 'not set to be automatically synchronized' % gr)
549
554
550 # now we calculate in which groups user should be == groups params
555 # now we calculate in which groups user should be == groups params
551 owner = User.get_first_super_admin().username
556 owner = User.get_first_super_admin().username
552 for gr in set(groups):
557 for gr in set(groups):
553 existing_group = UserGroup.get_by_group_name(gr)
558 existing_group = UserGroup.get_by_group_name(gr)
554 if not existing_group:
559 if not existing_group:
555 desc = 'Automatically created from plugin:%s' % extern_type
560 desc = 'Automatically created from plugin:%s' % extern_type
556 # we use first admin account to set the owner of the group
561 # we use first admin account to set the owner of the group
557 existing_group = UserGroupModel().create(
562 existing_group = UserGroupModel().create(
558 gr, desc, owner, group_data={'extern_type': extern_type})
563 gr, desc, owner, group_data={'extern_type': extern_type})
559
564
560 # we can only add users to groups which have set sync flag via
565 # we can only add users to groups which have set sync flag via
561 # extern_type attribute.
566 # extern_type attribute.
562 # This is either set and created via plugins, or manually
567 # This is either set and created via plugins, or manually
563 managed = existing_group.group_data.get('extern_type')
568 managed = existing_group.group_data.get('extern_type')
564 if managed:
569 if managed:
565 log.debug('Adding user %s to user group %s', user, gr)
570 log.debug('Adding user %s to user group %s', user, gr)
566 UserGroupModel().add_user_to_group(existing_group, user)
571 UserGroupModel().add_user_to_group(existing_group, user)
567 else:
572 else:
568 log.debug('Skipping addition to group %s since it is '
573 log.debug('Skipping addition to group %s since it is '
569 'not set to be automatically synchronized' % gr)
574 'not set to be automatically synchronized' % gr)
570
575
571 def change_groups(self, user, groups):
576 def change_groups(self, user, groups):
572 """
577 """
573 This method changes user group assignment
578 This method changes user group assignment
574 :param user: User
579 :param user: User
575 :param groups: array of UserGroupModel
580 :param groups: array of UserGroupModel
576 """
581 """
577 user = self._get_user(user)
582 user = self._get_user(user)
578 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
583 log.debug('Changing user(%s) assignment to groups(%s)', user, groups)
579 current_groups = user.group_member
584 current_groups = user.group_member
580 current_groups = [x.users_group for x in current_groups]
585 current_groups = [x.users_group for x in current_groups]
581
586
582 # calculate from what groups user should be removed/add
587 # calculate from what groups user should be removed/add
583 groups = set(groups)
588 groups = set(groups)
584 current_groups = set(current_groups)
589 current_groups = set(current_groups)
585
590
586 groups_to_remove = current_groups - groups
591 groups_to_remove = current_groups - groups
587 groups_to_add = groups - current_groups
592 groups_to_add = groups - current_groups
588
593
589 removed_from_groups = []
594 removed_from_groups = []
590 added_to_groups = []
595 added_to_groups = []
591 for gr in groups_to_remove:
596 for gr in groups_to_remove:
592 log.debug('Removing user %s from user group %s',
597 log.debug('Removing user %s from user group %s',
593 user.username, gr.users_group_name)
598 user.username, gr.users_group_name)
594 removed_from_groups.append(gr.users_group_id)
599 removed_from_groups.append(gr.users_group_id)
595 self.remove_user_from_group(gr.users_group_name, user.username)
600 self.remove_user_from_group(gr.users_group_name, user.username)
596 for gr in groups_to_add:
601 for gr in groups_to_add:
597 log.debug('Adding user %s to user group %s',
602 log.debug('Adding user %s to user group %s',
598 user.username, gr.users_group_name)
603 user.username, gr.users_group_name)
599 added_to_groups.append(gr.users_group_id)
604 added_to_groups.append(gr.users_group_id)
600 UserGroupModel().add_user_to_group(
605 UserGroupModel().add_user_to_group(
601 gr.users_group_name, user.username)
606 gr.users_group_name, user.username)
602
607
603 return added_to_groups, removed_from_groups
608 return added_to_groups, removed_from_groups
604
609
605 def _serialize_user_group(self, user_group):
610 def _serialize_user_group(self, user_group):
606 import rhodecode.lib.helpers as h
611 import rhodecode.lib.helpers as h
607 return {
612 return {
608 'id': user_group.users_group_id,
613 'id': user_group.users_group_id,
609 # TODO: marcink figure out a way to generate the url for the
614 # TODO: marcink figure out a way to generate the url for the
610 # icon
615 # icon
611 'icon_link': '',
616 'icon_link': '',
612 'value_display': 'Group: %s (%d members)' % (
617 'value_display': 'Group: %s (%d members)' % (
613 user_group.users_group_name, len(user_group.members),),
618 user_group.users_group_name, len(user_group.members),),
614 'value': user_group.users_group_name,
619 'value': user_group.users_group_name,
615 'description': user_group.user_group_description,
620 'description': user_group.user_group_description,
616 'owner': user_group.user.username,
621 'owner': user_group.user.username,
617
622
618 'owner_icon': h.gravatar_url(user_group.user.email, 30),
623 'owner_icon': h.gravatar_url(user_group.user.email, 30),
619 'value_display_owner': h.person(user_group.user.email),
624 'value_display_owner': h.person(user_group.user.email),
620
625
621 'value_type': 'user_group',
626 'value_type': 'user_group',
622 'active': user_group.users_group_active,
627 'active': user_group.users_group_active,
623 }
628 }
624
629
625 def get_user_groups(self, name_contains=None, limit=20, only_active=True,
630 def get_user_groups(self, name_contains=None, limit=20, only_active=True,
626 expand_groups=False):
631 expand_groups=False):
627 query = self.sa.query(UserGroup)
632 query = self.sa.query(UserGroup)
628 if only_active:
633 if only_active:
629 query = query.filter(UserGroup.users_group_active == true())
634 query = query.filter(UserGroup.users_group_active == true())
630
635
631 if name_contains:
636 if name_contains:
632 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
637 ilike_expression = u'%{}%'.format(safe_unicode(name_contains))
633 query = query.filter(
638 query = query.filter(
634 UserGroup.users_group_name.ilike(ilike_expression))\
639 UserGroup.users_group_name.ilike(ilike_expression))\
635 .order_by(func.length(UserGroup.users_group_name))\
640 .order_by(func.length(UserGroup.users_group_name))\
636 .order_by(UserGroup.users_group_name)
641 .order_by(UserGroup.users_group_name)
637
642
638 query = query.limit(limit)
643 query = query.limit(limit)
639 user_groups = query.all()
644 user_groups = query.all()
640 perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin']
645 perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin']
641 user_groups = UserGroupList(user_groups, perm_set=perm_set)
646 user_groups = UserGroupList(user_groups, perm_set=perm_set)
642
647
643 # store same serialize method to extract data from User
648 # store same serialize method to extract data from User
644 from rhodecode.model.user import UserModel
649 from rhodecode.model.user import UserModel
645 serialize_user = UserModel()._serialize_user
650 serialize_user = UserModel()._serialize_user
646
651
647 _groups = []
652 _groups = []
648 for group in user_groups:
653 for group in user_groups:
649 entry = self._serialize_user_group(group)
654 entry = self._serialize_user_group(group)
650 if expand_groups:
655 if expand_groups:
651 expanded_members = []
656 expanded_members = []
652 for member in group.members:
657 for member in group.members:
653 expanded_members.append(serialize_user(member.user))
658 expanded_members.append(serialize_user(member.user))
654 entry['members'] = expanded_members
659 entry['members'] = expanded_members
655 _groups.append(entry)
660 _groups.append(entry)
656 return _groups
661 return _groups
657
662
658 @staticmethod
663 @staticmethod
659 def get_user_groups_as_dict(user_group):
664 def get_user_groups_as_dict(user_group):
660 import rhodecode.lib.helpers as h
665 import rhodecode.lib.helpers as h
661
666
662 data = {
667 data = {
663 'users_group_id': user_group.users_group_id,
668 'users_group_id': user_group.users_group_id,
664 'group_name': user_group.users_group_name,
669 'group_name': user_group.users_group_name,
665 'group_description': user_group.user_group_description,
670 'group_description': user_group.user_group_description,
666 'active': user_group.users_group_active,
671 'active': user_group.users_group_active,
667 "owner": user_group.user.username,
672 "owner": user_group.user.username,
668 'owner_icon': h.gravatar_url(user_group.user.email, 30),
673 'owner_icon': h.gravatar_url(user_group.user.email, 30),
669 "owner_data": {
674 "owner_data": {
670 'owner': user_group.user.username,
675 'owner': user_group.user.username,
671 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
676 'owner_icon': h.gravatar_url(user_group.user.email, 30)}
672 }
677 }
673 return data
678 return data
General Comments 0
You need to be logged in to leave comments. Login now