Пример #1
0
    def get(self, request):
        status = request.GET.get('status')

        if status == 'published':
            queryset = SentryApp.objects.filter(status=SentryAppStatus.PUBLISHED)

        elif status == 'unpublished':
            if is_active_superuser(request):
                queryset = SentryApp.objects.filter(
                    status=SentryAppStatus.UNPUBLISHED
                )
            else:
                queryset = SentryApp.objects.filter(
                    status=SentryAppStatus.UNPUBLISHED,
                    owner__in=request.user.get_orgs(),
                )
        else:
            if is_active_superuser(request):
                queryset = SentryApp.objects.all()
            else:
                queryset = SentryApp.objects.filter(status=SentryAppStatus.PUBLISHED)

        return self.paginate(
            request=request,
            queryset=queryset,
            order_by='-date_added',
            paginator_cls=OffsetPaginator,
            on_results=lambda x: serialize(x, request.user),
        )
Пример #2
0
    def get(self, request, *args, **kwargs):
        next_uri = self.get_next_uri(request, *args, **kwargs)
        if request.user.is_authenticated():
            # if the user is a superuser, but not 'superuser authenticated'
            # we allow them to re-authenticate to gain superuser status
            if not request.user.is_superuser or is_active_superuser(request):
                return self.handle_authenticated(request, *args, **kwargs)

        request.session.set_test_cookie()

        # we always reset the state on GET so you dont end up at an odd location
        auth.initiate_login(request, next_uri)

        # Single org mode -- send them to the org-specific handler
        if settings.SENTRY_SINGLE_ORGANIZATION:
            org = Organization.get_default()
            next_uri = reverse('sentry-auth-organization', args=[org.slug])
            return HttpResponseRedirect(next_uri)

        session_expired = 'session_expired' in request.COOKIES
        if session_expired:
            messages.add_message(request, messages.WARNING,
                                 WARN_SESSION_EXPIRED)

        response = self.handle_basic_auth(request, *args, **kwargs)

        if session_expired:
            response.delete_cookie('session_expired')

        return response
Пример #3
0
    def get_allowed_projects(self, request, organization):
        has_valid_api_key = False
        if isinstance(request.auth, ApiKey):
            if request.auth.organization_id != organization.id:
                return []
            has_valid_api_key = request.auth.has_scope('project:releases') or \
                request.auth.has_scope('project:write')

        if not (has_valid_api_key or request.user.is_authenticated()):
            return []

        if has_valid_api_key or is_active_superuser(request) or organization.flags.allow_joinleave:
            allowed_teams = Team.objects.filter(organization=organization).values_list(
                'id', flat=True
            )
        else:
            allowed_teams = OrganizationMemberTeam.objects.filter(
                organizationmember__user=request.user,
                team__organization_id=organization.id,
            ).values_list(
                'team_id', flat=True
            )

        return Project.objects.filter(
            id__in=ProjectTeam.objects.filter(
                team_id__in=allowed_teams,
            ).values_list('project_id', flat=True)
        )
Пример #4
0
 def wrapped(request, *args, **kwargs):
     if not is_active_superuser(request):
         if request.user.is_superuser:
             auth.initiate_login(request, next_url=request.get_full_path())
             return HttpResponseRedirect(auth.get_login_url())
         return render_to_response('sentry/missing_permissions.html', {}, request, status=400)
     return func(request, *args, **kwargs)
Пример #5
0
    def post(self, request):
        if not (is_active_superuser(request) and request.access.has_permission('broadcasts.admin')):
            return self.respond(status=401)

        validator = AdminBroadcastValidator(data=request.DATA)
        if not validator.is_valid():
            return self.respond(validator.errors, status=400)

        result = validator.object

        with transaction.atomic():
            broadcast = Broadcast.objects.create(
                title=result['title'],
                message=result['message'],
                link=result['link'],
                is_active=result.get('isActive') or False,
                date_expires=result.get('expiresAt'),
            )
            logger.info('broadcasts.create', extra={
                'ip_address': request.META['REMOTE_ADDR'],
                'user_id': request.user.id,
                'broadcast_id': broadcast.id,
            })

        if result.get('hasSeen'):
            try:
                with transaction.atomic():
                    BroadcastSeen.objects.create(
                        broadcast=broadcast,
                        user=request.user,
                    )
            except IntegrityError:
                pass

        return self.respond(self._serialize_objects(broadcast, request))
Пример #6
0
    def get_projects(
        self,
        request,
        organization,
        force_global_perms=False,
        include_all_accessible=False,
    ):
        """
        Determines which project ids to filter the endpoint by. If a list of
        project ids is passed in via the `project` querystring argument then
        validate that these projects can be accessed. If not passed, then
        return all project ids that the user can access within this
        organization.

        :param request:
        :param organization: Organization to fetch projects for
        :param force_global_perms: Permission override. Allows subclasses to
        perform their own validation and allow the user to access any project
        in the organization. This is a hack to support the old
        `request.auth.has_scope` way of checking permissions, don't use it
        for anything else, we plan to remove this once we remove uses of
        `auth.has_scope`.
        :param include_all_accessible: Whether to factor the organization
        allow_joinleave flag into permission checks. We should ideally
        standardize how this is used and remove this parameter.
        :return: A list of project ids, or raises PermissionDenied.
        """
        project_ids = set(map(int, request.GET.getlist('project')))

        requested_projects = project_ids.copy()

        user = getattr(request, 'user', None)

        qs = Project.objects.filter(
            organization=organization,
            status=ProjectStatus.VISIBLE,
        )

        if project_ids:
            qs = qs.filter(id__in=project_ids)

        if force_global_perms:
            projects = list(qs)
        else:
            if (
                user and is_active_superuser(request) or
                requested_projects or
                include_all_accessible
            ):
                func = request.access.has_project_access
            else:
                func = request.access.has_project_membership
            projects = [p for p in qs if func(p)]

        project_ids = set(p.id for p in projects)

        if requested_projects and project_ids != requested_projects:
            raise PermissionDenied

        return projects
Пример #7
0
    def has_object_permission(self, request, view, project):
        result = super(ProjectPermission,
                       self).has_object_permission(request, view, project.organization)

        if not result:
            return result
        if project.teams.exists():
            return any(
                has_team_permission(request, team, self.scope_map) for team in project.teams.all()
            )
        elif request.user.is_authenticated():
            # this is only for team-less projects
            if is_active_superuser(request):
                return True
            try:
                role = OrganizationMember.objects.filter(
                    organization=project.organization,
                    user=request.user,
                ).values_list('role', flat=True).get()
            except OrganizationMember.DoesNotExist:
                # this should probably never happen?
                return False

            return roles.get(role).is_global
        elif hasattr(request.auth, 'project_id') and project.id == request.auth.project_id:
            return True

        return False
Пример #8
0
def from_request(request, organization, scopes=None):
    if not organization:
        return DEFAULT

    if is_active_superuser(request):
        # we special case superuser so that if they're a member of the org
        # they must still follow SSO checks, but they gain global access
        try:
            member = OrganizationMember.objects.get(
                user=request.user,
                organization=organization,
            )
        except OrganizationMember.DoesNotExist:
            requires_sso, sso_is_valid = False, True
        else:
            requires_sso, sso_is_valid = _sso_params(member)

        team_list = list(organization.team_set.all())
        return Access(
            scopes=scopes if scopes is not None else settings.SENTRY_SCOPES,
            is_active=True,
            teams=team_list,
            memberships=team_list,
            sso_is_valid=sso_is_valid,
            requires_sso=requires_sso,
        )
    return from_user(request.user, organization, scopes=scopes)
Пример #9
0
    def _serialize_objects(self, items, request):
        if is_active_superuser(request):
            serializer_cls = AdminBroadcastSerializer
        else:
            serializer_cls = BroadcastSerializer

        return serialize(items, request.user, serializer=serializer_cls())
Пример #10
0
    def serialize(self, obj, attrs, user):
        from sentry.mediators.service_hooks.creator import consolidate_events

        data = {
            'name': obj.name,
            'slug': obj.slug,
            'author': obj.author,
            'scopes': obj.get_scopes(),
            'events': consolidate_events(obj.events),
            'status': obj.get_status_display(),
            'schema': obj.schema,
            'uuid': obj.uuid,
            'webhookUrl': obj.webhook_url,
            'redirectUrl': obj.redirect_url,
            'isAlertable': obj.is_alertable,
            'overview': obj.overview,
        }

        if is_active_superuser(env.request) or (
            hasattr(user, 'get_orgs') and obj.owner in user.get_orgs()
        ):
            data.update({
                'clientId': obj.application.client_id,
                'clientSecret': obj.application.client_secret,
                'owner': {
                    'id': obj.owner.id,
                    'slug': obj.owner.slug,
                },
            })

        return data
Пример #11
0
    def handle(self, request, organization):
        try:
            auth_provider = AuthProvider.objects.get(
                organization=organization,
            )
        except AuthProvider.DoesNotExist:
            pass
        else:
            provider = auth_provider.get_provider()
            requires_feature = provider.required_feature

            # Provider is not enabled
            # Allow superusers to edit and disable SSO for orgs that
            # downgrade plans and can no longer access the feature
            if requires_feature and not features.has(
                requires_feature,
                organization,
                actor=request.user
            ) and not is_active_superuser(request):
                home_url = organization.get_url()
                messages.add_message(request, messages.ERROR, ERR_NO_SSO)

                return HttpResponseRedirect(home_url)

            return self.handle_existing_provider(
                request=request,
                organization=organization,
                auth_provider=auth_provider,
            )

        if request.method == 'POST':
            provider_key = request.POST.get('provider')
            if not manager.exists(provider_key):
                raise ValueError(u'Provider not found: {}'.format(provider_key))

            helper = AuthHelper(
                request=request,
                organization=organization,
                provider_key=provider_key,
                flow=AuthHelper.FLOW_SETUP_PROVIDER,
            )

            feature = helper.provider.required_feature
            if feature and not features.has(feature, organization, actor=request.user):
                return HttpResponse('Provider is not enabled', status=401)

            if request.POST.get('init'):
                helper.init_pipeline()

            if not helper.pipeline_is_valid():
                return helper.error('Something unexpected happened during authentication.')

            # render first time setup view
            return helper.current_step()

        # Otherwise user is in bad state since frontend/react should handle this case
        return HttpResponseRedirect(
            organization.get_url()
        )
Пример #12
0
 def can(self, request):
     if 'prof' not in request.GET:
         return False
     if settings.DEBUG:
         return True
     if is_active_superuser(request):
         return True
     return False
Пример #13
0
 def has_object_permission(self, request, view, user=None):
     if user is None:
         user = request.user
     if request.user == user:
         return True
     if request.auth:
         return False
     if is_active_superuser(request):
         return True
     return False
Пример #14
0
    def get_allowed_roles(self, request, organization, member=None):
        can_admin = request.access.has_scope('member:admin')

        allowed_roles = []
        if can_admin and not is_active_superuser(request):
            acting_member = OrganizationMember.objects.get(
                user=request.user,
                organization=organization,
            )
            if member and roles.get(acting_member.role).priority < roles.get(member.role).priority:
                can_admin = False
            else:
                allowed_roles = [
                    r for r in roles.get_all()
                    if r.priority <= roles.get(acting_member.role).priority
                ]
                can_admin = bool(allowed_roles)
        elif is_active_superuser(request):
            allowed_roles = roles.get_all()
        return (can_admin, allowed_roles, )
    def _can_access(self, request, member):
        # TODO(dcramer): ideally org owners/admins could perform these actions
        if is_active_superuser(request):
            return True

        if not request.user.is_authenticated():
            return False

        if request.user.id == member.user_id:
            return True

        return False
Пример #16
0
    def _get_identities(self, item_list, user):
        if not (env.request and is_active_superuser(env.request)):
            item_list = [x for x in item_list if x == user]

        queryset = AuthIdentity.objects.filter(
            user__in=item_list,
        ).select_related('auth_provider', 'auth_provider__organization')

        results = {i.id: [] for i in item_list}
        for item in queryset:
            results[item.user_id].append(item)
        return results
Пример #17
0
    def _get_broadcast(self, request, broadcast_id):
        if is_active_superuser(request) and request.access.has_permission('broadcasts.admin'):
            queryset = Broadcast.objects.all()
        else:
            queryset = Broadcast.objects.filter(
                Q(date_expires__isnull=True) | Q(date_expires__gt=timezone.now()),
                is_active=True,
            )

        try:
            return queryset.get(id=broadcast_id)
        except Broadcast.DoesNotExist:
            raise ResourceDoesNotExist
Пример #18
0
 def show_toolbar_for_request(self, request):
     # This avoids touching user session, which means we avoid
     # setting `Vary: Cookie` as a response header which will
     # break HTTP caching entirely.
     if request.path_info.startswith(settings.ANONYMOUS_STATIC_PREFIXES):
         return
     if not settings.SENTRY_DEBUGGER:
         return False
     if not is_active_superuser(request):
         return False
     if 'text/html' not in request.META.get('HTTP_ACCEPT', '*/*'):
         return False
     return True
Пример #19
0
    def convert_args(self, request, organization_slug, *args, **kwargs):
        if is_active_superuser(request):
            organizations = Organization.objects.all()
        else:
            organizations = request.user.get_orgs()

        try:
            organization = organizations.get(slug=organization_slug)
        except Organization.DoesNotExist:
            raise Http404
        self.check_object_permissions(request, organization)

        kwargs['organization'] = organization
        return (args, kwargs)
Пример #20
0
    def put(self, request, user):
        """
        Update Account Appearance options
        `````````````````````````````````

        Update account appearance options. Only supplied values are updated.

        :pparam string user_id: user id
        :param string language: language preference
        :param string stacktrace_order: One of -1 (default), 1 (most recent call last), 2 (most recent call first).
        :param string timezone: timezone option
        :param clock_24_hours boolean: use 24 hour clock
        :auth: required
        """

        if is_active_superuser(request):
            serializer_cls = AdminUserSerializer
        else:
            serializer_cls = UserSerializer
        serializer = serializer_cls(user, data=request.DATA, partial=True)

        serializer_options = UserOptionsSerializer(
            data=request.DATA.get('options', {}), partial=True)

        # This serializer should NOT include privileged fields e.g. password
        if not serializer.is_valid() or not serializer_options.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        # map API keys to keys in model
        key_map = {
            'language': 'language',
            'timezone': 'timezone',
            'stacktraceOrder': 'stacktrace_order',
            'clock24Hours': 'clock_24_hours',
            'seenReleaseBroadcast': 'seen_release_broadcast',
        }

        options_result = serializer_options.object

        for key in key_map:
            if key in options_result:
                UserOption.objects.set_value(
                    user=user,
                    key=key_map.get(key, key),
                    value=options_result.get(key),
                )

        user = serializer.save()

        return Response(serialize(user, request.user, DetailedUserSerializer()))
    def delete(self, request, organization, member_id):
        try:
            om = self._get_member(request, organization, member_id)
        except OrganizationMember.DoesNotExist:
            raise ResourceDoesNotExist

        if request.user.is_authenticated() and not is_active_superuser(request):
            try:
                acting_member = OrganizationMember.objects.get(
                    organization=organization,
                    user=request.user,
                )
            except OrganizationMember.DoesNotExist:
                return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400)
            else:
                if acting_member != om:
                    if not request.access.has_scope('member:admin'):
                        return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400)
                    elif not roles.can_manage(acting_member.role, om.role):
                        return Response({'detail': ERR_INSUFFICIENT_ROLE}, status=400)

        # TODO(dcramer): do we even need this check?
        elif not request.access.has_scope('member:admin'):
            return Response({'detail': ERR_INSUFFICIENT_SCOPE}, status=400)

        if self._is_only_owner(om):
            return Response({'detail': ERR_ONLY_OWNER}, status=403)

        audit_data = om.get_audit_log_data()

        with transaction.atomic():
            AuthIdentity.objects.filter(
                user=om.user,
                auth_provider__organization=organization,
            ).delete()

            om.delete()

        self.create_audit_entry(
            request=request,
            organization=organization,
            target_object=om.id,
            target_user=om.user,
            event=AuditLogEntryEvent.MEMBER_REMOVE,
            data=audit_data,
        )

        return Response(status=204)
Пример #22
0
    def has_object_permission(self, request, view, installation):
        if not hasattr(request, 'user') or not request.user:
            return False

        self.determine_access(request, installation.organization)

        if is_active_superuser(request):
            return True

        if installation.organization not in request.user.get_orgs():
            raise Http404

        return ensure_scoped_permission(
            request,
            self.scope_map.get(request.method),
        )
Пример #23
0
    def has_object_permission(self, request, view, sentry_app):
        if not hasattr(request, 'user') or not request.user:
            return False

        self.determine_access(request, sentry_app.owner)

        if is_active_superuser(request):
            return True

        # User must be in the Org who owns the app.
        if sentry_app.owner not in request.user.get_orgs():
            raise Http404

        return ensure_scoped_permission(
            request,
            self._scopes_for_sentry_app(sentry_app).get(request.method),
        )
Пример #24
0
    def has_object_permission(self, request, view, organization):
        if not hasattr(request, 'user') or not request.user:
            return False

        self.determine_access(request, organization)

        if is_active_superuser(request):
            return True

        # User must be a part of the Org they're trying to create the app in.
        if organization not in request.user.get_orgs():
            raise Http404

        return ensure_scoped_permission(
            request,
            self.scope_map.get(request.method),
        )
Пример #25
0
def is_member_disabled_from_limit(request, organization):
    user = request.user

    # never limit sentry apps
    if getattr(user, "is_sentry_app", False):
        return False

    # don't limit super users
    if is_active_superuser(request):
        return False

    # must be a simple user at this point
    try:
        member = get_cached_organization_member(user.id, organization.id)
    except OrganizationMember.DoesNotExist:
        # if org member doesn't exist, we should be getting an auth error later
        return False
    else:
        return member.flags["member-limit:restricted"]
Пример #26
0
    def serialize(self, obj, attrs, user, access):
        from sentry.mediators.service_hooks.creator import consolidate_events

        data = {
            "name": obj.name,
            "slug": obj.slug,
            "author": obj.author,
            "scopes": obj.get_scopes(),
            "events": consolidate_events(obj.events),
            "status": obj.get_status_display(),
            "schema": obj.schema,
            "uuid": obj.uuid,
            "webhookUrl": obj.webhook_url,
            "redirectUrl": obj.redirect_url,
            "isAlertable": obj.is_alertable,
            "verifyInstall": obj.verify_install,
            "overview": obj.overview,
            "allowedOrigins": obj.application.get_allowed_origins(),
        }

        data["featureData"] = []

        if obj.status != SentryAppStatus.INTERNAL:
            features = IntegrationFeature.objects.filter(sentry_app_id=obj.id)
            data["featureData"] = map(lambda x: serialize(x, user), features)

        if obj.status == SentryAppStatus.PUBLISHED and obj.date_published:
            data.update({"datePublished": obj.date_published})

        if (env.request and is_active_superuser(env.request)) or (hasattr(
                user, "get_orgs") and obj.owner in user.get_orgs()):
            client_secret = (obj.application.client_secret
                             if obj.show_auth_info(access) else MASKED_VALUE)
            data.update({
                "clientId": obj.application.client_id,
                "clientSecret": client_secret,
                "owner": {
                    "id": obj.owner.id,
                    "slug": obj.owner.slug
                },
            })

        return data
Пример #27
0
def from_request(request, organization=None, scopes=None):
    if not organization:
        return from_user(request.user,
                         organization=organization,
                         scopes=scopes)

    if getattr(request.user, "is_sentry_app", False):
        return _from_sentry_app(request.user, organization=organization)

    if is_active_superuser(request):
        role = None
        # we special case superuser so that if they're a member of the org
        # they must still follow SSO checks, but they gain global access
        try:
            member = OrganizationMember.objects.get(user=request.user,
                                                    organization=organization)
        except OrganizationMember.DoesNotExist:
            requires_sso, sso_is_valid = False, True
        else:
            requires_sso, sso_is_valid = _sso_params(member)
            role = member.role

        team_list = ()

        project_list = ()
        return Access(
            scopes=scopes if scopes is not None else settings.SENTRY_SCOPES,
            is_active=True,
            organization_id=organization.id if organization else None,
            teams=team_list,
            projects=project_list,
            sso_is_valid=sso_is_valid,
            requires_sso=requires_sso,
            has_global_access=True,
            permissions=UserPermission.for_user(request.user.id),
            role=role,
        )

    # TODO: from_auth does not take scopes as a parameter so this fails for anon user
    if hasattr(request, "auth") and not request.user.is_authenticated():
        return from_auth(request.auth, scopes=scopes)

    return from_user(request.user, organization, scopes=scopes)
Пример #28
0
    def get_attrs(
            self, item_list: Sequence[Team], user: User,
            **kwargs: Any) -> MutableMapping[Team, MutableMapping[str, Any]]:
        request = env.request
        org_ids = {t.organization_id for t in item_list}

        org_roles = get_org_roles(org_ids, user)

        member_totals = get_member_totals(item_list, user)
        memberships = get_team_memberships(item_list, user)
        access_requests = get_access_requests(item_list, user)

        avatars = {
            a.team_id: a
            for a in TeamAvatar.objects.filter(team__in=item_list)
        }

        is_superuser = request and is_active_superuser(
            request) and request.user == user
        result: MutableMapping[Team, MutableMapping[str, Any]] = {}

        for team in item_list:
            is_member = team.id in memberships
            org_role = org_roles.get(team.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif team.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[team] = {
                "pending_request": team.id in access_requests,
                "is_member": is_member,
                "has_access": has_access,
                "avatar": avatars.get(team.id),
                "member_count": member_totals.get(team.id, 0),
            }
        return result
Пример #29
0
    def get(self, request):
        if not is_active_superuser(request):
            return Response()

        results = status_checks.check_all()
        return Response(
            {
                'problems': [
                    {
                        'id': md5_text(problem.message).hexdigest(),
                        'message': problem.message,
                        'severity': problem.severity,
                        'url': problem.url,
                    } for problem in
                    sort_by_severity(itertools.chain.from_iterable(results.values()))
                ],
                'healthy':
                {type(check).__name__: not problems for check, problems in results.items()},
            }
        )
Пример #30
0
    def put(self, request, user):
        if is_active_superuser(request):
            serializer_cls = AdminUserSerializer
        else:
            serializer_cls = UserSerializer
        serializer = serializer_cls(user, data=request.DATA, partial=True)

        if serializer.is_valid():
            user = serializer.save()

            options = request.DATA.get('options', {})
            if options.get('seenReleaseBroadcast'):
                UserOption.objects.set_value(
                    user=user,
                    key='seen_release_broadcast',
                    value=options.get('seenReleaseBroadcast'),
                )
            return Response(serialize(user, request.user))

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Пример #31
0
    def put(self, request, user):
        if is_active_superuser(request):
            serializer_cls = AdminUserSerializer
        else:
            serializer_cls = UserSerializer
        serializer = serializer_cls(user, data=request.DATA, partial=True)

        if serializer.is_valid():
            user = serializer.save()

            options = request.DATA.get('options', {})
            if options.get('seenReleaseBroadcast'):
                UserOption.objects.set_value(
                    user=user,
                    key='seen_release_broadcast',
                    value=options.get('seenReleaseBroadcast'),
                )
            return Response(serialize(user, request.user))

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Пример #32
0
    def has_object_permission(self, request, view, installation):
        if not hasattr(request, 'user') or not request.user:
            return False

        self.determine_access(request, installation.organization)

        if is_active_superuser(request):
            return True

        # if user is an app, make sure it's for that same app
        if request.user.is_sentry_app:
            return request.user == installation.sentry_app.proxy_user

        if installation.organization not in request.user.get_orgs():
            raise Http404

        return ensure_scoped_permission(
            request,
            self.scope_map.get(request.method),
        )
Пример #33
0
    def _get_projects_by_id(
        self,
        project_ids,
        request,
        organization,
        force_global_perms=False,
        include_all_accessible=False,
    ):
        qs = Project.objects.filter(organization=organization, status=ProjectStatus.VISIBLE)
        user = getattr(request, "user", None)

        # A project_id of -1 means 'all projects I have access to'
        # While no project_ids means 'all projects I am a member of'.
        if project_ids == ALL_ACCESS_PROJECTS:
            include_all_accessible = True
            project_ids = set()

        requested_projects = project_ids.copy()
        if project_ids:
            qs = qs.filter(id__in=project_ids)

        if force_global_perms:
            projects = list(qs)
        else:
            if (
                user
                and is_active_superuser(request)
                or requested_projects
                or include_all_accessible
            ):
                func = request.access.has_project_access
            else:
                func = request.access.has_project_membership
            projects = [p for p in qs if func(p)]

        project_ids = set(p.id for p in projects)

        if requested_projects and project_ids != requested_projects:
            raise PermissionDenied

        return projects
Пример #34
0
def from_request(request, organization=None, scopes=None):
    if not organization:
        return from_user(request.user,
                         organization=organization,
                         scopes=scopes)

    if getattr(request.user, 'is_sentry_app', False):
        return from_sentry_app(request.user, organization=organization)

    if is_active_superuser(request):
        # we special case superuser so that if they're a member of the org
        # they must still follow SSO checks, but they gain global access
        try:
            member = OrganizationMember.objects.get(
                user=request.user,
                organization=organization,
            )
        except OrganizationMember.DoesNotExist:
            requires_sso, sso_is_valid = False, True
        else:
            requires_sso, sso_is_valid = _sso_params(member)

        team_list = ()

        project_list = ()
        return Access(
            scopes=scopes if scopes is not None else settings.SENTRY_SCOPES,
            is_active=True,
            organization_id=organization.id if organization else None,
            teams=team_list,
            projects=project_list,
            sso_is_valid=sso_is_valid,
            requires_sso=requires_sso,
            has_global_access=True,
            permissions=UserPermission.for_user(request.user.id),
        )

    if hasattr(request, 'auth') and not request.user.is_authenticated():
        return from_auth(request.auth, scopes=scopes)

    return from_user(request.user, organization, scopes=scopes)
Пример #35
0
def from_request(request, organization=None, scopes=None):
    if not organization:
        return from_user(request.user,
                         organization=organization,
                         scopes=scopes)

    if getattr(request.user, 'is_sentry_app', False):
        return from_sentry_app(request.user, organization=organization)

    if is_active_superuser(request):
        # we special case superuser so that if they're a member of the org
        # they must still follow SSO checks, but they gain global access
        try:
            member = OrganizationMember.objects.get(
                user=request.user,
                organization=organization,
            )
        except OrganizationMember.DoesNotExist:
            requires_sso, sso_is_valid = False, True
        else:
            requires_sso, sso_is_valid = _sso_params(member)

        team_list = ()

        project_list = ()
        return Access(
            scopes=scopes if scopes is not None else settings.SENTRY_SCOPES,
            is_active=True,
            organization_id=organization.id if organization else None,
            teams=team_list,
            projects=project_list,
            sso_is_valid=sso_is_valid,
            requires_sso=requires_sso,
            open_access_policy=True,
            permissions=UserPermission.for_user(request.user.id),
        )

    if hasattr(request, 'auth') and not request.user.is_authenticated():
        return from_auth(request.auth, scopes=scopes)

    return from_user(request.user, organization, scopes=scopes)
Пример #36
0
    def get(self, request: Request) -> Response:
        if not is_active_superuser(request):
            return Response()

        results = status_checks.check_all()
        return Response(
            {
                "problems": [
                    {
                        "id": md5_text(problem.message).hexdigest(),
                        "message": problem.message,
                        "severity": problem.severity,
                        "url": problem.url,
                    }
                    for problem in sort_by_severity(itertools.chain.from_iterable(results.values()))
                ],
                "healthy": {
                    type(check).__name__: not problems for check, problems in results.items()
                },
            }
        )
Пример #37
0
    def _is_authorized(self, user, organization_id):
        # If user is not logged in and member of the organization,
        # do not return the permalink which contains private information i.e. org name.
        request = env.request
        if request and is_active_superuser(request) and request.user == user:
            return True

        # If user is a sentry_app then it's a proxy user meaning we can't do a org lookup via `get_orgs()`
        # because the user isn't an org member. Instead we can use the auth token and the installation
        # it's associated with to find out what organization the token has access to.
        if (
            request
            and getattr(request.user, "is_sentry_app", False)
            and isinstance(request.auth, ApiToken)
        ):
            if SentryAppInstallationToken.objects.has_organization_access(
                request.auth, organization_id
            ):
                return True

        return user.is_authenticated and user.get_orgs().filter(id=organization_id).exists()
    def _can_access(self, request, member, organization):
        if is_active_superuser(request):
            return True

        if not request.user.is_authenticated():
            return False

        if request.user.id == member.user_id:
            return True

        acting_member = OrganizationMember.objects.get(
            organization=organization,
            user__id=request.user.id,
            user__is_active=True,
        )

        if roles.get(acting_member.role).is_global and \
                roles.can_manage(acting_member.role, member.role):
            return True

        return False
Пример #39
0
def is_member_disabled_from_limit(request, organization):
    user = request.user

    # never limit sentry apps
    if getattr(user, "is_sentry_app", False):
        return False

    # don't limit super users
    if is_active_superuser(request):
        return False

    # must be a simple user at this point
    try:
        member = get_cached_organization_member(user.id, organization.id)
    except OrganizationMember.DoesNotExist:
        # should never happen but if it does, don't block auth
        # but send error to logs/Sentry
        logger.error("is_member_disabled_from_limit.member_missing")
        return False
    else:
        return member.flags["member-limit:restricted"]
    def _can_access(self, request, member, organization):
        if is_active_superuser(request):
            return True

        if not request.user.is_authenticated():
            return False

        if request.user.id == member.user_id:
            return True

        acting_member = OrganizationMember.objects.get(
            organization=organization,
            user__id=request.user.id,
            user__is_active=True,
        )

        if roles.get(acting_member.role).is_global and \
                roles.can_manage(acting_member.role, member.role):
            return True

        return False
Пример #41
0
    def convert_args(self, request, organization_slug, *args, **kwargs):
        try:
            organization = Organization.objects.get_from_cache(slug=organization_slug)
        except Organization.DoesNotExist:
            raise ResourceDoesNotExist

        self.check_object_permissions(request, organization)

        bind_organization_context(organization)

        request._request.organization = organization

        # Track the 'active' organization when the request came from
        # a cookie based agent (react app)
        # Never track any org (regardless of whether the user does or doesn't have
        # membership in that org) when the user is in active superuser mode
        if request.auth is None and request.user and not is_active_superuser(request):
            request.session["activeorg"] = organization.slug

        kwargs["organization"] = organization
        return (args, kwargs)
Пример #42
0
    def get_allowed_projects(self, request, organization):
        has_valid_api_key = False
        if isinstance(request.auth, ApiKey):
            if request.auth.organization_id != organization.id:
                return []
            has_valid_api_key = request.auth.has_scope('project:releases') or \
                request.auth.has_scope('project:write')

        if not (has_valid_api_key or request.user.is_authenticated()):
            return []

        if has_valid_api_key or is_active_superuser(
                request) or organization.flags.allow_joinleave:
            allowed_teams = Team.objects.filter(
                organization=organization).values_list('id', flat=True)
        else:
            allowed_teams = OrganizationMemberTeam.objects.filter(
                organizationmember__user=request.user,
                team__organization_id=organization.id,
            ).values_list('team_id', flat=True)
        return Project.objects.filter(team_id__in=allowed_teams)
Пример #43
0
    def get(self, request, organization):
        """
        List your Teams In the Current Organization
        ```````````````````````````````````````````

        Return a list of the teams available to the authenticated session and
        with the supplied organization. If the user is a super user, then all
        teams within the organization are returned.
        """
        if is_active_superuser(request):
            # retrieve all teams within the organization
            queryset = Team.objects.filter(
                organization=organization,
                status=TeamStatus.VISIBLE).order_by("slug")
            return Response(
                serialize(list(queryset), request.user,
                          TeamWithProjectsSerializer()))
        else:
            return Response(
                serialize(list(request.access.teams), request.user,
                          TeamWithProjectsSerializer()))
Пример #44
0
    def get_attrs(self, item_list, user):
        request = env.request
        org_ids = set([t.organization_id for t in item_list])

        org_roles = get_org_roles(org_ids, user)

        member_totals = get_member_totals(item_list, user)
        memberships = get_team_memberships(item_list, user)
        access_requests = get_access_requests(item_list, user)

        avatars = {
            a.team_id: a
            for a in TeamAvatar.objects.filter(team__in=item_list)
        }

        is_superuser = (request and is_active_superuser(request)
                        and request.user == user)
        result = {}

        for team in item_list:
            is_member = team.id in memberships
            org_role = org_roles.get(team.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif team.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[team] = {
                'pending_request': team.id in access_requests,
                'is_member': is_member,
                'has_access': has_access,
                'avatar': avatars.get(team.id),
                'member_count': member_totals.get(team.id, 0),
            }
        return result
Пример #45
0
def from_request(request,
                 organization: Organization = None,
                 scopes: Optional[Iterable[str]] = None) -> Access:
    is_superuser = is_active_superuser(request)

    if not organization:
        return from_user(request.user,
                         organization=organization,
                         scopes=scopes,
                         is_superuser=is_superuser)

    if getattr(request.user, "is_sentry_app", False):
        return _from_sentry_app(request.user, organization=organization)

    if is_superuser:
        member = None
        # we special case superuser so that if they're a member of the org
        # they must still follow SSO checks, but they gain global access
        try:
            member = get_cached_organization_member(request.user.id,
                                                    organization.id)
        except OrganizationMember.DoesNotExist:
            requires_sso, sso_is_valid = False, True
        else:
            requires_sso, sso_is_valid = _sso_params(member)

        return OrganizationGlobalAccess(
            organization=organization,
            member=member,
            scopes=scopes if scopes is not None else settings.SENTRY_SCOPES,
            sso_is_valid=sso_is_valid,
            requires_sso=requires_sso,
            permissions=get_permissions_for_user(request.user.id),
        )

    # TODO: from_auth does not take scopes as a parameter so this fails for anon user
    if hasattr(request, "auth") and not request.user.is_authenticated:
        return from_auth(request.auth, scopes=scopes)

    return from_user(request.user, organization, scopes=scopes)
Пример #46
0
    def serialize(self, obj, attrs, user):
        from sentry.mediators.service_hooks.creator import consolidate_events

        data = {
            'name': obj.name,
            'slug': obj.slug,
            'author': obj.author,
            'scopes': obj.get_scopes(),
            'events': consolidate_events(obj.events),
            'status': obj.get_status_display(),
            'schema': obj.schema,
            'uuid': obj.uuid,
            'webhookUrl': obj.webhook_url,
            'redirectUrl': obj.redirect_url,
            'isAlertable': obj.is_alertable,
            'overview': obj.overview,
        }

        if is_active_superuser(
                env.request) or (hasattr(user, 'get_orgs')
                                 and obj.owner in user.get_orgs()):
            if obj.is_internal:
                install = obj.installations.first()
                data.update({
                    'installation': {
                        'uuid': install.uuid,
                    },
                    'token': install.api_token.token,
                })
            else:
                data.update({
                    'clientId': obj.application.client_id,
                    'clientSecret': obj.application.client_secret,
                    'owner': {
                        'id': obj.owner.id,
                        'slug': obj.owner.slug,
                    },
                })

        return data
Пример #47
0
    def get_attrs(self, item_list, user):
        request = env.request
        if user.is_authenticated():
            memberships = frozenset(
                OrganizationMemberTeam.objects.filter(
                    organizationmember__user=user,
                    team__in=item_list,
                ).values_list('team', flat=True)
            )
        else:
            memberships = frozenset()

        if user.is_authenticated():
            access_requests = frozenset(
                OrganizationAccessRequest.objects.filter(
                    team__in=item_list,
                    member__user=user,
                ).values_list('team', flat=True)
            )
        else:
            access_requests = frozenset()

        is_superuser = (request and is_active_superuser(request) and request.user == user)
        result = {}
        for team in item_list:
            is_member = team.id in memberships
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif team.organization.flags.allow_joinleave:
                has_access = True
            else:
                has_access = False
            result[team] = {
                'pending_request': team.id in access_requests,
                'is_member': is_member,
                'has_access': has_access,
            }
        return result
Пример #48
0
    def get_access_by_project(self, item_list, user):
        request = env.request

        project_teams = list(
            ProjectTeam.objects.filter(
                project__in=item_list,
            ).select_related('team')
        )

        project_team_map = defaultdict(list)

        for pt in project_teams:
            project_team_map[pt.project_id].append(pt.team)

        team_memberships = get_team_memberships([pt.team for pt in project_teams], user)
        org_roles = get_org_roles([i.organization_id for i in item_list], user)

        is_superuser = (request and is_active_superuser(request) and request.user == user)
        result = {}
        for project in item_list:
            is_member = any(
                t.id in team_memberships for t in project_team_map.get(project.id, [])
            )
            org_role = org_roles.get(project.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif project.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[project] = {
                'is_member': is_member,
                'has_access': has_access,
            }
        return result
Пример #49
0
    def get_attrs(self, item_list, user):
        request = env.request
        memberships = get_team_memberships(item_list, user)

        if user.is_authenticated():
            access_requests = frozenset(
                OrganizationAccessRequest.objects.filter(
                    team__in=item_list,
                    member__user=user,
                ).values_list('team', flat=True)
            )
        else:
            access_requests = frozenset()

        org_roles = get_org_roles([t.organization_id for t in item_list], user)
        avatars = {a.team_id: a for a in TeamAvatar.objects.filter(team__in=item_list)}

        is_superuser = (request and is_active_superuser(request) and request.user == user)
        result = {}
        for team in item_list:
            is_member = team.id in memberships
            org_role = org_roles.get(team.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif team.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[team] = {
                'pending_request': team.id in access_requests,
                'is_member': is_member,
                'has_access': has_access,
                'avatar': avatars.get(team.id),
            }
        return result
Пример #50
0
    def get_attrs(self, item_list, user):
        request = env.request
        memberships = get_team_memberships(item_list, user)

        if user.is_authenticated():
            access_requests = frozenset(
                OrganizationAccessRequest.objects.filter(
                    team__in=item_list,
                    member__user=user,
                ).values_list('team', flat=True)
            )
        else:
            access_requests = frozenset()

        org_roles = get_org_roles([t.organization_id for t in item_list], user)
        avatars = {a.team_id: a for a in TeamAvatar.objects.filter(team__in=item_list)}

        is_superuser = (request and is_active_superuser(request) and request.user == user)
        result = {}
        for team in item_list:
            is_member = team.id in memberships
            org_role = org_roles.get(team.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif team.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[team] = {
                'pending_request': team.id in access_requests,
                'is_member': is_member,
                'has_access': has_access,
                'avatar': avatars.get(team.id),
            }
        return result
Пример #51
0
    def _can_delete(self, request, member, organization, team_slug):
        """
        User can remove a member from a team:

        * If they are an active superuser
        * If they are removing their own membership
        * If they are a team admin or have global write access
        """

        if is_active_superuser(request):
            return True

        if not request.user.is_authenticated():
            return False

        if request.user.id == member.user_id:
            return True

        if self._can_admin_team(request, organization, team_slug):
            return True

        return False
Пример #52
0
    def get_access_by_project(self, item_list, user):
        request = env.request

        project_teams = list(
            ProjectTeam.objects.filter(
                project__in=item_list,
            ).select_related('team')
        )

        project_team_map = defaultdict(list)

        for pt in project_teams:
            project_team_map[pt.project_id].append(pt.team)

        team_memberships = get_team_memberships([pt.team for pt in project_teams], user)
        org_roles = get_org_roles([i.organization_id for i in item_list], user)

        is_superuser = (request and is_active_superuser(request) and request.user == user)
        result = {}
        for project in item_list:
            is_member = any(
                t.id in team_memberships for t in project_team_map.get(project.id, [])
            )
            org_role = org_roles.get(project.organization_id)
            if is_member:
                has_access = True
            elif is_superuser:
                has_access = True
            elif project.organization.flags.allow_joinleave:
                has_access = True
            elif org_role and roles.get(org_role).is_global:
                has_access = True
            else:
                has_access = False
            result[project] = {
                'is_member': is_member,
                'has_access': has_access,
            }
        return result
Пример #53
0
    def post(self, request):
        if not (is_active_superuser(request)
                and request.access.has_permission('broadcasts.admin')):
            return self.respond(status=401)

        validator = AdminBroadcastValidator(data=request.data)
        if not validator.is_valid():
            return self.respond(validator.errors, status=400)

        result = validator.validated_data

        with transaction.atomic():
            broadcast = Broadcast.objects.create(
                title=result['title'],
                message=result['message'],
                link=result['link'],
                cta=result['cta'],
                is_active=result.get('isActive') or False,
                date_expires=result.get('dateExpires'),
            )
            logger.info('broadcasts.create',
                        extra={
                            'ip_address': request.META['REMOTE_ADDR'],
                            'user_id': request.user.id,
                            'broadcast_id': broadcast.id,
                        })

        if result.get('hasSeen'):
            try:
                with transaction.atomic():
                    BroadcastSeen.objects.create(
                        broadcast=broadcast,
                        user=request.user,
                    )
            except IntegrityError:
                pass

        return self.respond(self._serialize_objects(broadcast, request))
Пример #54
0
    def post(self, request):
        if not (is_active_superuser(request)
                and request.access.has_permission("broadcasts.admin")):
            return self.respond(status=401)

        validator = AdminBroadcastValidator(data=request.data)
        if not validator.is_valid():
            return self.respond(validator.errors, status=400)

        result = validator.validated_data

        with transaction.atomic():
            broadcast = Broadcast.objects.create(
                title=result["title"],
                message=result["message"],
                link=result["link"],
                cta=result["cta"],
                is_active=result.get("isActive") or False,
                date_expires=result.get("dateExpires"),
            )
            logger.info(
                "broadcasts.create",
                extra={
                    "ip_address": request.META["REMOTE_ADDR"],
                    "user_id": request.user.id,
                    "broadcast_id": broadcast.id,
                },
            )

        if result.get("hasSeen"):
            try:
                with transaction.atomic():
                    BroadcastSeen.objects.create(broadcast=broadcast,
                                                 user=request.user)
            except IntegrityError:
                pass

        return self.respond(self._serialize_objects(broadcast, request))
Пример #55
0
    def has_object_permission(self, request, view, sentry_app):
        if not hasattr(request, "user") or not request.user:
            return False

        self.determine_access(request, sentry_app.owner)

        if is_active_superuser(request):
            return True

        # if app is unpublished, user must be in the Org who owns the app.
        if not sentry_app.is_published:
            if sentry_app.owner not in request.user.get_orgs():
                raise Http404

        # TODO(meredith): make a better way to allow for public
        # endpoints. we can't use ensure_scoped_permission now
        # that the public endpoint isn't denoted by '()'
        if sentry_app.is_published and request.method == "GET":
            return True

        return ensure_scoped_permission(
            request,
            self._scopes_for_sentry_app(sentry_app).get(request.method))
Пример #56
0
def get_access_by_project(
        projects: Sequence[Project],
        user: User) -> MutableMapping[Project, MutableMapping[str, Any]]:
    request = env.request

    project_teams = list(
        ProjectTeam.objects.filter(
            project__in=projects).select_related("team"))

    project_team_map = defaultdict(list)

    for pt in project_teams:
        project_team_map[pt.project_id].append(pt.team)

    team_memberships = get_team_memberships([pt.team for pt in project_teams],
                                            user)
    org_roles = get_org_roles({i.organization_id for i in projects}, user)

    is_superuser = request and is_active_superuser(
        request) and request.user == user
    result = {}
    for project in projects:
        is_member = any(t.id in team_memberships
                        for t in project_team_map.get(project.id, []))
        org_role = org_roles.get(project.organization_id)
        if is_member:
            has_access = True
        elif is_superuser:
            has_access = True
        elif project.organization.flags.allow_joinleave:
            has_access = True
        elif org_role and roles.get(org_role).is_global:
            has_access = True
        else:
            has_access = False
        result[project] = {"is_member": is_member, "has_access": has_access}
    return result
Пример #57
0
    def get_project_ids(self, request, organization):
        project_ids = set(map(int, request.GET.getlist('project')))

        before = project_ids.copy()
        if is_active_superuser(request):
            # Superusers can query any projects within the organization
            qs = Project.objects.filter(
                organization=organization,
                status=ProjectStatus.VISIBLE,
            )
        else:
            # Anyone else needs membership of the project
            qs = Project.objects.filter(
                organization=organization,
                teams__in=OrganizationMemberTeam.objects.filter(
                    organizationmember__user=request.user,
                    organizationmember__organization=organization,
                ).values_list('team'),
                status=ProjectStatus.VISIBLE,
            )

        # If no project's are passed through querystring, we want to
        # return all projects, otherwise, limit to the passed in ones
        if project_ids:
            qs = qs.filter(id__in=project_ids)

        project_ids = set(qs.values_list('id', flat=True))

        if before and project_ids != before:
            raise PermissionDenied

        if not project_ids:
            return

        # Make sure project_ids is now a list, otherwise
        # snuba isn't happy with it being a set
        return list(project_ids)
Пример #58
0
    def _get_permalink(self, obj, user):
        # If user is not logged in and member of the organization,
        # do not return the permalink which contains private information i.e. org name.
        request = env.request
        is_superuser = request and is_active_superuser(
            request) and request.user == user

        # If user is a sentry_app then it's a proxy user meaning we can't do a org lookup via `get_orgs()`
        # because the user isn't an org member. Instead we can use the auth token and the installation
        # it's associated with to find out what organization the token has access to.
        is_valid_sentryapp = False
        if (request and getattr(request.user, "is_sentry_app", False)
                and isinstance(request.auth, ApiToken)):
            is_valid_sentryapp = SentryAppInstallationToken.has_organization_access(
                request.auth, obj.organization)

        if (is_superuser or is_valid_sentryapp or
            (user.is_authenticated()
             and user.get_orgs().filter(id=obj.organization.id).exists())):
            with sentry_sdk.start_span(
                    op="GroupSerializerBase.serialize.permalink.build"):
                return obj.get_absolute_url()
        else:
            return None
Пример #59
0
    def delete(self, request, project, user_hash):
        """
        Delete an Event User
        ````````````````````````````````

        Delete an event's user.

        :pparam string organization_slug: the slug of the organization.
        :pparam string project_slug: the slug of the project.
        :pparam string user_hash: the user hash.
        """
        if is_active_superuser(request):
            try:
                euser = EventUser.objects.get(project_id=project.id,
                                              hash=user_hash)
            except EventUser.DoesNotExist:
                return Response(status=status.HTTP_404_NOT_FOUND)

            euser.delete()

            return Response(status=status.HTTP_200_OK)

        else:
            return Response(status=status.HTTP_403_FORBIDDEN)
Пример #60
0
    def has_object_permission(self, request, view, project):
        result = super().has_object_permission(request, view, project.organization)

        if not result:
            return result
        if project.teams.exists():
            return any(
                has_team_permission(request, team, self.scope_map) for team in project.teams.all()
            )
        elif is_system_auth(request.auth):
            return True
        elif request.user and request.user.is_authenticated:
            # this is only for team-less projects
            if is_active_superuser(request):
                return True
            elif request.user.is_sentry_app:
                return SentryApp.objects.check_project_permission_for_sentry_app_user(
                    request.user, project
                )
            try:
                role = (
                    OrganizationMember.objects.filter(
                        organization=project.organization, user=request.user
                    )
                    .values_list("role", flat=True)
                    .get()
                )
            except OrganizationMember.DoesNotExist:
                # this should probably never happen?
                return False

            return roles.get(role).is_global
        elif hasattr(request.auth, "project_id") and project.id == request.auth.project_id:
            return True

        return False