Skip to content
Snippets Groups Projects
Verified Commit 9660a560 authored by Daniel Göbel's avatar Daniel Göbel
Browse files

Add write-only buckets to the 'list buckets' response

#34
parent 2cff489b
Branches
No related tags found
No related merge requests found
......@@ -73,7 +73,7 @@ e2e-test-job: # Runs e2e tests on the API endpoints
OIDC_CLIENT_SECRET: "$TEST_OIDC_CLIENT_SECRET"
OIDC_CLIENT_ID: "$TEST_OIDC_CLIENT_ID"
OIDC_BASE_URI: "http://mock-oidc-server"
CLIENTS_CONFIGURATION_INLINE: "$TEST_OIDC_CLIENT_CONFIG"
CLIENTS_CONFIGURATION_PATH: "$TEST_OIDC_CLIENT_CONFIG"
services:
- name: mysql:8
alias: e2e-test-db
......@@ -82,7 +82,7 @@ e2e-test-job: # Runs e2e tests on the API endpoints
MYSQL_DATABASE: "$DB_DATABASE"
MYSQL_USER: "$DB_USER"
MYSQL_PASSWORD: "$DB_PASSWORD"
- name: ghcr.io/soluto/oidc-server-mock:latest
- name: ghcr.io/soluto/oidc-server-mock:0.8.1
alias: mock-oidc-server
variables:
ASPNETCORE_ENVIRONMENT: "Development"
......
## Version 1.1.2
### General
* When requesting a list of buckets, all buckets, including WRITE-only buckets, are returned #34
### Fixes
* User with WRITE/READWRITE permission can now delete multiple Objects with a single request to the S3 endpoint #34
## Version 1.1.1
### General
......
......@@ -152,7 +152,7 @@ async def get_current_bucket(
) -> Bucket:
"""
Get the Bucket from the database based on the name in the path.
Reject the request if user has no READ permission for this bucket.
Reject the request if user has no permission for this bucket.
FastAPI Dependency Injection Function
......
......@@ -5,7 +5,6 @@ from sqlalchemy.orm import joinedload
from app.models.bucket import Bucket
from app.models.bucket_permission import BucketPermission as BucketPermissionDB
from app.models.bucket_permission import PermissionEnum
from app.schemas.bucket import BucketIn as BucketInSchema
......@@ -34,7 +33,7 @@ class CRUDBucket:
@staticmethod
async def get_for_user(db: AsyncSession, uid: str) -> list[Bucket]:
"""
Get all buckets where the given user has READ permissions for.
Get all buckets where the given user is the owner or has any permission.
Parameters
----------
......@@ -57,7 +56,6 @@ class CRUDBucket:
WHERE bucket.owner_id = %s OR (EXISTS
(SELECT 1 FROM bucketpermission
WHERE bucket.name = bucketpermission.bucket_name AND bucketpermission.user_id = %s
AND(bucketpermission.permissions = %s OR bucketpermission.permissions = %s)
AND(datediff(now(), bucketpermission.`from`) <= %s OR bucketpermission.`from` IS NULL)
AND(datediff(now(), bucketpermission.`to`) >= %s OR bucketpermission.`to` IS NULL)))
"""
......@@ -68,12 +66,6 @@ class CRUDBucket:
or_(
Bucket.owner_id == uid,
Bucket.permissions.any(BucketPermissionDB.user_id == uid)
.where(
or_(
BucketPermissionDB.permissions == PermissionEnum.READ,
BucketPermissionDB.permissions == PermissionEnum.READWRITE,
)
)
.where(
or_(
func.datediff(func.now(), BucketPermissionDB.from_) >= 0,
......
......@@ -23,7 +23,7 @@ def custom_generate_unique_id(route: APIRoute) -> str:
app = FastAPI(
title="S3-Proxy",
version="1.1.1",
version="1.1.2",
description=description,
contact={
"name": "Daniel Goebel",
......
......@@ -75,11 +75,12 @@ class BucketPermissionIn(BucketPermissionParameters):
"Action": [],
"Condition": {},
}
bucket_policy["Action"] += ["s3:ListBucket"]
if self.permission == PermissionEnum.READ or self.permission == PermissionEnum.READWRITE:
bucket_policy["Action"] += ["s3:ListBucket"]
obj_policy["Action"] += ["s3:GetObject"]
if self.permission == PermissionEnum.WRITE or self.permission == PermissionEnum.READWRITE:
obj_policy["Action"] += ["s3:DeleteObject", "s3:PutObject"]
bucket_policy["Action"] += ["s3:DeleteObject"]
if self.to_timestamp is not None:
obj_policy["Condition"]["DateLessThan"] = {
"aws:CurrentTime": self.to_timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
......@@ -96,7 +97,7 @@ class BucketPermissionIn(BucketPermissionParameters):
del bucket_policy["Condition"]
if len(obj_policy["Condition"]) == 0:
del obj_policy["Condition"]
return [obj_policy] if self.permission == PermissionEnum.WRITE else [obj_policy, bucket_policy]
return [obj_policy, bucket_policy]
class BucketPermissionOut(BucketPermissionIn):
......
......@@ -169,7 +169,8 @@ class TestBucketCRUDGet:
buckets = await CRUDBucket.get_for_user(db, random_second_user.uid)
assert len(buckets) == 0
assert len(buckets) == 1
assert buckets[0] == random_bucket
@pytest.mark.asyncio
async def test_get_bucket_with_valid_time_permission(
......
......@@ -63,7 +63,7 @@ class TestPermissionPolicyPermissionType(_TestPermissionPolicy):
"""
random_base_permission.permission = PermissionEnum.WRITE
stmts = random_base_permission.map_to_bucket_policy_statement(user_id=random_lower_string())
assert len(stmts) == 1
assert len(stmts) == 2
object_stmt = stmts[0]
with pytest.raises(KeyError):
......@@ -72,6 +72,13 @@ class TestPermissionPolicyPermissionType(_TestPermissionPolicy):
assert "s3:PutObject" in object_stmt["Action"]
assert "s3:DeleteObject" in object_stmt["Action"]
bucket_stmt = stmts[1]
with pytest.raises(KeyError):
assert bucket_stmt["Condition"]
assert len(bucket_stmt["Action"]) == 2
assert "s3:ListBucket" in bucket_stmt["Action"]
assert "s3:DeleteObject" in bucket_stmt["Action"]
def test_READWRITE_permission(self, random_base_permission: BucketPermissionIn) -> None:
"""
Test for converting a READWRITE Permission into a bucket policy statement.
......@@ -96,8 +103,9 @@ class TestPermissionPolicyPermissionType(_TestPermissionPolicy):
bucket_stmt = stmts[1]
with pytest.raises(KeyError):
assert bucket_stmt["Condition"]
assert len(bucket_stmt["Action"]) == 1
assert bucket_stmt["Action"][0] == "s3:ListBucket"
assert len(bucket_stmt["Action"]) == 2
assert "s3:ListBucket" in bucket_stmt["Action"]
assert "s3:DeleteObject" in bucket_stmt["Action"]
class TestPermissionPolicyCondition(_TestPermissionPolicy):
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment