Show More
@@ -242,7 +242,8 b' class AdminUsersView(BaseAppView, DataGr' | |||||
242 | c.user = User.get_or_404(user_id, pyramid_exc=True) |
|
242 | c.user = User.get_or_404(user_id, pyramid_exc=True) | |
243 | c.data = c.user.group_member |
|
243 | c.data = c.user.group_member | |
244 | self._redirect_for_default_user(c.user.username) |
|
244 | self._redirect_for_default_user(c.user.username) | |
245 |
groups = [UserGroupModel.get_user_groups_as_dict(group.users_group) |
|
245 | groups = [UserGroupModel.get_user_groups_as_dict(group.users_group) | |
|
246 | for group in c.user.group_member] | |||
246 | c.groups = json.dumps(groups) |
|
247 | c.groups = json.dumps(groups) | |
247 | c.active = 'groups' |
|
248 | c.active = 'groups' | |
248 |
|
249 |
@@ -31,7 +31,7 b' from rhodecode.lib.utils2 import safe_un' | |||||
31 | from rhodecode.model.db import func, Repository, RepoGroup |
|
31 | from rhodecode.model.db import func, Repository, RepoGroup | |
32 | from rhodecode.model.repo import RepoModel |
|
32 | from rhodecode.model.repo import RepoModel | |
33 | from rhodecode.model.scm import ScmModel |
|
33 | from rhodecode.model.scm import ScmModel | |
34 |
|
34 | from rhodecode.model.user_group import UserGroupModel | ||
35 |
|
35 | |||
36 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
37 |
|
37 | |||
@@ -62,7 +62,7 b' class HomeView(BaseAppView):' | |||||
62 |
|
62 | |||
63 | if include_groups: |
|
63 | if include_groups: | |
64 | # extend with user groups |
|
64 | # extend with user groups | |
65 |
_user_groups = |
|
65 | _user_groups = UserGroupModel().get_user_groups( | |
66 | name_contains=query, only_active=active) |
|
66 | name_contains=query, only_active=active) | |
67 | _users = _users + _user_groups |
|
67 | _users = _users + _user_groups | |
68 |
|
68 | |||
@@ -79,8 +79,7 b' class HomeView(BaseAppView):' | |||||
79 | log.debug('generating user group list, query:%s, active:%s', |
|
79 | log.debug('generating user group list, query:%s, active:%s', | |
80 | query, active) |
|
80 | query, active) | |
81 |
|
81 | |||
82 | repo_model = RepoModel() |
|
82 | _user_groups = UserGroupModel().get_user_groups( | |
83 | _user_groups = repo_model.get_user_groups( |
|
|||
84 | name_contains=query, only_active=active) |
|
83 | name_contains=query, only_active=active) | |
85 | _user_groups = _user_groups |
|
84 | _user_groups = _user_groups | |
86 |
|
85 |
@@ -30,7 +30,6 b' import time' | |||||
30 | import traceback |
|
30 | import traceback | |
31 | from datetime import datetime, timedelta |
|
31 | from datetime import datetime, timedelta | |
32 |
|
32 | |||
33 | from sqlalchemy.sql import func |
|
|||
34 | from sqlalchemy.sql.expression import true, or_ |
|
33 | from sqlalchemy.sql.expression import true, or_ | |
35 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
34 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
36 |
|
35 | |||
@@ -40,19 +39,17 b' from rhodecode.lib.auth import HasUserGr' | |||||
40 | from rhodecode.lib.caching_query import FromCache |
|
39 | from rhodecode.lib.caching_query import FromCache | |
41 | from rhodecode.lib.exceptions import AttachedForksError |
|
40 | from rhodecode.lib.exceptions import AttachedForksError | |
42 | from rhodecode.lib.hooks_base import log_delete_repository |
|
41 | from rhodecode.lib.hooks_base import log_delete_repository | |
43 | from rhodecode.lib.markup_renderer import MarkupRenderer |
|
|||
44 | from rhodecode.lib.utils import make_db_config |
|
42 | from rhodecode.lib.utils import make_db_config | |
45 | from rhodecode.lib.utils2 import ( |
|
43 | from rhodecode.lib.utils2 import ( | |
46 | safe_str, safe_unicode, remove_prefix, obfuscate_url_pw, |
|
44 | safe_str, safe_unicode, remove_prefix, obfuscate_url_pw, | |
47 | get_current_rhodecode_user, safe_int, datetime_to_time, action_logger_generic) |
|
45 | get_current_rhodecode_user, safe_int, datetime_to_time, action_logger_generic) | |
48 | from rhodecode.lib.vcs.backends import get_backend |
|
46 | from rhodecode.lib.vcs.backends import get_backend | |
49 | from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError |
|
|||
50 | from rhodecode.model import BaseModel |
|
47 | from rhodecode.model import BaseModel | |
51 | from rhodecode.model.db import ( |
|
48 | from rhodecode.model.db import ( | |
52 | Repository, UserRepoToPerm, UserGroupRepoToPerm, UserRepoGroupToPerm, |
|
49 | Repository, UserRepoToPerm, UserGroupRepoToPerm, UserRepoGroupToPerm, | |
53 | UserGroupRepoGroupToPerm, User, Permission, Statistics, UserGroup, |
|
50 | UserGroupRepoGroupToPerm, User, Permission, Statistics, UserGroup, | |
54 | RepoGroup, RepositoryField) |
|
51 | RepoGroup, RepositoryField) | |
55 | from rhodecode.model.scm import UserGroupList |
|
52 | ||
56 | from rhodecode.model.settings import VcsSettingsModel |
|
53 | from rhodecode.model.settings import VcsSettingsModel | |
57 |
|
54 | |||
58 |
|
55 | |||
@@ -196,47 +193,6 b' class RepoModel(BaseModel):' | |||||
196 | ] |
|
193 | ] | |
197 | return _users |
|
194 | return _users | |
198 |
|
195 | |||
199 | def get_user_groups(self, name_contains=None, limit=20, only_active=True): |
|
|||
200 |
|
||||
201 | # TODO: mikhail: move this method to the UserGroupModel. |
|
|||
202 | query = self.sa.query(UserGroup) |
|
|||
203 | if only_active: |
|
|||
204 | query = query.filter(UserGroup.users_group_active == true()) |
|
|||
205 |
|
||||
206 | if name_contains: |
|
|||
207 | ilike_expression = u'%{}%'.format(safe_unicode(name_contains)) |
|
|||
208 | query = query.filter( |
|
|||
209 | UserGroup.users_group_name.ilike(ilike_expression))\ |
|
|||
210 | .order_by(func.length(UserGroup.users_group_name))\ |
|
|||
211 | .order_by(UserGroup.users_group_name) |
|
|||
212 |
|
||||
213 | query = query.limit(limit) |
|
|||
214 | user_groups = query.all() |
|
|||
215 | perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] |
|
|||
216 | user_groups = UserGroupList(user_groups, perm_set=perm_set) |
|
|||
217 |
|
||||
218 | _groups = [ |
|
|||
219 | { |
|
|||
220 | 'id': group.users_group_id, |
|
|||
221 | # TODO: marcink figure out a way to generate the url for the |
|
|||
222 | # icon |
|
|||
223 | 'icon_link': '', |
|
|||
224 | 'value_display': 'Group: %s (%d members)' % ( |
|
|||
225 | group.users_group_name, len(group.members),), |
|
|||
226 | 'value': group.users_group_name, |
|
|||
227 | 'description': group.user_group_description, |
|
|||
228 | 'owner': group.user.username, |
|
|||
229 |
|
||||
230 | 'owner_icon': h.gravatar_url(group.user.email, 30), |
|
|||
231 | 'value_display_owner': h.person(group.user.email), |
|
|||
232 |
|
||||
233 | 'value_type': 'user_group', |
|
|||
234 | 'active': group.users_group_active, |
|
|||
235 | } |
|
|||
236 | for group in user_groups |
|
|||
237 | ] |
|
|||
238 | return _groups |
|
|||
239 |
|
||||
240 | @classmethod |
|
196 | @classmethod | |
241 | def update_repoinfo(cls, repositories=None): |
|
197 | def update_repoinfo(cls, repositories=None): | |
242 | if not repositories: |
|
198 | if not repositories: |
@@ -27,9 +27,10 b' user group model for RhodeCode' | |||||
27 | import logging |
|
27 | import logging | |
28 | import traceback |
|
28 | import traceback | |
29 |
|
29 | |||
30 | from rhodecode.lib.utils2 import safe_str |
|
30 | from rhodecode.lib.utils2 import safe_str, safe_unicode | |
31 | from rhodecode.model import BaseModel |
|
31 | from rhodecode.model import BaseModel | |
32 |
from rhodecode.model. |
|
32 | from rhodecode.model.scm import UserGroupList | |
|
33 | from rhodecode.model.db import true, func, UserGroupMember, UserGroup,\ | |||
33 | UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm,\ |
|
34 | UserGroupRepoToPerm, Permission, UserGroupToPerm, User, UserUserGroupToPerm,\ | |
34 | UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm |
|
35 | UserGroupUserGroupToPerm, UserGroupRepoGroupToPerm | |
35 | from rhodecode.lib.exceptions import UserGroupAssignedException,\ |
|
36 | from rhodecode.lib.exceptions import UserGroupAssignedException,\ | |
@@ -539,6 +540,48 b' class UserGroupModel(BaseModel):' | |||||
539 | log.debug('Adding user %s to user group %s', user.username, gr.users_group_name) |
|
540 | log.debug('Adding user %s to user group %s', user.username, gr.users_group_name) | |
540 | UserGroupModel().add_user_to_group(gr.users_group_name, user.username) |
|
541 | UserGroupModel().add_user_to_group(gr.users_group_name, user.username) | |
541 |
|
542 | |||
|
543 | def get_user_groups(self, name_contains=None, limit=20, only_active=True, | |||
|
544 | expand_groups=False): | |||
|
545 | import rhodecode.lib.helpers as h | |||
|
546 | ||||
|
547 | query = self.sa.query(UserGroup) | |||
|
548 | if only_active: | |||
|
549 | query = query.filter(UserGroup.users_group_active == true()) | |||
|
550 | ||||
|
551 | if name_contains: | |||
|
552 | ilike_expression = u'%{}%'.format(safe_unicode(name_contains)) | |||
|
553 | query = query.filter( | |||
|
554 | UserGroup.users_group_name.ilike(ilike_expression))\ | |||
|
555 | .order_by(func.length(UserGroup.users_group_name))\ | |||
|
556 | .order_by(UserGroup.users_group_name) | |||
|
557 | ||||
|
558 | query = query.limit(limit) | |||
|
559 | user_groups = query.all() | |||
|
560 | perm_set = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] | |||
|
561 | user_groups = UserGroupList(user_groups, perm_set=perm_set) | |||
|
562 | ||||
|
563 | _groups = [ | |||
|
564 | { | |||
|
565 | 'id': group.users_group_id, | |||
|
566 | # TODO: marcink figure out a way to generate the url for the | |||
|
567 | # icon | |||
|
568 | 'icon_link': '', | |||
|
569 | 'value_display': 'Group: %s (%d members)' % ( | |||
|
570 | group.users_group_name, len(group.members),), | |||
|
571 | 'value': group.users_group_name, | |||
|
572 | 'description': group.user_group_description, | |||
|
573 | 'owner': group.user.username, | |||
|
574 | ||||
|
575 | 'owner_icon': h.gravatar_url(group.user.email, 30), | |||
|
576 | 'value_display_owner': h.person(group.user.email), | |||
|
577 | ||||
|
578 | 'value_type': 'user_group', | |||
|
579 | 'active': group.users_group_active, | |||
|
580 | } | |||
|
581 | for group in user_groups | |||
|
582 | ] | |||
|
583 | return _groups | |||
|
584 | ||||
542 | @staticmethod |
|
585 | @staticmethod | |
543 | def get_user_groups_as_dict(user_group): |
|
586 | def get_user_groups_as_dict(user_group): | |
544 | import rhodecode.lib.helpers as h |
|
587 | import rhodecode.lib.helpers as h | |
@@ -550,7 +593,9 b' class UserGroupModel(BaseModel):' | |||||
550 | 'active': user_group.users_group_active, |
|
593 | 'active': user_group.users_group_active, | |
551 | "owner": user_group.user.username, |
|
594 | "owner": user_group.user.username, | |
552 | 'owner_icon': h.gravatar_url(user_group.user.email, 30), |
|
595 | 'owner_icon': h.gravatar_url(user_group.user.email, 30), | |
553 | "owner_data": {'owner': user_group.user.username, 'owner_icon': h.gravatar_url(user_group.user.email, 30)} |
|
596 | "owner_data": { | |
|
597 | 'owner': user_group.user.username, | |||
|
598 | 'owner_icon': h.gravatar_url(user_group.user.email, 30)} | |||
554 | } |
|
599 | } | |
555 | return data |
|
600 | return data | |
556 |
|
601 |
@@ -29,10 +29,9 b' from rhodecode.model.db import Repositor' | |||||
29 | from rhodecode.model.meta import Session |
|
29 | from rhodecode.model.meta import Session | |
30 | from rhodecode.model.repo import RepoModel |
|
30 | from rhodecode.model.repo import RepoModel | |
31 | from rhodecode.model.scm import ScmModel |
|
31 | from rhodecode.model.scm import ScmModel | |
32 | from rhodecode.lib.utils2 import safe_unicode |
|
|||
33 |
|
32 | |||
34 |
|
33 | |||
35 | class TestRepoModel: |
|
34 | class TestRepoModel(object): | |
36 |
|
35 | |||
37 | def test_remove_repo(self, backend): |
|
36 | def test_remove_repo(self, backend): | |
38 | repo = backend.create_repo() |
|
37 | repo = backend.create_repo() | |
@@ -251,60 +250,3 b' class TestGetUsers(object):' | |||||
251 | fake_users = [u for u in users if u['last_name'].startswith('Fake')] |
|
250 | fake_users = [u for u in users if u['last_name'].startswith('Fake')] | |
252 | assert len(fake_users) == 3 |
|
251 | assert len(fake_users) == 3 | |
253 |
|
252 | |||
254 |
|
||||
255 | class TestGetUserGroups(object): |
|
|||
256 | def test_returns_filtered_list(self, backend, user_util): |
|
|||
257 | created_groups = [] |
|
|||
258 | for i in range(4): |
|
|||
259 | created_groups.append( |
|
|||
260 | user_util.create_user_group(users_group_active=True)) |
|
|||
261 |
|
||||
262 | group_filter = created_groups[-1].users_group_name[-2:] |
|
|||
263 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): |
|
|||
264 | with self._patch_user_group_list(): |
|
|||
265 | groups = RepoModel().get_user_groups(group_filter) |
|
|||
266 |
|
||||
267 | fake_groups = [ |
|
|||
268 | u for u in groups if u['value'].startswith('test_returns')] |
|
|||
269 | assert len(fake_groups) == 1 |
|
|||
270 | assert fake_groups[0]['value'] == created_groups[-1].users_group_name |
|
|||
271 | assert fake_groups[0]['value_display'].startswith( |
|
|||
272 | 'Group: test_returns') |
|
|||
273 |
|
||||
274 | def test_returns_limited_list(self, backend, user_util): |
|
|||
275 | created_groups = [] |
|
|||
276 | for i in range(3): |
|
|||
277 | created_groups.append( |
|
|||
278 | user_util.create_user_group(users_group_active=True)) |
|
|||
279 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): |
|
|||
280 | with self._patch_user_group_list(): |
|
|||
281 | groups = RepoModel().get_user_groups('test_returns') |
|
|||
282 |
|
||||
283 | fake_groups = [ |
|
|||
284 | u for u in groups if u['value'].startswith('test_returns')] |
|
|||
285 | assert len(fake_groups) == 3 |
|
|||
286 |
|
||||
287 | def test_returns_active_user_groups(self, backend, user_util): |
|
|||
288 | for i in range(4): |
|
|||
289 | is_active = i % 2 == 0 |
|
|||
290 | user_util.create_user_group(users_group_active=is_active) |
|
|||
291 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): |
|
|||
292 | with self._patch_user_group_list(): |
|
|||
293 | groups = RepoModel().get_user_groups() |
|
|||
294 | expected = ('id', 'icon_link', 'value_display', 'value', 'value_type') |
|
|||
295 | for group in groups: |
|
|||
296 | assert group['value_type'] is 'user_group' |
|
|||
297 | for key in expected: |
|
|||
298 | assert key in group |
|
|||
299 |
|
||||
300 | fake_groups = [ |
|
|||
301 | u for u in groups if u['value'].startswith('test_returns')] |
|
|||
302 | assert len(fake_groups) == 2 |
|
|||
303 | for user in fake_groups: |
|
|||
304 | assert user['value_display'].startswith('Group: test_returns') |
|
|||
305 |
|
||||
306 | def _patch_user_group_list(self): |
|
|||
307 | def side_effect(group_list, perm_set): |
|
|||
308 | return group_list |
|
|||
309 | return mock.patch( |
|
|||
310 | 'rhodecode.model.repo.UserGroupList', side_effect=side_effect) |
|
@@ -35,6 +35,64 b' def teardown_module(self):' | |||||
35 | _delete_all_user_groups() |
|
35 | _delete_all_user_groups() | |
36 |
|
36 | |||
37 |
|
37 | |||
|
38 | class TestGetUserGroups(object): | |||
|
39 | def test_returns_filtered_list(self, backend, user_util): | |||
|
40 | created_groups = [] | |||
|
41 | for i in range(4): | |||
|
42 | created_groups.append( | |||
|
43 | user_util.create_user_group(users_group_active=True)) | |||
|
44 | ||||
|
45 | group_filter = created_groups[-1].users_group_name[-2:] | |||
|
46 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): | |||
|
47 | with self._patch_user_group_list(): | |||
|
48 | groups = UserGroupModel().get_user_groups(group_filter) | |||
|
49 | ||||
|
50 | fake_groups = [ | |||
|
51 | u for u in groups if u['value'].startswith('test_returns')] | |||
|
52 | assert len(fake_groups) == 1 | |||
|
53 | assert fake_groups[0]['value'] == created_groups[-1].users_group_name | |||
|
54 | assert fake_groups[0]['value_display'].startswith( | |||
|
55 | 'Group: test_returns') | |||
|
56 | ||||
|
57 | def test_returns_limited_list(self, backend, user_util): | |||
|
58 | created_groups = [] | |||
|
59 | for i in range(3): | |||
|
60 | created_groups.append( | |||
|
61 | user_util.create_user_group(users_group_active=True)) | |||
|
62 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): | |||
|
63 | with self._patch_user_group_list(): | |||
|
64 | groups = UserGroupModel().get_user_groups('test_returns') | |||
|
65 | ||||
|
66 | fake_groups = [ | |||
|
67 | u for u in groups if u['value'].startswith('test_returns')] | |||
|
68 | assert len(fake_groups) == 3 | |||
|
69 | ||||
|
70 | def test_returns_active_user_groups(self, backend, user_util): | |||
|
71 | for i in range(4): | |||
|
72 | is_active = i % 2 == 0 | |||
|
73 | user_util.create_user_group(users_group_active=is_active) | |||
|
74 | with mock.patch('rhodecode.lib.helpers.gravatar_url'): | |||
|
75 | with self._patch_user_group_list(): | |||
|
76 | groups = UserGroupModel().get_user_groups() | |||
|
77 | expected = ('id', 'icon_link', 'value_display', 'value', 'value_type') | |||
|
78 | for group in groups: | |||
|
79 | assert group['value_type'] is 'user_group' | |||
|
80 | for key in expected: | |||
|
81 | assert key in group | |||
|
82 | ||||
|
83 | fake_groups = [ | |||
|
84 | u for u in groups if u['value'].startswith('test_returns')] | |||
|
85 | assert len(fake_groups) == 2 | |||
|
86 | for user in fake_groups: | |||
|
87 | assert user['value_display'].startswith('Group: test_returns') | |||
|
88 | ||||
|
89 | def _patch_user_group_list(self): | |||
|
90 | def side_effect(group_list, perm_set): | |||
|
91 | return group_list | |||
|
92 | return mock.patch( | |||
|
93 | 'rhodecode.model.user_group.UserGroupList', side_effect=side_effect) | |||
|
94 | ||||
|
95 | ||||
38 | @pytest.mark.parametrize( |
|
96 | @pytest.mark.parametrize( | |
39 | "pre_existing, regular_should_be, external_should_be, groups, " |
|
97 | "pre_existing, regular_should_be, external_should_be, groups, " | |
40 | "expected", [ |
|
98 | "expected", [ |
General Comments 0
You need to be logged in to leave comments.
Login now