diff --git a/sonar/json_schemas/deposits_json_schema.py b/sonar/json_schemas/deposits_json_schema.py
index db85c5a72..14f83327a 100644
--- a/sonar/json_schemas/deposits_json_schema.py
+++ b/sonar/json_schemas/deposits_json_schema.py
@@ -32,14 +32,33 @@ def process(self):
"""
schema = super().process()
- if not current_user_record or current_user_record.is_moderator:
+ organisation = {}
+ if current_user_record:
+ organisation = current_user_record.replace_refs() \
+ .get('organisation')
+
+ if not current_user_record or (current_user_record.is_moderator and \
+ organisation.get('isDedicated', False)):
return schema
+ # Remove some fields on json for the shared organisation
+ if not organisation.get('isDedicated', False):
+ # Remove collections field
+ schema['properties']['metadata']['properties']\
+ .pop('collections', None)
+ propertiesOrder = schema['properties']['metadata']\
+ .get('propertiesOrder', [])
+ if 'collections' in propertiesOrder:
+ schema['properties']['metadata']['propertiesOrder']\
+ .remove('collections')
+
+ # Remove subdivisions field
schema['properties']['diffusion']['properties'].pop(
- 'subdivisions', None)
- order = schema['properties']['diffusion']['propertiesOrder']
- schema['properties']['diffusion']['propertiesOrder'] = [
- v for v in order if v != 'subdivisions'
- ]
+ 'subdivisions', None)
+ propertiesOrder = schema['properties']['diffusion']\
+ .get('propertiesOrder', [])
+ if 'subdivisions' in propertiesOrder:
+ schema['properties']['diffusion']['propertiesOrder']\
+ .remove('subdivisions')
return schema
diff --git a/sonar/json_schemas/documents_json_schema.py b/sonar/json_schemas/documents_json_schema.py
new file mode 100644
index 000000000..73b0abd19
--- /dev/null
+++ b/sonar/json_schemas/documents_json_schema.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+#
+# Swiss Open Access Repository
+# Copyright (C) 2022 RERO
+#
+# 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, version 3 of the License.
+#
+# 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 .
+
+"""Documents JSON schema class."""
+
+from sonar.modules.users.api import current_user_record
+
+from .json_schema_base import JSONSchemaBase
+
+
+class DocumentsJSONSchema(JSONSchemaBase):
+ """JSON schema for deposits."""
+
+ def process(self):
+ """Documents JSON schema custom process.
+
+ :returns: The processed schema.
+ """
+ schema = super().process()
+
+ if not current_user_record:
+ return schema
+
+ # Get Organisation for the current logged user
+ organisation = current_user_record.replace_refs()\
+ .get('organisation', {})
+ # Remove some fields on json for the shared organisation
+ if not organisation.get('isDedicated', False):
+ for field in ['collections', 'subdivisions']:
+ schema['properties'].pop(field, None)
+ if field in schema.get('propertiesOrder', []):
+ schema['propertiesOrder'].remove(field)
+
+ if not current_user_record.is_superuser:
+ schema['properties'].pop('organisation', None)
+ if 'organisation' in schema.get('propertiesOrder', []):
+ schema['propertiesOrder'].remove('organisation')
+
+ return schema
diff --git a/sonar/json_schemas/factory.py b/sonar/json_schemas/factory.py
index 367e98f19..a153ca00b 100644
--- a/sonar/json_schemas/factory.py
+++ b/sonar/json_schemas/factory.py
@@ -18,14 +18,22 @@
"""Factory for JSON schema."""
from .deposits_json_schema import DepositsJSONSchema
+from .documents_json_schema import DocumentsJSONSchema
from .json_schema_base import JSONSchemaBase
+from .organisations_json_schema import OrganisationsJSONSchema
+from .projects_json_schema import ProjectsJSONSchema
+from .users_json_schema import UsersJSONSchema
class JSONSchemaFactory():
"""Factory for JSON schema."""
SCHEMAS = {
- 'deposits': DepositsJSONSchema
+ 'deposits': DepositsJSONSchema,
+ 'documents': DocumentsJSONSchema,
+ 'organisations': OrganisationsJSONSchema,
+ 'projects': ProjectsJSONSchema,
+ 'users': UsersJSONSchema
}
@staticmethod
diff --git a/sonar/json_schemas/organisations_json_schema.py b/sonar/json_schemas/organisations_json_schema.py
new file mode 100644
index 000000000..240c725ce
--- /dev/null
+++ b/sonar/json_schemas/organisations_json_schema.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+#
+# Swiss Open Access Repository
+# Copyright (C) 2022 RERO
+#
+# 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, version 3 of the License.
+#
+# 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 .
+
+"""Organisations JSON schema class."""
+
+from sonar.modules.users.api import current_user_record
+
+from .json_schema_base import JSONSchemaBase
+
+
+class OrganisationsJSONSchema(JSONSchemaBase):
+ """JSON schema for deposits."""
+
+ def process(self):
+ """Organisations JSON schema custom process.
+
+ :returns: The processed schema.
+ """
+ schema = super().process()
+
+ # Remove modes fields if user does not have superuser role.
+ if not current_user_record.is_superuser:
+ propertiesOrder = schema.get('propertiesOrder', []);
+ for field in ['isDedicated', 'isShared']:
+ if field in propertiesOrder:
+ schema['propertiesOrder'].remove(field)
+
+ return schema
diff --git a/sonar/json_schemas/projects_json_schema.py b/sonar/json_schemas/projects_json_schema.py
new file mode 100644
index 000000000..6c5ba7af8
--- /dev/null
+++ b/sonar/json_schemas/projects_json_schema.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+#
+# Swiss Open Access Repository
+# Copyright (C) 2022 RERO
+#
+# 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, version 3 of the License.
+#
+# 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 .
+
+"""Projects JSON schema class."""
+
+from sonar.modules.users.api import current_user_record
+
+from .json_schema_base import JSONSchemaBase
+
+
+class ProjectsJSONSchema(JSONSchemaBase):
+ """JSON schema for deposits."""
+
+ def process(self):
+ """Projects JSON schema custom process.
+
+ :returns: The processed schema.
+ """
+ schema = super().process()
+
+ # Remove modes fields if user does not have superuser role.
+ if current_user_record and not current_user_record.is_superuser:
+ schema['properties']['metadata']['properties'].pop(
+ 'organisation', None)
+ if 'organisation' in schema['properties']['metadata']\
+ ['propertiesOrder']:
+ schema['properties']['metadata']['propertiesOrder'].remove(
+ 'organisation')
+
+ return schema
diff --git a/sonar/json_schemas/users_json_schema.py b/sonar/json_schemas/users_json_schema.py
new file mode 100644
index 000000000..c54588070
--- /dev/null
+++ b/sonar/json_schemas/users_json_schema.py
@@ -0,0 +1,60 @@
+# -*- coding: utf-8 -*-
+#
+# Swiss Open Access Repository
+# Copyright (C) 2022 RERO
+#
+# 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, version 3 of the License.
+#
+# 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 .
+
+"""Users JSON schema class."""
+
+from flask_login import current_user
+
+from sonar.modules.users.api import current_user_record
+
+from .json_schema_base import JSONSchemaBase
+
+
+class UsersJSONSchema(JSONSchemaBase):
+ """JSON schema for deposits."""
+
+ def process(self):
+ """Users JSON schema custom process.
+
+ :returns: The processed schema.
+ """
+ schema = super().process()
+
+ # Remove modes fields if user does not have superuser role.
+ if not current_user.is_anonymous and current_user_record:
+ if current_user_record.is_admin:
+ reachable_roles = current_user_record.\
+ get_all_reachable_roles()
+
+ schema['properties']['role']['form']['options'] = [{
+ 'label': 'role_{role}'.format(role=role),
+ 'value': role
+ } for role in reachable_roles]
+ schema['properties']['role'][
+ 'enum'] = current_user_record.get_all_reachable_roles(
+ )
+ else:
+ schema['properties'].pop('role')
+ if 'role' in schema.get('propertiesOrder', []):
+ schema['propertiesOrder'].remove('role')
+
+ if not current_user_record.is_superuser:
+ schema['properties'].pop('organisation')
+ if 'organisation' in schema.get('propertiesOrder', []):
+ schema['propertiesOrder'].remove('organisation')
+
+ return schema
diff --git a/sonar/theme/views.py b/sonar/theme/views.py
index 79adbaa2c..8f0d8b672 100644
--- a/sonar/theme/views.py
+++ b/sonar/theme/views.py
@@ -206,56 +206,6 @@ def schemas(record_type):
"""
try:
json_schema = JSONSchemaFactory.create(record_type)
- schema = json_schema.get_schema()
-
- # TODO: Maybe find a proper way to do this.
- if record_type in [
- 'users', 'documents'
- ] and not current_user.is_anonymous and current_user_record:
- if record_type == 'users':
- # If user is admin, restrict available roles list.
- if current_user_record.is_admin:
- reachable_roles = current_user_record.\
- get_all_reachable_roles()
-
- schema['properties']['role']['form']['options'] = []
- for role in reachable_roles:
- schema['properties']['role']['form']['options'].append(
- {
- 'label': 'role_{role}'.format(role=role),
- 'value': role
- })
-
- schema['properties']['role'][
- 'enum'] = current_user_record.get_all_reachable_roles(
- )
- # User cannot select role
- else:
- schema['properties'].pop('role')
- if 'role' in schema.get('propertiesOrder', []):
- schema['propertiesOrder'].remove('role')
-
- if not current_user_record.is_superuser:
- schema['properties'].pop('organisation')
- if 'organisation' in schema.get('propertiesOrder', []):
- schema['propertiesOrder'].remove('organisation')
-
- if (record_type == 'projects' and not current_user.is_anonymous and
- current_user_record and not current_user_record.is_superuser):
- schema['properties']['metadata']['properties'].pop(
- 'organisation', None)
- schema['properties']['metadata']['propertiesOrder'].remove(
- 'organisation')
-
- # Remove modes fields if user does not have superuser role.
- if (record_type == 'organisations' and
- not current_user_record.is_superuser):
- if 'isDedicated' in schema.get('propertiesOrder', []):
- schema['propertiesOrder'].remove('isDedicated')
-
- if 'isShared' in schema.get('propertiesOrder', []):
- schema['propertiesOrder'].remove('isShared')
-
return jsonify({'schema': json_schema.process()})
except JSONSchemaNotFound:
abort(404)
diff --git a/tests/conftest.py b/tests/conftest.py
index 8bbe848ba..a1f1735f7 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -132,12 +132,12 @@ def app_config(app_config):
def make_organisation(app, db, bucket_location, without_oaiset_signals):
"""Factory for creating organisation."""
- def _make_organisation(code):
+ def _make_organisation(code, is_shared=True):
data = {
'code': code,
'name': code,
- 'isShared': True,
- 'isDedicated': False,
+ 'isShared': is_shared,
+ 'isDedicated': not is_shared,
'documentsCustomField1': {
'label': [{
'language': 'eng',
@@ -194,11 +194,13 @@ def roles(base_app, db):
def make_user(app, db, make_organisation):
"""Factory for creating user."""
- def _make_user(role_name, organisation='org', access=None):
+ def _make_user(
+ role_name, organisation='org', organisation_is_shared=True,
+ access=None):
name = role_name
if organisation:
- make_organisation(organisation)
+ make_organisation(organisation, is_shared=organisation_is_shared)
name = organisation + name
email = '{name}@rero.ch'.format(name=name)
@@ -283,6 +285,16 @@ def moderator(make_user):
return make_user('moderator', access='admin-access')
+@pytest.fixture()
+def moderator_dedicated(make_user):
+ """Create moderator organisation dedicated."""
+ return make_user(
+ 'moderator',
+ organisation='dedicated',
+ organisation_is_shared=False,
+ access='admin-access')
+
+
@pytest.fixture()
def submitter(make_user):
"""Create submitter."""
@@ -304,7 +316,7 @@ def superuser(make_user):
@pytest.fixture()
def document_json(app, db, bucket_location, organisation):
"""JSON document fixture."""
- data = {
+ return {
'identifiedBy': [{
'value': 'urn:nbn:ch:rero-006-108713',
'type': 'bf:Urn'
@@ -424,8 +436,6 @@ def document_json(app, db, bucket_location, organisation):
'customField1': ['Test']
}
- return data
-
@pytest.fixture()
def make_document(db, document_json, make_organisation, pdf_file, embargo_date):
diff --git a/tests/ui/test_views.py b/tests/ui/test_views.py
index 6ddf76c9f..4d70a1f40 100644
--- a/tests/ui/test_views.py
+++ b/tests/ui/test_views.py
@@ -134,52 +134,74 @@ def test_logged_user(app, client, superuser, admin, moderator, submitter,
assert not res.json['metadata']['permissions']['deposits']['list']
-def test_schemas(client, admin, user, submitter, moderator):
- """Test JSON schemas endpoint."""
- res = client.get(url_for('sonar.schemas', record_type='documents'))
- assert res.status_code == 200
- assert res.json['schema']['properties'].get('organisation')
+def test_non_existing_schema(client, user):
+ """Test schema no existing."""
+ login_user_via_session(client, email=user['email'])
+ res = client.get(url_for('sonar.schemas', record_type='not_existing'))
+ assert res.status_code == 404
- res = client.get(url_for('sonar.schemas', record_type='users'))
+
+def test_schema_documents(client, user, superuser):
+ """Test schema documents."""
+ res = client.get(url_for('sonar.schemas', record_type='documents'))
assert res.status_code == 200
assert res.json['schema']['properties'].get('organisation')
- assert res.json['schema']['properties'].get('role')
- res = client.get(url_for('sonar.schemas', record_type='deposits'))
+ login_user_via_session(client, email=user['email'])
+ res = client.get(url_for('sonar.schemas', record_type='documents'))
assert res.status_code == 200
+ assert not res.json['schema']['properties'].get('collections')
+ assert 'collections' not in res.json['schema']['propertiesOrder']
+ assert not res.json['schema']['properties'].get('subdivisions')
+ assert 'subdivisions' not in res.json['schema']['propertiesOrder']
+ assert not res.json['schema']['properties'].get('organisations')
+ assert 'organisations' not in res.json['schema']['propertiesOrder']
- login_user_via_session(client, email=admin['email'])
-
+ login_user_via_session(client, email=superuser['email'])
res = client.get(url_for('sonar.schemas', record_type='documents'))
assert res.status_code == 200
- assert not res.json['schema']['properties'].get('organisation')
+ assert not res.json['schema']['properties'].get('collections')
+ assert 'collections' not in res.json['schema']['propertiesOrder']
+ assert not res.json['schema']['properties'].get('subdivisions')
+ assert 'subdivisions' not in res.json['schema']['propertiesOrder']
+ assert res.json['schema']['properties'].get('organisation')
+ assert 'organisation' in res.json['schema']['propertiesOrder']
- res = client.get(url_for('sonar.schemas', record_type='deposits'))
+
+def test_schema_users(client, admin):
+ """Test schema users."""
+ res = client.get(url_for('sonar.schemas', record_type='users'))
assert res.status_code == 200
+ assert res.json['schema']['properties'].get('organisation')
+ assert res.json['schema']['properties'].get('role')
+ login_user_via_session(client, email=admin['email'])
res = client.get(url_for('sonar.schemas', record_type='users'))
assert res.status_code == 200
assert not res.json['schema']['properties'].get('organisation')
assert res.json['schema']['properties'].get('role')
assert len(res.json['schema']['properties']['role']['enum']) == 4
- res = client.get(url_for('sonar.schemas', record_type='not_existing'))
- assert res.status_code == 404
- # Organisations, with admin user --> no fields `isShared` and `isDedicated`
+def test_schema_organisations(client, admin, user):
+ """Test schema organisations."""
+ login_user_via_session(client, email=admin['email'])
+ # admin user --> no fields `isShared` and `isDedicated`
res = client.get(url_for('sonar.schemas', record_type='organisations'))
assert res.status_code == 200
assert 'isShared' not in res.json['schema']['propertiesOrder']
assert 'isDedicated' not in res.json['schema']['propertiesOrder']
login_user_via_session(client, email=user['email'])
-
res = client.get(url_for('sonar.schemas', record_type='users'))
assert res.status_code == 200
assert not res.json['schema']['properties'].get('organisation')
assert not res.json['schema']['properties'].get('role')
- # Projects
+
+def test_schema_projects(client, user):
+ """Test schema projects."""
+ login_user_via_session(client, email=user['email'])
res = client.get(url_for('sonar.schemas', record_type='projects'))
assert res.status_code == 200
assert not res.json['schema']['properties']['metadata']['properties'].get(
@@ -188,20 +210,45 @@ def test_schemas(client, admin, user, submitter, moderator):
assert 'organisation' not in res.json['schema']['properties']['metadata'][
'propertiesOrder']
+
+def test_schema_deposits(client, moderator, submitter, moderator_dedicated):
+ """Test schema deposits."""
login_user_via_session(client, email=moderator['email'])
res = client.get(url_for('sonar.schemas', record_type='deposits'))
assert res.status_code == 200
- assert res.json[
+ # Moderator with shared organisation
+ assert not res.json[
'schema']['properties']['diffusion']['properties'].get('subdivisions')
- assert 'subdivisions' in res.json[
+ assert 'subdivisions' not in res.json[
'schema']['properties']['diffusion']['propertiesOrder']
+ assert not res.json[
+ 'schema']['properties']['metadata']['properties'].get('collections')
+ assert 'collections' not in res.json[
+ 'schema']['properties']['metadata']['propertiesOrder']
login_user_via_session(client, email=submitter['email'])
res = client.get(url_for('sonar.schemas', record_type='deposits'))
assert res.status_code == 200
assert not res.json[
'schema']['properties']['diffusion']['properties'].get('subdivisions')
- assert not 'subdivisions' in res.json[
+ assert 'subdivisions' not in res.json[
+ 'schema']['properties']['diffusion']['propertiesOrder']
+ assert not res.json[
+ 'schema']['properties']['metadata']['properties'].get('collections')
+ assert 'collections' not in res.json[
+ 'schema']['properties']['metadata']['propertiesOrder']
+
+ # Moderator with dedicated organisation
+ login_user_via_session(client, email=moderator_dedicated['email'])
+ res = client.get(url_for('sonar.schemas', record_type='deposits'))
+ assert res.status_code == 200
+ assert res.json[
+ 'schema']['properties']['metadata']['properties'].get('collections')
+ assert 'collections' in res.json[
+ 'schema']['properties']['metadata']['propertiesOrder']
+ assert res.json[
+ 'schema']['properties']['diffusion']['properties'].get('subdivisions')
+ assert 'subdivisions' in res.json[
'schema']['properties']['diffusion']['propertiesOrder']