Projet

Général

Profil

0001-api-allow-http-basic-auth-access-to-api-forms-53882.patch

Frédéric Péters, 10 mai 2021 21:42

Télécharger (6,62 ko)

Voir les différences:

Subject: [PATCH] api: allow http basic auth access to /api/forms/ (#53882)

 tests/api/test_formdata.py | 69 ++++++++++++++++++++++++++++----------
 wcs/api.py                 |  5 +++
 2 files changed, 56 insertions(+), 18 deletions(-)
tests/api/test_formdata.py
788 788
    assert 'name' in resp.json['evolution'][1]['who']
789 789

  
790 790

  
791
@pytest.mark.parametrize('http_basic_auth', [False, True])
792
def test_api_access_restrict_to_anonymised_data(pub, local_user, http_basic_auth):
791
@pytest.mark.parametrize('auth', ['signature', 'http-basic'])
792
def test_api_access_restrict_to_anonymised_data(pub, local_user, auth):
793 793
    pub.role_class.wipe()
794 794
    role = pub.role_class(name='test')
795 795
    role.store()
......
826 826

  
827 827
    app = get_app(pub)
828 828

  
829
    if http_basic_auth:
829
    if auth == 'http-basic':
830 830
        # there's not "defaults to admin" permissions in case of basic authentication.
831 831
        access.roles = [role]
832 832
        access.store()
......
866 866
    resp = get_url('/api/forms/test/%s/' % formdata.id)
867 867
    assert 'user' not in resp.json
868 868

  
869
    if http_basic_auth:
869
    if auth == 'http-basic':
870 870
        # for basic HTTP authentication, check there's no access if roles are not given.
871 871
        access.roles = []
872 872
        access.store()
......
1101 1101
    assert len(resp.json['features']) == 20
1102 1102

  
1103 1103

  
1104
def test_api_global_listing(pub, local_user):
1104
@pytest.mark.parametrize('user', ['query-email', 'api-access'])
1105
@pytest.mark.parametrize('auth', ['signature', 'http-basic'])
1106
def test_api_global_listing(pub, local_user, user, auth):
1105 1107
    if not pub.is_using_postgresql():
1106 1108
        resp = get_app(pub).get(sign_uri('/api/forms/geojson', user=local_user), status=404)
1107 1109
        pytest.skip('this requires SQL')
......
1111 1113
    role = pub.role_class(name='test')
1112 1114
    role.store()
1113 1115

  
1116
    app = get_app(pub)
1117

  
1118
    if user == 'api-access':
1119
        access = ApiAccess()
1120
        access.name = 'test'
1121
        access.access_identifier = 'test'
1122
        access.access_key = '12345'
1123
        access.store()
1124

  
1125
        if auth == 'http-basic':
1126

  
1127
            def get_url(url, **kwargs):
1128
                app.set_authorization(('Basic', ('test', '12345')))
1129
                return app.get(url, **kwargs)
1130

  
1131
        else:
1132

  
1133
            def get_url(url, **kwargs):
1134
                return app.get(sign_uri(url, orig=access.access_identifier, key=access.access_key), **kwargs)
1135

  
1136
    else:
1137
        if auth == 'http-basic':
1138
            pytest.skip('http basic authentication requires ApiAccess')
1139

  
1140
        def get_url(url, **kwargs):
1141
            return app.get(sign_uri(url, user=local_user), **kwargs)
1142

  
1114 1143
    # check there's no crash if there are no formdefs
1115
    resp = get_app(pub).get(sign_uri('/api/forms/', user=local_user))
1144
    resp = get_url('/api/forms/')
1116 1145
    assert len(resp.json['data']) == 0
1117 1146

  
1118 1147
    FormDef.wipe()
......
1141 1170
        formdata.store()
1142 1171

  
1143 1172
    # check empty content if user doesn't have the appropriate role
1144
    resp = get_app(pub).get(sign_uri('/api/forms/', user=local_user))
1173
    resp = get_url('/api/forms/')
1145 1174
    assert len(resp.json['data']) == 0
1146 1175

  
1147 1176
    # add proper role to user
1148
    local_user.roles = [role.id]
1149
    local_user.store()
1177
    if user == 'api-access':
1178
        access.roles = [role]
1179
        access.store()
1180
    else:
1181
        local_user.roles = [role.id]
1182
        local_user.store()
1150 1183

  
1151 1184
    # check it gets the data
1152
    resp = get_app(pub).get(sign_uri('/api/forms/', user=local_user))
1185
    resp = get_url('/api/forms/')
1153 1186
    assert len(resp.json['data']) == 10
1154 1187

  
1155 1188
    # check with a filter
1156
    resp = get_app(pub).get(sign_uri('/api/forms/?status=done', user=local_user))
1189
    resp = get_url('/api/forms/?status=done')
1157 1190
    assert len(resp.json['data']) == 20
1158 1191

  
1159 1192
    # check limit/offset
1160
    resp = get_app(pub).get(sign_uri('/api/forms/?status=done&limit=5', user=local_user))
1193
    resp = get_url('/api/forms/?status=done&limit=5')
1161 1194
    assert len(resp.json['data']) == 5
1162
    resp = get_app(pub).get(sign_uri('/api/forms/?status=done&offset=5&limit=5', user=local_user))
1195
    resp = get_url('/api/forms/?status=done&offset=5&limit=5')
1163 1196
    assert len(resp.json['data']) == 5
1164
    resp = get_app(pub).get(sign_uri('/api/forms/?status=done&offset=18&limit=5', user=local_user))
1197
    resp = get_url('/api/forms/?status=done&offset=18&limit=5')
1165 1198
    assert len(resp.json['data']) == 2
1166 1199

  
1167 1200
    # check error handling
1168
    get_app(pub).get(sign_uri('/api/forms/?status=done&limit=plop', user=local_user), status=400)
1169
    get_app(pub).get(sign_uri('/api/forms/?status=done&offset=plop', user=local_user), status=400)
1201
    get_url('/api/forms/?status=done&limit=plop', status=400)
1202
    get_url('/api/forms/?status=done&offset=plop', status=400)
1170 1203

  
1171 1204
    # check when there are missing statuses
1172 1205
    for formdata in data_class.select():
1173 1206
        formdata.status = 'wf-missing'
1174 1207
        formdata.store()
1175
    resp = get_app(pub).get(sign_uri('/api/forms/?status=all', user=local_user))
1208
    resp = get_url('/api/forms/?status=all')
1176 1209
    assert resp.json['data'][0]['status'] is None
1177 1210
    assert 'unknown' in resp.json['data'][0]['title']
1178 1211

  
......
1250 1283

  
1251 1284

  
1252 1285
def test_api_global_listing_ignored_roles(pub, local_user):
1253
    test_api_global_listing(pub, local_user)
1286
    test_api_global_listing(pub, local_user, user='query-email', auth='signature')
1254 1287

  
1255 1288
    role = pub.role_class(name='test2')
1256 1289
    role.store()
wcs/api.py
368 368

  
369 369
    def check_access(self):
370 370
        if not is_url_signed():
371
            api_user = get_user_from_api_query_string()
372
            if api_user and api_user.is_api_user:
373
                # API users are ok
374
                return
375

  
371 376
            # grant access to admins, to ease debug
372 377
            if not (get_request().user and get_request().user.is_admin):
373 378
                raise AccessForbiddenError('user not authenticated')
374
-