diff --git a/datasette/app.py b/datasette/app.py index 16a29e20..70bd3c12 100644 --- a/datasette/app.py +++ b/datasette/app.py @@ -268,7 +268,16 @@ class Datasette: ) if plugins is None: return None - return plugins.get(plugin_name) + plugin_config = plugins.get(plugin_name) + # Resolve any $file and $env keys + if isinstance(plugin_config, dict): + for key, value in plugin_config.items(): + if isinstance(value, dict): + if list(value.keys()) == ["$env"]: + plugin_config[key] = os.environ.get(list(value.values())[0]) + elif list(value.keys()) == ["$file"]: + plugin_config[key] = open(list(value.values())[0]).read() + return plugin_config def app_css_hash(self): if not hasattr(self, "_app_css_hash"): diff --git a/tests/fixtures.py b/tests/fixtures.py index fab6509e..8903d02b 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -97,6 +97,7 @@ def make_app_client( memory=False, config=None, filename="fixtures.db", + metadata=None, is_immutable=False, extra_databases=None, inspect_data=None, @@ -139,7 +140,7 @@ def make_app_client( immutables=immutables, memory=memory, cors=cors, - metadata=METADATA, + metadata=metadata or METADATA, plugins_dir=plugins_dir, config=config, inspect_data=inspect_data, diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 9bdd491a..58e7fe7c 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,7 +1,8 @@ from bs4 import BeautifulSoup as Soup -from .fixtures import app_client # noqa +from .fixtures import app_client, make_app_client # noqa import base64 import json +import os import re import pytest import urllib @@ -125,6 +126,24 @@ def test_plugin_config(app_client): assert None is app_client.ds.plugin_config("unknown-plugin") +def test_plugin_config_env(): + os.environ["FOO_ENV"] = "FROM_ENVIRONMENT" + for client in make_app_client( + metadata={"plugins": {"env-plugin": {"foo": {"$env": "FOO_ENV"}}}} + ): + assert {"foo": "FROM_ENVIRONMENT"} == client.ds.plugin_config("env-plugin") + del os.environ["FOO_ENV"] + + +def test_plugin_config_file(tmpdir): + filepath = str(tmpdir / "secret-file") + open(filepath, "w").write("FROM_FILE") + for client in make_app_client( + metadata={"plugins": {"file-plugin": {"foo": {"$file": filepath}}}} + ): + assert {"foo": "FROM_FILE"} == client.ds.plugin_config("file-plugin") + + @pytest.mark.parametrize( "path,expected_extra_body_script", [