Ejemplo n.º 1
0
    def get(self, request, organization):
        """
        List an Organization's Teams
        ````````````````````````````

        Return a list of teams bound to a organization.

        :pparam string organization_slug: the slug of the organization for
                                          which the teams should be listed.
        :param string detailed: Specify "0" to return team details that do not include projects
        :auth: required
        """
        # TODO(dcramer): this should be system-wide default for organization
        # based endpoints
        if request.auth and hasattr(request.auth, "project"):
            return Response(status=403)

        queryset = Team.objects.filter(
            organization=organization, status=TeamStatus.VISIBLE
        ).order_by("slug")

        query = request.GET.get("query")

        if query:
            tokens = tokenize_query(query)
            for key, value in tokens.items():
                if key == "hasExternalTeams":
                    has_external_teams = "true" in value
                    if has_external_teams:
                        queryset = queryset.filter(
                            actor_id__in=ExternalActor.objects.filter(
                                organization=organization
                            ).values_list("actor_id")
                        )
                    else:
                        queryset = queryset.exclude(
                            actor_id__in=ExternalActor.objects.filter(
                                organization=organization
                            ).values_list("actor_id")
                        )

                elif key == "query":
                    value = " ".join(value)
                    queryset = queryset.filter(Q(name__icontains=value) | Q(slug__icontains=value))
                elif key == "slug":
                    queryset = queryset.filter(slug__in=value)
                else:
                    queryset = queryset.none()

        is_detailed = request.GET.get("detailed", "1") != "0"

        expand = ["projects", "externalTeams"] if is_detailed else []

        return self.paginate(
            request=request,
            queryset=queryset,
            order_by="slug",
            on_results=lambda x: serialize(x, request.user, TeamSerializer(expand=expand)),
            paginator_cls=OffsetPaginator,
        )
Ejemplo n.º 2
0
    def serialize(self, obj, attrs, user, access):
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        context = super().serialize(obj, attrs, user, access)

        team_list = self._team_list(obj, access)
        project_list = self._project_list(obj, access)

        context["teams"] = serialize(team_list, user, TeamSerializer())
        context["projects"] = serialize(project_list, user, ProjectSummarySerializer())

        return context
Ejemplo n.º 3
0
    def serialize(self, obj, attrs, user, access):
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        context = super(DetailedOrganizationSerializerWithProjectsAndTeams,
                        self).serialize(obj, attrs, user, access)

        team_list = self._team_list(obj, access)
        project_list = self._project_list(obj, access)

        context['teams'] = serialize(team_list, user, TeamSerializer())
        context['projects'] = serialize(project_list, user,
                                        ProjectSummarySerializer())

        return context
Ejemplo n.º 4
0
    def serialize(  # type: ignore
        self, obj: Organization, attrs: Mapping[str, Any], user: User, access: Access
    ) -> DetailedOrganizationSerializerWithProjectsAndTeamsResponse:
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        context = cast(
            DetailedOrganizationSerializerWithProjectsAndTeamsResponse,
            super().serialize(obj, attrs, user, access),
        )

        team_list = self._team_list(obj, access)
        project_list = self._project_list(obj, access)

        context["teams"] = serialize(team_list, user, TeamSerializer())
        context["projects"] = serialize(project_list, user, ProjectSummarySerializer())

        return context
Ejemplo n.º 5
0
    def serialize(self, obj, attrs, user, access):
        from sentry import experiments
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        team_list = self._team_list(obj, access)
        project_list = self._project_list(obj, access)

        onboarding_tasks = list(
            OrganizationOnboardingTask.objects.filter(
                organization=obj, ).select_related('user'))

        experiment_assignments = experiments.all(org=obj, actor=user)

        context = super(DetailedOrganizationSerializer,
                        self).serialize(obj, attrs, user)
        max_rate = quotas.get_maximum_quota(obj)
        context['experiments'] = experiment_assignments
        context['quota'] = {
            'maxRate':
            max_rate[0],
            'maxRateInterval':
            max_rate[1],
            'accountLimit':
            int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:account-rate-limit',
                    default=ACCOUNT_RATE_LIMIT_DEFAULT,
                )),
            'projectLimit':
            int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:project-rate-limit',
                    default=PROJECT_RATE_LIMIT_DEFAULT,
                )),
        }

        context.update({
            'isDefault':
            obj.is_default,
            'defaultRole':
            obj.default_role,
            'availableRoles': [{
                'id': r.id,
                'name': r.name,
            } for r in roles.get_all()],
            'openMembership':
            bool(obj.flags.allow_joinleave),
            'require2FA':
            bool(obj.flags.require_2fa),
            'allowSharedIssues':
            not obj.flags.disable_shared_issues,
            'enhancedPrivacy':
            bool(obj.flags.enhanced_privacy),
            'dataScrubber':
            bool(
                obj.get_option('sentry:require_scrub_data',
                               REQUIRE_SCRUB_DATA_DEFAULT)),
            'dataScrubberDefaults':
            bool(
                obj.get_option('sentry:require_scrub_defaults',
                               REQUIRE_SCRUB_DEFAULTS_DEFAULT)),
            'sensitiveFields':
            obj.get_option('sentry:sensitive_fields', SENSITIVE_FIELDS_DEFAULT)
            or [],
            'safeFields':
            obj.get_option('sentry:safe_fields', SAFE_FIELDS_DEFAULT) or [],
            'storeCrashReports':
            bool(
                obj.get_option('sentry:store_crash_reports',
                               STORE_CRASH_REPORTS_DEFAULT)),
            'scrubIPAddresses':
            bool(
                obj.get_option('sentry:require_scrub_ip_address',
                               REQUIRE_SCRUB_IP_ADDRESS_DEFAULT)),
            'scrapeJavaScript':
            bool(
                obj.get_option('sentry:scrape_javascript',
                               SCRAPE_JAVASCRIPT_DEFAULT)),
            'trustedRelays':
            obj.get_option('sentry:trusted-relays', TRUSTED_RELAYS_DEFAULT)
            or [],
        })
        context['teams'] = serialize(team_list, user, TeamSerializer())
        context['projects'] = serialize(project_list, user,
                                        ProjectSummarySerializer())
        context['access'] = access.scopes
        context[
            'pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
                team__organization=obj, ).count()
        context['onboardingTasks'] = serialize(onboarding_tasks, user,
                                               OnboardingTasksSerializer())
        return context
Ejemplo n.º 6
0
    def serialize(self, obj, attrs, user):
        from sentry import features
        from sentry.app import env
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        team_list = list(Team.objects.filter(
            organization=obj,
            status=TeamStatus.VISIBLE,
        ))

        for team in team_list:
            team._organization_cache = obj

        project_list = list(Project.objects.filter(
            organization=obj,
            status=ProjectStatus.VISIBLE,
        ))

        for project in project_list:
            project._organization_cache = obj

        onboarding_tasks = list(
            OrganizationOnboardingTask.objects.filter(
                organization=obj,
            ).select_related('user')
        )

        feature_list = []
        if features.has('organizations:sso', obj, actor=user):
            feature_list.append('sso')
        if features.has('organizations:onboarding', obj, actor=user) and \
                not OrganizationOption.objects.filter(organization=obj).exists():
            feature_list.append('onboarding')
        if features.has('organizations:api-keys', obj, actor=user) or \
                ApiKey.objects.filter(organization=obj).exists():
            feature_list.append('api-keys')
        if features.has('organizations:group-unmerge', obj, actor=user):
            feature_list.append('group-unmerge')
        if features.has('organizations:github-apps', obj, actor=user):
            feature_list.append('github-apps')
        if features.has('organizations:integrations-v3', obj, actor=user):
            feature_list.append('integrations-v3')
        if features.has('organizations:new-settings', obj, actor=user):
            feature_list.append('new-settings')
        if features.has('organizations:require-2fa', obj, actor=user):
            feature_list.append('require-2fa')
        if features.has('organizations:environments', obj, actor=user):
            feature_list.append('environments')
        if features.has('organizations:repos', obj, actor=user):
            feature_list.append('repos')
        if features.has('organizations:internal-catchall', obj, actor=user):
            feature_list.append('internal-catchall')
        if features.has('organizations:suggested-commits', obj, actor=user):
            feature_list.append('suggested-commits')
        if features.has('organizations:new-teams', obj, actor=user):
            feature_list.append('new-teams')
        if features.has('organizations:unreleased-changes', obj, actor=user):
            feature_list.append('unreleased-changes')
        if features.has('organizations:relay', obj, actor=user):
            feature_list.append('relay')
        if features.has('organizations:health', obj, actor=user):
            feature_list.append('health')

        if getattr(obj.flags, 'allow_joinleave'):
            feature_list.append('open-membership')
        if not getattr(obj.flags, 'disable_shared_issues'):
            feature_list.append('shared-issues')
        if getattr(obj.flags, 'require_2fa'):
            feature_list.append('require-2fa')

        context = super(DetailedOrganizationSerializer, self).serialize(obj, attrs, user)
        max_rate = quotas.get_maximum_quota(obj)
        context['quota'] = {
            'maxRate': max_rate[0],
            'maxRateInterval': max_rate[1],
            'accountLimit': int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:account-rate-limit',
                    default=0,
                )
            ),
            'projectLimit': int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:project-rate-limit',
                    default=100,
                )
            ),
        }

        context.update({
            'isDefault': obj.is_default,
            'defaultRole': obj.default_role,
            'availableRoles': [{
                'id': r.id,
                'name': r.name,
            } for r in roles.get_all()],
            'openMembership': bool(obj.flags.allow_joinleave),
            'require2FA': bool(obj.flags.require_2fa),
            'allowSharedIssues': not obj.flags.disable_shared_issues,
            'enhancedPrivacy': bool(obj.flags.enhanced_privacy),
            'dataScrubber': bool(obj.get_option('sentry:require_scrub_data', False)),
            'dataScrubberDefaults': bool(obj.get_option('sentry:require_scrub_defaults', False)),
            'sensitiveFields': obj.get_option('sentry:sensitive_fields', None) or [],
            'safeFields': obj.get_option('sentry:safe_fields', None) or [],
            'scrubIPAddresses': bool(obj.get_option('sentry:require_scrub_ip_address', False)),
        })
        context['teams'] = serialize(team_list, user, TeamSerializer())
        context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
        if env.request:
            context['access'] = access.from_request(env.request, obj).scopes
        else:
            context['access'] = access.from_user(user, obj).scopes
        context['features'] = feature_list
        context['pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
            team__organization=obj,
        ).count()
        context['onboardingTasks'] = serialize(onboarding_tasks, user, OnboardingTasksSerializer())
        return context
Ejemplo n.º 7
0
 def team_serializer_for_post(self):
     # allow child routes to supply own serializer, used in SCIM teams route
     return TeamSerializer()
Ejemplo n.º 8
0
    def serialize(self, obj, attrs, user):
        from sentry import features, experiments
        from sentry.features.base import OrganizationFeature
        from sentry.app import env
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        team_list = sorted(Team.objects.filter(
            organization=obj,
            status=TeamStatus.VISIBLE,
        ), key=lambda x: x.slug)

        for team in team_list:
            team._organization_cache = obj

        project_list = sorted(Project.objects.filter(
            organization=obj,
            status=ProjectStatus.VISIBLE,
        ), key=lambda x: x.slug)

        for project in project_list:
            project._organization_cache = obj

        onboarding_tasks = list(
            OrganizationOnboardingTask.objects.filter(
                organization=obj,
            ).select_related('user')
        )

        # Retrieve all registered organization features
        org_features = features.all(feature_type=OrganizationFeature).keys()
        feature_list = set()

        for feature_name in org_features:
            if not feature_name.startswith('organizations:'):
                continue
            if features.has(feature_name, obj, actor=user):
                # Remove the organization scope prefix
                feature_list.add(feature_name[len('organizations:'):])

        # Do not include the onboarding feature if OrganizationOptions exist
        if 'onboarding' in feature_list and \
                OrganizationOption.objects.filter(organization=obj).exists():
            feature_list.remove('onboarding')

        # Include api-keys feature if they previously had any api-keys
        if 'api-keys' not in feature_list and ApiKey.objects.filter(organization=obj).exists():
            feature_list.add('api-keys')

        # Organization flag features (not provided through the features module)
        if OrganizationOption.objects.filter(
                organization=obj, key__in=LEGACY_RATE_LIMIT_OPTIONS).exists():
            feature_list.add('legacy-rate-limits')
        if getattr(obj.flags, 'allow_joinleave'):  # noqa: B009
            feature_list.add('open-membership')
        if not getattr(obj.flags, 'disable_shared_issues'):  # noqa: B009
            feature_list.add('shared-issues')
        if getattr(obj.flags, 'require_2fa'):  # noqa: B009
            feature_list.add('require-2fa')

        experiment_assignments = experiments.all(org=obj, actor=user)

        context = super(DetailedOrganizationSerializer, self).serialize(obj, attrs, user)
        max_rate = quotas.get_maximum_quota(obj)
        context['experiments'] = experiment_assignments
        context['quota'] = {
            'maxRate': max_rate[0],
            'maxRateInterval': max_rate[1],
            'accountLimit': int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:account-rate-limit',
                    default=ACCOUNT_RATE_LIMIT_DEFAULT,
                )
            ),
            'projectLimit': int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:project-rate-limit',
                    default=PROJECT_RATE_LIMIT_DEFAULT,
                )
            ),
        }

        context.update({
            'isDefault': obj.is_default,
            'defaultRole': obj.default_role,
            'availableRoles': [{
                'id': r.id,
                'name': r.name,
            } for r in roles.get_all()],
            'openMembership': bool(obj.flags.allow_joinleave),
            'require2FA': bool(obj.flags.require_2fa),
            'allowSharedIssues': not obj.flags.disable_shared_issues,
            'enhancedPrivacy': bool(obj.flags.enhanced_privacy),
            'dataScrubber': bool(obj.get_option('sentry:require_scrub_data', REQUIRE_SCRUB_DATA_DEFAULT)),
            'dataScrubberDefaults': bool(obj.get_option('sentry:require_scrub_defaults', REQUIRE_SCRUB_DEFAULTS_DEFAULT)),
            'sensitiveFields': obj.get_option('sentry:sensitive_fields', SENSITIVE_FIELDS_DEFAULT) or [],
            'safeFields': obj.get_option('sentry:safe_fields', SAFE_FIELDS_DEFAULT) or [],
            'storeCrashReports': bool(obj.get_option('sentry:store_crash_reports', STORE_CRASH_REPORTS_DEFAULT)),
            'scrubIPAddresses': bool(obj.get_option('sentry:require_scrub_ip_address', REQUIRE_SCRUB_IP_ADDRESS_DEFAULT)),
            'scrapeJavaScript': bool(obj.get_option('sentry:scrape_javascript', SCRAPE_JAVASCRIPT_DEFAULT)),
            'trustedRelays': obj.get_option('sentry:trusted-relays', TRUSTED_RELAYS_DEFAULT) or [],
        })
        context['teams'] = serialize(team_list, user, TeamSerializer())
        context['projects'] = serialize(project_list, user, ProjectSummarySerializer())
        if env.request:
            context['access'] = access.from_request(env.request, obj).scopes
        else:
            context['access'] = access.from_user(user, obj).scopes
        context['features'] = feature_list
        context['pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
            team__organization=obj,
        ).count()
        context['onboardingTasks'] = serialize(onboarding_tasks, user, OnboardingTasksSerializer())
        return context
Ejemplo n.º 9
0
    def serialize(self, obj, attrs, user):
        from sentry import features, experiments
        from sentry.app import env
        from sentry.api.serializers.models.project import ProjectSummarySerializer
        from sentry.api.serializers.models.team import TeamSerializer

        team_list = sorted(Team.objects.filter(
            organization=obj,
            status=TeamStatus.VISIBLE,
        ),
                           key=lambda x: x.slug)

        for team in team_list:
            team._organization_cache = obj

        project_list = sorted(Project.objects.filter(
            organization=obj,
            status=ProjectStatus.VISIBLE,
        ),
                              key=lambda x: x.slug)

        for project in project_list:
            project._organization_cache = obj

        onboarding_tasks = list(
            OrganizationOnboardingTask.objects.filter(
                organization=obj, ).select_related('user'))

        feature_list = []
        if features.has('organizations:sso', obj, actor=user):
            feature_list.append('sso')
        if features.has('organizations:onboarding', obj, actor=user) and \
                not OrganizationOption.objects.filter(organization=obj).exists():
            feature_list.append('onboarding')
        if features.has('organizations:api-keys', obj, actor=user) or \
                ApiKey.objects.filter(organization=obj).exists():
            feature_list.append('api-keys')
        if features.has('organizations:group-unmerge', obj, actor=user):
            feature_list.append('group-unmerge')
        if features.has('organizations:github-apps', obj, actor=user):
            feature_list.append('github-apps')
        if features.has('organizations:require-2fa', obj, actor=user):
            feature_list.append('require-2fa')
        if features.has('organizations:repos', obj, actor=user):
            feature_list.append('repos')
        if features.has('organizations:internal-catchall', obj, actor=user):
            feature_list.append('internal-catchall')
        if features.has('organizations:new-issue-ui', obj, actor=user):
            feature_list.append('new-issue-ui')
        if features.has('organizations:github-enterprise', obj, actor=user):
            feature_list.append('github-enterprise')
        if features.has('organizations:bitbucket-integration', obj,
                        actor=user):
            feature_list.append('bitbucket-integration')
        if features.has('organizations:jira-integration', obj, actor=user):
            feature_list.append('jira-integration')
        if features.has('organizations:vsts-integration', obj, actor=user):
            feature_list.append('vsts-integration')
        if features.has('organizations:integrations-issue-basic',
                        obj,
                        actor=user):
            feature_list.append('integrations-issue-basic')
        if features.has('organizations:integrations-issue-sync',
                        obj,
                        actor=user):
            feature_list.append('integrations-issue-sync')
        if features.has('organizations:suggested-commits', obj, actor=user):
            feature_list.append('suggested-commits')
        if features.has('organizations:new-teams', obj, actor=user):
            feature_list.append('new-teams')
        if features.has('organizations:unreleased-changes', obj, actor=user):
            feature_list.append('unreleased-changes')
        if features.has('organizations:relay', obj, actor=user):
            feature_list.append('relay')
        if features.has('organizations:js-loader', obj, actor=user):
            feature_list.append('js-loader')
        if features.has('organizations:health', obj, actor=user):
            feature_list.append('health')
        if features.has('organizations:discover', obj, actor=user):
            feature_list.append('discover')
        if features.has('organizations:events-stream', obj, actor=user):
            feature_list.append('events-stream')
        if OrganizationOption.objects.filter(
                organization=obj, key__in=LEGACY_RATE_LIMIT_OPTIONS).exists():
            feature_list.append('legacy-rate-limits')
        if getattr(obj.flags, 'allow_joinleave'):
            feature_list.append('open-membership')
        if not getattr(obj.flags, 'disable_shared_issues'):
            feature_list.append('shared-issues')
        if getattr(obj.flags, 'require_2fa'):
            feature_list.append('require-2fa')
        if features.has('organizations:event-attachments', obj, actor=user):
            feature_list.append('event-attachments')

        experiment_assignments = experiments.all(org=obj)

        context = super(DetailedOrganizationSerializer,
                        self).serialize(obj, attrs, user)
        max_rate = quotas.get_maximum_quota(obj)
        context['experiments'] = experiment_assignments
        context['quota'] = {
            'maxRate':
            max_rate[0],
            'maxRateInterval':
            max_rate[1],
            'accountLimit':
            int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:account-rate-limit',
                    default=ACCOUNT_RATE_LIMIT_DEFAULT,
                )),
            'projectLimit':
            int(
                OrganizationOption.objects.get_value(
                    organization=obj,
                    key='sentry:project-rate-limit',
                    default=PROJECT_RATE_LIMIT_DEFAULT,
                )),
        }

        context.update({
            'isDefault':
            obj.is_default,
            'defaultRole':
            obj.default_role,
            'availableRoles': [{
                'id': r.id,
                'name': r.name,
            } for r in roles.get_all()],
            'openMembership':
            bool(obj.flags.allow_joinleave),
            'require2FA':
            bool(obj.flags.require_2fa),
            'allowSharedIssues':
            not obj.flags.disable_shared_issues,
            'enhancedPrivacy':
            bool(obj.flags.enhanced_privacy),
            'dataScrubber':
            bool(
                obj.get_option('sentry:require_scrub_data',
                               REQUIRE_SCRUB_DATA_DEFAULT)),
            'dataScrubberDefaults':
            bool(
                obj.get_option('sentry:require_scrub_defaults',
                               REQUIRE_SCRUB_DEFAULTS_DEFAULT)),
            'sensitiveFields':
            obj.get_option('sentry:sensitive_fields', SENSITIVE_FIELDS_DEFAULT)
            or [],
            'safeFields':
            obj.get_option('sentry:safe_fields', SAFE_FIELDS_DEFAULT) or [],
            'storeCrashReports':
            bool(
                obj.get_option('sentry:store_crash_reports',
                               STORE_CRASH_REPORTS_DEFAULT)),
            'scrubIPAddresses':
            bool(
                obj.get_option('sentry:require_scrub_ip_address',
                               REQUIRE_SCRUB_IP_ADDRESS_DEFAULT)),
            'scrapeJavaScript':
            bool(
                obj.get_option('sentry:scrape_javascript',
                               SCRAPE_JAVASCRIPT_DEFAULT)),
            'trustedRelays':
            obj.get_option('sentry:trusted-relays', TRUSTED_RELAYS_DEFAULT)
            or [],
        })
        context['teams'] = serialize(team_list, user, TeamSerializer())
        context['projects'] = serialize(project_list, user,
                                        ProjectSummarySerializer())
        if env.request:
            context['access'] = access.from_request(env.request, obj).scopes
        else:
            context['access'] = access.from_user(user, obj).scopes
        context['features'] = feature_list
        context[
            'pendingAccessRequests'] = OrganizationAccessRequest.objects.filter(
                team__organization=obj, ).count()
        context['onboardingTasks'] = serialize(onboarding_tasks, user,
                                               OnboardingTasksSerializer())
        return context