13
13
from sentry import roles
14
14
from sentry .api .api_publish_status import ApiPublishStatus
15
15
from sentry .api .base import control_silo_endpoint
16
- from sentry .api .bases .user import UserEndpoint
16
+ from sentry .api .bases .user import UserAndStaffPermission , UserEndpoint
17
17
from sentry .api .decorators import sudo_required
18
18
from sentry .api .endpoints .organization_details import post_org_pending_deletion
19
19
from sentry .api .serializers import serialize
20
20
from sentry .api .serializers .models .user import DetailedSelfUserSerializer
21
21
from sentry .api .serializers .rest_framework import CamelSnakeModelSerializer
22
- from sentry .auth .superuser import is_active_superuser
22
+ from sentry .auth .elevated_mode import has_elevated_mode
23
23
from sentry .constants import LANGUAGES
24
24
from sentry .models .options .user_option import UserOption
25
25
from sentry .models .organization import OrganizationStatus
@@ -154,6 +154,8 @@ class UserDetailsEndpoint(UserEndpoint):
154
154
"PUT" : ApiPublishStatus .UNKNOWN ,
155
155
}
156
156
157
+ permission_classes = (UserAndStaffPermission ,)
158
+
157
159
def get (self , request : Request , user ) -> Response :
158
160
"""
159
161
Retrieve User Details
@@ -182,7 +184,13 @@ def put(self, request: Request, user) -> Response:
182
184
:param string default_issue_event: Event displayed by default, "recommended", "latest" or "oldest"
183
185
:auth: required
184
186
"""
185
- if not request .access .has_permission ("users.admin" ):
187
+ # We want to prevent superusers from setting users to superuser or staff
188
+ # because this is only done through _admin. This will always be enforced
189
+ # once the feature flag is removed.
190
+ can_elevate_user = has_elevated_mode (request ) and request .access .has_permission (
191
+ "users.admin"
192
+ )
193
+ if not can_elevate_user :
186
194
if not user .is_superuser and request .data .get ("isSuperuser" ):
187
195
return Response (
188
196
{"detail" : "Missing required permission to add superuser." },
@@ -194,11 +202,13 @@ def put(self, request: Request, user) -> Response:
194
202
status = status .HTTP_403_FORBIDDEN ,
195
203
)
196
204
197
- if request . access . has_permission ( "users.admin" ) :
205
+ if can_elevate_user :
198
206
serializer_cls = PrivilegedUserSerializer
199
- # with superuser read write separation, superuser read cannot hit this endpoint
200
- # so we can keep this as is_active_superuser
201
- elif is_active_superuser (request ):
207
+ # With superuser read/write separation, superuser read cannot hit this endpoint
208
+ # so we can keep this as is_active_superuser. Once the feature flag is
209
+ # removed and we only check is_active_staff, we can remove this comment.
210
+ elif has_elevated_mode (request ):
211
+ # TODO(schew2381): Rename to staff serializer
202
212
serializer_cls = SuperuserUserSerializer
203
213
else :
204
214
serializer_cls = UserSerializer
@@ -257,7 +267,6 @@ def delete(self, request: Request, user) -> Response:
257
267
:param list organizations: List of organization ids to remove
258
268
:auth required:
259
269
"""
260
-
261
270
serializer = DeleteUserSerializer (data = request .data )
262
271
263
272
if not serializer .is_valid ():
@@ -328,9 +337,12 @@ def delete(self, request: Request, user) -> Response:
328
337
}
329
338
330
339
hard_delete = serializer .validated_data .get ("hardDelete" , False )
340
+ can_delete = has_elevated_mode (request ) and request .access .has_permission ("users.admin" )
331
341
332
342
# Only active superusers can hard delete accounts
333
- if hard_delete and not request .access .has_permission ("users.admin" ):
343
+ # This will be changed to only active staff can delete accounts once the
344
+ # staff feature flag is removed.
345
+ if hard_delete and not can_delete :
334
346
return Response (
335
347
{"detail" : "Missing required permission to hard delete account." },
336
348
status = status .HTTP_403_FORBIDDEN ,
0 commit comments