Skip to content

Commit be9a434

Browse files
committed
Merge branch 'main' into fix-database-settings
2 parents 4dca8a9 + 98466e2 commit be9a434

File tree

12 files changed

+116
-9
lines changed

12 files changed

+116
-9
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Write the date in place of the "Unreleased" in the case a new version is release
99

1010
- Optional `persist` query parameter to PUT and PATCH /array/... routes, and
1111
the corresponding DaskArrayClient methods: `write`, `write_block`, `patch`.
12+
- Added new delete:node and delete:revision scopes
1213

1314
### Changed
1415

@@ -17,6 +18,13 @@ Write the date in place of the "Unreleased" in the case a new version is release
1718
manage the deployment and associated certificates.) **The demo remains
1819
world-public, with no login required.** This change affects some
1920
documentation and one test.
21+
- Deletion of nodes or metadata revisions now requires deletion scopes,
22+
rather than writing scopes.
23+
24+
## Fixed
25+
26+
- Fixed a couple of bugs in the example config, to restore it to working order
27+
2028

2129
## v0.2.0 (2025-10-29)
2230

docs/source/reference/scopes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ with restricted scopes.
1111
* `create` --- Create a new node.
1212
* `write:metadata` --- Write metadata.
1313
* `write:data` --- Write (array, table) data.
14+
* `delete:revision` --- Delete metadata revisions
15+
* `delete:node` --- Delete a node
1416
* `apikeys` --- Manage API keys for the currently-authenticated user or service.
1517
* `metrics` --- Access Prometheus metrics.
1618
* `admin:apikeys` --- Manage API keys on behalf of any user or service.

example_configs/access_tags/tag_definitions.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ roles:
22
facility_user:
33
scopes: ["read:data", "read:metadata"]
44
facility_admin:
5-
scopes: ["read:data", "read:metadata", "write:data", "write:metadata", "create", "register"]
5+
scopes: ["read:data", "read:metadata",
6+
"write:data", "write:metadata",
7+
"delete:node", "delete:revision",
8+
"create", "register"]
69
tags:
710
data_A:
811
groups:

example_configs/toy_authentication.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ authentication:
1212
tiled_admins:
1313
- provider: toy
1414
id: admin
15+
database:
16+
uri: "sqlite:///file:authn_mem?mode=memory&cache=shared&uri=true"
17+
init_if_not_exists: true
1518
access_control:
1619
access_policy: "tiled.access_control.access_policies:TagBasedAccessPolicy"
1720
args:
@@ -21,7 +24,10 @@ access_control:
2124
- "read:data"
2225
- "write:metadata"
2326
- "write:data"
27+
- "delete:revision"
28+
- "delete:node"
2429
- "create"
30+
- "register"
2531
tags_db:
2632
uri: "file:example_configs/access_tags/compiled_tags.sqlite"
2733
access_tags_parser: "tiled.access_control.access_tags:AccessTagsParser"

pixi.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ msgpack-python = ">=1.0.0"
1616
orjson = "*"
1717
platformdirs = "*"
1818
pydantic = ">=2,<3"
19-
pydantic-settings = ">=2,<3"
19+
pydantic-settings = ">=2, <2.12.0",
2020
pyyaml = "*"
2121
typer = "*"
2222

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies = [
2727
"orjson",
2828
"platformdirs",
2929
"pydantic >=2, <3",
30-
"pydantic-settings >=2, <3",
30+
"pydantic-settings >=2, <2.12.0",
3131
"pyyaml",
3232
"typer",
3333
]

tiled/_tests/test_access_control.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
"read:metadata",
6767
"write:data",
6868
"write:metadata",
69+
"delete:node",
70+
"delete:revision",
6971
"create",
7072
"register",
7173
]
@@ -651,6 +653,23 @@ def test_writing_access_control(access_control_test_context_factory):
651653
sue_client[top].write_array(arr, key="data_X", access_tags=["chemists_tag"])
652654

653655

656+
def test_deletion_access_control(access_control_test_context_factory):
657+
"""
658+
Test that deletion access control is working.
659+
Only tests that the deletion request does not fail.
660+
Does not test that data is actually deleted.
661+
"""
662+
663+
alice_client = access_control_test_context_factory("alice", "alice")
664+
chris_client = access_control_test_context_factory("chris", "chris")
665+
666+
top = "foo"
667+
alice_client[top].write_array(arr, key="data_H", access_tags=["alice_tag"])
668+
with fail_with_status_code(HTTP_403_FORBIDDEN):
669+
chris_client[top]["data_H"].delete(external_only=False)
670+
alice_client[top]["data_H"].delete(external_only=False)
671+
672+
654673
def test_user_owned_node_access_control(access_control_test_context_factory):
655674
"""
656675
Test that user-owned nodes (i.e. nodes created without access tags applied)
@@ -756,6 +775,8 @@ def test_update_node_access_control(access_control_test_context_factory):
756775
This tests the following:
757776
- Update metadata while having write access
758777
- Prevent updating metadata without having write access
778+
- Prevent deleting a metadata revision without having deletion access
779+
- Delete a metadata revision while having deletion access
759780
- Successfully add an access tag and remove an access tag
760781
- Prevent adding or removing an access tag without having write access
761782
- Prevent adding or removing access tags which the user does not own
@@ -783,6 +804,13 @@ def test_update_node_access_control(access_control_test_context_factory):
783804
)
784805
assert "Au" not in chris_client[top][data].metadata["materials"]
785806

807+
# fails to delete a metadata revision
808+
with fail_with_status_code(HTTP_403_FORBIDDEN):
809+
chris_client[top][data].metadata_revisions.delete_revision(1)
810+
811+
# succeeds to delete a metadata revision
812+
alice_client[top][data].metadata_revisions.delete_revision(1)
813+
786814
# succeeds to add a new access tag and remove the old access tag
787815
alice_client[top][data].replace_metadata(access_tags=["biologists_tag"])
788816
access_tags = alice_client[top][data].access_blob["tags"]

tiled/access_control/scopes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"read:data": {"description": "Read data."},
44
"write:metadata": {"description": "Write metadata."},
55
"write:data": {"description": "Write data."},
6+
"delete:revision": {"description": "Delete metadata revisions."},
7+
"delete:node": {"description": "Delete a node."},
68
"create": {"description": "Add a node."},
79
"register": {"description": "Register externally-managed assets."},
810
"metrics": {"description": "Access (Prometheus) metrics."},
@@ -28,6 +30,8 @@
2830
"read:data",
2931
"write:metadata",
3032
"write:data",
33+
"delete:revision",
34+
"delete:node",
3135
"create",
3236
"register",
3337
"metrics",

tiled/adapters/zarr.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def write(
145145
raise NotImplementedError
146146
self._array[self._stencil()] = data
147147

148-
async def write_block(
148+
def write_block(
149149
self,
150150
data: NDArray[Any],
151151
block: Tuple[int, ...],
@@ -155,7 +155,7 @@ async def write_block(
155155
)
156156
self._array[block_slice] = data
157157

158-
async def patch(
158+
def patch(
159159
self,
160160
data: NDArray[Any],
161161
offset: Tuple[int, ...],

tiled/authn_database/core.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
# This is list of all valid alembic revisions (from current to oldest).
1515
ALL_REVISIONS = [
16+
"27e069ba3bf5",
1617
"a806cc635ab2",
1718
"0c705a02954c",
1819
"d88e91ea03f9",
@@ -38,6 +39,8 @@ async def create_default_roles(db):
3839
"create",
3940
"write:metadata",
4041
"write:data",
42+
"delete:revision",
43+
"delete:node",
4144
"apikeys",
4245
],
4346
),
@@ -51,6 +54,8 @@ async def create_default_roles(db):
5154
"register",
5255
"write:metadata",
5356
"write:data",
57+
"delete:revision",
58+
"delete:node",
5459
"admin:apikeys",
5560
"read:principals",
5661
"write:principals",

0 commit comments

Comments
 (0)