def delete(self, request, project, team_slug): """ Revoke a team's access to a project ``````````````````````````````````` :pparam string organization_slug: the slug of the organization. :pparam string project_slug: the slug of the project. :pparam string team_slug: the slug of the project. :auth: required """ try: team = Team.objects.get( organization_id=project.organization_id, slug=team_slug, ) except Team.DoesNotExist: raise Http404 if not request.access.has_team_scope(team, 'project:write'): return Response( { 'detail': ['You do not have permission to perform this action.'] }, status=403) project.remove_team(team) return Response( serialize(project, request.user, ProjectWithTeamSerializer()), status=200, )
def post(self, request: Request, project, team_slug) -> Response: """ Give a team access to a project ``````````````````````````````` :pparam string organization_slug: the slug of the organization. :pparam string project_slug: the slug of the project. :pparam string team_slug: the slug of the team. :auth: required """ try: team = Team.objects.get(organization_id=project.organization_id, slug=team_slug) except Team.DoesNotExist: raise Http404 if not request.access.has_team_scope(team, "project:write"): return Response( { "detail": ["You do not have permission to perform this action."] }, status=403) project.add_team(team) return Response(serialize(project, request.user, ProjectWithTeamSerializer()), status=201)
def test_simple(self): user = self.create_user(username='******') organization = self.create_organization(owner=user) team = self.create_team(organization=organization) project = self.create_project(team=team, organization=organization, name='foo') result = serialize(project, user, ProjectWithTeamSerializer()) assert result['slug'] == project.slug assert result['name'] == project.name assert result['id'] == six.text_type(project.id) assert result['team'] == serialize(team, user)
def test_simple(self): 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") result = serialize(project, user, ProjectWithTeamSerializer()) assert result["slug"] == project.slug assert result["name"] == project.name assert result["id"] == str(project.id) assert result["team"] == { "id": str(team.id), "slug": team.slug, "name": team.name, }
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 """ if request.auth and not request.user.is_authenticated(): # TODO: remove this, no longer supported probably if hasattr(request.auth, 'project'): team_list = [request.auth.project.team] queryset = queryset = Project.objects.filter( id=request.auth.project.id, ).select_related('team') elif request.auth.organization is not None: org = request.auth.organization team_list = list(Team.objects.filter( organization=org, )) queryset = Project.objects.filter( team__in=team_list, ).select_related('team') else: return Response( { 'detail': 'Current access does not point to ' 'organization.' }, status=400 ) else: team_list = list(request.access.teams) queryset = Project.objects.filter( team__in=team_list, ).select_related('team') return self.paginate( request=request, queryset=queryset, order_by='slug', on_results=lambda x: serialize(x, request.user, ProjectWithTeamSerializer()), paginator_cls=OffsetPaginator, )
def test_simple(self): 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') result = serialize(project, user, ProjectWithTeamSerializer()) # remove for mysql tests result['team'].pop('dateCreated') serialized_team = serialize(team, user) serialized_team.pop('dateCreated') assert result['slug'] == project.slug assert result['name'] == project.name assert result['id'] == six.text_type(project.id) assert result['team'] == serialized_team
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 = 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') return self.paginate( request=request, queryset=queryset, order_by='slug', on_results=lambda x: serialize( x, request.user, ProjectWithTeamSerializer(stats_period=stats_period, )), paginator_cls=OffsetPaginator, )
def serialize(self, obj, attrs, user): from sentry import features from sentry.app import env from sentry.api.serializers.models.project import ProjectWithTeamSerializer 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: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 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, ProjectWithTeamSerializer()) 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