esup_signature: add new-with-workflow endpoint (#77670) #251
|
@ -69,6 +69,69 @@ SIGN_REQUEST_SCHEMA = {
|
|||
}
|
||||
|
||||
|
||||
SIGN_REQUEST_WITH_WORKFLOW_SCHEMA = {
|
||||
'$schema': 'http://json-schema.org/draft-04/schema#',
|
||||
|
||||
'title': '',
|
||||
'description': '',
|
||||
'type': 'object',
|
||||
'required': ['file', 'eppn', 'workflow_id'],
|
||||
'unflatten': True,
|
||||
'properties': collections.OrderedDict(
|
||||
{
|
||||
'file': {
|
||||
'type': 'object',
|
||||
'description': 'File object',
|
||||
'required': ['filename', 'content_type', 'content'],
|
||||
'properties': {
|
||||
'filename': {
|
||||
'type': 'string',
|
||||
},
|
||||
'content_type': {
|
||||
'type': 'string',
|
||||
'description': 'MIME content-type',
|
||||
},
|
||||
'content': {
|
||||
'type': 'string',
|
||||
'description': 'Content, base64 encoded',
|
||||
},
|
||||
},
|
||||
},
|
||||
'recipients_emails': {
|
||||
'type': 'array',
|
||||
'description': 'Recipients emails at each step',
|
||||
'items': {'type': 'string'},
|
||||
},
|
||||
'target_emails': {
|
||||
'type': 'array',
|
||||
'description': 'Target emails',
|
||||
'items': {'type': 'string'},
|
||||
},
|
||||
'all_sign_to_completes': {
|
||||
pmarillonnet
commented
Typo ici (s/WTIH/WITH), à reporter dans le test aussi. Typo ici (s/WTIH/WITH), à reporter dans le test aussi.
ecazenave
commented
Corrigé. Corrigé.
|
||||
'type': 'array',
|
||||
'description': 'Steps numbers were every recipient has to sign',
|
||||
'items': {'type': 'string'},
|
||||
},
|
||||
'eppn': {'type': 'string', 'description': 'EPPN of the sign request owner'},
|
||||
'workflow_id': {'type': 'string', 'description': 'Identifier of the workflow'},
|
||||
'title': {'type': 'string', 'description': 'Title'},
|
||||
'target_urls': {
|
||||
'type': 'array',
|
||||
'description': 'End locations',
|
||||
'items': {'type': 'string'},
|
||||
},
|
||||
'signrequest_params_jsonstring': {
|
||||
'type': 'string',
|
||||
'description': 'Signature parameters',
|
||||
},
|
||||
}
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def clean_list(some_list):
|
||||
return [elem for elem in some_list if elem]
|
||||
|
||||
|
||||
class EsupSignature(BaseResource, HTTPResource):
|
||||
base_url = models.URLField(_('API URL'))
|
||||
|
||||
|
@ -143,10 +206,9 @@ class EsupSignature(BaseResource, HTTPResource):
|
|||
)
|
||||
}
|
||||
|
||||
recipients_emails = [email for email in post_data['recipients_emails'] if email]
|
||||
data = {
|
||||
'signType': 'pdfImageStamp',
|
||||
'recipientsEmails': recipients_emails,
|
||||
'recipientsEmails': clean_list(post_data['recipients_emails']),
|
||||
'eppn': post_data['eppn'],
|
||||
'title': post_data.get('title', ''),
|
||||
'pending': True,
|
||||
|
@ -154,6 +216,69 @@ class EsupSignature(BaseResource, HTTPResource):
|
|||
|
||||
return {'data': self._call('ws/signrequests/new', method='post', data=data, files=files)}
|
||||
|
||||
@endpoint(
|
||||
name='new-with-workflow',
|
||||
description=_('Create a sign request'),
|
||||
perm='can_access',
|
||||
post={
|
||||
'request_body': {
|
||||
'schema': {
|
||||
'application/json': SIGN_REQUEST_WITH_WORKFLOW_SCHEMA,
|
||||
}
|
||||
},
|
||||
'input_example': {
|
||||
'file': {
|
||||
'filename': 'example-1.pdf',
|
||||
'content_type': 'application/pdf',
|
||||
'content': 'JVBERi0xL...(base64 PDF)...',
|
||||
},
|
||||
'workflow_id': '99',
|
||||
'eppn': 'aa@foo.com',
|
||||
'title': 'a title',
|
||||
'recipients_emails/0': '0*xx@foo.com',
|
||||
'recipients_emails/1': '0*yy@foo.com',
|
||||
'recipients_emails/2': '1*zz@foo.com',
|
||||
'all_sign_to_completes/0': '12',
|
||||
'all_sign_to_completes/1': '13',
|
||||
'target_emails/0': 'xx@foo.com',
|
||||
'target_emails/1': 'yy@foo.com',
|
||||
'target_emails/2': 'zz@foo.com',
|
||||
'signrequest_params_jsonstring': 'List [ OrderedMap { "xPos": 100, "yPos": 100, "signPageNumber": 1 }, '
|
||||
'OrderedMap { "xPos": 200, "yPos": 200, "signPageNumber": 1 } ]',
|
||||
'target_urls/0': 'smb://foo.bar/location-1/',
|
||||
'target_urls/1': 'smb://foo.bar/location-2/',
|
||||
},
|
||||
},
|
||||
)
|
||||
def new_with_workflow(self, request, post_data):
|
||||
try:
|
||||
file_bytes = io.BytesIO(base64.b64decode(post_data['file']['content']))
|
||||
except (TypeError, binascii.Error):
|
||||
raise APIError("Can't decode file")
|
||||
files = {
|
||||
'multipartFiles': (
|
||||
post_data['file']['filename'],
|
||||
file_bytes,
|
||||
post_data['file']['content_type'],
|
||||
)
|
||||
}
|
||||
|
||||
data = {
|
||||
'createByEppn': post_data['eppn'],
|
||||
'title': post_data.get('title', ''),
|
||||
'recipientsEmails': clean_list(post_data.get('recipients_emails', [])),
|
||||
'allSignToCompletes': clean_list(post_data.get('all_sign_to_completes', [])),
|
||||
'targetEmails': clean_list(post_data.get('target_emails', [])),
|
||||
'signRequestParamsJsonString': post_data.get('signrequest_params_jsonstring', ''),
|
||||
'targetUrls': clean_list(post_data.get('target_urls', [])),
|
||||
pmarillonnet
commented
Du détail, mais pas compris pourquoi la valeur par défaut est en dur ici et ne reprend pas celle définie dans le schéma. Du détail, mais pas compris pourquoi la valeur par défaut est en dur ici et ne reprend pas celle définie dans le schéma.
ecazenave
commented
Dans la norme JSON schema : "The default keyword specifies a default value. This value is not used to fill in missing values during the validation process." Charge donc à l'application de "fournir" les valeurs par défaut. Dans la norme JSON schema : "The default keyword specifies a default value. This value is not used to fill in missing values during the validation process."
Charge donc à l'application de "fournir" les valeurs par défaut.
pmarillonnet
commented
Cool, j’ignorais ça, merci pour la clarification. Cool, j’ignorais ça, merci pour la clarification.
|
||||
}
|
||||
|
||||
return {
|
||||
'data': self._call(
|
||||
'/ws/workflows/%s/new' % post_data['workflow_id'], method='post', data=data, files=files
|
||||
)
|
||||
}
|
||||
|
||||
@endpoint(
|
||||
methods=['get'],
|
||||
name='status',
|
||||
|
|
|
@ -44,6 +44,39 @@ def test_new(app, connector):
|
|||
assert json_resp['data'] == 9
|
||||
|
||||
|
||||
def test_new_with_workflow(app, connector):
|
||||
params = {
|
||||
'file': {
|
||||
'filename': 'bla',
|
||||
'content': base64.b64encode(b'who what').decode(),
|
||||
'content_type': 'text/plain',
|
||||
},
|
||||
'workflow_id': '99',
|
||||
'eppn': 'aa@foo.com',
|
||||
'title': 'a title',
|
||||
'recipients_emails/0': '0*xx@foo.com',
|
||||
'recipients_emails/1': '0*yy@foo.com',
|
||||
'recipients_emails/2': '1*zz@foo.com',
|
||||
'all_sign_to_completes/0': '12',
|
||||
'all_sign_to_completes/1': '13',
|
||||
'target_emails/0': 'xx@foo.com',
|
||||
'target_emails/1': 'yy@foo.com',
|
||||
'target_emails/2': 'zz@foo.com',
|
||||
'signrequest_params_jsonstring': 'List [ OrderedMap { "xPos": 100, "yPos": 100, "signPageNumber": 1 }, '
|
||||
'OrderedMap { "xPos": 200, "yPos": 200, "signPageNumber": 1 } ]',
|
||||
'target_urls/0': 'smb://foo.bar/location-1/',
|
||||
'target_urls/1': 'smb://foo.bar/location-2/',
|
||||
}
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.post('https://esup-signature.invalid/ws/workflows/99/new', status=200, json=9)
|
||||
resp = app.post_json('/esup-signature/esup-signature/new-with-workflow', params=params)
|
||||
assert len(rsps.calls) == 1
|
||||
assert rsps.calls[0].request.headers['Content-Type'].startswith('multipart/form-data')
|
||||
json_resp = resp.json
|
||||
assert json_resp['err'] == 0
|
||||
assert json_resp['data'] == 9
|
||||
|
||||
|
||||
def test_status(app, connector):
|
||||
with responses.RequestsMock() as rsps:
|
||||
rsps.get('https://esup-signature.invalid/ws/signrequests/1', status=200, json={'status': 'completed'})
|
||||
|
|
Loading…
Reference in New Issue
Est-ce que pour plus de clarté on n’a pas intérêt à décider d’une valeur par défaut pour tous ces paramètres booléens nouvellement ajoutés au schéma ?
Fait.