Skip to content

Commit

Permalink
schemas: remove fields on documents and deposits
Browse files Browse the repository at this point in the history
Move the schema processing to dedicated classes.

* Removes collections and subdivisions on documents and deposits schema.
* Closes #752.

Co-Authored-by: Bertrand Zuchuat <bertrand.zuchuat@rero.ch>
  • Loading branch information
Garfield-fr committed Feb 9, 2022
1 parent cb7fad2 commit 091073a
Show file tree
Hide file tree
Showing 9 changed files with 318 additions and 85 deletions.
31 changes: 25 additions & 6 deletions sonar/json_schemas/deposits_json_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
53 changes: 53 additions & 0 deletions sonar/json_schemas/documents_json_schema.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

"""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
10 changes: 9 additions & 1 deletion sonar/json_schemas/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
42 changes: 42 additions & 0 deletions sonar/json_schemas/organisations_json_schema.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

"""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
44 changes: 44 additions & 0 deletions sonar/json_schemas/projects_json_schema.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

"""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
60 changes: 60 additions & 0 deletions sonar/json_schemas/users_json_schema.py
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.

"""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
50 changes: 0 additions & 50 deletions sonar/theme/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 18 additions & 8 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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."""
Expand All @@ -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'
Expand Down Expand Up @@ -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):
Expand Down
Loading

0 comments on commit 091073a

Please sign in to comment.