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()
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
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