This commit is contained in:
parent
764a1997f9
commit
9ccf11fbd2
|
@ -0,0 +1,86 @@
|
|||
# Generated by Django 3.2.18 on 2024-03-11 09:20
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import passerelle.utils.templates
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('base', '0030_resourcelog_base_resour_appname_298cbc_idx'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Mgdis',
|
||||
fields=[
|
||||
(
|
||||
'id',
|
||||
models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
('title', models.CharField(max_length=50, verbose_name='Title')),
|
||||
('slug', models.SlugField(unique=True, verbose_name='Identifier')),
|
||||
('description', models.TextField(verbose_name='Description')),
|
||||
(
|
||||
'basic_auth_username',
|
||||
models.CharField(
|
||||
blank=True, max_length=128, verbose_name='Basic authentication username'
|
||||
),
|
||||
),
|
||||
(
|
||||
'basic_auth_password',
|
||||
models.CharField(
|
||||
blank=True, max_length=128, verbose_name='Basic authentication password'
|
||||
),
|
||||
),
|
||||
(
|
||||
'client_certificate',
|
||||
models.FileField(
|
||||
blank=True, null=True, upload_to='', verbose_name='TLS client certificate'
|
||||
),
|
||||
),
|
||||
(
|
||||
'trusted_certificate_authorities',
|
||||
models.FileField(blank=True, null=True, upload_to='', verbose_name='TLS trusted CAs'),
|
||||
),
|
||||
(
|
||||
'verify_cert',
|
||||
models.BooleanField(blank=True, default=True, verbose_name='TLS verify certificates'),
|
||||
),
|
||||
(
|
||||
'http_proxy',
|
||||
models.CharField(blank=True, max_length=128, verbose_name='HTTP and HTTPS proxy'),
|
||||
),
|
||||
(
|
||||
'base_url',
|
||||
models.URLField(
|
||||
help_text='Example: https://test.mgcloud.fr/', verbose_name='Webservice Base URL'
|
||||
),
|
||||
),
|
||||
('tenant_id', models.CharField(max_length=128, verbose_name='Tenant identifier')),
|
||||
(
|
||||
'demand_name_template',
|
||||
models.CharField(
|
||||
default='{{ text }}',
|
||||
max_length=128,
|
||||
validators=[passerelle.utils.templates.validate_template],
|
||||
verbose_name='Demand name template',
|
||||
),
|
||||
),
|
||||
(
|
||||
'users',
|
||||
models.ManyToManyField(
|
||||
blank=True,
|
||||
related_name='_mgdis_mgdis_users_+',
|
||||
related_query_name='+',
|
||||
to='base.ApiUser',
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'MGDIS',
|
||||
},
|
||||
),
|
||||
]
|
|
@ -0,0 +1,81 @@
|
|||
# passerelle - uniform access to multiple data sources and services
|
||||
# Copyright (C) 2024 Entr'ouvert
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Affero General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from urllib.parse import urljoin
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from passerelle.base.models import BaseResource, HTTPResource
|
||||
from passerelle.utils.api import endpoint
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
from passerelle.utils.templates import evaluate_template, validate_template
|
||||
|
||||
|
||||
class Mgdis(BaseResource, HTTPResource):
|
||||
base_url = models.URLField(_('Webservice Base URL'), help_text=_('Example: https://test.mgcloud.fr/'))
|
||||
tenant_id = models.CharField(_('Tenant identifier'), max_length=128)
|
||||
demand_name_template = models.CharField(
|
||||
_('Demand name template'), max_length=128, default='{{ text }}', validators=[validate_template]
|
||||
)
|
||||
|
||||
category = _('Business Process Connectors')
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('MGDIS')
|
||||
|
||||
@endpoint(
|
||||
description=_('Returns user forms'),
|
||||
parameters={
|
||||
'NameID': {'description': _('Publik NameID'), 'example_value': 'xyz'},
|
||||
'status': {'description': _('Demands status'), 'example_value': 'all'},
|
||||
'tiers_id': {'description': _('Tiers identifier')},
|
||||
},
|
||||
)
|
||||
def demands(self, request, NameID, status='all', tiers_id=None):
|
||||
url = urljoin(
|
||||
self.base_url, 'pda-semi-public-api/api/tenants/%s/gru-publik/mes-demandes' % self.tenant_id
|
||||
)
|
||||
|
||||
response = self.requests.get(url, params={'suboidc': NameID, 'size': 50})
|
||||
demands = []
|
||||
try:
|
||||
json_response = response.json()
|
||||
if json_response['err']:
|
||||
raise APIError('MGDIS error: %s' % json_response['err_desc'])
|
||||
data = json_response.get('data', {})
|
||||
|
||||
for tiers in data['tiers']:
|
||||
for demand in tiers.pop('demandes', []):
|
||||
if tiers_id is not None and tiers['id'] != tiers_id:
|
||||
continue
|
||||
if status == 'draft' and not demand['draft']:
|
||||
continue
|
||||
if status == 'done' and not demand['form_status_is_endpoint']:
|
||||
continue
|
||||
if status == 'pending' and demand['draft'] and demand['form_status_is_endpoint']:
|
||||
continue
|
||||
|
||||
demand['tiers'] = tiers
|
||||
demand['status'] = demand['status']['text']
|
||||
demand['name'] = evaluate_template(self.demand_name_template, demand)
|
||||
demands.append(demand)
|
||||
|
||||
except ValueError:
|
||||
raise APIError(
|
||||
'MGDIS error: unparsable response', data={'content': repr(response.content[:1024])}
|
||||
)
|
||||
return {'data': demands}
|
|
@ -168,6 +168,7 @@ INSTALLED_APPS = (
|
|||
'passerelle.apps.matrix42',
|
||||
'passerelle.apps.mdel',
|
||||
'passerelle.apps.mdel_ddpacs',
|
||||
'passerelle.apps.mgdis',
|
||||
'passerelle.apps.mobyt',
|
||||
'passerelle.apps.okina',
|
||||
'passerelle.apps.opendatasoft',
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
import os
|
||||
|
||||
import pytest
|
||||
import responses
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
import tests.utils
|
||||
from passerelle.apps.mgdis.models import Mgdis
|
||||
from passerelle.base.models import AccessRight, ApiUser
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
MGDIS_RESPONSE = {
|
||||
'data': {
|
||||
'tiers': [
|
||||
{
|
||||
'id': 'cOy8DSnSH',
|
||||
'referenceAdministrative': '00000180',
|
||||
'status': {'id': 'TEMPORARY', 'text': 'En cours de cr\u00e9ation'},
|
||||
'famille': {'id': ''},
|
||||
'demandes': [
|
||||
{
|
||||
'id': 'pFuGTUYDQ',
|
||||
'text': 'Demande de financement - Associations',
|
||||
'datetime': '2024-01-18T10:37:33.896Z',
|
||||
'status': {'id': 'REQUESTED', 'text': 'En cours de saisie'},
|
||||
'teleservice': {'text': 'Demande de financement - Associations', 'id': 'F_FINASSO'},
|
||||
'form_status_is_endpoint': False,
|
||||
'draft': True,
|
||||
'url': 'https://mgdis.example.net/aides/#/mgdis-tenant/connecte/dashboard/pFuGTUYDQ/recapitulatif',
|
||||
'action_usager': False,
|
||||
'compte_demandeur': True,
|
||||
'tiers_beneficiaire': True,
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
'id': 'L7dYZD1_o',
|
||||
'text': 'Monsieur Foo Bar',
|
||||
'referenceAdministrative': '00000181',
|
||||
'status': {'id': 'TEMPORARY', 'text': 'En cours de cr\u00e9ation'},
|
||||
'famille': {'text': 'Particulier', 'id': '01'},
|
||||
'mail': 'foot@example.net',
|
||||
'telephone': '06 07 08 09 00',
|
||||
'demandes': [
|
||||
{
|
||||
'id': 'BgpRIrS0X',
|
||||
'text': 'Transport - Allocation individuelle de transport - Monsieur Foo Bar',
|
||||
'datetime': '2024-01-18T10:37:58.355Z',
|
||||
'status': {'id': 'REQUESTED', 'text': 'En cours de saisie'},
|
||||
'teleservice': {
|
||||
'text': 'Transport - Allocation individuelle de transport',
|
||||
'id': 'F_TRANSPAIT',
|
||||
},
|
||||
'form_status_is_endpoint': False,
|
||||
'draft': True,
|
||||
'url': 'https://mdgis.example.net/aides/#/mdgis-tenant/connecte/dashboard/BgpRIrS0X/recapitulatif',
|
||||
'action_usager': False,
|
||||
'compte_demandeur': True,
|
||||
'tiers_beneficiaire': True,
|
||||
}
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
'err': 0,
|
||||
}
|
||||
|
||||
MGDIS_ERROR_RESPONSE = {'data': {}, 'err': 500, 'err_desc': "Cet utilisateur n'est pas connu"}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mgdis():
|
||||
conn = Mgdis.objects.create(slug='test', base_url='https://mgdis.example.net/', tenant_id='mgdis-tenant')
|
||||
api = ApiUser.objects.create(username='all', keytype='', key='')
|
||||
obj_type = ContentType.objects.get_for_model(conn)
|
||||
AccessRight.objects.create(
|
||||
codename='can_access', apiuser=api, resource_type=obj_type, resource_pk=conn.pk
|
||||
)
|
||||
|
||||
return conn
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_get_user_demands(app, mgdis):
|
||||
endpoint = tests.utils.generic_endpoint_url('mgdis', 'demands', slug=mgdis.slug)
|
||||
assert endpoint == '/mgdis/test/demands'
|
||||
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'{mgdis.base_url}pda-semi-public-api/api/tenants/{mgdis.tenant_id}/gru-publik/mes-demandes',
|
||||
json=MGDIS_RESPONSE,
|
||||
status=200,
|
||||
)
|
||||
|
||||
resp = app.get(endpoint, params={'NameID': 'xyz'})
|
||||
assert len(responses.calls) == 1
|
||||
assert resp.json['err'] == 0
|
||||
assert len(resp.json['data']) == 2
|
||||
for item in resp.json['data']:
|
||||
assert 'name' in item
|
||||
assert 'url' in item
|
||||
assert 'draft' in item
|
||||
assert 'datetime' in item
|
||||
assert 'status' in item
|
||||
assert 'form_status_is_endpoint' in item
|
||||
|
||||
resp = app.get(endpoint, params={'NameID': 'xyz', 'status': 'done'})
|
||||
assert len(resp.json['data']) == 0
|
||||
|
||||
resp = app.get(endpoint, params={'NameID': 'xyz', 'tiers_id': 'L7dYZD1_o'})
|
||||
assert len(resp.json['data']) == 1
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_mgdis_invalid_response(app, mgdis):
|
||||
endpoint = tests.utils.generic_endpoint_url('mgdis', 'demands', slug=mgdis.slug)
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'{mgdis.base_url}pda-semi-public-api/api/tenants/{mgdis.tenant_id}/gru-publik/mes-demandes',
|
||||
body='<h2>Error 500</h2>',
|
||||
status=200,
|
||||
)
|
||||
|
||||
resp = app.get(endpoint, params={'NameID': 'xyz'})
|
||||
assert resp.json['err'] == 1
|
||||
assert resp.json['err_desc'] == 'MGDIS error: unparsable response'
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_mgdis_error_response(app, mgdis):
|
||||
endpoint = tests.utils.generic_endpoint_url('mgdis', 'demands', slug=mgdis.slug)
|
||||
responses.add(
|
||||
responses.GET,
|
||||
f'{mgdis.base_url}pda-semi-public-api/api/tenants/{mgdis.tenant_id}/gru-publik/mes-demandes',
|
||||
json=MGDIS_ERROR_RESPONSE,
|
||||
status=200,
|
||||
)
|
||||
|
||||
resp = app.get(endpoint, params={'NameID': 'xyz'})
|
||||
assert resp.json['err'] != 0
|
||||
assert not resp.json['data']
|
Loading…
Reference in New Issue