def get_default_context(request, existing_context=None, team=None): from sentry.plugins import plugins context = { 'EVENTS_PER_PAGE': EVENTS_PER_PAGE, 'URL_PREFIX': settings.SENTRY_URL_PREFIX, 'SINGLE_ORGANIZATION': settings.SENTRY_SINGLE_ORGANIZATION, 'PLUGINS': plugins, 'ALLOWED_HOSTS': settings.ALLOWED_HOSTS, 'SENTRY_RAVEN_JS_URL': settings.SENTRY_RAVEN_JS_URL, } if existing_context: if team is None and 'team' in existing_context: team = existing_context['team'] if 'project' in existing_context: project = existing_context['project'] else: project = None else: project = None if team: organization = team.organization elif project: organization = project.organization else: organization = None if request: context.update({ 'request': request, }) if (not existing_context or 'TEAM_LIST' not in existing_context) and team: context['TEAM_LIST'] = Team.objects.get_for_user( organization=team.organization, user=request.user, with_projects=True, ) user = request.user else: user = AnonymousUser() if organization: context['selectedOrganization'] = serialize(organization, user) if team: context['selectedTeam'] = serialize(team, user) if project: context['selectedProject'] = serialize(project, user) if not existing_context or 'ACCESS' not in existing_context: context['ACCESS'] = access.from_user( user=user, organization=organization, ).to_django_context() return context
def get_view_response(self, request, group): from sentry.models import Event self.selected = request.path == self.get_url(group) if not self.selected: return response = self.view(request, group) if not response: return if isinstance(response, HttpResponseRedirect): return response if not isinstance(response, Response): raise NotImplementedError('Use self.render() when returning responses.') event = group.get_latest_event() or Event() event.group = group request.access = access.from_user(request.user, group.organization) return response.respond(request, { 'plugin': self, 'project': group.project, 'group': group, 'event': event, 'can_admin_event': request.access.has_scope('event:write'), 'can_remove_event': request.access.has_scope('event:delete'), })
def serialize(self, obj, attrs, user): from sentry import features from sentry.api.serializers.models.team import TeamWithProjectsSerializer team_list = list(Team.objects.filter( organization=obj, status=TeamStatus.VISIBLE, )) feature_list = [] if features.has('organizations:sso', obj, actor=user): feature_list.append('sso') if getattr(obj.flags, 'allow_joinleave'): feature_list.append('open-membership') context = super(DetailedOrganizationSerializer, self).serialize( obj, attrs, user) context['teams'] = serialize( team_list, user, TeamWithProjectsSerializer()) context['access'] = access.from_user(user, obj).scopes context['features'] = feature_list context['pendingAccessRequests'] = OrganizationAccessRequest.objects.filter( team__organization=obj, ).count() return context
def serialize(self, obj, attrs, user): from sentry import features from sentry.app import env from sentry.api.serializers.models.team import TeamWithProjectsSerializer team_list = list(Team.objects.filter(organization=obj, status=TeamStatus.VISIBLE)) feature_list = [] if features.has("organizations:events", obj, actor=user): feature_list.append("events") if features.has("organizations:sso", obj, actor=user): feature_list.append("sso") if getattr(obj.flags, "allow_joinleave"): feature_list.append("open-membership") context = super(DetailedOrganizationSerializer, self).serialize(obj, attrs, user) context["quota"] = { "maxRate": quotas.get_organization_quota(obj), "projectLimit": int( OrganizationOption.objects.get_value(organization=obj, key="sentry:project-rate-limit", default=100) ), } context["teams"] = serialize(team_list, user, TeamWithProjectsSerializer()) 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() return context
def tag_value_details(request, organization, project, key, value_id): tag_key = TagKey.objects.get( project=project, key=key) tag_value = TagValue.objects.get( project=project, key=key, id=value_id) event_list = Group.objects.filter( grouptag__project=project, grouptag__key=key, grouptag__value=tag_value.value, ).order_by('-score') return render_to_response('sentry/explore/tag_value_details.html', { 'SECTION': 'explore', 'project': project, 'team': project.team, 'organization': organization, 'tag_key': tag_key, 'tag_value': tag_value, 'event_list': event_list, 'ACCESS': access.from_user( user=request.user, organization=organization, ).to_django_context(), }, request)
def test_anonymous_user(self): user = self.create_user() anon_user = AnonymousUser() organization = self.create_organization(owner=user) result = access.from_user(anon_user, organization) assert not result.is_active
def tag_value_list(request, organization, project, key): tag_key = TagKey.objects.select_related('project').get( project=project, key=key) tag_values_qs = TagValue.objects.filter( project=project, key=key).select_related('project') sort = request.GET.get('sort') if sort not in SORT_OPTIONS: sort = DEFAULT_SORT_OPTION if sort == 'recent': tag_values_qs = tag_values_qs.order_by('-last_seen') elif sort == 'newest': tag_values_qs = tag_values_qs.order_by('-first_seen') elif sort == 'events': tag_values_qs = tag_values_qs.order_by('-times_seen') return render_to_response('sentry/explore/tag_value_list.html', { 'SECTION': 'explore', 'project': project, 'team': project.team, 'organization': organization, 'SORT_OPTIONS': SORT_OPTIONS, 'sort_label': SORT_OPTIONS[sort], 'tag_key': tag_key, 'tag_values': tag_values_qs, 'ACCESS': access.from_user( user=request.user, organization=project.organization, ).to_django_context(), }, request)
def tag_list(request, organization, project): tag_key_qs = sorted(TagKey.objects.filter( project=project ), key=lambda x: x.get_label()) tag_value_qs = TagValue.objects.filter( project=project).order_by('-times_seen') # O(N) db access tag_list = [] for tag_key in tag_key_qs: # prevent some excess queries by binding project tag_key.project = project tag_values = tag_value_qs.filter(key=tag_key.key)[:5] for tag_value in tag_values: tag_value.project = project tag_list.append((tag_key, tag_values)) return render_to_response('sentry/explore/tag_list.html', { 'SECTION': 'explore', 'project': project, 'team': project.team, 'organization': organization, 'tag_list': tag_list, 'ACCESS': access.from_user( user=request.user, organization=organization, ).to_django_context(), }, request)
def test_member_no_teams_open_membership(self): user = self.create_user() organization = self.create_organization( owner=self.user, flags=Organization.flags.allow_joinleave, ) member = self.create_member( organization=organization, user=user, role='member', teams=(), ) team = self.create_team(organization=organization) project = self.create_project(organization=organization, teams=[team]) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso assert result.scopes == member.get_scopes() assert result.has_team_access(team) assert result.has_team_scope(team, 'project:read') assert result.has_project_access(project) assert result.has_projects_access([project]) assert result.has_project_scope(project, 'project:read') assert not result.has_project_membership(project)
def get(self, request, organization): """ Retrieve an organization Return details on an individual organization including various details such as membership access, features, and teams. {method} {path} """ team_list = list(Team.objects.filter( organization=organization, status=TeamStatus.VISIBLE, )) feature_list = [] if features.has('organizations:sso', organization, actor=request.user): feature_list.append('sso') if getattr(organization.flags, 'allow_joinleave'): feature_list.append('open-membership') context = serialize(organization, request.user) context['access'] = access.from_user(request.user, organization).scopes context['features'] = feature_list context['teams'] = serialize( team_list, request.user, TeamWithProjectsSerializer()) return Response(context)
def render_with_group_context(group, template, context, request=None, event=None, is_public=False): context.update({ 'team': group.project.team, 'organization': group.project.organization, 'project': group.project, 'group': group, }) if request and request.user.is_authenticated(): context['ACCESS'] = access.from_user( user=request.user, organization=group.organization, ).to_django_context() else: context['ACCESS'] = access.DEFAULT.to_django_context() if event: if event.id: # TODO(dcramer): we dont want to actually use gt/lt here as it should # be inclusive. However, that would need to ensure we have some kind # of way to know which event was the previous (an offset), or to add # a third sort key (which is not yet indexed) base_qs = group.event_set.exclude(id=event.id) try: next_event = base_qs.filter( datetime__gt=event.datetime, ).order_by('datetime')[0:1].get() except Event.DoesNotExist: next_event = None try: prev_event = base_qs.filter( datetime__lt=event.datetime, ).order_by('-datetime')[0:1].get() except Event.DoesNotExist: prev_event = None else: next_event = None prev_event = None if not is_public: extra_data = event.data.get('extra', {}) if not isinstance(extra_data, dict): extra_data = {} context.update({ 'tags': event.get_tags(), 'json_data': extra_data, }) context.update({ 'event': event, 'version_data': event.data.get('modules', None), 'next_event': next_event, 'prev_event': prev_event, }) return render_to_response(template, context, request)
def group_list(request, organization, project): query = request.GET.get("query") if query and uuid_re.match(query): # Forward to event if it exists try: group_id = EventMapping.objects.filter(project=project, event_id=query).values_list("group", flat=True)[0] except IndexError: pass else: return HttpResponseRedirect( reverse( "sentry-group", kwargs={ "project_id": project.slug, "organization_slug": project.organization.slug, "group_id": group_id, }, ) ) response = _get_group_list(request=request, project=project) if isinstance(response, HttpResponse): return response # XXX: this is duplicate in _get_group_list sort_label = SORT_OPTIONS[response["sort"]] has_realtime = not request.GET.get("cursor") query_dict = request.GET.copy() if "cursor" in query_dict: del query_dict["cursor"] cursorless_query_string = query_dict.urlencode() GroupMeta.objects.populate_cache(response["event_list"]) return render_to_response( "sentry/groups/group_list.html", { "team": project.team, "organization": organization, "project": project, "from_date": response["date_from"], "to_date": response["date_to"], "date_type": response["date_type"], "has_realtime": has_realtime, "event_list": response["event_list"], "prev_cursor": response["prev_cursor"], "next_cursor": response["next_cursor"], "today": response["today"], "sort": response["sort"], "query": query, "cursorless_query_string": cursorless_query_string, "sort_label": sort_label, "SORT_OPTIONS": SORT_OPTIONS, "ACCESS": access.from_user(user=request.user, organization=organization).to_django_context(), }, request, )
def test_anonymous_user(self): from django.contrib.auth.models import AnonymousUser user = self.create_user() anon_user = AnonymousUser() organization = self.create_organization(owner=user) result = access.from_user(anon_user, organization) assert not result.is_active
def group_list(request, organization, project): query = request.GET.get('query') if query and uuid_re.match(query): # Forward to event if it exists try: group_id = EventMapping.objects.filter( project=project, event_id=query ).values_list('group', flat=True)[0] except IndexError: pass else: return HttpResponseRedirect(reverse('sentry-group', kwargs={ 'project_id': project.slug, 'organization_slug': project.organization.slug, 'group_id': group_id, })) response = _get_group_list( request=request, project=project, ) if isinstance(response, HttpResponse): return response # XXX: this is duplicate in _get_group_list sort_label = SORT_OPTIONS[response['sort']] has_realtime = not request.GET.get('cursor') query_dict = request.GET.copy() if 'cursor' in query_dict: del query_dict['cursor'] cursorless_query_string = query_dict.urlencode() GroupMeta.objects.populate_cache(response['event_list']) return render_to_response('sentry/groups/group_list.html', { 'team': project.team, 'organization': organization, 'project': project, 'from_date': response['date_from'], 'to_date': response['date_to'], 'date_type': response['date_type'], 'has_realtime': has_realtime, 'event_list': response['event_list'], 'prev_cursor': response['prev_cursor'], 'next_cursor': response['next_cursor'], 'today': response['today'], 'sort': response['sort'], 'query': query, 'cursorless_query_string': cursorless_query_string, 'sort_label': sort_label, 'SORT_OPTIONS': SORT_OPTIONS, 'ACCESS': access.from_user( user=request.user, organization=organization, ).to_django_context(), }, request)
def serialize(self, obj, attrs, user): from sentry import features from sentry.app import env from sentry.api.serializers.models.team import TeamWithProjectsSerializer team_list = list(Team.objects.filter( organization=obj, status=TeamStatus.VISIBLE, )) for team in team_list: team._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:callsigns', obj, actor=user): feature_list.append('callsigns') if features.has('organizations:new-tracebacks', obj, actor=user): feature_list.append('new-tracebacks') 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 getattr(obj.flags, 'allow_joinleave'): feature_list.append('open-membership') if not getattr(obj.flags, 'disable_shared_issues'): feature_list.append('shared-issues') context = super(DetailedOrganizationSerializer, self).serialize( obj, attrs, user) context['quota'] = { 'maxRate': quotas.get_organization_quota(obj), 'projectLimit': int(OrganizationOption.objects.get_value( organization=obj, key='sentry:project-rate-limit', default=100, )), } context['teams'] = serialize( team_list, user, TeamWithProjectsSerializer()) 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
def has_object_permission(self, request, view, organization): if request.auth: if self.is_project_key(request): return False return request.auth.organization_id == organization.id request.access = access.from_user(request.user, organization) allowed_scopes = set(self.scope_map[request.method]) return any(request.access.has_scope(s) for s in allowed_scopes)
def test_unlinked_sso(self): user = self.create_user() organization = self.create_organization(owner=user) member = organization.member_set.get(user=user) team = self.create_team(organization=organization) AuthProvider.objects.create(organization=organization, provider="dummy") result = access.from_user(user, organization) assert not result.sso_is_valid
def render_with_group_context(group, template, context, request=None, event=None, is_public=False): context.update( { "team": group.project.team, "organization": group.project.organization, "project": group.project, "group": group, } ) if request and request.user.is_authenticated(): context["ACCESS"] = access.from_user(user=request.user, organization=group.organization).to_django_context() else: context["ACCESS"] = access.DEFAULT.to_django_context() if event: if event.id: # HACK(dcramer): work around lack of unique sorting on datetime base_qs = Event.objects.filter(group=event.group_id).exclude(id=event.id) try: next_event = sorted( base_qs.filter(datetime__gte=event.datetime).order_by("datetime")[0:5], key=lambda x: (x.datetime, x.id), )[0] except IndexError: next_event = None try: prev_event = sorted( base_qs.filter(datetime__lte=event.datetime).order_by("-datetime")[0:5], key=lambda x: (x.datetime, x.id), reverse=True, )[0] except IndexError: prev_event = None else: next_event = None prev_event = None if not is_public: extra_data = event.data.get("extra", {}) if not isinstance(extra_data, dict): extra_data = {} context.update({"tags": event.get_tags(), "json_data": extra_data}) context.update( { "event": event, "version_data": event.data.get("modules", None), "next_event": next_event, "prev_event": prev_event, } ) return render_to_response(template, context, request)
def test_no_access(self): organization = self.create_organization() team = self.create_team(organization=organization) user = self.create_user() result = access.from_user(user, organization) assert not result.is_active assert result.sso_is_valid assert not result.scopes assert not result.has_team(team)
def test_detailed(self): user = self.create_user() organization = self.create_organization(owner=user) acc = access.from_user(user, organization) serializer = DetailedOrganizationSerializer() result = serialize(organization, user, serializer, access=acc) assert result["id"] == six.text_type(organization.id) assert result["role"] == "owner" assert result["access"] == settings.SENTRY_SCOPES
def test_no_access(self): organization = self.create_organization() team = self.create_team(organization=organization) user = self.create_user() result = access.from_user(user, organization) assert not result.sso_is_valid assert not result.requires_sso assert not result.scopes assert not result.has_team_access(team) assert not result.has_team_membership(team)
def test_unlinked_sso(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) AuthProvider.objects.create( organization=organization, provider='dummy', ) result = access.from_user(user, organization) assert not result.sso_is_valid
def test_global_org_member_access(self): user = self.create_user() organization = self.create_organization(owner=user) member = organization.member_set.get(user=user) team = self.create_team(organization=organization) result = access.from_user(user, organization) assert result.is_active assert result.sso_is_valid assert result.scopes == member.get_scopes() assert result.has_team(team)
def test_inactive_user(self): user = self.create_user(is_active=False) organization = self.create_organization(owner=user) request = self.make_request(user=user) results = [ access.from_user(user, organization), access.from_request(request, organization) ] for result in results: assert result is access.DEFAULT
def serialize(self, obj, attrs, user): from sentry import features from sentry.app import env from sentry.api.serializers.models.team import TeamWithProjectsSerializer team_list = list( Team.objects.filter( organization=obj, status=TeamStatus.VISIBLE, )) 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 getattr(obj.flags, 'allow_joinleave'): feature_list.append('open-membership') if not getattr(obj.flags, 'disable_shared_issues'): feature_list.append('shared-issues') context = super(DetailedOrganizationSerializer, self).serialize(obj, attrs, user) context['quota'] = { 'maxRate': quotas.get_organization_quota(obj), 'projectLimit': int( OrganizationOption.objects.get_value( organization=obj, key='sentry:project-rate-limit', default=100, )), } context['teams'] = serialize(team_list, user, TeamWithProjectsSerializer()) 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
def test_unlinked_sso(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) ap = AuthProvider.objects.create(organization=organization, provider="dummy") AuthIdentity.objects.create(auth_provider=ap, user=user) result = access.from_user(user, organization) assert not result.sso_is_valid assert result.requires_sso
def test_unlinked_sso_with_no_owners(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) AuthProvider.objects.create(organization=organization, provider="dummy") request = self.make_request(user=user) results = [access.from_user(user, organization), access.from_request(request, organization)] for result in results: assert not result.sso_is_valid assert not result.requires_sso
def test_sso_without_link_requirement(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) AuthProvider.objects.create(organization=organization, provider="dummy", flags=AuthProvider.flags.allow_unlinked) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso
def test_sso_without_link_requirement(self): user = self.create_user() organization = self.create_organization(owner=user) member = organization.member_set.get(user=user) team = self.create_team(organization=organization) AuthProvider.objects.create( organization=organization, provider="dummy", flags=AuthProvider.flags.allow_unlinked ) result = access.from_user(user, organization) assert result.sso_is_valid
def test_mixed_access(self): user = self.create_user() organization = self.create_organization(flags=0) # disable default allow_joinleave team = self.create_team(organization=organization) team_no_access = self.create_team(organization=organization) project = self.create_project(organization=organization, teams=[team]) project_no_access = self.create_project(organization=organization, teams=[team_no_access]) self.create_member(organization=organization, user=user, teams=[team]) result = access.from_user(user, organization) assert result.has_project_access(project) assert not result.has_project_access(project_no_access) assert not result.has_projects_access([project, project_no_access])
def _get_user_from_email(group, email): from sentry.models import User # TODO(dcramer): we should encode the userid in emails so we can avoid this for user in User.objects.filter(email__iexact=email): # Make sure that the user actually has access to this project context = access.from_user(user=user, organization=group.organization) if not context.has_team(group.project.team): logger.warning('User %r does not have access to group %r', user, group) continue return user
def _get_user_from_email(group, email): from sentry.models import User # TODO(dcramer): we should encode the userid in emails so we can avoid this for user in User.objects.filter(email__iexact=email): # Make sure that the user actually has access to this project context = access.from_user(user=user, organization=group.organization) if not any(context.has_team(t) for t in group.project.teams.all()): logger.warning("User %r does not have access to group %r", user, group) continue return user
def has_object_permission(self, request, view, project): if request.auth: if self.is_project_key(request): return request.auth.project_id == project.id return request.auth.organization_id == project.organization_id request.access = access.from_user(request.user, project.organization) for scope in self.scope_map.get(request.method, []): if request.access.has_team_scope(project.team, scope): return True return False
def test_unlinked_sso_with_no_owners(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) AuthProvider.objects.create( organization=organization, provider='dummy', ) result = access.from_user(user, organization) assert not result.sso_is_valid assert not result.requires_sso
def get_default_context(request, existing_context=None, team=None): from sentry import options from sentry.plugins.base import plugins context = { "URL_PREFIX": options.get("system.url-prefix"), "SINGLE_ORGANIZATION": settings.SENTRY_SINGLE_ORGANIZATION, "PLUGINS": plugins, # Maintain ONPREMISE key for backcompat (plugins?). TBH context could # probably be removed entirely: github.com/getsentry/sentry/pull/30970. "ONPREMISE": is_self_hosted(), "SELF_HOSTED": is_self_hosted(), } if existing_context: if team is None and "team" in existing_context: team = existing_context["team"] if "project" in existing_context: project = existing_context["project"] else: project = None else: project = None if team: organization = team.organization elif project: organization = project.organization else: organization = None if request: if (not existing_context or "TEAM_LIST" not in existing_context) and team: context["TEAM_LIST"] = Team.objects.get_for_user( organization=team.organization, user=request.user, with_projects=True ) user = request.user else: user = AnonymousUser() if not existing_context or "ACCESS" not in existing_context: if request: context["ACCESS"] = access.from_request( request=request, organization=organization ).to_django_context() else: context["ACCESS"] = access.from_user( user=user, organization=organization ).to_django_context() return context
def has_object_permission(self, request, view, team): if request.auth: if self.is_project_key(request): return False return request.auth.organization_id == team.organization_id request.access = access.from_user(request.user, team.organization) if not request.access.has_team(team): return False allowed_scopes = set(self.scope_map.get(request.method, [])) return any(request.access.has_scope(s) for s in allowed_scopes)
def test_team_restricted_org_member_access(self): user = self.create_user() organization = self.create_organization() team = self.create_team(organization=organization) member = organization.member_set.create(organization=organization, user=user, has_global_access=False) member.teams.add(team) result = access.from_user(user, organization) assert not result.is_global assert result.is_active assert result.sso_is_valid assert result.scopes == member.get_scopes() assert result.has_team(team)
def has_object_permission(self, request, view, team): if request.auth: if self.is_project_key(request): return False return request.auth.organization_id == team.organization_id request.access = access.from_user(request.user, team.organization) if not request.access.has_team(team): return False allowed_scopes = set(self.scope_map[request.method]) return any(request.access.has_scope(s) for s in allowed_scopes)
def serialize_detailed_org(context, obj): if "request" in context: user = context["request"].user access = from_user(user, obj) else: user = None access = NoAccess() context = serialize_func( obj, user, DetailedOrganizationSerializerWithProjectsAndTeams(), access=access ) return convert_to_json(context)
def test_sso_without_link_requirement(self): user = self.create_user() organization = self.create_organization(owner=user) member = organization.member_set.get(user=user) team = self.create_team(organization=organization) AuthProvider.objects.create( organization=organization, provider='dummy', flags=AuthProvider.flags.allow_unlinked, ) result = access.from_user(user, organization) assert result.sso_is_valid
def test_sso_without_link_requirement(self): user = self.create_user() organization = self.create_organization(owner=user) self.create_team(organization=organization) AuthProvider.objects.create( organization=organization, provider='dummy', flags=AuthProvider.flags.allow_unlinked, ) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso
def get_default_context(request, existing_context=None, team=None): from sentry import options from sentry.plugins.base import plugins context = { "URL_PREFIX": options.get("system.url-prefix"), "SINGLE_ORGANIZATION": settings.SENTRY_SINGLE_ORGANIZATION, "PLUGINS": plugins, "ONPREMISE": settings.SENTRY_ONPREMISE, } if existing_context: if team is None and "team" in existing_context: team = existing_context["team"] if "project" in existing_context: project = existing_context["project"] else: project = None else: project = None if team: organization = team.organization elif project: organization = project.organization else: organization = None if request: if (not existing_context or "TEAM_LIST" not in existing_context) and team: context["TEAM_LIST"] = Team.objects.get_for_user( organization=team.organization, user=request.user, with_projects=True) user = request.user else: user = AnonymousUser() if not existing_context or "ACCESS" not in existing_context: if request: context["ACCESS"] = access.from_request( request=request, organization=organization).to_django_context() else: context["ACCESS"] = access.from_user( user=user, organization=organization).to_django_context() return context
def test_member_no_teams(self): user = self.create_user() organization = self.create_organization(owner=self.user) member = self.create_member( organization=organization, user=user, role='member', ) team = self.create_team(organization=organization) result = access.from_user(user, organization) assert result.is_active assert result.sso_is_valid assert result.scopes == member.get_scopes() assert not result.has_team(team)
def test_unique_projects(self): user = self.create_user() organization = self.create_organization(owner=self.user) team = self.create_team(organization=organization) other_team = self.create_team(organization=organization) self.create_member( organization=organization, user=user, role="owner", teams=[team, other_team] ) project = self.create_project(organization=organization, teams=[team, other_team]) result = access.from_user(user, organization) assert result.has_project_access(project) assert len(result.projects) == 1
def serialize_detailed_org(context, obj): if 'request' in context: user = context['request'].user access = from_user(user, obj) else: user = None access = NoAccess() context = serialize_func(obj, user, DetailedOrganizationSerializer(), access=access) return convert_to_json(context)
def test_no_deleted_projects(self): user = self.create_user() organization = self.create_organization(owner=self.user) team = self.create_team(organization=organization) self.create_member(organization=organization, user=user, role="owner", teams=[team]) project = self.create_project( organization=organization, status=ObjectStatus.PENDING_DELETION, teams=[team] ) result = access.from_user(user, organization) assert result.has_project_access(project) is True assert result.has_project_membership(project) is False assert len(result.projects) == 0
def wall_display(request, organization, team): project_list = list(Project.objects.filter(team=team)) for project in project_list: project.team = team return render_to_response('sentry/wall.html', { 'team': team, 'organization': team.organization, 'project_list': project_list, 'ACCESS': access.from_user( user=request.user, organization=organization, ).to_django_context(), }, request)
def test_team_restricted_org_member_access(self): user = self.create_user() organization = self.create_organization() team = self.create_team(organization=organization) member = self.create_member( organization=organization, user=user, teams=[team], ) result = access.from_user(user, organization) assert result.is_active assert result.sso_is_valid assert result.scopes == member.get_scopes() assert result.has_team(team)
def test_no_access(self): organization = self.create_organization() team = self.create_team(organization=organization) project = self.create_project(organization=organization, teams=[team]) user = self.create_user() result = access.from_user(user, organization) assert not result.sso_is_valid assert not result.requires_sso assert not result.scopes assert not result.has_team_access(team) assert not result.has_team_scope(team, 'project:read') assert not result.has_project_access(project) assert not result.has_project_scope(project, 'project:read') assert not result.has_project_membership(project)
def test_owner_all_teams(self): user = self.create_user() organization = self.create_organization(owner=self.user) member = self.create_member( organization=organization, user=user, role='owner', ) team = self.create_team(organization=organization) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso assert result.scopes == member.get_scopes() assert result.has_team_access(team) assert result.has_team_membership(team)
def get(self, request, organization): """ Retrieve an organization Return details on an individual organization. {method} {path} """ team_list = Team.objects.get_for_user( organization=organization, user=request.user, with_projects=True, ) team_map = { t[0].id: s for t, s in zip( team_list, serialize([t for t, _ in team_list], request.user) ) } project_list = list(itertools.chain(*[p for _, p in team_list])) project_map = { p.id: s for p, s in zip( project_list, serialize(project_list, request.user) ) } teams_context = [] for team, project_list in team_list: team_data = team_map[team.id] team_data['projects'] = [project_map[p.id] for p in project_list] teams_context.append(team_data) feature_list = [] if features.has('organizations:sso', organization, actor=request.user): feature_list.append('organizations:sso') context = serialize(organization, request.user) context['teams'] = teams_context context['access'] = access.from_user(request.user, organization).scopes context['features'] = feature_list return Response(context)
def test_team_restricted_org_member_access(self): user = self.create_user() organization = self.create_organization() team = self.create_team(organization=organization) project = self.create_project(organization=organization, teams=[team]) member = self.create_member(organization=organization, user=user, teams=[team]) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso assert result.scopes == member.get_scopes() assert result.has_team_access(team) assert result.has_team_scope(team, "project:read") assert result.has_project_access(project) assert result.has_projects_access([project]) assert result.has_project_scope(project, "project:read") assert result.has_project_membership(project)
def test_team_restricted_org_member_access(self): user = self.create_user() organization = self.create_organization() team = self.create_team(organization=organization) member = organization.member_set.create( organization=organization, user=user, has_global_access=False, ) member.teams.add(team) result = access.from_user(user, organization) assert not result.is_global assert result.is_active assert result.sso_is_valid assert result.scopes == member.scopes assert result.has_team(team)
def test_detailed_org_projs_teams(self): # access the test fixtures so they're initialized self.team self.project acc = access.from_user(self.user, self.organization) serializer = DetailedOrganizationSerializerWithProjectsAndTeams() result = serialize(self.organization, self.user, serializer, access=acc) assert result["id"] == str(self.organization.id) assert result["role"] == "owner" assert result["access"] == settings.SENTRY_SCOPES assert result["relayPiiConfig"] is None assert len(result["teams"]) == 1 assert len(result["projects"]) == 1
def test_owner_all_teams(self): user = self.create_user() organization = self.create_organization(owner=self.user) member = self.create_member(organization=organization, user=user, role="owner") team = self.create_team(organization=organization) project = self.create_project(organization=organization, teams=[team]) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso assert result.scopes == member.get_scopes() assert result.has_team_access(team) assert result.has_team_scope(team, "project:read") assert result.has_project_access(project) assert result.has_projects_access([project]) assert result.has_project_scope(project, "project:read") # owners should have access but not membership assert result.has_project_membership(project) is False
def test_member_no_teams_closed_membership(self): user = self.create_user() organization = self.create_organization( owner=self.user, flags=0, # disable default allow_joinleave ) member = self.create_member( organization=organization, user=user, role='member', ) team = self.create_team(organization=organization) result = access.from_user(user, organization) assert result.sso_is_valid assert not result.requires_sso assert result.scopes == member.get_scopes() assert not result.has_team_access(team) assert not result.has_team_membership(team)