Projet

Général

Profil

0001-toulouse_axel-lock-unlock-locked-endpoints-38133.patch

Lauréline Guérin, 05 décembre 2019 10:46

Télécharger (8,07 ko)

Voir les différences:

Subject: [PATCH] toulouse_axel: lock/unlock/locked endpoints (#38133)

 .../migrations/0003_auto_20191205_0948.py     | 29 ++++++
 passerelle/contrib/toulouse_axel/models.py    | 50 +++++++++++
 tests/test_toulouse_axel.py                   | 90 +++++++++++++++++++
 3 files changed, 169 insertions(+)
 create mode 100644 passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py
passerelle/contrib/toulouse_axel/migrations/0003_auto_20191205_0948.py
1
# -*- coding: utf-8 -*-
2
from __future__ import unicode_literals
3

  
4
from django.db import migrations, models
5
import django.db.models.deletion
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('toulouse_axel', '0002_auto_20191122_0946'),
12
    ]
13

  
14
    operations = [
15
        migrations.CreateModel(
16
            name='Lock',
17
            fields=[
18
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19
                ('key', models.CharField(max_length=256)),
20
                ('lock_date', models.DateTimeField(auto_now_add=True)),
21
                ('locker', models.CharField(blank=True, max_length=256)),
22
                ('resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='toulouse_axel.ToulouseAxel')),
23
            ],
24
        ),
25
        migrations.AlterUniqueTogether(
26
            name='lock',
27
            unique_together=set([('resource', 'key')]),
28
        ),
29
    ]
passerelle/contrib/toulouse_axel/models.py
132 132
    LINK_SCHEMA['properties'].pop('IDPERSONNE')
133 133
    LINK_SCHEMA['required'].remove('IDPERSONNE')
134 134

  
135
    @endpoint(
136
        description=_('Lock a resource'),
137
        perm='can_access',
138
        parameters={
139
            'key': {'description': _('Key of the resource to lock')},
140
            'locker': {'description': _('Identifier of the locker (can be empty)')}
141
        })
142
    def lock(self, request, key, locker):
143
        if not key:
144
            raise APIError('key is empty', err='bad-request', http_status=400)
145
        lock, created = Lock.objects.get_or_create(resource=self, key=key, defaults={'locker': locker})
146
        return {'key': key, 'locked': True, 'locker': lock.locker, 'lock_date': lock.lock_date}
147

  
148
    @endpoint(
149
        description=_('Unlock a resource'),
150
        perm='can_access',
151
        parameters={
152
            'key': {'description': _('Key of the resource to unlock')},
153
        })
154
    def unlock(self, request, key):
155
        try:
156
            lock = Lock.objects.get(resource=self, key=key)
157
            lock.delete()
158
            return {'key': key, 'locked': False, 'locker': lock.locker, 'lock_date': lock.lock_date}
159
        except Lock.DoesNotExist:
160
            return {'key': key, 'locked': False}
161

  
162
    @endpoint(
163
        description=_('Get the lock status of a resource'),
164
        perm='can_access',
165
        parameters={
166
            'key': {'description': _('Key of the resource')},
167
        })
168
    def locked(self, request, key):
169
        try:
170
            lock = Lock.objects.get(resource=self, key=key)
171
            return {'key': key, 'locked': True, 'locker': lock.locker, 'lock_date': lock.lock_date}
172
        except Lock.DoesNotExist:
173
            return {'key': key, 'locked': False}
174

  
135 175
    @endpoint(
136 176
        description=_('Create link between user and Toulouse Axel'),
137 177
        perm='can_access',
......
216 256

  
217 257
    class Meta:
218 258
        unique_together = ('resource', 'name_id')
259

  
260

  
261
class Lock(models.Model):
262
    resource = models.ForeignKey(ToulouseAxel, on_delete=models.CASCADE)
263
    key = models.CharField(max_length=256)
264
    lock_date = models.DateTimeField(auto_now_add=True)
265
    locker = models.CharField(max_length=256, blank=True)
266

  
267
    class Meta:
268
        unique_together = ('resource', 'key')
tests/test_toulouse_axel.py
23 23
from passerelle.contrib.toulouse_axel.models import (
24 24
    AxelError,
25 25
    Link,
26
    Lock,
26 27
    ToulouseAxel,
27 28
    ref_famille_dui,
28 29
    ref_verif_dui,
......
48 49
    }
49 50

  
50 51

  
52
def test_lock(app, resource):
53
    resp = app.get('/toulouse-axel/test/lock?key=&locker=', status=400)
54
    assert resp.json['err_desc'] == "key is empty"
55

  
56
    assert Lock.objects.count() == 0
57
    resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
58
    assert resp.json['err'] == 0
59
    assert resp.json['key'] == 'foobar'
60
    assert resp.json['locked'] is True
61
    assert resp.json['locker'] == ''
62
    assert resp.json['lock_date'] is not None
63
    lock_date = resp.json['lock_date']
64
    lock = Lock.objects.latest('pk')
65
    assert lock.resource == resource
66
    assert lock.key == 'foobar'
67
    assert lock.locker == ''
68

  
69
    # again
70
    resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
71
    assert resp.json['err'] == 0
72
    assert resp.json['key'] == 'foobar'
73
    assert resp.json['locked'] is True
74
    assert Lock.objects.count() == 1
75
    assert resp.json['locker'] == ''
76
    assert resp.json['lock_date'] == lock_date
77

  
78

  
79
def test_lock_with_locker(app, resource):
80
    assert Lock.objects.count() == 0
81
    resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=something')
82
    assert resp.json['err'] == 0
83
    assert resp.json['key'] == 'foobar'
84
    assert resp.json['locked'] is True
85
    assert resp.json['locker'] == 'something'
86
    assert resp.json['lock_date'] is not None
87
    lock_date = resp.json['lock_date']
88
    lock = Lock.objects.latest('pk')
89
    assert lock.resource == resource
90
    assert lock.key == 'foobar'
91
    assert lock.locker == 'something'
92

  
93
    # again
94
    resp = app.get('/toulouse-axel/test/lock?key=foobar&locker=')
95
    assert resp.json['err'] == 0
96
    assert resp.json['key'] == 'foobar'
97
    assert resp.json['locked'] is True
98
    assert Lock.objects.count() == 1
99
    assert resp.json['locker'] == 'something'
100
    assert resp.json['lock_date'] == lock_date
101

  
102

  
103
def test_unlock(app, resource):
104
    Lock.objects.create(resource=resource, key='foobar', locker='something')
105
    resp = app.get('/toulouse-axel/test/unlock?key=foobar')
106
    assert resp.json['err'] == 0
107
    assert resp.json['key'] == 'foobar'
108
    assert resp.json['locked'] is False
109
    assert resp.json['locker'] == 'something'
110
    assert resp.json['lock_date'] is not None
111
    assert Lock.objects.count() == 0
112

  
113
    # again
114
    resp = app.get('/toulouse-axel/test/unlock?key=foobar')
115
    assert resp.json['err'] == 0
116
    assert resp.json['key'] == 'foobar'
117
    assert resp.json['locked'] is False
118
    assert 'locker' not in resp.json
119
    assert 'lock_date' not in resp.json
120
    assert Lock.objects.count() == 0
121

  
122

  
123
def test_locked(app, resource):
124
    assert Lock.objects.count() == 0
125
    resp = app.get('/toulouse-axel/test/locked?key=foobar')
126
    assert resp.json['err'] == 0
127
    assert resp.json['key'] == 'foobar'
128
    assert resp.json['locked'] is False
129
    assert 'locker' not in resp.json
130
    assert 'lock_date' not in resp.json
131

  
132
    Lock.objects.create(resource=resource, key='foobar', locker='something')
133
    resp = app.get('/toulouse-axel/test/locked?key=foobar')
134
    assert resp.json['err'] == 0
135
    assert resp.json['key'] == 'foobar'
136
    assert resp.json['locked'] is True
137
    assert resp.json['locker'] == 'something'
138
    assert resp.json['lock_date'] is not None
139

  
140

  
51 141
def test_operation_status_error(resource):
52 142
    resp = '''
53 143
    <?xml version="1.0"?>
54
-