api_views: accept .png and .pdf as validation attachments (fixes #29506)

This commit is contained in:
Benjamin Dauvergne 2019-01-24 15:47:58 +01:00
parent 40c1d36c08
commit eabdb36bf5
6 changed files with 125 additions and 21 deletions

View File

@ -90,6 +90,14 @@ class CUTValidateSerializer(serializers.ModelSerializer):
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',
permission_classes=(api_views.DjangoPermission('custom_user.cut_validate_user'),))
def validate_cut(self, request, uuid):
@ -119,11 +127,12 @@ def validate_cut(self, request, uuid):
'page': i,
'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({
'code': 'justificatifs-bad-format',
'page': i,
'accepted': ['image/jpeg'],
'accepted': accepted_mime_types,
})
# rewind cursor
content.seek(0)

View File

@ -1,34 +1,54 @@
import copy
import pytest
import django_webtest
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
def app(request, db):
def app(request, db, settings, tmpdir):
wtm = django_webtest.WebTestMixin()
wtm._patch_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'})
@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
oidc_client = OIDCClient.objects.create(
name='Client 1',
slug='client1',
ou=a2_rbac_utils.get_default_ou(),
ou=partner_ou,
client_id='client1',
client_secret='client1',
# IMPORTANT !
has_api_access=True,
identifier_policy=OIDCClient.POLICY_PAIRWISE_REVERSIBLE,
)
GLC = namedtuple('GLC', ['oidc_client', 'app'])
return GLC(oidc_client=oidc_client, app=app)
GLC = namedtuple('GLC', ['oidc_client'])
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):

BIN
tests/minimal.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

5
tests/minimal.pdf Normal file
View File

@ -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>>

BIN
tests/minimal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 B

View File

@ -1,26 +1,96 @@
# -*- 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'
DOE = u'Dôe'
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)
assert set(response.json['errors']) == set(['first_name', 'last_name', 'email'])
assert response.json['result'] == 0
response = app.post_json('/api/users/', params={
'first_name': JOHN,
'last_name': DOE,
'email': EMAIL,
})
assert response.json['sub']
assert response.json['first_name'] == JOHN
assert response.json['last_name'] == DOE
assert response.json['email'] == EMAIL
def test_create_user(john):
assert john
@pytest.fixture
def jpeg_file():
with (TEST_DIR / 'minimal.jpg').open('rb') as fd:
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)