mirror of
https://github.com/ansible/awx.git
synced 2024-11-01 08:21:15 +03:00
impersonate requesting user in inventory deletion task
This commit is contained in:
parent
faa40b23e2
commit
55cc23a712
@ -1848,7 +1848,7 @@ class InventoryDetail(ControlledByScmMixin, RetrieveUpdateDestroyAPIView):
|
||||
if not request.user.can_access(self.model, 'delete', obj):
|
||||
raise PermissionDenied()
|
||||
try:
|
||||
obj.schedule_deletion()
|
||||
obj.schedule_deletion(getattr(request.user, 'id', None))
|
||||
return Response(status=status.HTTP_202_ACCEPTED)
|
||||
except RuntimeError, e:
|
||||
return Response(dict(error=_("{0}".format(e))), status=status.HTTP_400_BAD_REQUEST)
|
||||
|
@ -376,14 +376,14 @@ class Inventory(CommonModelNameNotUnique, ResourceMixin):
|
||||
return self.insights_credential
|
||||
|
||||
@transaction.atomic
|
||||
def schedule_deletion(self):
|
||||
def schedule_deletion(self, user_id=None):
|
||||
from awx.main.tasks import delete_inventory
|
||||
if self.pending_deletion is True:
|
||||
raise RuntimeError("Inventory is already pending deletion.")
|
||||
self.pending_deletion = True
|
||||
self.save(update_fields=['pending_deletion'])
|
||||
self.websocket_emit_status('pending_deletion')
|
||||
delete_inventory.delay(self.pk)
|
||||
delete_inventory.delay(self.pk, user_id)
|
||||
|
||||
def _update_host_smart_inventory_memeberships(self):
|
||||
if self.kind == 'smart' and settings.AWX_REBUILD_SMART_MEMBERSHIP:
|
||||
|
@ -13,7 +13,7 @@ from django.db.models.signals import post_save, pre_delete, post_delete, m2m_cha
|
||||
from django.dispatch import receiver
|
||||
|
||||
# Django-CRUM
|
||||
from crum import get_current_request
|
||||
from crum import get_current_request, get_current_user
|
||||
from crum.signals import current_user_getter
|
||||
|
||||
# AWX
|
||||
@ -385,7 +385,8 @@ def activity_stream_create(sender, instance, created, **kwargs):
|
||||
activity_entry = ActivityStream(
|
||||
operation='create',
|
||||
object1=object1,
|
||||
changes=json.dumps(changes))
|
||||
changes=json.dumps(changes),
|
||||
actor=get_current_user())
|
||||
activity_entry.save()
|
||||
#TODO: Weird situation where cascade SETNULL doesn't work
|
||||
# it might actually be a good idea to remove all of these FK references since
|
||||
@ -412,7 +413,8 @@ def activity_stream_update(sender, instance, **kwargs):
|
||||
activity_entry = ActivityStream(
|
||||
operation='update',
|
||||
object1=object1,
|
||||
changes=json.dumps(changes))
|
||||
changes=json.dumps(changes),
|
||||
actor=get_current_user())
|
||||
activity_entry.save()
|
||||
if instance._meta.model_name != 'setting': # Is not conf.Setting instance
|
||||
getattr(activity_entry, object1).add(instance)
|
||||
@ -430,7 +432,8 @@ def activity_stream_delete(sender, instance, **kwargs):
|
||||
activity_entry = ActivityStream(
|
||||
operation='delete',
|
||||
changes=json.dumps(changes),
|
||||
object1=object1)
|
||||
object1=object1,
|
||||
actor=get_current_user())
|
||||
activity_entry.save()
|
||||
|
||||
|
||||
@ -477,7 +480,8 @@ def activity_stream_associate(sender, instance, **kwargs):
|
||||
operation=action,
|
||||
object1=object1,
|
||||
object2=object2,
|
||||
object_relationship_type=obj_rel)
|
||||
object_relationship_type=obj_rel,
|
||||
actor=get_current_user())
|
||||
activity_entry.save()
|
||||
getattr(activity_entry, object1).add(obj1)
|
||||
getattr(activity_entry, object2).add(obj2_actual)
|
||||
@ -515,8 +519,9 @@ def get_current_user_from_drf_request(sender, **kwargs):
|
||||
@receiver(pre_delete, sender=Organization)
|
||||
def delete_inventory_for_org(sender, instance, **kwargs):
|
||||
inventories = Inventory.objects.filter(organization__pk=instance.pk)
|
||||
user = get_current_user()
|
||||
for inventory in inventories:
|
||||
try:
|
||||
inventory.schedule_deletion()
|
||||
inventory.schedule_deletion(user_id=getattr(user, 'id', None))
|
||||
except RuntimeError, e:
|
||||
logger.debug(e)
|
||||
|
@ -42,6 +42,9 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
|
||||
# Django-CRUM
|
||||
from crum import impersonate
|
||||
|
||||
# AWX
|
||||
from awx import __version__ as awx_application_version
|
||||
from awx.main.constants import CLOUD_PROVIDERS, PRIVILEGE_ESCALATION_METHODS
|
||||
@ -410,9 +413,16 @@ def update_host_smart_inventory_memberships():
|
||||
|
||||
|
||||
@task(bind=True, queue='tower', base=LogErrorsTask, max_retries=5)
|
||||
def delete_inventory(self, inventory_id):
|
||||
with ignore_inventory_computed_fields(), \
|
||||
ignore_inventory_group_removal():
|
||||
def delete_inventory(self, inventory_id, user_id):
|
||||
# Delete inventory as user
|
||||
if user_id is None:
|
||||
user = None
|
||||
else:
|
||||
try:
|
||||
user = User.objects.get(id=user_id)
|
||||
except:
|
||||
user = None
|
||||
with ignore_inventory_computed_fields(), ignore_inventory_group_removal(), impersonate(user):
|
||||
try:
|
||||
i = Inventory.objects.get(id=inventory_id)
|
||||
i.delete()
|
||||
@ -420,7 +430,7 @@ def delete_inventory(self, inventory_id):
|
||||
'inventories-status_changed',
|
||||
{'group_name': 'inventories', 'inventory_id': inventory_id, 'status': 'deleted'}
|
||||
)
|
||||
logger.debug('Deleted inventory: %s' % inventory_id)
|
||||
logger.debug('Deleted inventory %s as user %s.' % (inventory_id, user_id))
|
||||
except OperationalError:
|
||||
logger.warning('Database error deleting inventory {}, but will retry.'.format(inventory_id))
|
||||
self.retry(countdown=10)
|
||||
|
@ -16,6 +16,9 @@ from awx.main.models import (
|
||||
from awx.main.utils import model_to_dict
|
||||
from awx.api.serializers import InventorySourceSerializer
|
||||
|
||||
# Django-CRUM
|
||||
from crum import impersonate
|
||||
|
||||
|
||||
model_serializer_mapping = {
|
||||
InventorySource: InventorySourceSerializer
|
||||
@ -157,3 +160,11 @@ def test_missing_related_on_delete(inventory_source):
|
||||
inventory_source.inventory.delete()
|
||||
d = model_to_dict(old_is, serializer_mapping=model_serializer_mapping)
|
||||
assert d['inventory'] == '<missing inventory source>-{}'.format(old_is.inventory_id)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_activity_stream_actor(admin_user):
|
||||
with impersonate(admin_user):
|
||||
o = Organization.objects.create(name='test organization')
|
||||
entry = o.activitystream_set.get(operation='create')
|
||||
assert entry.actor == admin_user
|
||||
|
Loading…
Reference in New Issue
Block a user