# Copyright (C) 2010-2023 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 mock import pytest from rhodecode.model.db import User from rhodecode.tests import TEST_USER_REGULAR_LOGIN from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.model.user_group import UserGroupModel from rhodecode.model.meta import Session fixture = Fixture() def teardown_module(self): _delete_all_user_groups() class TestGetUserGroups(object): def test_returns_filtered_list(self, backend, user_util): created_groups = [] for i in range(4): created_groups.append( user_util.create_user_group(users_group_active=True)) group_filter = created_groups[-1].users_group_name[-2:] with mock.patch('rhodecode.lib.helpers.gravatar_url'): with self._patch_user_group_list(): groups = UserGroupModel().get_user_groups(group_filter) fake_groups = [ u for u in groups if u['value'].startswith('test_returns')] assert len(fake_groups) == 1 assert fake_groups[0]['value'] == created_groups[-1].users_group_name assert fake_groups[0]['value_display'].startswith( 'Group: test_returns') def test_returns_limited_list(self, backend, user_util): created_groups = [] for i in range(3): created_groups.append( user_util.create_user_group(users_group_active=True)) with mock.patch('rhodecode.lib.helpers.gravatar_url'): with self._patch_user_group_list(): groups = UserGroupModel().get_user_groups('test_returns') fake_groups = [ u for u in groups if u['value'].startswith('test_returns')] assert len(fake_groups) == 3 def test_returns_active_user_groups(self, backend, user_util): for i in range(4): is_active = i % 2 == 0 user_util.create_user_group(users_group_active=is_active) with mock.patch('rhodecode.lib.helpers.gravatar_url'): with self._patch_user_group_list(): groups = UserGroupModel().get_user_groups() expected = ('id', 'icon_link', 'value_display', 'value', 'value_type') for group in groups: assert group['value_type'] == 'user_group' for key in expected: assert key in group fake_groups = [ u for u in groups if u['value'].startswith('test_returns')] assert len(fake_groups) == 2 for user in fake_groups: assert user['value_display'].startswith('Group: test_returns') def _patch_user_group_list(self): def side_effect(group_list, perm_set): return group_list return mock.patch( 'rhodecode.model.user_group.UserGroupList', side_effect=side_effect) @pytest.mark.parametrize( "pre_existing, regular_should_be, external_should_be, groups, " "expected", [ ([], [], [], [], []), # no changes of regular ([], ['regular'], [], [], ['regular']), # not added to regular group (['some_other'], [], [], ['some_other'], []), ( [], ['regular'], ['container'], ['container'], ['regular', 'container'] ), ( [], ['regular'], [], ['container', 'container2'], ['regular', 'container', 'container2'] ), # remove not used ([], ['regular'], ['other'], [], ['regular']), ( ['some_other'], ['regular'], ['other', 'container'], ['container', 'container2'], ['regular', 'container', 'container2'] ), ]) def test_enforce_groups(pre_existing, regular_should_be, external_should_be, groups, expected, backend_hg): # TODO: anderson: adding backend_hg fixture so it sets up the database # for when running this file alone _delete_all_user_groups() user = User.get_by_username(TEST_USER_REGULAR_LOGIN) for gr in pre_existing: gr = fixture.create_user_group(gr) Session().commit() # make sure use is just in those groups for gr in regular_should_be: gr = fixture.create_user_group(gr) Session().commit() UserGroupModel().add_user_to_group(gr, user) Session().commit() # now special external groups created by auth plugins for gr in external_should_be: gr = fixture.create_user_group( gr, user_group_data={'extern_type': 'container'}) Session().commit() UserGroupModel().add_user_to_group(gr, user) Session().commit() UserGroupModel().enforce_groups(user, groups, 'container') Session().commit() user = User.get_by_username(TEST_USER_REGULAR_LOGIN) in_groups = user.group_member expected.sort() assert ( expected == sorted(x.users_group.users_group_name for x in in_groups)) def _delete_all_user_groups(): for gr in UserGroupModel.get_all(): fixture.destroy_user_group(gr) Session().commit() def test_add_and_remove_user_from_group(user_regular, user_util): user_group = user_util.create_user_group() assert user_group.members == [] UserGroupModel().add_user_to_group(user_group, user_regular) Session().commit() assert user_group.members[0].user == user_regular UserGroupModel().remove_user_from_group(user_group, user_regular) Session().commit() assert user_group.members == [] @pytest.mark.parametrize('data, expected', [ ([], []), ([{"member_user_id": 1, "type": "new"}], [1]), ([{"member_user_id": 1, "type": "new"}, {"member_user_id": 1, "type": "existing"}], [1]), ([{"member_user_id": 1, "type": "new"}, {"member_user_id": 2, "type": "new"}, {"member_user_id": 3, "type": "remove"}], [1, 2]) ]) def test_clean_members_data(data, expected): cleaned = UserGroupModel()._clean_members_data(data) assert cleaned == expected def _create_test_members(): members = [] for member_number in range(3): member = mock.Mock() member.user_id = member_number + 1 member.user.user_id = member_number + 1 members.append(member) return members def test_get_added_and_removed_users(): members = _create_test_members() mock_user_group = mock.Mock() mock_user_group.members = [members[0], members[1]] new_users_list = [members[1].user.user_id, members[2].user.user_id] model = UserGroupModel() added, removed = model._get_added_and_removed_user_ids( mock_user_group, new_users_list) assert added == [members[2].user.user_id] assert removed == [members[0].user.user_id] def test_set_users_as_members_and_find_user_in_group( user_util, user_regular, user_admin): user_group = user_util.create_user_group() assert len(user_group.members) == 0 user_list = [user_regular.user_id, user_admin.user_id] UserGroupModel()._set_users_as_members(user_group, user_list) assert len(user_group.members) == 2 assert UserGroupModel()._find_user_in_group(user_regular, user_group)