mirror of
https://github.com/ansible/awx.git
synced 2026-03-09 05:29:26 -02:30
Superuser fix redux.
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
# Python
|
# Python
|
||||||
import datetime
|
import datetime
|
||||||
import dateutil
|
import dateutil
|
||||||
|
import functools
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
@@ -431,30 +432,32 @@ class DashboardInventoryGraphView(APIView):
|
|||||||
return Response(dashboard_data)
|
return Response(dashboard_data)
|
||||||
|
|
||||||
|
|
||||||
class UserCreateAPIMixin(object):
|
def disallow_superuser_escalation(cls):
|
||||||
"""A mixin subclass that ensures that only a superuser is able to create
|
"""Decorator that ensures that the post, put, and patch methods on the
|
||||||
another superuser.
|
class, if they exist, perform a sanity check and disallow superuser
|
||||||
|
escalation by non-superusers.
|
||||||
"""
|
"""
|
||||||
def post(self, request, pk=None):
|
# Create a method decorator that ensures superuser escalation by
|
||||||
self._superuser_sanity_check(request)
|
# non-superusers is disallowed.
|
||||||
return super(UserCreateAPIMixin, self).post(request, pk=pk)
|
def superuser_lockdown(method):
|
||||||
|
@functools.wraps(method)
|
||||||
|
def fx(self, request, *a, **kw):
|
||||||
|
if not request.user.is_superuser:
|
||||||
|
if request.DATA.get('is_superuser', False):
|
||||||
|
raise PermissionDenied('Only superusers may create '
|
||||||
|
'other superusers.')
|
||||||
|
return method(self, request, *a, **kw)
|
||||||
|
return fx
|
||||||
|
|
||||||
# def put(self, request, pk=None):
|
# Ensure that if post, put, or patch methods exist, that they are decorated
|
||||||
# self._superuser_sanity_check(request)
|
# with the sanity check decorator.
|
||||||
# return super(UserCreateAPIMixin, self).put(request, pk=pk)
|
for vuln_method in ('post', 'put', 'patch'):
|
||||||
|
original_method = getattr(cls, vuln_method, None)
|
||||||
|
if original_method is not None:
|
||||||
|
setattr(cls, vuln_method, superuser_lockdown(original_method))
|
||||||
|
|
||||||
# def patch(self, request, pk=None):
|
# Return the class object.
|
||||||
# self._superuser_sanity_check(request)
|
return cls
|
||||||
# return super(UserCreateAPIMixin, self).patch(request, pk=pk)
|
|
||||||
|
|
||||||
def _superuser_sanity_check(self, request):
|
|
||||||
"""Ensure that if a non-superuser tries to create a superuser,
|
|
||||||
that the request is rejected.
|
|
||||||
"""
|
|
||||||
if not request.user.is_superuser:
|
|
||||||
if request.DATA.get('is_superuser', False):
|
|
||||||
raise PermissionDenied('Only superusers may create '
|
|
||||||
'other superusers.')
|
|
||||||
|
|
||||||
|
|
||||||
class ScheduleList(ListAPIView):
|
class ScheduleList(ListAPIView):
|
||||||
@@ -518,14 +521,16 @@ class OrganizationInventoriesList(SubListAPIView):
|
|||||||
parent_model = Organization
|
parent_model = Organization
|
||||||
relationship = 'inventories'
|
relationship = 'inventories'
|
||||||
|
|
||||||
class OrganizationUsersList(UserCreateAPIMixin, SubListCreateAPIView):
|
@disallow_superuser_escalation
|
||||||
|
class OrganizationUsersList(SubListCreateAPIView):
|
||||||
|
|
||||||
model = User
|
model = User
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
parent_model = Organization
|
parent_model = Organization
|
||||||
relationship = 'users'
|
relationship = 'users'
|
||||||
|
|
||||||
class OrganizationAdminsList(UserCreateAPIMixin, SubListCreateAPIView):
|
@disallow_superuser_escalation
|
||||||
|
class OrganizationAdminsList(SubListCreateAPIView):
|
||||||
|
|
||||||
model = User
|
model = User
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
@@ -565,7 +570,8 @@ class TeamDetail(RetrieveUpdateDestroyAPIView):
|
|||||||
model = Team
|
model = Team
|
||||||
serializer_class = TeamSerializer
|
serializer_class = TeamSerializer
|
||||||
|
|
||||||
class TeamUsersList(UserCreateAPIMixin, SubListCreateAPIView):
|
@disallow_superuser_escalation
|
||||||
|
class TeamUsersList(SubListCreateAPIView):
|
||||||
|
|
||||||
model = User
|
model = User
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
@@ -760,7 +766,9 @@ class ProjectUpdateCancel(GenericAPIView):
|
|||||||
else:
|
else:
|
||||||
return self.http_method_not_allowed(request, *args, **kwargs)
|
return self.http_method_not_allowed(request, *args, **kwargs)
|
||||||
|
|
||||||
class UserList(UserCreateAPIMixin, ListCreateAPIView):
|
|
||||||
|
@disallow_superuser_escalation
|
||||||
|
class UserList(ListCreateAPIView):
|
||||||
|
|
||||||
model = User
|
model = User
|
||||||
serializer_class = UserSerializer
|
serializer_class = UserSerializer
|
||||||
|
|||||||
Reference in New Issue
Block a user