datasette-secrets 0.1a4__tar.gz → 0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of datasette-secrets might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: datasette-secrets
3
- Version: 0.1a4
3
+ Version: 0.2
4
4
  Summary: Manage secrets such as API keys for use with other Datasette plugins
5
5
  Author: Datasette
6
6
  License: Apache-2.0
@@ -13,11 +13,12 @@ Classifier: License :: OSI Approved :: Apache Software License
13
13
  Requires-Python: >=3.8
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
- Requires-Dist: datasette>=1.0a13
16
+ Requires-Dist: datasette
17
17
  Requires-Dist: cryptography
18
18
  Provides-Extra: test
19
19
  Requires-Dist: pytest; extra == "test"
20
20
  Requires-Dist: pytest-asyncio; extra == "test"
21
+ Requires-Dist: datasette-test>=0.3.2; extra == "test"
21
22
 
22
23
  # datasette-secrets
23
24
 
@@ -1,7 +1,7 @@
1
1
  import click
2
2
  from cryptography.fernet import Fernet
3
3
  import dataclasses
4
- from datasette import hookimpl, Forbidden, Permission, Response
4
+ from datasette import hookimpl, Forbidden, Response
5
5
  from datasette.plugins import pm
6
6
  from datasette.utils import await_me_maybe, sqlite3
7
7
  import os
@@ -89,7 +89,7 @@ create table if not exists datasette_secrets (
89
89
  def get_database(datasette):
90
90
  plugin_config = datasette.plugin_config("datasette-secrets") or {}
91
91
  database = plugin_config.get("database") or "_internal"
92
- if database == "_internal":
92
+ if database == "_internal" and hasattr(datasette, "get_internal_database"):
93
93
  return datasette.get_internal_database()
94
94
  return datasette.get_database(database)
95
95
 
@@ -108,6 +108,8 @@ def get_config(datasette):
108
108
 
109
109
  @hookimpl
110
110
  def register_permissions(datasette):
111
+ from datasette import Permission
112
+
111
113
  return [
112
114
  Permission(
113
115
  name="manage-secrets",
@@ -187,15 +189,22 @@ async def secrets_index(datasette, request):
187
189
  )
188
190
  existing_secrets = {row["name"]: dict(row) for row in existing_secrets_result.rows}
189
191
  # Try to turn updated_by into actors
190
- actors = await datasette.actors_from_ids(
191
- {row["updated_by"] for row in existing_secrets.values() if row["updated_by"]}
192
- )
193
- for secret in existing_secrets.values():
194
- if secret["updated_by"]:
195
- actor = actors.get(secret["updated_by"])
196
- if actor:
197
- display = actor.get("username") or actor.get("name") or actor.get("id")
198
- secret["updated_by"] = display
192
+ if hasattr(datasette, "actors_from_ids"):
193
+ actors = await datasette.actors_from_ids(
194
+ {
195
+ row["updated_by"]
196
+ for row in existing_secrets.values()
197
+ if row["updated_by"]
198
+ }
199
+ )
200
+ for secret in existing_secrets.values():
201
+ if secret["updated_by"]:
202
+ actor = actors.get(secret["updated_by"])
203
+ if actor:
204
+ display = (
205
+ actor.get("username") or actor.get("name") or actor.get("id")
206
+ )
207
+ secret["updated_by"] = display
199
208
  unset_secrets = [
200
209
  secret
201
210
  for secret in all_secrets
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: datasette-secrets
3
- Version: 0.1a4
3
+ Version: 0.2
4
4
  Summary: Manage secrets such as API keys for use with other Datasette plugins
5
5
  Author: Datasette
6
6
  License: Apache-2.0
@@ -13,11 +13,12 @@ Classifier: License :: OSI Approved :: Apache Software License
13
13
  Requires-Python: >=3.8
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
- Requires-Dist: datasette>=1.0a13
16
+ Requires-Dist: datasette
17
17
  Requires-Dist: cryptography
18
18
  Provides-Extra: test
19
19
  Requires-Dist: pytest; extra == "test"
20
20
  Requires-Dist: pytest-asyncio; extra == "test"
21
+ Requires-Dist: datasette-test>=0.3.2; extra == "test"
21
22
 
22
23
  # datasette-secrets
23
24
 
@@ -1,6 +1,7 @@
1
- datasette>=1.0a13
1
+ datasette
2
2
  cryptography
3
3
 
4
4
  [test]
5
5
  pytest
6
6
  pytest-asyncio
7
+ datasette-test>=0.3.2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datasette-secrets"
3
- version = "0.1a4"
3
+ version = "0.2"
4
4
  description = "Manage secrets such as API keys for use with other Datasette plugins"
5
5
  readme = "README.md"
6
6
  authors = [{name = "Datasette"}]
@@ -11,7 +11,7 @@ classifiers=[
11
11
  ]
12
12
  requires-python = ">=3.8"
13
13
  dependencies = [
14
- "datasette>=1.0a13",
14
+ "datasette",
15
15
  "cryptography"
16
16
  ]
17
17
 
@@ -25,7 +25,7 @@ CI = "https://github.com/datasette/datasette-secrets/actions"
25
25
  secrets = "datasette_secrets"
26
26
 
27
27
  [project.optional-dependencies]
28
- test = ["pytest", "pytest-asyncio"]
28
+ test = ["pytest", "pytest-asyncio", "datasette-test>=0.3.2"]
29
29
 
30
30
  [tool.pytest.ini_options]
31
31
  asyncio_mode = "strict"
@@ -1,9 +1,9 @@
1
1
  from click.testing import CliRunner
2
2
  from cryptography.fernet import Fernet
3
3
  from datasette import hookimpl
4
- from datasette.app import Datasette
5
4
  from datasette.cli import cli
6
5
  from datasette.plugins import pm
6
+ from datasette_test import Datasette, actor_cookie
7
7
  from datasette_secrets import get_secret, Secret, startup, get_config
8
8
  import pytest
9
9
  from unittest.mock import ANY
@@ -11,6 +11,13 @@ from unittest.mock import ANY
11
11
  TEST_ENCRYPTION_KEY = "-LujHtwFWGaBpznrV1zduoZBmCnMOW7J0H5hmeXgAVo="
12
12
 
13
13
 
14
+ def get_internal_database(ds):
15
+ if hasattr(ds, "get_internal_database"):
16
+ return ds.get_internal_database()
17
+ else:
18
+ return ds.get_database("_internal")
19
+
20
+
14
21
  def test_generate_command():
15
22
  runner = CliRunner()
16
23
  result = runner.invoke(cli, ["secrets", "generate-encryption-key"])
@@ -89,15 +96,13 @@ def register_multiple_secrets():
89
96
  @pytest.fixture
90
97
  def ds():
91
98
  return Datasette(
92
- config={
93
- "plugins": {
94
- "datasette-secrets": {
95
- "database": "_internal",
96
- "encryption-key": TEST_ENCRYPTION_KEY,
97
- }
98
- },
99
- "permissions": {"manage-secrets": {"id": "admin"}},
100
- }
99
+ plugin_config={
100
+ "datasette-secrets": {
101
+ "database": "_internal",
102
+ "encryption-key": TEST_ENCRYPTION_KEY,
103
+ }
104
+ },
105
+ permissions={"manage-secrets": {"id": "admin"}},
101
106
  )
102
107
 
103
108
 
@@ -115,7 +120,7 @@ async def test_permissions(ds, path, verb, data, user):
115
120
  kwargs = {}
116
121
  if user:
117
122
  kwargs["cookies"] = {
118
- "ds_actor": ds.client.actor_cookie({"id": user}),
123
+ "ds_actor": actor_cookie(ds, {"id": user}),
119
124
  }
120
125
  if data:
121
126
  kwargs["data"] = data
@@ -131,7 +136,7 @@ async def test_permissions(ds, path, verb, data, user):
131
136
 
132
137
  @pytest.mark.asyncio
133
138
  async def test_set_secret(ds, use_actors_plugin):
134
- cookies = {"ds_actor": ds.client.actor_cookie({"id": "admin"})}
139
+ cookies = {"ds_actor": actor_cookie(ds, {"id": "admin"})}
135
140
  get_response = await ds.client.get("/-/secrets/EXAMPLE_SECRET", cookies=cookies)
136
141
  csrftoken = get_response.cookies["ds_csrftoken"]
137
142
  cookies["ds_csrftoken"] = csrftoken
@@ -142,7 +147,7 @@ async def test_set_secret(ds, use_actors_plugin):
142
147
  )
143
148
  assert post_response.status_code == 302
144
149
  assert post_response.headers["Location"] == "/-/secrets"
145
- internal_db = ds.get_internal_database()
150
+ internal_db = get_internal_database(ds)
146
151
  secrets = await internal_db.execute("select * from datasette_secrets")
147
152
  rows = [dict(r) for r in secrets.rows]
148
153
  assert rows == [
@@ -174,7 +179,12 @@ async def test_set_secret(ds, use_actors_plugin):
174
179
  assert response.status_code == 200
175
180
  assert "EXAMPLE_SECRET" in response.text
176
181
  assert "new-note" in response.text
177
- assert "<td>ADMIN</td>" in response.text
182
+
183
+ if hasattr(ds, "actors_from_ids"):
184
+ assert "<td>ADMIN</td>" in response.text
185
+ else:
186
+ # Pre 1.0, so can't use that mechanism
187
+ assert "<td>admin</td>" in response.text
178
188
 
179
189
  # Now let's edit it
180
190
  post_response2 = await ds.client.post(
@@ -213,11 +223,11 @@ async def test_set_secret(ds, use_actors_plugin):
213
223
  @pytest.mark.asyncio
214
224
  async def test_get_secret(ds, monkeypatch):
215
225
  # First set it manually
216
- cookies = {"ds_actor": ds.client.actor_cookie({"id": "admin"})}
226
+ cookies = {"ds_actor": actor_cookie(ds, {"id": "admin"})}
217
227
  get_response = await ds.client.get("/-/secrets/EXAMPLE_SECRET", cookies=cookies)
218
228
  csrftoken = get_response.cookies["ds_csrftoken"]
219
229
  cookies["ds_csrftoken"] = csrftoken
220
- db = ds.get_internal_database()
230
+ db = get_internal_database(ds)
221
231
  # Reset state
222
232
  await db.execute_write(
223
233
  "update datasette_secrets set last_used_at = null, last_used_by = null"
@@ -288,7 +298,7 @@ async def test_secret_index_page(ds, register_multiple_secrets):
288
298
  response = await ds.client.get(
289
299
  "/-/secrets",
290
300
  cookies={
291
- "ds_actor": ds.client.actor_cookie({"id": "admin"}),
301
+ "ds_actor": actor_cookie(ds, {"id": "admin"}),
292
302
  },
293
303
  )
294
304
  assert response.status_code == 200