Commit 19827348 authored by Mathieu Coupé's avatar Mathieu Coupé Committed by Pierre Smeyers
Browse files

fix: check access level before trying to process a project

parent e884b5e1
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ class Butler:

    def cleaning_enabled_project(self, project: Project) -> bool:
        """
        Check if project should be cleaned. Projects can be excluded or be in read-only mode.
        Check if project should be cleaned. Projects can be excluded or be in read-only mode. Also check if our access level is high enough.
        :param project:
        :return: True if project should be cleaned, False otherwise
        """
@@ -226,6 +226,18 @@ class Butler:
            )
            return False

        # check if access level is high enough to process project (*_access can be missing or explicitly set to None)
        access_level = max(
            (project.permissions.get('project_access') or {}).get('access_level', 0),
            (project.permissions.get('group_access') or {}).get('access_level', 0)
        )

        if access_level < 30:
            print(
                f"  - 🏠 Project {AnsiColors.BLUE}{project.path_with_namespace}{AnsiColors.RESET} access right is too low, check token: {AnsiColors.HGRAY}skip{AnsiColors.RESET}"
            )
            return False

        return True

    def find_pipeline_source_status(self, project: Project, pipeline: ProjectPipeline, caches: dict) -> PipelineSource | None:
+170 −165

File changed.

Preview size limit exceeded, changes collapsed.

+44 −3
Original line number Diff line number Diff line
@@ -7,9 +7,14 @@ from gitlab_butler.main import to_url


# project details : https://docs.gitlab.com/ee/api/projects.html#get-single-project
def mock_empty_project(project_id, archived: bool = False):
def mock_empty_project(project_id, archived: bool = False, project_access: int = 30, group_access: int = 30):
    permission = dict()
    permission['project_access'] = { 'access_level': project_access } if project_access is not None else None
    permission['group_access'] = { 'access_level': group_access } if group_access is not None else None

    responses.add(responses.GET, f'http://gitlab.test/api/v4/projects/{project_id}', status=200, json=
        {'id': project_id, 'path': f'project_{project_id}', 'path_with_namespace': f'path/to/group/project_{project_id}', 'default_branch': 'main', 'archived': archived}
    {'id': project_id, 'path': f'project_{project_id}', 'path_with_namespace': f'path/to/group/project_{project_id}',
     'default_branch': 'main', 'archived': archived, 'permissions': permission }
    )
    responses.add(responses.GET, f'http://gitlab.test/api/v4/projects/{project_id}/repository/files/.butlercfg.yaml?ref=main', status=404)
    responses.add(responses.GET, f'http://gitlab.test/api/v4/projects/{project_id}/repository/files/.butlercfg.yml?ref=main', status=404)
@@ -17,7 +22,6 @@ def mock_empty_project(project_id, archived: bool = False):
    responses.add(responses.GET, f'http://gitlab.test/api/v4/projects/{project_id}/repository/tags?per_page=100', status=200, json=[])
    responses.add(responses.GET, f'http://gitlab.test/api/v4/projects/{project_id}/pipelines?sort=asc&order_by=updated_at&per_page=100', status=200, json=[])


class TestGroups:
    @staticmethod
    def create_butler() -> Butler:
@@ -230,5 +234,42 @@ class TestGroups:
        assert butler.groups_count == 1
        assert butler.projects_count == 2

    @responses.activate
    def test_process_group_access_levels(self):
        butler = self.create_butler()

        # setup mock responses
        responses.add(responses.GET, 'http://gitlab.test/api/v4/groups/path%2Fto%2Fgroup', status=200,
                      json={'id': 42, 'name': 'Test Group', 'full_path': 'path/to/group'})
        responses.add(responses.GET, 'http://gitlab.test/api/v4/groups/43', status=200,
                      json={'id': 43, 'name': 'Sub Group 1', 'full_path': 'path/to/group/sub1'})

        responses.add(responses.GET, 'http://gitlab.test/api/v4/groups/42/projects?per_page=100', status=200, json=[
            {'id': 1000, 'path': 'path/to/group/project0'},
            {'id': 1001, 'path': 'path/to/group/project1'},
            {'id': 1002, 'path': 'path/to/group/project2'},
            {'id': 1003, 'path': 'path/to/group/project3'},
            {'id': 1004, 'path': 'path/to/group/project4'},
            {'id': 1005, 'path': 'path/to/group/project5'},
        ])
        responses.add(responses.GET, 'http://gitlab.test/api/v4/groups/42/descendant_groups?per_page=100', status=200, json=[])

        # Setup empty project
        mock_empty_project('1000', project_access=None, group_access=None) # no access
        mock_empty_project('1001', project_access=10, group_access=None)   # project access too low
        mock_empty_project('1002', project_access=30, group_access=None)   # project access ok
        mock_empty_project('1003', project_access=None, group_access=10)   # group access too low
        mock_empty_project('1004', project_access=None, group_access=30)   # group access ok
        mock_empty_project('1005', project_access=10, group_access=30)     # project access too low but group access ok

        # get initial group
        group = butler.client.groups.get(butler.group_path)
        assert group.id == 42 and group.name == 'Test Group'

        # clean initial group
        butler.clean_group(group)
        assert butler.groups_count == 1
        assert butler.projects_count == 3