cmis: add object type and property support (#39416)
This commit is contained in:
parent
af5fa68c06
commit
45428e944a
|
@ -25,6 +25,7 @@ from cmislib.exceptions import CmisException
|
|||
from cmislib.exceptions import ObjectNotFoundException
|
||||
from cmislib.exceptions import PermissionDeniedException
|
||||
from cmislib.exceptions import UpdateConflictException
|
||||
from cmislib.exceptions import InvalidArgumentException
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.six import BytesIO
|
||||
|
@ -63,8 +64,14 @@ UPLOAD_SCHEMA = {
|
|||
'type': 'string',
|
||||
'pattern': FILE_PATH_PATTERN,
|
||||
},
|
||||
'object_type': {'type': 'string'},
|
||||
'properties': {
|
||||
'type': 'object',
|
||||
'additionalProperties': {'type': 'string'}
|
||||
},
|
||||
},
|
||||
'required': ['file', 'path']
|
||||
'required': ['file', 'path'],
|
||||
'unflatten': True,
|
||||
}
|
||||
|
||||
|
||||
|
@ -103,7 +110,10 @@ class CmisConnector(BaseResource):
|
|||
doc = cmis_gateway.create_doc(
|
||||
filename,
|
||||
data['path'],
|
||||
data['file_byte_content'])
|
||||
data['file_byte_content'],
|
||||
object_type=data.get('object_type'),
|
||||
properties=data.get('properties'),
|
||||
)
|
||||
return {'data': {'properties': doc.properties}}
|
||||
|
||||
def _validate_inputs(self, data):
|
||||
|
@ -119,6 +129,10 @@ class CmisConnector(BaseResource):
|
|||
except (TypeError, binascii.Error):
|
||||
return True, '"file[\'content\']" must be a valid base64 string', None
|
||||
|
||||
if 'properties' in data and 'object_type' not in data:
|
||||
if any(prop for prop in data['properties'] if not prop.startswith('cmis:')):
|
||||
return True, 'Properties other than cmis: require object_type to be set', None
|
||||
|
||||
return False, '', data
|
||||
|
||||
|
||||
|
@ -134,6 +148,8 @@ def wrap_cmis_error(f):
|
|||
raise APIError("permission denied: %s" % e)
|
||||
except UpdateConflictException as e:
|
||||
raise APIError("update conflict: %s" % e)
|
||||
except InvalidArgumentException as e:
|
||||
raise APIError("invalid property name: %s" % e)
|
||||
except CmisException as e:
|
||||
raise APIError("cmis binding error: %s" % e)
|
||||
return wrapper
|
||||
|
@ -169,6 +185,11 @@ class CMISGateway(object):
|
|||
return folder
|
||||
|
||||
@wrap_cmis_error
|
||||
def create_doc(self, file_name, file_path, file_byte_content):
|
||||
def create_doc(self, file_name, file_path, file_byte_content,
|
||||
object_type=None, properties=None):
|
||||
folder = self._get_or_create_folder(file_path)
|
||||
return folder.createDocument(file_name, contentFile=BytesIO(file_byte_content))
|
||||
properties = properties or {}
|
||||
if object_type:
|
||||
properties['cmis:objectTypeId'] = object_type
|
||||
return folder.createDocument(file_name, contentFile=BytesIO(file_byte_content),
|
||||
properties=properties)
|
||||
|
|
|
@ -7,6 +7,7 @@ from cmislib.exceptions import CmisException
|
|||
from cmislib.exceptions import ObjectNotFoundException
|
||||
from cmislib.exceptions import PermissionDeniedException
|
||||
from cmislib.exceptions import UpdateConflictException
|
||||
from cmislib.exceptions import InvalidArgumentException
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.encoding import force_bytes, force_text
|
||||
from django.utils.six.moves.urllib import error as urllib2
|
||||
|
@ -41,7 +42,8 @@ def test_uploadfile(app, setup, tmpdir, monkeypatch):
|
|||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def create_doc(self, file_name, file_path, file_byte_content):
|
||||
def create_doc(self, file_name, file_path, file_byte_content,
|
||||
object_type=None, properties=None):
|
||||
with open(file_name, 'wb') as f:
|
||||
f.write(file_byte_content)
|
||||
return Mock(properties={"toto": "tata"})
|
||||
|
@ -82,6 +84,34 @@ def test_uploadfile(app, setup, tmpdir, monkeypatch):
|
|||
assert json_result['data']['properties'] == {"toto": "tata"}
|
||||
|
||||
|
||||
def test_upload_file_metadata(app, setup, monkeypatch):
|
||||
|
||||
class FakeFolder:
|
||||
def createDocument(self, filename, contentFile, properties):
|
||||
return Mock(properties=properties)
|
||||
|
||||
from passerelle.apps.cmis.models import CMISGateway
|
||||
monkeypatch.setattr(CMISGateway, '_get_or_create_folder', lambda x, y: FakeFolder())
|
||||
response = app.post_json(
|
||||
'/cmis/slug-cmis/uploadfile',
|
||||
params={"path": "/some/folder/structure",
|
||||
"file": {"filename": "bla",
|
||||
"content": b64encode('bla')},
|
||||
"object_type": "D:dui:type",
|
||||
"properties": {
|
||||
"cmis:description": "Coucou",
|
||||
"dui:tnumDossier": "42",
|
||||
},
|
||||
"properties/dui:ttypeStructure": "Accueil de loisirs",
|
||||
})
|
||||
assert response.json['data']['properties'] == {
|
||||
"cmis:objectTypeId": "D:dui:type",
|
||||
"cmis:description": "Coucou",
|
||||
"dui:tnumDossier": "42",
|
||||
"dui:ttypeStructure": "Accueil de loisirs",
|
||||
}
|
||||
|
||||
|
||||
def test_uploadfile_error_if_no_file_name(app, setup):
|
||||
response = app.post_json(
|
||||
'/cmis/slug-cmis/uploadfile',
|
||||
|
@ -208,6 +238,20 @@ def test_uploadfile_error_if_no_proper_base64_encoding(app, setup):
|
|||
assert response.json['err_desc'].startswith('"file[\'content\']" must be a valid base64 string')
|
||||
|
||||
|
||||
def test_upload_file_error_metadata(app, setup):
|
||||
|
||||
response = app.post_json(
|
||||
'/cmis/slug-cmis/uploadfile',
|
||||
params={"path": "/some/folder/structure",
|
||||
"file": {"filename": "bla",
|
||||
"content": b64encode('bla')},
|
||||
"properties": {"dui:tnumDossier": "42"}},
|
||||
expect_errors=True)
|
||||
assert response.status_code == 400
|
||||
assert response.json['err'] == 1
|
||||
assert 'object_type' in response.json['err_desc']
|
||||
|
||||
|
||||
def test_uploadfile_cmis_gateway_error(app, setup, monkeypatch):
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
cmis_gateway = Mock()
|
||||
|
@ -315,6 +359,7 @@ def test_create_doc():
|
|||
(urllib2.URLError, "connection error"),
|
||||
(PermissionDeniedException, "permission denied"),
|
||||
(UpdateConflictException, "update conflict"),
|
||||
(InvalidArgumentException, "invalid property"),
|
||||
(CmisException, "cmis binding error")
|
||||
])
|
||||
def test_wrap_cmis_error(app, setup, monkeypatch, cmis_exc, err_msg):
|
||||
|
|
Loading…
Reference in New Issue