agent/authentic2: prevent error if instance is deleted during current transaction (#65553)
gitea/hobo/pipeline/head This commit looks good Details

This commit is contained in:
Benjamin Dauvergne 2022-05-24 23:55:24 +02:00
parent 2daa7b3170
commit 52d45851f6
2 changed files with 20 additions and 18 deletions

View File

@ -46,7 +46,6 @@ class Provisionning(threading.local):
{
'saved': {},
'deleted': {},
'in_atomic_block': connection.in_atomic_block,
}
)
@ -58,7 +57,6 @@ class Provisionning(threading.local):
return
context = self.stack.pop()
context.pop('in_atomic_block')
if provision:
@ -85,34 +83,35 @@ class Provisionning(threading.local):
if not self.stack:
return
in_atomic_block = self.stack[-1]['in_atomic_block']
# prevent losing pk of the model instances between call to add_saved
# and its execution at the end of the current transaction
instances = [copy.copy(instance) for instance in args]
saved = self.saved
def callback():
for instance in args:
for instance in instances:
klass = User if isinstance(instance, User) else Role
self.saved.setdefault(klass, set()).add(instance)
saved.setdefault(klass, set()).add(instance)
if in_atomic_block:
callback()
else:
transaction.on_commit(callback)
transaction.on_commit(callback)
def add_deleted(self, *args):
if not self.stack:
return
in_atomic_block = self.stack[-1]['in_atomic_block']
# prevent losing pk of the model instances between call to add_saved
# and its execution at the end of the current transaction
instances = [copy.copy(instance) for instance in args]
deleted = self.deleted
saved = self.saved
def callback():
for instance in args:
for instance in instances:
klass = User if isinstance(instance, User) else Role
self.deleted.setdefault(klass, set()).add(instance)
self.saved.get(klass, set()).discard(instance)
deleted.setdefault(klass, set()).add(instance)
saved.get(klass, set()).discard(instance)
if in_atomic_block:
callback()
else:
transaction.on_commit(callback)
transaction.on_commit(callback)
def resolve_ou(self, instances, ous):
for instance in instances:

View File

@ -10,6 +10,7 @@ from authentic2.models import Attribute, AttributeValue
from authentic2.saml.models import LibertyProvider
from django.contrib.auth import get_user_model
from django.core.management import call_command
from django.db import transaction
from tenant_schemas.utils import tenant_context
from hobo import signature
@ -546,7 +547,9 @@ def test_provision_user(transactional_db, tenant, caplog):
protocol_conformance=lasso.PROTOCOL_SAML_2_0,
)
with provisionning:
user1.delete()
with transaction.atomic():
user1.save()
user1.delete()
user2.delete()
assert notify_agents.call_count == 1
arg = notify_agents.call_args