Make sure filesources can access user level and app level vaults

This commit is contained in:
Nuwan Goonasekera
2021-11-28 06:56:35 +05:30
parent 569db6b465
commit 76951a4bda
4 changed files with 125 additions and 3 deletions
+14 -3
View File
@@ -264,10 +264,17 @@ class ProvidesUserFileSourcesUserContext:
return self.trans.user_is_admin
@property
def vault(self):
def user_vault(self):
"""User vault namespace"""
user_vault = self.trans.user_vault
return user_vault or defaultdict(lambda: None)
@property
def app_vault(self):
"""App vault namespace"""
vault = self.trans.app.vault
return vault or defaultdict(lambda: None)
class DictFileSourcesUserContext:
@@ -303,5 +310,9 @@ class DictFileSourcesUserContext:
return self._kwd.get("is_admin")
@property
def vault(self):
return self._kwd.get("vault")
def user_vault(self):
return self._kwd.get("user_vault")
@property
def app_vault(self):
return self._kwd.get("app_vault")
@@ -0,0 +1,8 @@
- type: posix
id: test_user_vault
root: ${user.user_vault.read_secret('posix/root_path')}
label: a user level test path
- type: posix
id: test_app_vault
root: ${user.app_vault.read_secret('posix/root_path')}
label: an app level test path
@@ -0,0 +1,90 @@
import os
import tempfile
from galaxy.security.vault import UserVaultWrapper
from galaxy_test.base import api_asserts
from galaxy_test.driver import integration_util
SCRIPT_DIRECTORY = os.path.abspath(os.path.dirname(__file__))
FILE_SOURCES_VAULT_CONF = os.path.join(SCRIPT_DIRECTORY, "file_sources_conf_vault.yml")
VAULT_CONF = os.path.join(SCRIPT_DIRECTORY, "vault_conf.yml")
class VaultFileSourceIntegrationTestCase(integration_util.IntegrationTestCase):
USER_1_APP_VAULT_ENTRY = "randomvaultuser1@universe.com"
USER_2_APP_VAULT_ENTRY = "randomvaultuser2@universe.com"
@classmethod
def handle_galaxy_config_kwds(cls, config):
config["file_sources_config_file"] = FILE_SOURCES_VAULT_CONF
config["vault_config_file"] = VAULT_CONF
config["user_library_import_symlink_allowlist"] = os.path.realpath(tempfile.mkdtemp())
def test_vault_secret_per_user_in_file_source(self):
"""
This file source performs a user vault lookup. The secret stored for the first user is a
valid path and should succeed, while the second user's stored secret should fail.
"""
with self._different_user(email=self.USER_1_APP_VAULT_ENTRY):
app = self._app
user = app.model.context.query(app.model.User).filter(
app.model.User.email == self.USER_1_APP_VAULT_ENTRY).first()
user_vault = UserVaultWrapper(self._app.vault, user)
# use a valid symlink path so the posix list succeeds
user_vault.write_secret('posix/root_path', app.config.user_library_import_symlink_allowlist[0])
data = {"target": "gxfiles://test_user_vault"}
list_response = self.galaxy_interactor.get("remote_files", data)
api_asserts.assert_status_code_is_ok(list_response)
remote_files = list_response.json()
print(remote_files)
with self._different_user(email=self.USER_2_APP_VAULT_ENTRY):
app = self._app
user = app.model.context.query(app.model.User).filter(
app.model.User.email == self.USER_2_APP_VAULT_ENTRY).first()
user_vault = UserVaultWrapper(self._app.vault, user)
# use an invalid symlink path so the posix list fails
user_vault.write_secret('posix/root_path', '/invalid/root')
data = {"target": "gxfiles://test_user_vault"}
list_response = self.galaxy_interactor.get("remote_files", data)
api_asserts.assert_status_code_is(list_response, 404)
def test_vault_secret_per_app_in_file_source(self):
"""
This file source performs an app level vault lookup. Although the secret stored for the first user is a
valid path and the second user's stored secret is invalid, we are performing an app level lookup
which should succeed for both users.
"""
# write app level secret
app = self._app
# use a valid symlink path so the posix list succeeds
app.vault.write_secret('posix/root_path', app.config.user_library_import_symlink_allowlist[0])
with self._different_user(email=self.USER_1_APP_VAULT_ENTRY):
user = app.model.context.query(app.model.User).filter(
app.model.User.email == self.USER_1_APP_VAULT_ENTRY).first()
user_vault = UserVaultWrapper(self._app.vault, user)
# use a valid symlink path so the posix list succeeds
user_vault.write_secret('posix/root_path', app.config.user_library_import_symlink_allowlist[0])
data = {"target": "gxfiles://test_app_vault"}
list_response = self.galaxy_interactor.get("remote_files", data)
api_asserts.assert_status_code_is_ok(list_response)
remote_files = list_response.json()
print(remote_files)
with self._different_user(email=self.USER_2_APP_VAULT_ENTRY):
user = app.model.context.query(app.model.User).filter(
app.model.User.email == self.USER_2_APP_VAULT_ENTRY).first()
user_vault = UserVaultWrapper(self._app.vault, user)
# use an invalid symlink path so the posix list would fail if used
user_vault.write_secret('posix/root_path', '/invalid/root')
data = {"target": "gxfiles://test_app_vault"}
list_response = self.galaxy_interactor.get("remote_files", data)
api_asserts.assert_status_code_is_ok(list_response)
remote_files = list_response.json()
print(remote_files)
+13
View File
@@ -0,0 +1,13 @@
type: database
# Encryption keys must be valid fernet keys
# To generate a valid key:
# >>> from cryptography.fernet import Fernet
# >>> Fernet.generate_key()
# b'pZDP8_baVs3oWT4597HJWCysm49j-XELONQ-EdoU0DE='
#
# Use the ascii string value as a key
# For more details, see: https://cryptography.io/en/latest/fernet/#
encryption_keys:
- 5RrT94ji178vQwha7TAmEix7DojtsLlxVz8Ef17KWgg=
- iNdXd7tRjLnSqRHxuhqQ98GTLU8HUbd5_Xx38iF8nZ0=
- IK83IXhE4_7W7xCFEtD9op0BAs11pJqYN236Spppp7g=