From ae64de668d85291e28bbcfbe36613c7d01b1612a Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Tue, 16 Apr 2024 12:54:10 +0200 Subject: [PATCH 1/3] Fix token retrieval for invenio Do not force to use the Vault and rely on the config template value. --- lib/galaxy/files/sources/_rdm.py | 34 +++++++++++--------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/lib/galaxy/files/sources/_rdm.py b/lib/galaxy/files/sources/_rdm.py index fb33cf444579..4f841871974c 100644 --- a/lib/galaxy/files/sources/_rdm.py +++ b/lib/galaxy/files/sources/_rdm.py @@ -1,6 +1,5 @@ import logging from typing import ( - cast, List, NamedTuple, Optional, @@ -138,11 +137,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 +148,6 @@ def __init__(self, **kwd: Unpack[FilesSourceProperties]): 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 +184,19 @@ def get_error_msg(details: str) -> str: 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 From c02750ec7e4a8c314aa28d545b8844c228e7e41a Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:10:53 +0200 Subject: [PATCH 2/3] Fix public_name retrieval for invenio --- lib/galaxy/files/sources/_rdm.py | 9 ++++++++- lib/galaxy/files/sources/invenio.py | 30 +++++++++++++++++------------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/lib/galaxy/files/sources/_rdm.py b/lib/galaxy/files/sources/_rdm.py index 4f841871974c..14f7e9e1daa0 100644 --- a/lib/galaxy/files/sources/_rdm.py +++ b/lib/galaxy/files/sources/_rdm.py @@ -25,6 +25,7 @@ class RDMFilesSourceProperties(FilesSourceProperties): url: str token: str + public_name: str class RecordFilename(NamedTuple): @@ -79,7 +80,9 @@ def get_files_in_record( """ 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. @@ -200,3 +203,7 @@ def get_authorization_token(self, user_context: OptionalUserContext) -> str: f"Please provide a personal access token in your user's preferences for '{self.label}'" ) return token + + def get_public_name(self, user_context: OptionalUserContext) -> Optional[str]: + effective_props = self._serialization_props(user_context) + return effective_props.get("public_name") diff --git a/lib/galaxy/files/sources/invenio.py b/lib/galaxy/files/sources/invenio.py index 3ddf4fee107b..6e22f4107e7c 100644 --- a/lib/galaxy/files/sources/invenio.py +++ b/lib/galaxy/files/sources/invenio.py @@ -135,7 +135,8 @@ def _create_entry( 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 @@ def get_files_in_record( 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 @@ def _get_record_files_from_response(self, record_id: str, response: dict) -> Lis ) 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 @@ def _get_creator_from_user_context(self, user_context: OptionalUserContext): 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 From 133730c221ddd308c3e13108342c91896033c1e6 Mon Sep 17 00:00:00 2001 From: davelopez <46503462+davelopez@users.noreply.github.com> Date: Tue, 16 Apr 2024 14:24:52 +0200 Subject: [PATCH 3/3] Fix sample file source for Invenio --- lib/galaxy/config/sample/file_sources_conf.yml.sample | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/galaxy/config/sample/file_sources_conf.yml.sample b/lib/galaxy/config/sample/file_sources_conf.yml.sample index 76b1a8616903..b21bb1339b60 100644 --- a/lib/galaxy/config/sample/file_sources_conf.yml.sample +++ b/lib/galaxy/config/sample/file_sources_conf.yml.sample @@ -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