api_views: accept .png and .pdf as validation attachments (fixes #29506)
This commit is contained in:
parent
40c1d36c08
commit
eabdb36bf5
|
@ -90,6 +90,14 @@ class CUTValidateSerializer(serializers.ModelSerializer):
|
||||||
fields = ('id', 'created', 'external_id', 'status', 'reason', 'validated', 'sub')
|
fields = ('id', 'created', 'external_id', 'status', 'reason', 'validated', 'sub')
|
||||||
|
|
||||||
|
|
||||||
|
def _get_cut_validation_accepted_mime_types():
|
||||||
|
return getattr(settings, 'CUT_VALIDATION_ACCEPTED_MIME_TYPES', [
|
||||||
|
'image/jpeg',
|
||||||
|
'application/pdf',
|
||||||
|
'image/png',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
@detail_route(methods=['get', 'post'], url_path='validate',
|
@detail_route(methods=['get', 'post'], url_path='validate',
|
||||||
permission_classes=(api_views.DjangoPermission('custom_user.cut_validate_user'),))
|
permission_classes=(api_views.DjangoPermission('custom_user.cut_validate_user'),))
|
||||||
def validate_cut(self, request, uuid):
|
def validate_cut(self, request, uuid):
|
||||||
|
@ -119,11 +127,12 @@ def validate_cut(self, request, uuid):
|
||||||
'page': i,
|
'page': i,
|
||||||
'max-size': max_size,
|
'max-size': max_size,
|
||||||
})
|
})
|
||||||
if magic.from_buffer(content.read(10000), mime=True) != 'image/jpeg':
|
accepted_mime_types = _get_cut_validation_accepted_mime_types()
|
||||||
|
if magic.from_buffer(content.read(10000), mime=True) not in accepted_mime_types:
|
||||||
errors.append({
|
errors.append({
|
||||||
'code': 'justificatifs-bad-format',
|
'code': 'justificatifs-bad-format',
|
||||||
'page': i,
|
'page': i,
|
||||||
'accepted': ['image/jpeg'],
|
'accepted': accepted_mime_types,
|
||||||
})
|
})
|
||||||
# rewind cursor
|
# rewind cursor
|
||||||
content.seek(0)
|
content.seek(0)
|
||||||
|
|
|
@ -1,34 +1,54 @@
|
||||||
|
import copy
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
import django_webtest
|
import django_webtest
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
from authentic2.a2_rbac import utils as a2_rbac_utils
|
from django.core.management import call_command
|
||||||
|
from django_rbac.utils import get_ou_model
|
||||||
|
|
||||||
|
OU = get_ou_model()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def app(request, db):
|
def app(request, db, settings, tmpdir):
|
||||||
wtm = django_webtest.WebTestMixin()
|
wtm = django_webtest.WebTestMixin()
|
||||||
wtm._patch_settings()
|
wtm._patch_settings()
|
||||||
request.addfinalizer(wtm._unpatch_settings)
|
request.addfinalizer(wtm._unpatch_settings)
|
||||||
|
settings.MEDIA_DIR = str(tmpdir.mkdir('media'))
|
||||||
|
call_command('loaddata', 'cut_attributes.json')
|
||||||
return django_webtest.DjangoTestApp(extra_environ={'HTTP_HOST': 'localhost'})
|
return django_webtest.DjangoTestApp(extra_environ={'HTTP_HOST': 'localhost'})
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def glc(app, db):
|
def partner_ou(db):
|
||||||
|
return OU.objects.create(name='partner', slug='ou')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def glc(app, partner_ou, db):
|
||||||
from authentic2_idp_oidc.models import OIDCClient
|
from authentic2_idp_oidc.models import OIDCClient
|
||||||
|
|
||||||
oidc_client = OIDCClient.objects.create(
|
oidc_client = OIDCClient.objects.create(
|
||||||
name='Client 1',
|
name='Client 1',
|
||||||
slug='client1',
|
slug='client1',
|
||||||
ou=a2_rbac_utils.get_default_ou(),
|
ou=partner_ou,
|
||||||
client_id='client1',
|
client_id='client1',
|
||||||
client_secret='client1',
|
client_secret='client1',
|
||||||
# IMPORTANT !
|
# IMPORTANT !
|
||||||
has_api_access=True,
|
has_api_access=True,
|
||||||
identifier_policy=OIDCClient.POLICY_PAIRWISE_REVERSIBLE,
|
identifier_policy=OIDCClient.POLICY_PAIRWISE_REVERSIBLE,
|
||||||
)
|
)
|
||||||
GLC = namedtuple('GLC', ['oidc_client', 'app'])
|
GLC = namedtuple('GLC', ['oidc_client'])
|
||||||
return GLC(oidc_client=oidc_client, app=app)
|
return GLC(oidc_client=oidc_client)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def glc_app(app, glc):
|
||||||
|
app = copy.copy(app)
|
||||||
|
app.authorization = ('Basic', (glc.oidc_client.client_id, glc.oidc_client.client_secret))
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
class AllHook(object):
|
class AllHook(object):
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 107 B |
|
@ -0,0 +1,5 @@
|
||||||
|
%PDF-1.
|
||||||
|
1 0 obj<</Pages 2 0 R>>endobj
|
||||||
|
2 0 obj<</Kids[3 0 R]/Count 1>>endobj
|
||||||
|
3 0 obj<</Parent 2 0 R>>endobj
|
||||||
|
trailer <</Root 1 0 R>>
|
Binary file not shown.
After Width: | Height: | Size: 51 B |
|
@ -1,26 +1,96 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
import base64
|
||||||
|
import uuid
|
||||||
|
from mock import MagicMock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pathlib2
|
||||||
|
|
||||||
|
from django.contrib.auth import get_user_model
|
||||||
|
|
||||||
|
User = get_user_model()
|
||||||
|
|
||||||
JOHN = u'Jôhn'
|
JOHN = u'Jôhn'
|
||||||
DOE = u'Dôe'
|
DOE = u'Dôe'
|
||||||
EMAIL = 'john.doe@example.com'
|
EMAIL = 'john.doe@example.com'
|
||||||
|
|
||||||
|
TEST_DIR = pathlib2.Path(__file__).parent
|
||||||
|
|
||||||
def test_no_email(glc):
|
|
||||||
app = glc.app
|
|
||||||
oidc_client = glc.oidc_client
|
|
||||||
|
|
||||||
app.authorization = ('Basic', (oidc_client.client_id, oidc_client.client_secret))
|
@pytest.fixture
|
||||||
|
def john(glc_app):
|
||||||
|
response = glc_app.post_json('/api/users/', params={
|
||||||
|
'first_name': JOHN,
|
||||||
|
'last_name': DOE,
|
||||||
|
'email': EMAIL,
|
||||||
|
})
|
||||||
|
user = User.objects.get(first_name=JOHN)
|
||||||
|
assert response.json['sub'] != user.uuid
|
||||||
|
assert response.json['first_name'] == JOHN
|
||||||
|
assert response.json['last_name'] == DOE
|
||||||
|
assert response.json['email'] == EMAIL
|
||||||
|
assert user.first_name == JOHN
|
||||||
|
assert user.last_name == DOE
|
||||||
|
assert user.email == EMAIL
|
||||||
|
assert user.ou.slug == 'usagers'
|
||||||
|
user._oidc_sub = response.json['sub']
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def test_no_email(glc_app):
|
||||||
|
app = glc_app
|
||||||
|
|
||||||
response = app.post_json('/api/users/', params={}, status=400)
|
response = app.post_json('/api/users/', params={}, status=400)
|
||||||
assert set(response.json['errors']) == set(['first_name', 'last_name', 'email'])
|
assert set(response.json['errors']) == set(['first_name', 'last_name', 'email'])
|
||||||
assert response.json['result'] == 0
|
assert response.json['result'] == 0
|
||||||
|
|
||||||
response = app.post_json('/api/users/', params={
|
|
||||||
'first_name': JOHN,
|
def test_create_user(john):
|
||||||
'last_name': DOE,
|
assert john
|
||||||
'email': EMAIL,
|
|
||||||
})
|
|
||||||
assert response.json['sub']
|
@pytest.fixture
|
||||||
assert response.json['first_name'] == JOHN
|
def jpeg_file():
|
||||||
assert response.json['last_name'] == DOE
|
with (TEST_DIR / 'minimal.jpg').open('rb') as fd:
|
||||||
assert response.json['email'] == EMAIL
|
yield fd.read()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def png_file():
|
||||||
|
with (TEST_DIR / 'minimal.png').open('rb') as fd:
|
||||||
|
yield fd.read()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def pdf_file():
|
||||||
|
with (TEST_DIR / 'minimal.pdf').open('rb') as fd:
|
||||||
|
yield fd.read()
|
||||||
|
|
||||||
|
|
||||||
|
def helper_test_validation_image(glc_app, john, image_file):
|
||||||
|
external_id = uuid.uuid4().hex
|
||||||
|
response = glc_app.post_json('/api/users/%s/validate/' % john._oidc_sub, params={
|
||||||
|
'external_id': external_id,
|
||||||
|
'justificatifs': [{
|
||||||
|
'b64_content': base64.b64encode(image_file),
|
||||||
|
}],
|
||||||
|
}, status=201)
|
||||||
|
assert response.json == {
|
||||||
|
'status': 'received',
|
||||||
|
'id': response.json['id'],
|
||||||
|
'result': 1,
|
||||||
|
'external_id': external_id,
|
||||||
|
'sub': john._oidc_sub,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_jpg(glc_app, john, jpeg_file):
|
||||||
|
helper_test_validation_image(glc_app, john, jpeg_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_png(glc_app, john, png_file):
|
||||||
|
helper_test_validation_image(glc_app, john, png_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_validation_pdf(glc_app, john, pdf_file):
|
||||||
|
helper_test_validation_image(glc_app, john, pdf_file)
|
||||||
|
|
Loading…
Reference in New Issue