Blame tests/test_pagure_lib_git_auth_paguregitauth.py

Patrick Uiterwijk f66bad
# -*- coding: utf-8 -*-
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
"""
Patrick Uiterwijk f66bad
 (c) 2019-2019 - Copyright Red Hat Inc
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
 Authors:
Patrick Uiterwijk f66bad
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Patrick Uiterwijk f66bad
   Patrick Uiterwijk <patrick@puiterwijk.org></patrick@puiterwijk.org>
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
"""
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
from __future__ import unicode_literals, absolute_import
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
import json
Patrick Uiterwijk f66bad
import os
Patrick Uiterwijk f66bad
import sys
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
from mock import Mock
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
sys.path.insert(
Patrick Uiterwijk f66bad
    0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..")
Patrick Uiterwijk f66bad
)
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
import pagure.lib.query
Patrick Uiterwijk f66bad
import tests
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
from pagure.config import config as pagure_config
Patrick Uiterwijk f66bad
from pagure.lib.repo import PagureRepo
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
class PagureLibGitAuthPagureGitAuthtests(tests.Modeltests):
Patrick Uiterwijk f66bad
    """ Tests for pagure.lib.git_auth PagureGitAuth dynamic ACL """
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
    config_values = {"authbackend": "pagure"}
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
    def setUp(self):
Patrick Uiterwijk f66bad
        super(PagureLibGitAuthPagureGitAuthtests, self).setUp()
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
        tests.create_projects(self.session)
Patrick Uiterwijk f66bad
        tests.create_tokens(self.session)
Patrick Uiterwijk f66bad
        tests.create_tokens_acl(self.session)
Patrick Uiterwijk f66bad
        self.create_project_full("acltest")
Patrick Uiterwijk f66bad
        project = pagure.lib.query._get_project(self.session, "acltest")
Patrick Uiterwijk f66bad
        # Create non-push deploy key
Patrick Uiterwijk f66bad
        non_push_dkey = pagure.lib.model.SSHKey(
Patrick Uiterwijk f66bad
            project_id=project.id,
Patrick Uiterwijk f66bad
            pushaccess=False,
Patrick Uiterwijk f66bad
            public_ssh_key="\n foo bar",
Patrick Uiterwijk f66bad
            ssh_short_key="\n foo bar",
Patrick Uiterwijk f66bad
            ssh_search_key="\n foo bar",
Patrick Uiterwijk f66bad
            creator_user_id=1,  # pingou
Patrick Uiterwijk f66bad
        )
Patrick Uiterwijk f66bad
        self.session.add(non_push_dkey)
Patrick Uiterwijk f66bad
        # Create push deploy key
Patrick Uiterwijk f66bad
        push_dkey = pagure.lib.model.SSHKey(
Patrick Uiterwijk f66bad
            project_id=project.id,
Patrick Uiterwijk f66bad
            pushaccess=True,
Patrick Uiterwijk f66bad
            public_ssh_key="\n bar foo",
Patrick Uiterwijk f66bad
            ssh_short_key="\n bar foo",
Patrick Uiterwijk f66bad
            ssh_search_key="\n bar foo",
Patrick Uiterwijk f66bad
            creator_user_id=1,  # pingou
Patrick Uiterwijk f66bad
        )
Patrick Uiterwijk f66bad
        self.session.add(push_dkey)
Patrick Uiterwijk f66bad
        self.session.commit()
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
    def create_fork(self):
Patrick Uiterwijk f66bad
        # Create fork
Patrick Uiterwijk f66bad
        headers = {"Authorization": "token aaabbbcccddd"}
Patrick Uiterwijk f66bad
        data = {"repo": "acltest"}
Patrick Uiterwijk f66bad
        output = self.app.post("/api/0/fork/", data=data, headers=headers)
Patrick Uiterwijk f66bad
        self.assertEqual(output.status_code, 200)
Patrick Uiterwijk f66bad
        data = json.loads(output.get_data(as_text=True))
Patrick Uiterwijk f66bad
        self.assertDictEqual(
Patrick Uiterwijk f66bad
            data, {"message": 'Repo "acltest" cloned to "pingou/acltest"'}
Patrick Uiterwijk f66bad
        )
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
    CASES = (
Patrick Uiterwijk f66bad
        # Internal push
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": True,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Internal push allowed"],
Patrick Uiterwijk f66bad
            "expected_result": True,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # Globally PR required push: PR merges are always internal
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": True,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Pull request required"],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # GLobally PR required, push is to fork
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": True,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest", "user": "pingou"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Has commit access: False"],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # PR required push: PR merges are always internal
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": True,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Pull request required"],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # PR required for main repo, but not for ticket
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": True,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "ticket",
Patrick Uiterwijk f66bad
            "expected_messages": ["Has commit access: False"],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # Non-push deploy key
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "deploykey_acltest_1",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": [
Patrick Uiterwijk f66bad
                "Deploykey used. Push access: False",
Patrick Uiterwijk f66bad
                "Has commit access: False",
Patrick Uiterwijk f66bad
            ],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # Push deploy key
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "deploykey_acltest_2",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": [
Patrick Uiterwijk f66bad
                "Deploykey used. Push access: True",
Patrick Uiterwijk f66bad
                "Has commit access: True",
Patrick Uiterwijk f66bad
            ],
Patrick Uiterwijk f66bad
            "expected_result": True,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # Non-committer
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "foo",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Has commit access: False"],
Patrick Uiterwijk f66bad
            "expected_result": False,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
        # Committer
Patrick Uiterwijk f66bad
        {
Patrick Uiterwijk f66bad
            "internal": False,
Patrick Uiterwijk f66bad
            "username": "pingou",
Patrick Uiterwijk f66bad
            "project_pr_only": False,
Patrick Uiterwijk f66bad
            "global_pr_only": False,
Patrick Uiterwijk f66bad
            "project": {"name": "acltest"},
Patrick Uiterwijk f66bad
            "repotype": "main",
Patrick Uiterwijk f66bad
            "expected_messages": ["Has commit access: True"],
Patrick Uiterwijk f66bad
            "expected_result": True,
Patrick Uiterwijk f66bad
        },
Patrick Uiterwijk f66bad
    )
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
    def test_cases(self):
Patrick Uiterwijk f66bad
        self.create_fork()
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
        ga = pagure.lib.git_auth.PagureGitAuth()
Patrick Uiterwijk f66bad
        ga.info = Mock()
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
        casenum = 0
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
        for case in self.CASES:
Patrick Uiterwijk f66bad
            casenum += 1
Patrick Uiterwijk f66bad
            print("Case %d: %s" % (casenum, case))
Patrick Uiterwijk f66bad
            project = pagure.lib.query._get_project(
Patrick Uiterwijk f66bad
                self.session, **case["project"]
Patrick Uiterwijk f66bad
            )
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
            # Set global PR setting
Patrick Uiterwijk f66bad
            pagure_config["PR_ONLY"] = case["global_pr_only"]
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
            # Set per-project PR setting
Patrick Uiterwijk f66bad
            curset = project.settings
Patrick Uiterwijk f66bad
            curset["pull_request_access_only"] = case["project_pr_only"]
Patrick Uiterwijk f66bad
            project.settings = curset
Patrick Uiterwijk f66bad
            self.session.commit()
Patrick Uiterwijk f66bad
Patrick Uiterwijk f66bad
            result = ga.check_acl(
Patrick Uiterwijk f66bad
                session=self.session,
Patrick Uiterwijk f66bad
                project=project,
Patrick Uiterwijk f66bad
                username=case["username"],
Patrick Uiterwijk f66bad
                refname="refs/heads/master",
Patrick Uiterwijk f66bad
                pull_request=None,
Patrick Uiterwijk f66bad
                repotype=case["repotype"],
Patrick Uiterwijk f66bad
                is_internal=case["internal"],
Patrick Uiterwijk f66bad
            )
Patrick Uiterwijk f66bad
            print("Result: %s" % result)
Patrick Uiterwijk f66bad
            self.assertEqual(
Patrick Uiterwijk f66bad
                result,
Patrick Uiterwijk f66bad
                case["expected_result"],
Patrick Uiterwijk f66bad
                "Expected result not met in case %s" % case,
Patrick Uiterwijk f66bad
            )
Patrick Uiterwijk f66bad
            print("Correct result")
Patrick Uiterwijk f66bad
            self.assertListEqual(
Patrick Uiterwijk f66bad
                case["expected_messages"],
Patrick Uiterwijk f66bad
                [info_call[0][0] for info_call in ga.info.call_args_list],
Patrick Uiterwijk f66bad
            )
Patrick Uiterwijk f66bad
            print("Correct messages")
Patrick Uiterwijk f66bad
            ga.info.reset_mock()