Exemplo n.º 1
0
    def test_has_sessions_flag(self):
        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["hasSessions"] is False

        self.project.first_event = timezone.now()
        self.project.update(flags=F("flags").bitor(Project.flags.has_sessions))

        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["hasSessions"] is True
Exemplo n.º 2
0
    def test_first_event_properties(self):
        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["firstEvent"] is None
        assert result["firstTransactionEvent"] is False

        self.project.first_event = timezone.now()
        self.project.update(flags=F("flags").bitor(Project.flags.has_transactions))

        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["firstEvent"]
        assert result["firstTransactionEvent"] is True
Exemplo n.º 3
0
    def test_avoid_hidden_and_no_env(self):
        hidden_env = Environment.objects.create(
            organization_id=self.organization.id, name="staging 2")
        EnvironmentProject.objects.create(project=self.project,
                                          environment=hidden_env,
                                          is_hidden=True)

        no_env = Environment.objects.create(
            organization_id=self.organization.id, name="")
        no_env.add_project(self.project)
        no_env.save()

        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result["id"] == six.text_type(self.project.id)
        assert result["name"] == self.project.name
        assert result["slug"] == self.project.slug
        assert result["firstEvent"] == self.project.first_event
        assert "releases" in result["features"]
        assert result["platform"] == self.project.platform

        assert result["latestDeploys"] == {
            "production": {
                "dateFinished": self.date,
                "version": self.release.version
            }
        }
        assert result["latestRelease"] == {"version": self.release.version}
        assert result["environments"] == ["production", "staging"]
Exemplo n.º 4
0
    def test_stats_with_transactions(self):
        two_min_ago = before_now(minutes=2)
        self.store_event(
            data={
                "event_id": "d" * 32,
                "message": "oh no",
                "timestamp": iso_format(two_min_ago)
            },
            project_id=self.project.id,
        )
        transaction = load_data("transaction", timestamp=two_min_ago)
        self.store_event(data=transaction, project_id=self.project.id)
        serializer = ProjectSummarySerializer(stats_period="24h",
                                              transaction_stats=True)
        results = serialize([self.project], self.user, serializer)
        assert "stats" in results[0]
        assert 24 == len(results[0]["stats"])

        assert [1] == [v[1] for v in results[0]["stats"] if v[1] > 0]

        assert "transactionStats" in results[0]
        assert 24 == len(results[0]["transactionStats"])
        assert [1] == [
            v[1] for v in results[0]["transactionStats"] if v[1] > 0
        ]
Exemplo n.º 5
0
    def test_avoid_hidden_and_no_env(self):
        hidden_env = Environment.objects.create(
            organization_id=self.organization.id,
            name='staging 2',
        )
        EnvironmentProject.objects.create(
            project=self.project,
            environment=hidden_env,
            is_hidden=True,
        )

        no_env = Environment.objects.create(
            organization_id=self.organization.id,
            name='',
        )
        no_env.add_project(self.project)
        no_env.save()

        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result['id'] == six.text_type(self.project.id)
        assert result['name'] == self.project.name
        assert result['slug'] == self.project.slug
        assert result['firstEvent'] == self.project.first_event
        assert 'releases' in result['features']
        assert result['platform'] == self.project.platform

        assert result['latestDeploys'] == {
            'production': {
                'dateFinished': self.date,
                'version': self.release.version
            }
        }
        assert result['latestRelease'] == {'version': self.release.version}
        assert result['environments'] == ['production', 'staging']
Exemplo n.º 6
0
    def test_stats_with_sessions_and_none_crash_free_rates(
            self, get_current_and_previous_crash_free_rates,
            check_has_health_data):
        """
        Test that ensures if both `currentCrashFreeRate` and `previousCrashFreeRate` are None, then
        we need to make a call to `check_has_health_data` to know if we have health data in that
        specific project_id(s)
        """
        check_has_health_data.return_value = {self.project.id}
        get_current_and_previous_crash_free_rates.return_value = {
            self.project.id: {
                "currentCrashFreeRate": None,
                "previousCrashFreeRate": None,
            }
        }
        serializer = ProjectSummarySerializer(stats_period="24h",
                                              session_stats=True)
        results = serialize([self.project], self.user, serializer)

        assert "sessionStats" in results[0]
        assert results[0]["sessionStats"]["previousCrashFreeRate"] is None
        assert results[0]["sessionStats"]["currentCrashFreeRate"] is None
        assert results[0]["sessionStats"]["hasHealthData"]

        check_has_health_data.assert_called()  # NOQA
Exemplo n.º 7
0
 def serialize_on_result(result):
     environment_id = self._get_environment_id_from_request(
         request, organization.id)
     serializer = ProjectSummarySerializer(
         environment_id=environment_id,
         stats_period=stats_period,
     )
     return serialize(result, request.user, serializer)
Exemplo n.º 8
0
 def serialize_on_result(result):
     transaction_stats = request.GET.get("transactionStats")
     environment_id = self._get_environment_id_from_request(request, organization.id)
     serializer = ProjectSummarySerializer(
         environment_id=environment_id,
         stats_period=stats_period,
         transaction_stats=transaction_stats,
     )
     return serialize(result, request.user, serializer)
Exemplo n.º 9
0
 def test_stats_errors(self):
     two_min_ago = before_now(minutes=2)
     self.store_event(
         data={"event_id": "d" * 32, "message": "oh no", "timestamp": iso_format(two_min_ago)},
         project_id=self.project.id,
     )
     serializer = ProjectSummarySerializer(stats_period="24h")
     results = serialize([self.project], self.user, serializer)
     assert "stats" in results[0]
     assert 24 == len(results[0]["stats"])
     assert [1] == [v[1] for v in results[0]["stats"] if v[1] > 0]
Exemplo n.º 10
0
    def test_user_reports(self):
        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["hasUserReports"] is False

        UserReport.objects.create(
            project=self.project,
            event_id="1",
            name="foo",
            email="*****@*****.**",
            comments="It broke!",
        )
        UserReport.objects.create(
            project=self.project,
            event_id="2",
            name="foo",
            email="*****@*****.**",
            comments="It broke again!",
        )

        result = serialize(self.project, self.user, ProjectSummarySerializer())
        assert result["hasUserReports"] is True
Exemplo n.º 11
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
Exemplo n.º 12
0
    def test_simple(self):
        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result["id"] == str(self.project.id)
        assert result["name"] == self.project.name
        assert result["slug"] == self.project.slug
        assert result["firstEvent"] == self.project.first_event
        assert "releases" in result["features"]
        assert result["platform"] == self.project.platform

        assert result["latestDeploys"] == {
            "production": {"dateFinished": self.date, "version": self.release.version}
        }
        assert result["latestRelease"] == {"version": self.release.version}
        assert result["environments"] == ["production", "staging"]
Exemplo n.º 13
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
Exemplo n.º 14
0
    def test_simple(self):
        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result['id'] == six.text_type(self.project.id)
        assert result['name'] == self.project.name
        assert result['slug'] == self.project.slug
        assert result['firstEvent'] == self.project.first_event
        assert 'releases' in result['features']
        assert result['platform'] == self.project.platform

        assert result['latestDeploys'] == {
            'production': {'dateFinished': self.date, 'version': self.release.version}
        }
        assert result['latestRelease'] == serialize(self.release)
        assert result['environments'] == ['production', 'staging']
Exemplo n.º 15
0
    def test_simple(self):
        date = datetime.datetime(2018, 1, 12, 3, 8, 25, tzinfo=timezone.utc)
        user = self.create_user(username='******')
        organization = self.create_organization(owner=user)
        team = self.create_team(organization=organization)
        project = self.create_project(teams=[team],
                                      organization=organization,
                                      name='foo')
        project.flags.has_releases = True
        project.save()

        release = Release.objects.create(
            organization_id=organization.id,
            version='1',
        )

        environment = Environment.objects.create(
            organization_id=organization.id,
            name='production',
        )

        deploy = Deploy.objects.create(environment_id=environment.id,
                                       organization_id=organization.id,
                                       release=release,
                                       date_finished=date)

        ReleaseProjectEnvironment.objects.create(project_id=project.id,
                                                 release_id=release.id,
                                                 environment_id=environment.id,
                                                 last_deploy_id=deploy.id)

        result = serialize(project, user, ProjectSummarySerializer())

        assert result['id'] == six.text_type(project.id)
        assert result['name'] == project.name
        assert result['slug'] == project.slug
        assert result['firstEvent'] == project.first_event
        assert 'releases' in result['features']
        assert result['platform'] == project.platform

        assert result['latestDeploys'] == {
            'production': {
                'dateFinished': date,
                'version': '1'
            }
        }
Exemplo n.º 16
0
    def test_no_enviroments(self):
        # remove environments and related models
        Deploy.objects.all().delete()
        Release.objects.all().delete()
        Environment.objects.all().delete()

        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result['id'] == six.text_type(self.project.id)
        assert result['name'] == self.project.name
        assert result['slug'] == self.project.slug
        assert result['firstEvent'] == self.project.first_event
        assert 'releases' in result['features']
        assert result['platform'] == self.project.platform

        assert result['latestDeploys'] is None
        assert result['latestRelease'] is None
        assert result['environments'] == []
Exemplo n.º 17
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
Exemplo n.º 18
0
    def test_no_environments(self):
        # remove environments and related models
        Deploy.objects.all().delete()
        Release.objects.all().delete()
        Environment.objects.all().delete()

        result = serialize(self.project, self.user, ProjectSummarySerializer())

        assert result["id"] == six.text_type(self.project.id)
        assert result["name"] == self.project.name
        assert result["slug"] == self.project.slug
        assert result["firstEvent"] == self.project.first_event
        assert "releases" in result["features"]
        assert result["platform"] == self.project.platform

        assert result["latestDeploys"] is None
        assert result["latestRelease"] is None
        assert result["environments"] == []
Exemplo n.º 19
0
    def test_stats_with_sessions(self,
                                 get_current_and_previous_crash_free_rates,
                                 check_has_health_data):
        get_current_and_previous_crash_free_rates.return_value = {
            self.project.id: {
                "currentCrashFreeRate": 75.63453,
                "previousCrashFreeRate": 99.324543,
            }
        }
        serializer = ProjectSummarySerializer(stats_period="24h",
                                              session_stats=True)
        results = serialize([self.project], self.user, serializer)

        assert "sessionStats" in results[0]
        assert results[0]["sessionStats"]["previousCrashFreeRate"] == 99.324543
        assert results[0]["sessionStats"]["currentCrashFreeRate"] == 75.63453
        assert results[0]["sessionStats"]["hasHealthData"]

        check_has_health_data.assert_not_called()  # NOQA
Exemplo n.º 20
0
    def test_simple(self):
        date = datetime.datetime(2018, 1, 12, 3, 8, 25, tzinfo=timezone.utc)
        user = self.create_user(username='******')
        organization = self.create_organization(owner=user)
        team = self.create_team(organization=organization)
        project = self.create_project(teams=[team],
                                      organization=organization,
                                      name='foo')

        release = Release.objects.create(
            organization_id=organization.id,
            version='1',
        )

        environment = Environment.objects.create(
            organization_id=organization.id,
            name='production',
        )

        deploy = Deploy.objects.create(environment_id=environment.id,
                                       organization_id=organization.id,
                                       release=release,
                                       date_finished=date)

        ReleaseProjectEnvironment.objects.create(project_id=project.id,
                                                 release_id=release.id,
                                                 environment_id=environment.id,
                                                 last_deploy_id=deploy.id)

        result = serialize(project, user, ProjectSummarySerializer())

        assert result['latestDeploys'] == {
            'production': {
                'dateFinished': date,
                'version': '1'
            }
        }
Exemplo n.º 21
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
Exemplo n.º 22
0
    def test_multiple_environments_deploys(self):
        env_1_release = self.create_release(self.project)
        env_1_deploy = Deploy.objects.create(
            environment_id=self.environment_1.id,
            organization_id=self.organization.id,
            release=env_1_release,
            date_finished=self.date + timedelta(minutes=20),
        )
        ReleaseProjectEnvironment.objects.create(
            project_id=self.project.id,
            release_id=env_1_release.id,
            environment_id=self.environment_1.id,
            last_deploy_id=env_1_deploy.id,
        )

        env_2_release = self.create_release(self.project)
        Deploy.objects.create(
            environment_id=self.environment_2.id,
            organization_id=self.organization.id,
            release=env_2_release,
            date_finished=self.date - timedelta(days=5),
        )
        env_2_deploy = Deploy.objects.create(
            environment_id=self.environment_2.id,
            organization_id=self.organization.id,
            release=env_2_release,
            date_finished=self.date,
        )
        ReleaseProjectEnvironment.objects.create(
            project_id=self.project.id,
            release_id=env_2_release.id,
            environment_id=self.environment_2.id,
            last_deploy_id=env_2_deploy.id,
        )
        other_project = self.create_project()
        other_project_release = self.create_release(other_project)
        other_project_deploy = Deploy.objects.create(
            environment_id=self.environment_2.id,
            organization_id=self.organization.id,
            release=other_project_release,
            date_finished=self.date - timedelta(minutes=350),
        )
        ReleaseProjectEnvironment.objects.create(
            project_id=other_project.id,
            release_id=other_project_release.id,
            environment_id=self.environment_2.id,
            last_deploy_id=other_project_deploy.id,
        )
        result = serialize([self.project, other_project], self.user,
                           ProjectSummarySerializer())
        assert result[0]["id"] == six.text_type(self.project.id)
        assert result[0]["latestDeploys"] == {
            self.environment_1.name: {
                "version": env_1_release.version,
                "dateFinished": env_1_deploy.date_finished,
            },
            self.environment_2.name: {
                "version": env_2_release.version,
                "dateFinished": env_2_deploy.date_finished,
            },
        }
        assert result[1]["id"] == six.text_type(other_project.id)
        assert result[1]["latestDeploys"] == {
            self.environment_2.name: {
                "version": other_project_release.version,
                "dateFinished": other_project_deploy.date_finished,
            }
        }
Exemplo n.º 23
0
    def get(self, request: Request, organization) -> Response:
        """
        List an Organization's Projects
        ```````````````````````````````

        Return a list of projects bound to a organization.

        :pparam string organization_slug: the slug of the organization for
                                          which the projects should be listed.
        :auth: required
        """
        stats_period = request.GET.get("statsPeriod")
        collapse = request.GET.getlist("collapse", [])
        if stats_period not in (None, "", "1h", "24h", "7d", "14d", "30d"):
            return Response(
                {
                    "error": {
                        "params": {
                            "stats_period": {
                                "message": ERR_INVALID_STATS_PERIOD
                            }
                        }
                    }
                },
                status=400,
            )
        elif not stats_period:
            # disable stats
            stats_period = None

        if request.auth and not request.user.is_authenticated:
            # TODO: remove this, no longer supported probably
            if hasattr(request.auth, "project"):
                team_list = list(request.auth.project.teams.all())
                queryset = Project.objects.filter(id=request.auth.project.id)
            elif request.auth.organization is not None:
                org = request.auth.organization
                team_list = list(Team.objects.filter(organization=org))
                queryset = Project.objects.filter(teams__in=team_list)
            else:
                return Response(
                    {
                        "detail":
                        "Current access does not point to "
                        "organization."
                    },
                    status=400)
        else:
            queryset = Project.objects.filter(organization=organization)

        order_by = ["slug"]

        if request.user.is_authenticated:
            queryset = queryset.extra(
                select={
                    "is_bookmarked":
                    """exists (
                        select *
                        from sentry_projectbookmark spb
                        where spb.project_id = sentry_project.id and spb.user_id = %s
                    )"""
                },
                select_params=(request.user.id, ),
            )
            order_by.insert(0, "-is_bookmarked")

        query = request.GET.get("query")
        if query:
            tokens = tokenize_query(query)
            for key, value in tokens.items():
                if key == "query":
                    value = " ".join(value)
                    queryset = queryset.filter(
                        Q(name__icontains=value) | Q(slug__icontains=value))
                elif key == "id":
                    queryset = queryset.filter(id__in=value)
                elif key == "slug":
                    queryset = queryset.filter(slug__in=value)
                elif key == "team":
                    team_list = list(Team.objects.filter(slug__in=value))
                    queryset = queryset.filter(teams__in=team_list)
                elif key == "!team":
                    team_list = list(Team.objects.filter(slug__in=value))
                    queryset = queryset.exclude(teams__in=team_list)
                elif key == "is_member":
                    queryset = queryset.filter(
                        teams__organizationmember__user=request.user)
                else:
                    queryset = queryset.none()

        queryset = queryset.filter(status=ProjectStatus.VISIBLE).distinct()

        # TODO(davidenwang): remove this after frontend requires only paginated projects
        get_all_projects = request.GET.get("all_projects") == "1"

        if get_all_projects:
            queryset = queryset.order_by("slug").select_related("organization")
            return Response(
                serialize(list(queryset), request.user,
                          ProjectSummarySerializer(collapse=collapse)))
        else:

            def serialize_on_result(result):
                transaction_stats = request.GET.get("transactionStats")
                session_stats = request.GET.get("sessionStats")
                environment_id = self._get_environment_id_from_request(
                    request, organization.id)
                serializer = ProjectSummarySerializer(
                    environment_id=environment_id,
                    stats_period=stats_period,
                    transaction_stats=transaction_stats,
                    session_stats=session_stats,
                    collapse=collapse,
                )
                return serialize(result, request.user, serializer)

            return self.paginate(
                request=request,
                queryset=queryset,
                order_by=order_by,
                on_results=serialize_on_result,
                paginator_cls=OffsetPaginator,
            )
Exemplo n.º 24
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
Exemplo n.º 25
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
Exemplo n.º 26
0
    def get(self, request, organization):
        """
        List an Organization's Projects
        ```````````````````````````````

        Return a list of projects bound to a organization.

        :pparam string organization_slug: the slug of the organization for
                                          which the projects should be listed.
        :auth: required
        """
        stats_period = request.GET.get('statsPeriod')
        if stats_period not in (None, '', '24h', '14d', '30d'):
            return Response(
                {
                    'error': {
                        'params': {
                            'stats_period': {
                                'message': ERR_INVALID_STATS_PERIOD
                            },
                        },
                    }
                },
                status=400)
        elif not stats_period:
            # disable stats
            stats_period = None

        if request.auth and not request.user.is_authenticated():
            # TODO: remove this, no longer supported probably
            if hasattr(request.auth, 'project'):
                team_list = list(request.auth.project.teams.all())
                queryset = Project.objects.filter(
                    id=request.auth.project.id, ).prefetch_related('teams')
            elif request.auth.organization is not None:
                org = request.auth.organization
                team_list = list(Team.objects.filter(organization=org, ))
                queryset = Project.objects.filter(
                    teams__in=team_list, ).prefetch_related('teams')
            else:
                return Response(
                    {
                        'detail':
                        'Current access does not point to '
                        'organization.'
                    },
                    status=400)
        else:
            team_list = list(request.access.teams)
            queryset = Project.objects.filter(
                teams__in=team_list, ).prefetch_related('teams')

        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))
                else:
                    queryset = queryset.none()

        queryset = queryset.distinct()

        return self.paginate(
            request=request,
            queryset=queryset,
            order_by='slug',
            on_results=lambda x: serialize(
                x, request.user,
                ProjectSummarySerializer(
                    environment_id=self._get_environment_id_from_request(
                        request,
                        organization.id,
                    ),
                    stats_period=stats_period,
                )),
            paginator_cls=OffsetPaginator,
        )
Exemplo n.º 27
0
    def get(self, request, organization):
        """
        List an Organization's Projects
        ```````````````````````````````

        Return a list of projects bound to a organization.

        :pparam string organization_slug: the slug of the organization for
                                          which the projects should be listed.
        :auth: required
        """
        stats_period = request.GET.get("statsPeriod")
        if stats_period not in (None, "", "24h", "14d", "30d"):
            return Response(
                {
                    "error": {
                        "params": {
                            "stats_period": {
                                "message": ERR_INVALID_STATS_PERIOD
                            }
                        }
                    }
                },
                status=400,
            )
        elif not stats_period:
            # disable stats
            stats_period = None

        if request.auth and not request.user.is_authenticated():
            # TODO: remove this, no longer supported probably
            if hasattr(request.auth, "project"):
                team_list = list(request.auth.project.teams.all())
                queryset = Project.objects.filter(
                    id=request.auth.project.id).prefetch_related("teams")
            elif request.auth.organization is not None:
                org = request.auth.organization
                team_list = list(Team.objects.filter(organization=org))
                queryset = Project.objects.filter(
                    teams__in=team_list).prefetch_related("teams")
            else:
                return Response(
                    {
                        "detail":
                        "Current access does not point to "
                        "organization."
                    },
                    status=400)
        else:
            queryset = Project.objects.filter(
                organization=organization).prefetch_related("teams")

        order_by = ["slug"]

        if request.user.is_authenticated():
            queryset = queryset.extra(
                select={
                    "is_bookmarked":
                    """exists (
                        select *
                        from sentry_projectbookmark spb
                        where spb.project_id = sentry_project.id and spb.user_id = %s
                    )"""
                },
                select_params=(request.user.id, ),
            )
            order_by.insert(0, "-is_bookmarked")

        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 == "id":
                    queryset = queryset.filter(id__in=value)
                elif key == "slug":
                    queryset = queryset.filter(slug__in=value)
                elif key == "team":
                    team_list = list(Team.objects.filter(slug__in=value))
                    queryset = queryset.filter(teams__in=team_list)
                elif key == "!team":
                    team_list = list(Team.objects.filter(slug__in=value))
                    queryset = queryset.exclude(teams__in=team_list)
                else:
                    queryset = queryset.none()

        queryset = queryset.filter(status=ProjectStatus.VISIBLE).distinct()

        return self.paginate(
            request=request,
            queryset=queryset,
            order_by=order_by,
            on_results=lambda x: serialize(
                x,
                request.user,
                ProjectSummarySerializer(
                    environment_id=self._get_environment_id_from_request(
                        request, organization.id),
                    stats_period=stats_period,
                ),
            ),
            paginator_cls=OffsetPaginator,
        )
Exemplo n.º 28
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