Projet

Général

Profil

0001-api-add-basic-auth-support-to-formdefs-56690.patch

Lauréline Guérin, 14 septembre 2021 15:57

Télécharger (6,59 ko)

Voir les différences:

Subject: [PATCH] api: add basic auth support to formdefs (#56690)

 tests/api/test_formdef.py | 54 +++++++++++++++++++++++++++++++++------
 wcs/api.py                |  7 +++--
 2 files changed, 51 insertions(+), 10 deletions(-)
tests/api/test_formdef.py
5 5
import os
6 6
import time
7 7
import urllib.parse
8
from functools import partial
8 9
from unittest import mock
9 10

  
10 11
import pytest
......
12 13
from quixote import get_publisher
13 14

  
14 15
from wcs import fields, qommon
16
from wcs.api_access import ApiAccess
15 17
from wcs.api_utils import sign_url
16 18
from wcs.categories import Category
17 19
from wcs.data_sources import NamedDataSource
......
66 68
    return user
67 69

  
68 70

  
71
def _get_url(url, app, auth, access, user, **kwargs):
72
    if auth == 'http-basic':
73
        app.set_authorization(('Basic', ('test', '12345')))
74
        return app.get(url, **kwargs)
75
    else:
76
        return app.get(
77
            sign_uri(url, user=user, orig=access.access_identifier, key=access.access_key), **kwargs
78
        )
79

  
80

  
81
@pytest.fixture
82
def access(pub):
83
    ApiAccess.wipe()
84
    access = ApiAccess()
85
    access.name = 'test'
86
    access.access_identifier = 'test'
87
    access.access_key = '12345'
88
    access.store()
89
    return access
90

  
91

  
69 92
def test_formdef_list(pub):
70 93
    pub.role_class.wipe()
71 94
    role = pub.role_class(name='Foo bar')
......
187 210
    assert len(resp.json['data']) == 2
188 211

  
189 212

  
190
def test_limited_formdef_list(pub, local_user):
213
@pytest.mark.parametrize('auth', ['signature', 'http-basic'])
214
def test_limited_formdef_list(pub, local_user, access, auth):
191 215
    pub.role_class.wipe()
192 216
    role = pub.role_class(name='Foo bar')
193 217
    role.id = '14'
......
201 225
    formdef.fields = []
202 226
    formdef.store()
203 227

  
228
    app = get_app(pub)
229
    get_url = partial(_get_url, app=app, auth=auth, access=access, user=local_user)
230

  
204 231
    resp = get_app(pub).get(sign_uri('/api/formdefs/'))
205 232
    assert resp.json['err'] == 0
206 233
    assert len(resp.json['data']) == 1
......
216 243
    resp = get_app(pub).get(sign_uri('/api/formdefs/'))
217 244
    resp2 = get_app(pub).get(sign_uri('/api/formdefs/?NameID='))
218 245
    resp3 = get_app(pub).get(sign_uri('/api/formdefs/?NameID=XXX'))
219
    resp4 = get_app(pub).get(sign_uri('/api/formdefs/?NameID=%s' % local_user.name_identifiers[0]))
246
    resp4 = get_url('/api/formdefs/')
220 247
    assert resp.json['err'] == 0
221 248
    assert len(resp.json['data']) == 1  # advertised in naked calls (as done from combo)
222 249
    assert len(resp2.json['data']) == 0  # not advertised otherwise
......
229 256
    # unless user has correct roles
230 257
    local_user.roles = [role.id]
231 258
    local_user.store()
232
    resp = get_app(pub).get(sign_uri('/api/formdefs/?NameID=%s' % local_user.name_identifiers[0]))
259
    if auth == 'http-basic':
260
        access.roles = [role]
261
        access.store()
262
    resp = get_url('/api/formdefs/')
233 263
    assert resp.json['err'] == 0
234 264
    assert len(resp.json['data']) == 1
235 265

  
236 266
    local_user.roles = []
237 267
    local_user.store()
268
    if auth == 'http-basic':
269
        access.roles = []
270
        access.store()
238 271

  
239 272
    # check it's also included in anonymous/signed calls, but marked for
240 273
    # authentication
......
248 281
    resp = get_app(pub).get(sign_uri('/api/formdefs/'))
249 282
    resp2 = get_app(pub).get(sign_uri('/api/formdefs/?NameID='))
250 283
    resp3 = get_app(pub).get(sign_uri('/api/formdefs/?NameID=XXX'))
251
    resp4 = get_app(pub).get(sign_uri('/api/formdefs/?NameID=%s' % local_user.name_identifiers[0]))
284
    resp4 = get_url('/api/formdefs/')
252 285
    assert resp.json['err'] == 0
253 286
    assert len(resp.json['data']) == 1
254 287
    assert resp.json['data'][0]['authentication_required']
......
277 310
    assert 'count' not in resp1.json['data'][0]
278 311

  
279 312

  
280
def test_backoffice_submission_formdef_list(pub, local_user):
313
@pytest.mark.parametrize('auth', ['signature', 'http-basic'])
314
def test_backoffice_submission_formdef_list(pub, local_user, access, auth):
281 315
    pub.role_class.wipe()
282 316
    role = pub.role_class(name='Foo bar')
283 317
    role.id = '14'
......
296 330
    formdef2.fields = []
297 331
    formdef2.store()
298 332

  
333
    app = get_app(pub)
334
    get_url = partial(_get_url, app=app, auth=auth, access=access, user=local_user)
335

  
299 336
    resp = get_app(pub).get(sign_uri('/api/formdefs/?backoffice-submission=on'))
300 337
    assert resp.json['err'] == 0
301 338
    assert len(resp.json['data']) == 0
......
328 365
    # ... unless user has correct roles
329 366
    local_user.roles = [role.id]
330 367
    local_user.store()
331
    resp = get_app(pub).get(
332
        sign_uri('/api/formdefs/?backoffice-submission=on&NameID=%s' % local_user.name_identifiers[0])
333
    )
368
    if auth == 'http-basic':
369
        access.roles = [role]
370
        access.store()
371
    resp = get_url('/api/formdefs/?backoffice-submission=on')
334 372
    assert resp.json['err'] == 0
335 373
    assert len(resp.json['data']) == 1
336 374
    assert 'backoffice_submission_url' in resp.json['data'][0]
wcs/api.py
758 758
            # signed URL with a None user is considered like an appropriate
759 759
            # webservice call.
760 760
            user = False
761
        if not is_url_signed():
761
        url_signed = is_url_signed()
762
        if user and user.is_api_user:
763
            pass  # API users are ok
764
        elif not url_signed:
762 765
            if not (get_request().user and get_request().user.is_admin):
763 766
                raise AccessForbiddenError('user not authenticated')
764 767
            user = get_request().user
765 768

  
766
        list_all_forms = (user and user.is_admin) or (is_url_signed() and user is None)
769
        list_all_forms = (user and user.is_admin) or (url_signed and user is None)
767 770
        backoffice_submission = get_request().form.get('backoffice-submission') == 'on'
768 771

  
769 772
        list_forms = self.get_list_forms(user, list_all_forms, backoffice_submission=backoffice_submission)
770
-