Projet

Général

Profil

0002-api-search-api-keys-from-dedicated-storage-objects-t.patch

Nicolas Roche, 27 novembre 2020 17:19

Télécharger (4,49 ko)

Voir les différences:

Subject: [PATCH 2/2] api: search api keys from dedicated storage objects too
 (#48751)

 tests/test_api.py | 25 +++++++++++++++++++++++++
 wcs/api_access.py |  7 +++++++
 wcs/api_utils.py  |  3 ++-
 3 files changed, 34 insertions(+), 1 deletion(-)
tests/test_api.py
294 294
            )
295 295
    url = signed_url[len('http://example.net'):]
296 296
    output = get_app(pub).get(url)
297 297
    assert output.json['user_display_name'] == u'Jean Darmette'
298 298
    assert [x['name'] for x in output.json['user_roles']] == ['Foo bar']
299 299
    assert [x['slug'] for x in output.json['user_roles']] == ['foo-bar']
300 300

  
301 301

  
302
def test_api_access_from_xml_storable_object(pub, local_user, admin_user):
303
    app = login(get_app(pub))
304
    resp = app.get('/backoffice/settings/api-access/new')
305
    resp.form['name'] = 'salut'
306
    resp.form['access_key'] = '5678'
307
    resp = resp.form.submit('submit')
308

  
309
    Role.wipe()
310
    role = Role(name='Foo bar')
311
    role.store()
312
    local_user.roles = [role.id]
313
    local_user.store()
314
    signed_url = sign_url('http://example.net/api/user/?format=json&orig=UNKNOWN_USER&email=%s' % (
315
        urllib.quote(local_user.email)), '5678')
316
    url = signed_url[len('http://example.net'):]
317
    output = get_app(pub).get(url, status=403)
318
    assert output.json['err_desc'] == 'invalid orig'
319

  
320
    signed_url = sign_url('http://example.net/api/user/?format=json&orig=salut&email=%s' % (
321
        urllib.quote(local_user.email)), '5678')
322
    url = signed_url[len('http://example.net'):]
323
    output = get_app(pub).get(url)
324
    assert output.json['user_display_name'] == u'Jean Darmette'
325

  
326

  
302 327
def test_is_url_signed_check_nonce(pub, local_user, freezer):
303 328
    ORIG = 'xxx'
304 329
    KEY = 'xxx'
305 330

  
306 331
    pub.site_options.add_section('api-secrets')
307 332
    pub.site_options.set('api-secrets', ORIG, KEY)
308 333
    pub.site_options.write(open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w'))
309 334
    # test clean_nonces do not bark when nonces directory is empty
wcs/api_access.py
63 63
                    break
64 64
            else:
65 65
                break
66 66
            if obj.id == self.id:
67 67
                break
68 68
            suffix_no += 1
69 69
            new_access_id = '%s_%s' % (base_new_access_id, suffix_no)
70 70
        return new_access_id
71

  
72
    @classmethod
73
    def get_access_key(cls, access_id):
74
        for api_access in cls.select():
75
            if api_access.access_id == access_id:
76
                return api_access.access_key
77
        return None
wcs/api_utils.py
24 24
import calendar
25 25

  
26 26
from django.utils import six
27 27
from django.utils.encoding import force_bytes, force_text
28 28
from django.utils.six.moves.urllib import parse as urllib
29 29
from django.utils.six.moves.urllib import parse as urlparse
30 30

  
31 31
from quixote import get_request, get_publisher
32
from .api_access import ApiAccess
32 33
from .qommon.errors import (AccessForbiddenError, HttpResponse401Error, UnknownNameIdAccessForbiddenError)
33 34
import qommon.misc
34 35

  
35 36
DEFAULT_DURATION = 30
36 37

  
37 38

  
38 39
def is_url_signed(utcnow=None, duration=DEFAULT_DURATION):
39 40
    if get_request().signed:
......
44 45
    signature = get_request().form.get('signature')
45 46
    if not isinstance(signature, six.string_types):
46 47
        return False
47 48
    signature = force_bytes(signature)
48 49
    # verify signature
49 50
    orig = get_request().form.get('orig')
50 51
    if not isinstance(orig, six.string_types):
51 52
        raise AccessForbiddenError('missing/multiple orig field')
52
    key = get_publisher().get_site_option(orig, 'api-secrets')
53
    key = ApiAccess.get_access_key(orig) or get_publisher().get_site_option(orig, 'api-secrets')
53 54
    if not key:
54 55
        raise AccessForbiddenError('invalid orig')
55 56
    algo = get_request().form.get('algo')
56 57
    if not isinstance(algo, six.string_types):
57 58
        raise AccessForbiddenError('missing/multiple algo field')
58 59
    if algo not in hashlib.algorithms_guaranteed:
59 60
        raise AccessForbiddenError('invalid algo')
60 61
    try:
61
-