|
21 | 21 | from ..client import Context, from_context
|
22 | 22 | from ..client.xarray import write_xarray_dataset
|
23 | 23 | from ..queries import Eq, Key
|
24 |
| -from ..server.app import build_app |
| 24 | +from ..server.app import build_app, build_app_from_config |
25 | 25 | from ..server.schemas import Asset, DataSource
|
26 | 26 | from ..structures.core import StructureFamily
|
| 27 | +from .utils import enter_password |
27 | 28 |
|
28 | 29 |
|
29 | 30 | @pytest_asyncio.fixture
|
@@ -342,3 +343,71 @@ async def test_delete_tree(tmpdir):
|
342 | 343 | assert len(data_sources_after_delete) == 0
|
343 | 344 | assets_after_delete = (await tree.context.execute("SELECT * from assets")).all()
|
344 | 345 | assert len(assets_after_delete) == 0
|
| 346 | + |
| 347 | + |
| 348 | +@pytest.mark.asyncio |
| 349 | +async def test_access_control(tmpdir): |
| 350 | + config = { |
| 351 | + "authentication": { |
| 352 | + "allow_anonymous_access": True, |
| 353 | + "secret_keys": ["SECRET"], |
| 354 | + "providers": [ |
| 355 | + { |
| 356 | + "provider": "toy", |
| 357 | + "authenticator": "tiled.authenticators:DictionaryAuthenticator", |
| 358 | + "args": { |
| 359 | + "users_to_passwords": { |
| 360 | + "alice": "secret1", |
| 361 | + "bob": "secret2", |
| 362 | + "admin": "admin", |
| 363 | + } |
| 364 | + }, |
| 365 | + } |
| 366 | + ], |
| 367 | + }, |
| 368 | + "database": { |
| 369 | + "uri": "sqlite+aiosqlite://", # in-memory |
| 370 | + }, |
| 371 | + "trees": [ |
| 372 | + { |
| 373 | + "tree": "catalog", |
| 374 | + "path": "/", |
| 375 | + "args": { |
| 376 | + "uri": f"sqlite+aiosqlite:///{tmpdir}/catalog.db", |
| 377 | + "writable_storage": str(tmpdir / "data"), |
| 378 | + "init_if_not_exists": True, |
| 379 | + }, |
| 380 | + "access_control": { |
| 381 | + "access_policy": "tiled.access_policies:SimpleAccessPolicy", |
| 382 | + "args": { |
| 383 | + "provider": "toy", |
| 384 | + "access_lists": { |
| 385 | + "alice": ["outer_x"], |
| 386 | + "bob": ["outer_y"], |
| 387 | + }, |
| 388 | + "admins": ["admin"], |
| 389 | + "public": ["outer_z"], |
| 390 | + }, |
| 391 | + }, |
| 392 | + }, |
| 393 | + ], |
| 394 | + } |
| 395 | + |
| 396 | + app = build_app_from_config(config) |
| 397 | + with Context.from_app(app) as context: |
| 398 | + with enter_password("admin"): |
| 399 | + admin_client = from_context(context, username="admin") |
| 400 | + for key in ["outer_x", "outer_y", "outer_z"]: |
| 401 | + container = admin_client.create_container(key) |
| 402 | + container.write_array([1, 2, 3], key="inner") |
| 403 | + admin_client.logout() |
| 404 | + with enter_password("secret1"): |
| 405 | + alice_client = from_context(context, username="alice") |
| 406 | + alice_client["outer_x"]["inner"].read() |
| 407 | + with pytest.raises(KeyError): |
| 408 | + alice_client["outer_y"] |
| 409 | + alice_client.logout() |
| 410 | + public_client = from_context(context) |
| 411 | + public_client["outer_z"]["inner"].read() |
| 412 | + with pytest.raises(KeyError): |
| 413 | + public_client["outer_x"] |
0 commit comments