Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

moderation: add 'verified' field to records #1399

Merged
merged 2 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions invenio_rdm_records/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ def always_valid(identifier):
},
}

RDM_SEARCH_SORT_BY_VERIFIED = False
"""Sort records by 'verified' first."""

RDM_SORT_OPTIONS = {
"bestmatch": dict(
title=_("Best match"),
Expand Down
5 changes: 5 additions & 0 deletions invenio_rdm_records/records/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
PIDStatusCheckField,
)
from invenio_requests.records.api import Request
from invenio_requests.records.dumpers import CalculatedFieldDumperExt
from invenio_requests.records.systemfields.relatedrecord import RelatedRecord
from invenio_vocabularies.contrib.affiliations.api import Affiliation
from invenio_vocabularies.contrib.awards.api import Award
Expand All @@ -47,6 +48,7 @@
)
from .systemfields import (
HasDraftCheckField,
IsVerifiedField,
ParentRecordAccessField,
RecordAccessField,
RecordDeletionStatusField,
Expand All @@ -68,6 +70,7 @@ class RDMParent(ParentRecordBase):
dumper = SearchDumper(
extensions=[
GrantTokensDumperExt("access.grant_tokens"),
CalculatedFieldDumperExt("is_verified"),
]
)

Expand All @@ -87,6 +90,8 @@ class RDMParent(ParentRecordBase):

pids = DictField("pids")

is_verified = IsVerifiedField("is_verified")


#
# Common properties between records and drafts.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"review": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"created": {
"type": "date"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"permission_flags": {
"type": "object",
"dynamic": true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"review": {
"type": "object",
"properties": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"created": {
"type": "date"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"communities": {
"properties": {
"ids": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"communities": {
"properties": {
"ids": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
"id" : {
"type" : "keyword"
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"access": {
"properties" : {
"owned_by" : {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"created": {
"type": "date"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,9 @@
}
}
},
"is_verified": {
"type": "boolean"
},
"communities": {
"properties": {
"ids": {
Expand Down
2 changes: 2 additions & 0 deletions invenio_rdm_records/records/systemfields/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
from .deletion_status import RecordDeletionStatusField
from .draft_status import DraftStatus
from .has_draftcheck import HasDraftCheckField
from .is_verified import IsVerifiedField
from .statistics import RecordStatisticsField
from .tombstone import TombstoneField

__all__ = (
"DraftStatus",
"HasDraftCheckField",
"IsVerifiedField",
"ParentRecordAccessField",
"RecordAccessField",
"RecordStatisticsField",
Expand Down
24 changes: 24 additions & 0 deletions invenio_rdm_records/records/systemfields/is_verified.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2023 CERN.
#
# Invenio-RDM-Records is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
"""Record 'verified' system field."""

from invenio_records_resources.records.systemfields.calculated import CalculatedField


class IsVerifiedField(CalculatedField):
"""Systemfield for calculating whether or not the request is expired."""

def __init__(self, key=None):
"""Constructor."""
super().__init__(key=key, use_cache=False)

def calculate(self, record):
"""Calculate the ``is_verified`` property of the record."""
owner = record.access.owner.resolve()
if not owner:
return False
return owner.verified_at is not None
4 changes: 2 additions & 2 deletions invenio_rdm_records/requests/user_moderation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
# it under the terms of the MIT License; see LICENSE file for more details.
"""User moderation actions specific to RDM-Records."""

from .actions import on_block, on_restore
from .actions import on_approve, on_block, on_restore

__all__ = ("on_block", "on_restore")
__all__ = ("on_approve", "on_block", "on_restore")
17 changes: 17 additions & 0 deletions invenio_rdm_records/requests/user_moderation/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
# it under the terms of the MIT License; see LICENSE file for more details.
"""RDM user moderation action."""

from invenio_access.permissions import system_identity

from invenio_rdm_records.proxies import current_rdm_records_service


def on_block(user_id, uow=None, **kwargs):
"""Removes records that belong to a user."""
Expand All @@ -15,3 +19,16 @@ def on_block(user_id, uow=None, **kwargs):
def on_restore(user_id, uow=None, **kwargs):
"""Restores records that belong to a user."""
pass


def on_approve(user_id, uow=None, **kwargs):
"""Execute on user approve.

Re-index user records and dump verified field into records.
"""
from invenio_search.engine import dsl

user_records_q = dsl.Q("term", **{"parent.access.owned_by.user": user_id})
current_rdm_records_service.reindex_latest_first(
identity=system_identity, extra_filter=user_records_q, uow=uow
)
16 changes: 16 additions & 0 deletions invenio_rdm_records/services/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
is_draft,
is_record,
)
from invenio_drafts_resources.services.records.search_params import AllVersionsParam
from invenio_indexer.api import RecordIndexer
from invenio_records_resources.services import ConditionalLink, FileServiceConfig
from invenio_records_resources.services.base.config import (
Expand All @@ -47,6 +48,11 @@
RecordLink,
pagination_links,
)
from invenio_records_resources.services.records.params import (
FacetsParam,
PaginationParam,
QueryStrParam,
)
from invenio_requests.services.requests import RequestItem, RequestList
from invenio_requests.services.requests.config import RequestSearchOptions
from requests import Request
Expand Down Expand Up @@ -75,6 +81,7 @@
from .schemas.parent.access import Grant as GrantSchema
from .schemas.parent.access import SecretLink as SecretLinkSchema
from .schemas.record_communities import RecordCommunitiesSchema
from .sort import VerifiedRecordsSortParam


def is_draft_and_has_review(record, ctx):
Expand Down Expand Up @@ -126,6 +133,15 @@ class RDMSearchOptions(SearchOptions, SearchOptionsMixin):
"access_status": facets.access_status,
}

# Override params interpreters to avoid having duplicated SortParam.
params_interpreters_cls = [
AllVersionsParam.factory("versions.is_latest"),
QueryStrParam,
PaginationParam,
FacetsParam,
VerifiedRecordsSortParam,
]


class RDMSearchDraftsOptions(SearchDraftsOptions, SearchOptionsMixin):
"""Search options for drafts search."""
Expand Down
1 change: 1 addition & 0 deletions invenio_rdm_records/services/schemas/parent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class RDMParentSchema(ParentSchema, FieldPermissionsMixin):
values=fields.Nested(PIDSchema),
dump_only=True,
)
is_verified = fields.Boolean(dump_only=True)
alejandromumo marked this conversation as resolved.
Show resolved Hide resolved

# TODO: move to a reusable place (taken from records-resources)
@pre_load
Expand Down
26 changes: 26 additions & 0 deletions invenio_rdm_records/services/sort.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
#
# Copyright (C) 2023 CERN.
#
# Invenio-RDM-Records is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.
"""Sort parameter interpreter API."""

from flask import current_app
from invenio_records_resources.services.records.params.sort import SortParam


class VerifiedRecordsSortParam(SortParam):
"""Evaluate the 'sort' parameter for RDM records."""

def apply(self, identity, search, params):
"""Evaluate the sort parameter on the search.

If the config "RDM_SEARCH_SORT_BY_VERIFIED" is set, then all the sorting is
prepended by the record's `is_verified` property.
"""
if current_app.config["RDM_SEARCH_SORT_BY_VERIFIED"]:
fields = self._compute_sort_fields(params)
fields.insert(0, "-parent.is_verified")
return search.sort(*fields)
return super().apply(identity, search, params)
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ invenio_oauth2server.scopes =
invenio_users_resources.moderation.actions =
block = invenio_rdm_records.requests.user_moderation.actions:on_block
restore = invenio_rdm_records.requests.user_moderation.actions:on_restore
approve = invenio_rdm_records.requests.user_moderation.actions:on_approve

[build_sphinx]
source-dir = docs/
Expand Down
Loading
Loading