solis: add links parameter to retreive rsa _links information (#33377)

This commit is contained in:
Thomas NOËL 2019-05-24 16:07:57 +02:00
parent 1554c5c634
commit 4905c677b1
2 changed files with 107 additions and 6 deletions

View File

@ -15,12 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64
import copy
import json
import re
import unicodedata
from django.db import models
from django.template.loader import get_template
from django.utils.encoding import force_text
from django.utils.translation import ugettext_lazy as _
from django.utils.http import urlencode
@ -454,8 +456,23 @@ class Solis(BaseResource):
})
return response.get('token')
def rsa_get_link_content(self, link):
'''returns content of a '_links' entry in a grsa referential'''
if (not isinstance(link, dict) or not link.get('href')
or not link['href'].startswith(self.service_url)):
return None
endpoint = link['href'][len(self.service_url):]
try:
return self.request(endpoint)
except APIError as e: # do not raise on linked informations
return {
'err': 1,
'err_class': e.__class__.__name__,
'err_desc': force_text(e)
}
def rsa_get_information(self, information, user_id=None, code=None, token=None,
index='search'):
index='search', links=None):
# simulate "individu" referential: get user details from civi/individu/user_id
if information == 'individu':
if not user_id:
@ -473,7 +490,26 @@ class Solis(BaseResource):
if index.startswith('search'): # it can be "search/next" in rdvs referential
args = [('indexIndividu', user_id)] + args
endpoint += '?' + urlencode(args)
return self.request(endpoint)
information = self.request(endpoint)
if isinstance(information, dict) and '_links' in information:
# return links in non-underscored key, usable in Django template
information['rsa_links'] = copy.deepcopy(information['_links'])
if links is not None:
if not links.strip(): # get all links
links = information['rsa_links'].keys()
else:
links = [link.strip() for link in links.split(',') if link.strip()]
links = [link for link in links if link in information['rsa_links']
and information['rsa_links'][link].get('href')]
for link in links:
content = self.rsa_get_link_content(information['rsa_links'][link])
if content is not None:
information['rsa_links'][link]['content'] = content
return information
@endpoint(name='rsa-link', methods=['post'], perm='can_access',
description=_('Create link between name_id and '
@ -549,17 +585,21 @@ class Solis(BaseResource):
},
'index': {
'description': _('get a specific item, if applicable'),
},
'links': {
'description': _('get linked informations (comma separated list, empty for all)'),
'example_value': 'etatCivil,conjoint',
}
})
def rsa_user_info(self, request, name_id, user_id, information='individu',
index='search'):
index='search', links=None):
try:
link = SolisRSALink.objects.get(resource=self, name_id=name_id, user_id=user_id)
except SolisRSALink.DoesNotExist:
raise APIError('unknown link')
response = self.rsa_get_information(information=information,
user_id=user_id, code=link.code,
index=index)
index=index, links=links)
if information == 'individu':
text = get_template(self.text_template_name_rsa).render(response).strip()
if text != link.text:

View File

@ -47,10 +47,10 @@ RSAALLOCATAIRES = '''{
"oriente": true,
"_links": {
"etatCivil": {
"href": "http://solis.infodb.fr/solisapi-rsa/referentiels/civi/individu/4242/"
"href": "https://solis.example.net/solisapi/referentiels/civi/individu/4242/"
},
"conjoint": {
"href": "http://solis.infodb.fr/solisapi-rsa/referentiels/civi/individu/4273/"
"href": "https://solis.example.net/solisapi/referentiels/civi/individu/4273/"
}
}
}'''
@ -830,6 +830,67 @@ def test_solis_rsa_link_infos_unlink(app, solis):
assert resp.json['err_desc'] == 'unknown link'
assert resp.json['data'] is None
# get referential for a linked user with links
with mock.patch('passerelle.utils.Request.get') as requests_get:
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = utils.FakedResponse(content=RSATOKEN, status_code=200)
endpoint_base = utils.generic_endpoint_url('solis', 'rsa-user-info', slug=solis.slug)
requests_get.side_effect = [
utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES), # base info
utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU), # link 1
utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU)] # link 2
endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
resp = app.get(endpoint, status=200)
assert requests_post.call_count == 1 # get a token
assert requests_get.call_count == 3 # get informations + two links
assert resp.json['err'] == 0
assert resp.json['data']['rsa_links']['etatCivil']['content']['index'] == 4273
assert resp.json['data']['rsa_links']['conjoint']['content']['index'] == 4273
# get only conjoint
requests_post.reset_mock()
requests_get.reset_mock()
requests_get.side_effect = [
utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES), # base info
utils.FakedResponse(status_code=200, content=CIVI_INDIVIDU)] # link 1
endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links=conjoint, ,xx,' % NAMEID
resp = app.get(endpoint, status=200)
assert requests_post.call_count == 1 # get a token
assert requests_get.call_count == 2 # get informations + conjoint
assert resp.json['err'] == 0
assert resp.json['data']['rsa_links']['conjoint']['content']['index'] == 4273
assert 'content' not in resp.json['data']['rsa_links']['etatCivil']
# error on link retreival
requests_post.reset_mock()
requests_get.reset_mock()
requests_get.side_effect = [
utils.FakedResponse(status_code=200, content=RSAALLOCATAIRES), # base info
utils.FakedResponse(status_code=404, content='{"foo": "bar"}'), # link 1
utils.FakedResponse(status_code=500, content='boom')] # link 2
endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
resp = app.get(endpoint, status=200)
assert requests_post.call_count == 1 # get a token
assert requests_get.call_count == 3 # get informations + two links
assert resp.json['err'] == 0
assert resp.json['data']['rsa_links']['etatCivil']['content']['err'] == 1
assert resp.json['data']['rsa_links']['conjoint']['content']['err'] == 1
# bad links, do nothing
for content in (RSAALLOCATAIRES.replace('https:', 'http:'),
RSAALLOCATAIRES.replace('href', 'xxxx')):
requests_post.reset_mock()
requests_get.reset_mock()
requests_get.side_effect = [utils.FakedResponse(status_code=200, content=content)]
endpoint = endpoint_base + '?name_id=%s&user_id=4242&information=allocataires&links' % NAMEID
resp = app.get(endpoint, status=200)
assert requests_post.call_count == 1 # get a token
assert requests_get.call_count == 1 # get informations only, not links
assert resp.json['err'] == 0
assert 'content' not in resp.json['data']['rsa_links']['conjoint']
assert 'content' not in resp.json['data']['rsa_links']['etatCivil']
# unlink
endpoint = utils.generic_endpoint_url('solis', 'rsa-unlink', slug=solis.slug)
for bad_params in ({}, {'user_id': '4273'}, {'name_id': NAMEID}):