Unverified Commit 6a280805 authored by David López's avatar David López Committed by GitHub
Browse files

Merge pull request #17997 from davelopez/23.2_invenio_plugin_fixes

[23.2] Invenio plugin fixes
parents c36005b7 133730c2
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -199,10 +199,14 @@
  doc: Make sure to define this generic drs file source if you have defined any other drs file sources, or stock drs download capability will be disabled.

- type: inveniordm
  id: invenio
  doc: Invenio RDM turn-key research data management repository
  label: Invenio RDM Demo Repository
  id: invenio_sandbox
  doc: This is the Sandbox instance of Invenio. It is used for testing purposes only, content is NOT preserved. DOIs created in this instance are not real and will not resolve.
  label: Invenio RDM Sandbox Repository (TESTING ONLY)
  url: https://inveniordm.web.cern.ch/
  token: ${user.user_vault.read_secret('preferences/invenio_sandbox/token')}
  # token: ${user.preferences['invenio_sandbox|token']} # Alternatively use this for retrieving the token from user preferences instead of the Vault
  public_name: ${user.preferences['invenio_sandbox|public_name']}
  writable: true

- type: onedata
  id: onedata1
+18 −23
Original line number Diff line number Diff line
import logging
from typing import (
    cast,
    List,
    NamedTuple,
    Optional,
@@ -26,6 +25,7 @@ OptionalUserContext = Optional[ProvidesUserFileSourcesUserContext]
class RDMFilesSourceProperties(FilesSourceProperties):
    url: str
    token: str
    public_name: str


class RecordFilename(NamedTuple):
@@ -80,7 +80,9 @@ class RDMRepositoryInteractor:
        """
        raise NotImplementedError()

    def create_draft_record(self, title: str, user_context: OptionalUserContext = None):
    def create_draft_record(
        self, title: str, public_name: Optional[str] = None, user_context: OptionalUserContext = None
    ):
        """Creates a draft record (directory) in the repository with basic metadata.

        The metadata is usually just the title of the record and the user that created it.
@@ -138,11 +140,10 @@ class RDMFilesSource(BaseFilesSource):

    def __init__(self, **kwd: Unpack[FilesSourceProperties]):
        props = self._parse_common_config_opts(kwd)
        base_url = props.get("url", None)
        base_url = props.get("url")
        if not base_url:
            raise Exception("URL for RDM repository must be provided in configuration")
        self._repository_url = base_url
        self._token = props.get("token", None)
        self._props = props
        self._repository_interactor = self.get_repository_interactor(base_url)

@@ -150,10 +151,6 @@ class RDMFilesSource(BaseFilesSource):
    def repository(self) -> RDMRepositoryInteractor:
        return self._repository_interactor

    @property
    def token(self) -> Optional[str]:
        return self._token if self._token and not self._token.startswith("$") else None

    def get_repository_interactor(self, repository_url: str) -> RDMRepositoryInteractor:
        """Returns an interactor compatible with the given repository URL.

@@ -190,25 +187,23 @@ class RDMFilesSource(BaseFilesSource):
    def get_record_id_from_path(self, source_path: str) -> str:
        return self.parse_path(source_path, record_id_only=True).record_id

    def _serialization_props(self, user_context: OptionalUserContext = None) -> RDMFilesSourceProperties:
    def _serialization_props(self, user_context: OptionalUserContext = None):
        effective_props = {}
        for key, val in self._props.items():
            effective_props[key] = self._evaluate_prop(val, user_context=user_context)
        effective_props["url"] = self._repository_url
        effective_props["token"] = self.safe_get_authorization_token(user_context)
        return cast(RDMFilesSourceProperties, effective_props)
        return effective_props

    def get_authorization_token(self, user_context: OptionalUserContext) -> str:
        token = self.token
        if not token and user_context:
            vault = user_context.user_vault if user_context else None
            token = vault.read_secret(f"preferences/{self.id}/token") if vault else None
        if token is None:
            raise AuthenticationRequired(f"No authorization token provided in user's settings for '{self.label}'")
        token = None
        if user_context:
            effective_props = self._serialization_props(user_context)
            token = effective_props.get("token")
        if not token:
            raise AuthenticationRequired(
                f"Please provide a personal access token in your user's preferences for '{self.label}'"
            )
        return token

    def safe_get_authorization_token(self, user_context: OptionalUserContext) -> Optional[str]:
        try:
            return self.get_authorization_token(user_context)
        except AuthenticationRequired:
            return None
    def get_public_name(self, user_context: OptionalUserContext) -> Optional[str]:
        effective_props = self._serialization_props(user_context)
        return effective_props.get("public_name")
+18 −12
Original line number Diff line number Diff line
@@ -135,7 +135,8 @@ class InvenioRDMFilesSource(RDMFilesSource):
        user_context: OptionalUserContext = None,
        opts: Optional[FilesSourceOptions] = None,
    ) -> Entry:
        record = self.repository.create_draft_record(entry_data["name"], user_context=user_context)
        public_name = self.get_public_name(user_context)
        record = self.repository.create_draft_record(entry_data["name"], public_name, user_context=user_context)
        return {
            "uri": self.repository.to_plugin_uri(record["id"]),
            "name": record["metadata"]["title"],
@@ -198,9 +199,11 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
        response_data = self._get_response(user_context, request_url)
        return self._get_record_files_from_response(record_id, response_data)

    def create_draft_record(self, title: str, user_context: OptionalUserContext = None) -> RemoteDirectory:
    def create_draft_record(
        self, title: str, public_name: Optional[str] = None, user_context: OptionalUserContext = None
    ) -> RemoteDirectory:
        today = datetime.date.today().isoformat()
        creator = self._get_creator_from_user_context(user_context)
        creator = self._get_creator_from_public_name(public_name)
        create_record_request = {
            "files": {"enabled": True},
            "metadata": {
@@ -360,10 +363,9 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
                )
        return rval

    def _get_creator_from_user_context(self, user_context: OptionalUserContext):
        public_name = self.get_user_preference_by_key("public_name", user_context)
        family_name = "Galaxy User"
    def _get_creator_from_public_name(self, public_name: Optional[str] = None) -> Creator:
        given_name = "Anonymous"
        family_name = "Galaxy User"
        if public_name:
            tokens = public_name.split(", ")
            if len(tokens) == 2:
@@ -371,12 +373,16 @@ class InvenioRepositoryInteractor(RDMRepositoryInteractor):
                given_name = tokens[1]
            else:
                given_name = public_name
        return {"person_or_org": {"family_name": family_name, "given_name": given_name, "type": "personal"}}

    def get_user_preference_by_key(self, key: str, user_context: OptionalUserContext):
        preferences = user_context.preferences if user_context else None
        value = preferences.get(f"{self.plugin.id}|{key}", None) if preferences else None
        return value
        return {
            "person_or_org": {
                "name": f"{given_name} {family_name}",
                "family_name": family_name,
                "given_name": given_name,
                "type": "personal",
                "identifiers": [],
            },
            "affiliations": [],
        }

    def _get_response(
        self, user_context: OptionalUserContext, request_url: str, params: Optional[Dict[str, Any]] = None