def _get_permalink(self, obj, user): # If user is not logged in and member of the organization, # do not return the permalink which contains private information i.e. org name. request = env.request is_superuser = request and is_active_superuser(request) and request.user == user # If user is a sentry_app then it's a proxy user meaning we can't do a org lookup via `get_orgs()` # because the user isn't an org member. Instead we can use the auth token and the installation # it's associated with to find out what organization the token has access to. is_valid_sentryapp = False if ( request and getattr(request.user, "is_sentry_app", False) and isinstance(request.auth, ApiToken) ): is_valid_sentryapp = SentryAppInstallationToken.has_organization_access( request.auth, obj.organization ) if ( is_superuser or is_valid_sentryapp or (user.is_authenticated() and user.get_orgs().filter(id=obj.organization.id).exists()) ): with sentry_sdk.start_span(op="GroupSerializerBase.serialize.permalink.build"): return obj.get_absolute_url() else: return None
def get_payload_and_token( payload: Mapping[str, Any], organization_id: int, sentry_project_id: int) -> Tuple[Mapping[str, Any], str]: meta = payload["deployment"]["meta"] # look up the project so we can get the slug project = Project.objects.get(id=sentry_project_id) # find the connected sentry app installation installation_for_provider = SentryAppInstallationForProvider.objects.select_related( "sentry_app_installation").get(organization_id=organization_id, provider="vercel") sentry_app_installation = installation_for_provider.sentry_app_installation # find a token associated with the installation so we can use it for authentication sentry_app_installation_token = ( SentryAppInstallationToken.objects.select_related("api_token").filter( sentry_app_installation=sentry_app_installation).first()) if not sentry_app_installation_token: raise SentryAppInstallationToken.DoesNotExist() commit_sha = get_commit_sha(meta) repository = get_repository(meta) release_payload = { "version": commit_sha, "projects": [project.slug], "refs": [{ "repository": repository, "commit": commit_sha }], } return release_payload, sentry_app_installation_token.api_token.token
def get_payload_and_token(self, payload, organization_id, sentry_project_id): meta = payload["deployment"]["meta"] # look up the project so we can get the slug project = Project.objects.get(id=sentry_project_id) # find the connected sentry app installation installation_for_provider = SentryAppInstallationForProvider.objects.select_related( "sentry_app_installation").get(organization_id=organization_id, provider=self.provider) sentry_app_installation = installation_for_provider.sentry_app_installation # find a token associated with the installation so we can use it for authentication sentry_app_installation_token = ( SentryAppInstallationToken.objects.select_related("api_token"). filter(sentry_app_installation=sentry_app_installation).first()) if not sentry_app_installation_token: raise SentryAppInstallationToken.DoesNotExist() # find the commmit sha so we can use it as as the release commit_sha = (meta.get("githubCommitSha") or meta.get("gitlabCommitSha") or meta.get("bitbucketCommitSha")) # contruct the repo depeding what provider we use if meta.get("githubCommitSha"): # we use these instead of githubOrg and githubRepo since it's the repo the user has access to repository = "%s/%s" % (meta["githubCommitOrg"], meta["githubCommitRepo"]) elif meta.get("gitlabCommitSha"): # gitlab repos are formatted with a space for some reason repository = "%s / %s" % ( meta["gitlabProjectNamespace"], meta["gitlabProjectName"], ) elif meta.get("bitbucketCommitSha"): repository = "%s/%s" % (meta["bitbucketRepoOwner"], meta["bitbucketRepoName"]) else: # this can happen with manual builds raise NoCommitFoundError("No commit found") release_payload = { "version": commit_sha, "projects": [project.slug], "refs": [{ "repository": repository, "commit": commit_sha }], } return [release_payload, sentry_app_installation_token.api_token.token]
def serialize(self, obj, attrs, user): status = obj.status status_details = {} if attrs["ignore_until"]: snooze = attrs["ignore_until"] if snooze.is_valid(group=obj): # counts return the delta remaining when window is not set status_details.update({ "ignoreCount": (snooze.count - (obj.times_seen - snooze.state["times_seen"]) if snooze.count and not snooze.window else snooze.count), "ignoreUntil": snooze.until, "ignoreUserCount": (snooze.user_count - (attrs["user_count"] - snooze.state["users_seen"]) if snooze.user_count and not snooze.user_window else snooze.user_count), "ignoreUserWindow": snooze.user_window, "ignoreWindow": snooze.window, "actor": attrs["ignore_actor"], }) else: status = GroupStatus.UNRESOLVED if status == GroupStatus.UNRESOLVED and obj.is_over_resolve_age(): status = GroupStatus.RESOLVED status_details["autoResolved"] = True if status == GroupStatus.RESOLVED: status_label = "resolved" if attrs["resolution_type"] == "release": res_type, res_version, _ = attrs["resolution"] if res_type in (GroupResolution.Type.in_next_release, None): status_details["inNextRelease"] = True elif res_type == GroupResolution.Type.in_release: status_details["inRelease"] = res_version status_details["actor"] = attrs["resolution_actor"] elif attrs["resolution_type"] == "commit": status_details["inCommit"] = attrs["resolution"] elif status == GroupStatus.IGNORED: status_label = "ignored" elif status in [ GroupStatus.PENDING_DELETION, GroupStatus.DELETION_IN_PROGRESS ]: status_label = "pending_deletion" elif status == GroupStatus.PENDING_MERGE: status_label = "pending_merge" else: status_label = "unresolved" # If user is not logged in and member of the organization, # do not return the permalink which contains private information i.e. org name. request = env.request is_superuser = request and is_active_superuser( request) and request.user == user # If user is a sentry_app then it's a proxy user meaning we can't do a org lookup via `get_orgs()` # because the user isn't an org member. Instead we can use the auth token and the installation # it's associated with to find out what organization the token has access to. is_valid_sentryapp = False if (request and getattr(request.user, "is_sentry_app", False) and isinstance(request.auth, ApiToken)): is_valid_sentryapp = SentryAppInstallationToken.has_organization_access( request.auth, obj.organization) if (is_superuser or (user.is_authenticated() and user.get_orgs().filter(id=obj.organization.id).exists()) or is_valid_sentryapp): permalink = obj.get_absolute_url() else: permalink = None subscription_details = None if attrs["subscription"] is not disabled: is_subscribed, subscription = attrs["subscription"] if subscription is not None and subscription.is_active: subscription_details = { "reason": SUBSCRIPTION_REASON_MAP.get(subscription.reason, "unknown") } else: is_subscribed = False subscription_details = {"disabled": True} share_id = attrs["share_id"] return { "id": six.text_type(obj.id), "shareId": share_id, "shortId": obj.qualified_short_id, "count": six.text_type(attrs["times_seen"]), "userCount": attrs["user_count"], "title": obj.title, "culprit": obj.culprit, "permalink": permalink, "firstSeen": attrs["first_seen"], "lastSeen": attrs["last_seen"], "logger": obj.logger or None, "level": LOG_LEVELS.get(obj.level, "unknown"), "status": status_label, "statusDetails": status_details, "isPublic": share_id is not None, "platform": obj.platform, "project": { "id": six.text_type(obj.project.id), "name": obj.project.name, "slug": obj.project.slug, "platform": obj.project.platform, }, "type": obj.get_event_type(), "metadata": obj.get_event_metadata(), "numComments": obj.num_comments, "assignedTo": serialize(attrs["assigned_to"], user, ActorSerializer()), "isBookmarked": attrs["is_bookmarked"], "isSubscribed": is_subscribed, "subscriptionDetails": subscription_details, "hasSeen": attrs["has_seen"], "annotations": attrs["annotations"], }
def get(self, request): """ List your Projects `````````````````` Return a list of projects available to the authenticated session. :auth: required """ queryset = Project.objects.select_related("organization").distinct() status = request.GET.get("status", "active") if status == "active": queryset = queryset.filter(status=ProjectStatus.VISIBLE) elif status == "deleted": queryset = queryset.exclude(status=ProjectStatus.VISIBLE) elif status: queryset = queryset.none() if request.auth and not request.user.is_authenticated(): if hasattr(request.auth, "project"): queryset = queryset.filter(id=request.auth.project_id) elif request.auth.organization is not None: queryset = queryset.filter( organization=request.auth.organization.id) else: queryset = queryset.none() elif not (is_active_superuser(request) and request.GET.get("show") == "all"): if request.user.is_sentry_app: queryset = SentryAppInstallationToken.get_projects( request.auth) else: queryset = queryset.filter( teams__organizationmember__user=request.user) query = request.GET.get("query") if query: tokens = tokenize_query(query) for key, value in six.iteritems(tokens): if key == "query": value = " ".join(value) queryset = queryset.filter( Q(name__icontains=value) | Q(slug__icontains=value)) elif key == "slug": queryset = queryset.filter(in_iexact("slug", value)) elif key == "name": queryset = queryset.filter(in_iexact("name", value)) elif key == "platform": queryset = queryset.filter( id__in=ProjectPlatform.objects.filter( platform__in=value).values("project_id")) elif key == "id": queryset = queryset.filter(id__in=value) else: queryset = queryset.none() return self.paginate( request=request, queryset=queryset, order_by="-date_added", on_results=lambda x: serialize( x, request.user, ProjectWithOrganizationSerializer()), paginator_cls=DateTimePaginator, )