コード例 #1
0
    def handle_pull_request(self):

        collaborators = self.project.who_can_merge_pr()
        cbh = CoprBuildJobHelper(self.config, self.package_config,
                                 self.project, self.event)
        if self.event.github_login not in collaborators | self.config.admins:
            msg = "Only collaborators can trigger Packit-as-a-Service"
            cbh.report_status_to_all("failure", msg)
            return HandlerResults(success=False, details={"msg": msg})

        handler_results = cbh.run_copr_build()

        return handler_results
コード例 #2
0
    def _check_pr_event(
        self,
        event: Union[PullRequestGithubEvent, PullRequestCommentGithubEvent,
                     MergeRequestGitlabEvent,
                     MergeRequestCommentGitlabEvent, ],
        project: GitProject,
        service_config: ServiceConfig,
        job_configs: Iterable[JobConfig],
    ) -> bool:
        actor_name = event.actor
        if not actor_name:
            raise KeyError(
                f"Failed to get login of the actor from {type(event)}")

        project_url = self._strip_protocol_and_add_git(event.project_url)

        namespace_approved = self.is_approved(project_url)
        user_approved = (project.can_merge_pr(actor_name)
                         or project.get_pr(event.pr_id).author == actor_name)

        if namespace_approved and user_approved:
            # TODO: clear failing check when present
            return True

        msg = (
            f"Project {project_url} is not on our allowlist!"
            if not namespace_approved else
            f"Account {actor_name} has no write access nor is author of PR!")
        logger.debug(msg)
        if isinstance(
                event,
            (PullRequestCommentGithubEvent, MergeRequestCommentGitlabEvent)):
            project.get_pr(event.pr_id).comment(msg)
        else:
            for job_config in job_configs:
                job_helper = CoprBuildJobHelper(
                    service_config=service_config,
                    package_config=event.get_package_config(),
                    project=project,
                    metadata=EventData.from_event_dict(event.get_dict()),
                    db_trigger=event.db_trigger,
                    job_config=job_config,
                    targets_override=event.targets_override,
                )
                msg = ("Namespace is not allowed!"
                       if not namespace_approved else "User cannot trigger!")
                job_helper.report_status_to_all(description=msg,
                                                state=BaseCommitStatus.neutral,
                                                url=FAQ_URL)

        return False
コード例 #3
0
    def check_and_report(self, event: Optional[Any], project: GitProject,
                         config: ServiceConfig) -> bool:
        """
        Check if account is approved and report status back in case of PR
        :param config: service config
        :param event: PullRequest and Release TODO: handle more
        :param project: GitProject
        :return:
        """
        # TODO: modify event hierarchy so we can use some abstract classes instead
        if isinstance(event, ReleaseEvent):
            account_name = event.repo_namespace
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)}")
            if not self.is_approved(account_name):
                logger.info(
                    f"Refusing release event on not whitelisted repo namespace"
                )
                return False
            return True
        if isinstance(
                event,
            (CoprBuildEvent, TestingFarmResultsEvent, DistGitEvent,
             InstallationEvent),
        ):
            return True
        if isinstance(event, (PullRequestEvent, PullRequestCommentEvent)):
            account_name = event.github_login
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)}")
            namespace = event.base_repo_namespace
            # FIXME:
            #  Why check account_name when we whitelist namespace only (in whitelist.add_account())?
            if not (self.is_approved(account_name)
                    or self.is_approved(namespace)):
                msg = f"Neither account {account_name} nor owner {namespace} are on our whitelist!"
                logger.error(msg)
                # TODO also check blacklist,
                # but for that we need to know who triggered the action
                if event.trigger == JobTriggerType.comment:
                    project.pr_comment(event.pr_id, msg)
                else:
                    job_helper = CoprBuildJobHelper(
                        config=config,
                        package_config=event.get_package_config(),
                        project=project,
                        event=event,
                    )
                    msg = "Account is not whitelisted!"  # needs to be shorter
                    job_helper.report_status_to_all(description=msg,
                                                    state="error",
                                                    url=FAQ_URL)
                return False
            # TODO: clear failing check when present
            return True
        if isinstance(event, IssueCommentEvent):
            account_name = event.github_login
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)}")
            namespace = event.base_repo_namespace
            # FIXME:
            #  Why check account_name when we whitelist namespace only (in whitelist.add_account())?
            if not (self.is_approved(account_name)
                    or self.is_approved(namespace)):
                msg = f"Neither account {account_name} nor owner {namespace} are on our whitelist!"
                logger.error(msg)
                project.issue_comment(event.issue_id, msg)
                # TODO also check blacklist,
                # but for that we need to know who triggered the action
                return False
            return True

        msg = f"Failed to validate account: Unrecognized event type {type(event)}."
        logger.error(msg)
        raise PackitException(msg)
コード例 #4
0
    def check_and_report(
        self,
        event: Optional[Any],
        project: GitProject,
        service_config: ServiceConfig,
        job_configs: Iterable[JobConfig],
    ) -> bool:
        """
        Check if account is approved and report status back in case of PR
        :param service_config: service config
        :param event: PullRequest and Release TODO: handle more
        :param project: GitProject
        :param job_configs: iterable of jobconfigs - so we know how to update status of the PR
        :return:
        """

        # whitelist checks dont apply to CentOS (Pagure, Gitlab)
        if isinstance(
                event,
            (
                PushPagureEvent,
                PullRequestPagureEvent,
                PullRequestCommentPagureEvent,
                MergeRequestCommentGitlabEvent,
                IssueCommentGitlabEvent,
                MergeRequestGitlabEvent,
                PushGitlabEvent,
            ),
        ):
            logger.info(
                "Centos (Pagure, Gitlab) events don't require whitelist checks."
            )
            return True

        # TODO: modify event hierarchy so we can use some abstract classes instead
        if isinstance(event, (ReleaseEvent, PushGitHubEvent)):
            account_name = event.repo_namespace
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)!r}")
            if not self.is_approved(account_name):
                logger.info(
                    "Refusing release event on not whitelisted repo namespace."
                )
                return False
            return True
        if isinstance(
                event,
            (
                CoprBuildEvent,
                TestingFarmResultsEvent,
                DistGitEvent,
                InstallationEvent,
                KojiBuildEvent,
            ),
        ):
            return True
        if isinstance(event,
                      (PullRequestGithubEvent, PullRequestCommentGithubEvent)):
            account_name = event.user_login
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)}")
            namespace = event.target_repo_namespace
            # FIXME:
            #  Why check account_name when we whitelist namespace only (in whitelist.add_account())?
            if not (self.is_approved(account_name)
                    or self.is_approved(namespace)):
                msg = f"Neither account {account_name} nor owner {namespace} are on our whitelist!"
                logger.error(msg)
                if event.trigger == TheJobTriggerType.pr_comment:
                    project.pr_comment(event.pr_id, msg)
                else:
                    for job_config in job_configs:
                        job_helper = CoprBuildJobHelper(
                            service_config=service_config,
                            package_config=event.get_package_config(),
                            project=project,
                            metadata=EventData.from_event_dict(
                                event.get_dict()),
                            db_trigger=event.db_trigger,
                            job_config=job_config,
                        )
                        msg = "Account is not whitelisted!"  # needs to be shorter
                        job_helper.report_status_to_all(
                            description=msg,
                            state=CommitStatus.error,
                            url=FAQ_URL)
                return False
            # TODO: clear failing check when present
            return True
        if isinstance(event, IssueCommentEvent):
            account_name = event.user_login
            if not account_name:
                raise KeyError(
                    f"Failed to get account_name from {type(event)}")
            namespace = event.repo_namespace
            # FIXME:
            #  Why check account_name when we whitelist namespace only (in whitelist.add_account())?
            if not (self.is_approved(account_name)
                    or self.is_approved(namespace)):
                msg = f"Neither account {account_name} nor owner {namespace} are on our whitelist!"
                logger.error(msg)
                project.issue_comment(event.issue_id, msg)
                return False
            return True

        msg = f"Failed to validate account: Unrecognized event type {type(event)!r}."
        logger.error(msg)
        raise PackitException(msg)