Projet

Général

Profil

0001-agent-authentic2-prevent-error-if-instance-is-delete.patch

Benjamin Dauvergne, 25 mai 2022 01:33

Télécharger (3,99 ko)

Voir les différences:

Subject: [PATCH] agent/authentic2: prevent error if instance is deleted during
 current transaction (#65553)

 hobo/agent/authentic2/provisionning.py | 33 +++++++++++++-------------
 tests_authentic/test_provisionning.py  |  5 +++-
 2 files changed, 20 insertions(+), 18 deletions(-)
hobo/agent/authentic2/provisionning.py
49 49
            {
50 50
                'saved': {},
51 51
                'deleted': {},
52
                'in_atomic_block': connection.in_atomic_block,
53 52
            }
54 53
        )
55 54

  
......
61 60
            return
62 61

  
63 62
        context = self.stack.pop()
64
        context.pop('in_atomic_block')
65 63

  
66 64
        if provision:
67 65

  
......
88 86
        if not self.stack:
89 87
            return
90 88

  
91
        in_atomic_block = self.stack[-1]['in_atomic_block']
89
        # prevent losing pk of the model instances between call to add_saved
90
        # and its execution at the end of the current transaction
91
        instances = [copy.copy(instance) for instance in args]
92
        saved = self.saved
92 93

  
93 94
        def callback():
94
            for instance in args:
95
            for instance in instances:
95 96
                klass = User if isinstance(instance, User) else Role
96
                self.saved.setdefault(klass, set()).add(instance)
97
                saved.setdefault(klass, set()).add(instance)
97 98

  
98
        if in_atomic_block:
99
            callback()
100
        else:
101
            transaction.on_commit(callback)
99
        transaction.on_commit(callback)
102 100

  
103 101
    def add_deleted(self, *args):
104 102
        if not self.stack:
105 103
            return
106 104

  
107
        in_atomic_block = self.stack[-1]['in_atomic_block']
105
        # prevent losing pk of the model instances between call to add_saved
106
        # and its execution at the end of the current transaction
107
        instances = [copy.copy(instance) for instance in args]
108
        deleted = self.deleted
109
        saved = self.saved
108 110

  
109 111
        def callback():
110
            for instance in args:
112
            for instance in instances:
111 113
                klass = User if isinstance(instance, User) else Role
112
                self.deleted.setdefault(klass, set()).add(instance)
113
                self.saved.get(klass, set()).discard(instance)
114
                deleted.setdefault(klass, set()).add(instance)
115
                saved.get(klass, set()).discard(instance)
114 116

  
115
        if in_atomic_block:
116
            callback()
117
        else:
118
            transaction.on_commit(callback)
117
        transaction.on_commit(callback)
119 118

  
120 119
    def resolve_ou(self, instances, ous):
121 120
        for instance in instances:
tests_authentic/test_provisionning.py
12 12
from authentic2.saml.models import LibertyProvider
13 13
from django.contrib.auth import get_user_model
14 14
from django.core.management import call_command
15
from django.db import transaction
15 16
from django_rbac.utils import get_ou_model
16 17
from mock import ANY, call, patch
17 18
from tenant_schemas.utils import tenant_context
......
447 448
                protocol_conformance=lasso.PROTOCOL_SAML_2_0,
448 449
            )
449 450
            with provisionning:
450
                user1.delete()
451
                with transaction.atomic():
452
                    user1.save()
453
                    user1.delete()
451 454
                user2.delete()
452 455
            assert notify_agents.call_count == 1
453 456
            arg = notify_agents.call_args
454
-