Esempio n. 1
0
    def notify_project_users(cls, projects):
        """
        Notify project users of deprecated view.

        :param projects: List of project instances
        :type projects: [:py:class:`Project`]
        """
        for project in projects:
            # Send one notification to each admin of the project
            for user in AdminPermission.admins(project):
                notification = cls(
                    context_object=project,
                    request=HttpRequest(),
                    user=user,
                )
                notification.send()
Esempio n. 2
0
 def get_token_for_project(cls, project, force_local=False):
     """Get access token for project by iterating over project users."""
     # TODO why does this only target GitHub?
     if not settings.ALLOW_PRIVATE_REPOS:
         return None
     token = None
     try:
         if settings.DONT_HIT_DB and not force_local:
             token = api.project(project.pk).token().get()['token']
         else:
             for user in AdminPermission.admins(project):
                 tokens = SocialToken.objects.filter(
                     account__user=user,
                     app__provider=cls.adapter.provider_id,
                 )
                 if tokens.exists():
                     token = tokens[0].token
     except Exception:
         log.exception('Failed to get token for project')
     return token
Esempio n. 3
0
def send_build_status(build_pk, commit, status, link_to_build=False):
    """
    Send Build Status to Git Status API for project external versions.

    It tries using these services' account in order:

    1. user's account that imported the project
    2. each user's account from the project's maintainers

    :param build_pk: Build primary key
    :param commit: commit sha of the pull/merge request
    :param status: build status failed, pending, or success to be sent.
    """
    # TODO: Send build status for BitBucket.
    build = Build.objects.filter(pk=build_pk).first()
    if not build:
        return

    provider_name = build.project.git_provider_name

    log.info('Sending build status. build=%s project=%s', build.pk,
             build.project.slug)

    if provider_name in [GITHUB_BRAND, GITLAB_BRAND]:
        # get the service class for the project e.g: GitHubService.
        service_class = build.project.git_service_class()
        users = AdminPermission.admins(build.project)

        if build.project.remote_repository:
            remote_repository = build.project.remote_repository
            remote_repository_relations = (
                remote_repository.remote_repository_relations.filter(
                    account__isnull=False,
                    # Use ``user_in=`` instead of ``user__projects=`` here
                    # because User's are not related to Project's directly in
                    # Read the Docs for Business
                    user__in=AdminPermission.members(build.project),
                ).select_related('account', 'user').only('user', 'account'))

            # Try using any of the users' maintainer accounts
            # Try to loop through all remote repository relations for the projects users
            for relation in remote_repository_relations:
                service = service_class(relation.user, relation.account)
                # Send status report using the API.
                success = service.send_build_status(
                    build=build,
                    commit=commit,
                    state=status,
                    link_to_build=link_to_build,
                )

                if success:
                    log.info(
                        'Build status report sent correctly. '
                        'project=%s build=%s status=%s commit=%s user=%s',
                        build.project.slug,
                        build.pk,
                        status,
                        commit,
                        relation.user.username,
                    )
                    return True
        else:
            log.warning(
                'Project does not have a RemoteRepository. project=%s',
                build.project.slug,
            )
            # Try to send build status for projects with no RemoteRepository
            for user in users:
                services = service_class.for_user(user)
                # Try to loop through services for users all social accounts
                # to send successful build status
                for service in services:
                    success = service.send_build_status(build, commit, status)
                    if success:
                        log.info(
                            'Build status report sent correctly using an user account. '
                            'project=%s build=%s status=%s commit=%s user=%s',
                            build.project.slug,
                            build.pk,
                            status,
                            commit,
                            user.username,
                        )
                        return True

        for user in users:
            # Send Site notification about Build status reporting failure
            # to all the users of the project.
            notification = GitBuildStatusFailureNotification(
                context_object=build.project,
                extra_context={'provider_name': provider_name},
                user=user,
                success=False,
            )
            notification.send()

        log.info(
            'No social account or repository permission available. project=%s',
            build.project.slug)
        return False