# HG changeset patch # User Bartłomiej Wołyńczyk # Date 2018-02-18 20:58:45 # Node ID 01feb8aae1f1145aa81a343922dfaed2ede3c713 # Parent 96836581ac4c059e544fdebfc90f649ac780a498 Public user group profile Task #5326 diff --git a/rhodecode/apps/user_group_profile/__init__.py b/rhodecode/apps/user_group_profile/__init__.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_group_profile/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2018 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + + +def includeme(config): + config.add_route( + name='user_group_profile', + pattern='/_profile_user_group/{user_group_name}') + # Scan module for configuration decorators. + config.scan('.views', ignore='.tests') diff --git a/rhodecode/apps/user_group_profile/tests/__init__.py b/rhodecode/apps/user_group_profile/tests/__init__.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_group_profile/tests/__init__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2018 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ diff --git a/rhodecode/apps/user_group_profile/tests/test_user_group.py b/rhodecode/apps/user_group_profile/tests/test_user_group.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_group_profile/tests/test_user_group.py @@ -0,0 +1,76 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2010-2018 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ +from rhodecode.model.user_group import UserGroupModel +from rhodecode.tests import ( + TestController, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests.fixture import Fixture +from rhodecode.tests.utils import AssertResponse + +fixture = Fixture() + + +def route_path(name, **kwargs): + return '/_profile_user_group/{user_group_name}'.format(**kwargs) + + +class TestUsersController(TestController): + + def test_user_group_profile(self, user_util): + self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + user, usergroup = user_util.create_user_with_group() + + response = self.app.get(route_path('profile_user_group', user_group_name=usergroup.users_group_name)) + response.mustcontain(usergroup.users_group_name) + response.mustcontain(user.username) + + def test_user_can_check_own_group(self, user_util): + user = user_util.create_user( + TEST_USER_REGULAR_LOGIN, password=TEST_USER_REGULAR_PASS, email='testme@rhodecode.org') + self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + usergroup = user_util.create_user_group(owner=user) + response = self.app.get(route_path('profile_user_group', user_group_name=usergroup.users_group_name)) + response.mustcontain(usergroup.users_group_name) + response.mustcontain(user.username) + + def test_user_can_not_check_other_group(self, user_util): + self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + user_group = user_util.create_user_group() + UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), 'usergroup.none') + response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name), status=404) + assert response.status_code == 404 + + def test_another_user_can_check_if_he_is_in_group(self, user_util): + self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + user = user_util.create_user( + 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + user_group = user_util.create_user_group() + UserGroupModel().add_user_to_group(user_group, user) + UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), 'usergroup.read') + response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name)) + response.mustcontain(user_group.users_group_name) + response.mustcontain(user.username) + + def test_with_anonymous_user(self, user_util): + user = user_util.create_user( + 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + user_group = user_util.create_user_group() + UserGroupModel().add_user_to_group(user_group, user) + response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name), status=302) + assert response.status_code == 302 \ No newline at end of file diff --git a/rhodecode/apps/user_group_profile/views.py b/rhodecode/apps/user_group_profile/views.py new file mode 100644 --- /dev/null +++ b/rhodecode/apps/user_group_profile/views.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- + +# Copyright (C) 2016-2018 RhodeCode GmbH +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License, version 3 +# (only), as published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# This program is dual-licensed. If you wish to learn more about the +# RhodeCode Enterprise Edition, including its added features, Support services, +# and proprietary license terms, please see https://rhodecode.com/licenses/ + +import logging + +from pyramid.httpexceptions import HTTPNotFound +from pyramid.view import view_config + +from rhodecode.apps._base import BaseAppView +from rhodecode.lib.auth import HasUserGroupPermissionAnyDecorator, LoginRequired, NotAnonymous +from rhodecode.model.db import UserGroup, User + + +log = logging.getLogger(__name__) + + +class UserGroupProfileView(BaseAppView): + + @LoginRequired() + @NotAnonymous() + @HasUserGroupPermissionAnyDecorator('usergroup.read', 'usergroup.write', 'usergroup.admin',) + @view_config( + route_name='user_group_profile', request_method='GET', + renderer='rhodecode:templates/user_group/user_group.mako') + def user_group_profile(self): + c = self._get_local_tmpl_context() + c.active = 'profile' + self.db_user_group_name = self.request.matchdict.get('user_group_name') + c.user_group = UserGroup().get_by_group_name(self.db_user_group_name) + if not c.user_group: + raise HTTPNotFound() + group_members_obj = sorted((x.user for x in c.user_group.members), + key=lambda u: u.username.lower()) + c.group_members = group_members_obj + c.anonymous = self._rhodecode_user.username == User.DEFAULT_USER + return self._get_template_context(c) diff --git a/rhodecode/config/middleware.py b/rhodecode/config/middleware.py --- a/rhodecode/config/middleware.py +++ b/rhodecode/config/middleware.py @@ -226,6 +226,7 @@ def includeme(config): config.include('rhodecode.apps.user_group') config.include('rhodecode.apps.search') config.include('rhodecode.apps.user_profile') + config.include('rhodecode.apps.user_group_profile') config.include('rhodecode.apps.my_account') config.include('rhodecode.apps.svn_support') config.include('rhodecode.apps.ssh_support') diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -896,6 +896,13 @@ def link_to_user(author, length=0, **kwa return escape(display_person) +def link_to_group(users_group_name, **kwargs): + return link_to( + escape(users_group_name), + route_path('user_group_profile', user_group_name=users_group_name), + **kwargs) + + def person(author, show_attr="username_and_name"): user = discover_user(author) if user: diff --git a/rhodecode/lib/utils.py b/rhodecode/lib/utils.py --- a/rhodecode/lib/utils.py +++ b/rhodecode/lib/utils.py @@ -134,13 +134,17 @@ def get_user_group_slug(request): elif getattr(request, 'matchdict', None): # pyramid _user_group = request.matchdict.get('user_group_id') - + _user_group_name = request.matchdict.get('user_group_name') try: - _user_group = UserGroup.get(_user_group) + if _user_group: + _user_group = UserGroup.get(_user_group) + elif _user_group_name: + _user_group = UserGroup.get_by_group_name(_user_group_name) + if _user_group: _user_group = _user_group.users_group_name except Exception: - log.exception('Failed to get user group by id') + log.exception('Failed to get user group by id and name') # catch all failures here return None diff --git a/rhodecode/templates/admin/repo_groups/repo_group_edit_permissions.mako b/rhodecode/templates/admin/repo_groups/repo_group_edit_permissions.mako --- a/rhodecode/templates/admin/repo_groups/repo_group_edit_permissions.mako +++ b/rhodecode/templates/admin/repo_groups/repo_group_edit_permissions.mako @@ -98,7 +98,7 @@ ${_user_group.users_group_name} %else: - ${_user_group.users_group_name} + ${h.link_to_group(_user_group.users_group_name)} %endif diff --git a/rhodecode/templates/admin/repos/repo_edit_permissions.mako b/rhodecode/templates/admin/repos/repo_edit_permissions.mako --- a/rhodecode/templates/admin/repos/repo_edit_permissions.mako +++ b/rhodecode/templates/admin/repos/repo_edit_permissions.mako @@ -89,7 +89,7 @@ ${_user_group.users_group_name} %else: - ${_user_group.users_group_name} + ${h.link_to_group(_user_group.users_group_name)} %endif diff --git a/rhodecode/templates/admin/user_groups/user_group_edit_perms.mako b/rhodecode/templates/admin/user_groups/user_group_edit_perms.mako --- a/rhodecode/templates/admin/user_groups/user_group_edit_perms.mako +++ b/rhodecode/templates/admin/user_groups/user_group_edit_perms.mako @@ -100,7 +100,7 @@ ${_user_group.users_group_name} %else: - ${_user_group.users_group_name} + ${h.link_to_group(_user_group.users_group_name)} %endif diff --git a/rhodecode/templates/user_group/profile.mako b/rhodecode/templates/user_group/profile.mako new file mode 100644 --- /dev/null +++ b/rhodecode/templates/user_group/profile.mako @@ -0,0 +1,70 @@ +<%namespace name="base" file="/base/base.mako"/> + + \ No newline at end of file diff --git a/rhodecode/templates/user_group/user_group.mako b/rhodecode/templates/user_group/user_group.mako new file mode 100644 --- /dev/null +++ b/rhodecode/templates/user_group/user_group.mako @@ -0,0 +1,46 @@ +<%inherit file="/base/base.mako"/> + +<%def name="title()"> + ${_('User group')}: ${c.user_group.users_group_name} + %if c.rhodecode_name: + · ${h.branding(c.rhodecode_name)} + %endif + + +<%def name="breadcrumbs_links()"> + ${_('User group')}: ${c.user_group.users_group_name} + + +<%def name="menu_bar_nav()"> + ${self.menu_items(active='my_account')} + + +<%def name="main()"> +
+
+ ${self.breadcrumbs()} +
+ + +
+ +