Projet

Général

Profil

0001-api-fix-handling-of-query-string-and-errors-in-provi.patch

Frédéric Péters, 28 septembre 2021 20:16

Télécharger (4,3 ko)

Voir les différences:

Subject: [PATCH] api: fix handling of query string and errors in provision API
 (#57361)

 tests/test_hobo_notify.py | 52 ++++++++++++++++++++++++++++++++++++++-
 wcs/api.py                |  2 +-
 wcs/compat.py             | 14 ++++++++---
 3 files changed, 63 insertions(+), 5 deletions(-)
tests/test_hobo_notify.py
1
import os
1 2
import uuid
2 3

  
3 4
import pytest
4 5

  
6
from wcs.api_utils import sign_url
5 7
from wcs.ctl.hobo_notify import CmdHoboNotify
6 8
from wcs.qommon import force_str
7 9
from wcs.qommon import storage as st
10
from wcs.qommon.afterjobs import AfterJob
8 11
from wcs.qommon.http_request import HTTPRequest
9 12

  
10
from .utilities import create_temporary_pub
13
from .utilities import create_temporary_pub, get_app
11 14

  
12 15

  
13 16
def pytest_generate_tests(metafunc):
......
24 27
    pub.cfg['sp'] = {'saml2_providerid': 'test'}
25 28
    pub.write_cfg()
26 29

  
30
    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
31
        fd.write(
32
            '''\
33
[api-secrets]
34
coucou = 1234
35
'''
36
        )
37

  
27 38
    pub.role_class.wipe()
28 39
    r = pub.role_class(name='Service étt civil')
29 40
    r.slug = 'service-ett-civil'
......
849 860
    CmdHoboNotify.process_notification(notification)
850 861
    assert User.count() == 1
851 862
    assert len(User.select([st.NotNull('deleted_timestamp')])) == 1
863

  
864

  
865
def test_provision_http_endpoint(pub):
866
    get_app(pub).get('/__provision__/', status=403)
867

  
868
    get_app(pub).get(sign_url('/__provision__/?orig=coucou', '1234'), status=400)
869

  
870
    notification = {
871
        '@type': 'provision',
872
        'issuer': 'http://idp.example.net/idp/saml/metadata',
873
        'audience': ['test'],
874
        'objects': {
875
            '@type': 'user',
876
            'data': [
877
                {
878
                    'uuid': 'a' * 32,
879
                    'first_name': 'John',
880
                    'last_name': 'Doé',
881
                    'email': 'john.doe@example.net',
882
                    'zipcode': '13400',
883
                    'is_superuser': False,
884
                    'is_active': True,
885
                    'roles': [],
886
                }
887
            ],
888
        },
889
    }
890

  
891
    AfterJob.wipe()
892
    pub.user_class.wipe()
893
    get_app(pub).post_json(sign_url('/__provision__/?orig=coucou', '1234'), notification)
894
    assert AfterJob.count() == 1  # async by default
895
    assert pub.user_class.count() == 1
896

  
897
    AfterJob.wipe()
898
    pub.user_class.wipe()
899
    get_app(pub).post_json(sign_url('/__provision__/?orig=coucou&sync=1', '1234'), notification)
900
    assert AfterJob.count() == 0  # sync
901
    assert pub.user_class.count() == 1
wcs/api.py
1345 1345
    if not is_url_signed():
1346 1346
        raise AccessForbiddenError()
1347 1347

  
1348
    sync = request.form.get('sync') == '1'
1348
    sync = request.GET.get('sync') == '1'
1349 1349

  
1350 1350
    if sync:
1351 1351
        CmdHoboNotify().process_notification(get_request().json)
wcs/compat.py
263 263
        if not isinstance(exception, PublishError):
264 264
            return None
265 265
        request = get_request()
266
        exception_body = exception.render()
266

  
267
        content_type = None
268
        status_code = getattr(exception, 'status_code', None)
269

  
270
        if hasattr(exception, 'render'):
271
            exception_body = exception.render()
272
        else:
273
            exception_body = str(exception)
274
            content_type = 'text/plain'
267 275

  
268 276
        django_response = HttpResponse(
269 277
            exception_body,
270
            content_type=request.response.content_type,
271
            status=request.response.status_code,
278
            content_type=content_type or request.response.content_type,
279
            status=status_code or request.response.status_code,
272 280
            reason=request.response.reason_phrase,
273 281
        )
274 282

  
275
-