Skip to content

Commit

Permalink
Merge pull request #141 from ghga-de/feature/bucket_name_restriction
Browse files Browse the repository at this point in the history
Allow colon characters in bucket names
  • Loading branch information
lkuchenb authored Nov 19, 2024
2 parents 9cd407f + a95cee2 commit 5cec4f8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/hexkit/providers/s3/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# ruff: noqa: PLR0913

import asyncio
import re
from functools import lru_cache
from pathlib import Path
from typing import Any, Optional
Expand All @@ -31,6 +32,7 @@
import botocore.config
import botocore.configloader
import botocore.exceptions
import botocore.handlers
from boto3.s3.transfer import TransferConfig
from pydantic import Field, SecretStr
from pydantic_settings import BaseSettings
Expand All @@ -39,6 +41,10 @@
from hexkit.utils import calc_part_size

__all__ = ["ObjectStorageProtocol", "PresignedPostURL"]
# Allow colon character in bucket names to accommodate Ceph multi tenancy S3
botocore.handlers.VALID_BUCKET = re.compile(
r"^(?:[a-zA-Z0-9_]{1,191}:)?[a-z0-9\-]{3,63}$"
)


class S3Config(BaseSettings):
Expand Down Expand Up @@ -116,6 +122,8 @@ def read_aws_config_ini(aws_config_ini: Path) -> botocore.config.Config:
class S3ObjectStorage(ObjectStorageProtocol):
"""S3-based provider implementing the ObjectStorageProtocol."""

_re_bucket_id = botocore.handlers.VALID_BUCKET

def __init__(
self,
*,
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ async def test_object_existence_checks(s3: S3Fixture, tmp_file: FileObject): #
)


async def test_bucket_name_with_tenant(s3: S3Fixture):
"""Test if bucket names containing a tenant work correctly."""
check_bucket = s3.storage.does_bucket_exist
assert not await check_bucket("non-existing-bucket")
assert not await check_bucket("tenant:non-existing-bucket")
with pytest.raises(ObjectStorageProtocol.BucketIdValidationError):
assert not await check_bucket("tenant:invalid:bucket")
with pytest.raises(ObjectStorageProtocol.BucketIdValidationError):
assert not await check_bucket("tenant-invalid:bucket-valid")
with pytest.raises(ObjectStorageProtocol.BucketIdValidationError):
assert not await check_bucket("tenant_valid:bucket_invalid")


async def test_get_object_etag(s3: S3Fixture, tmp_file: FileObject): # noqa: F811
"""Test ETag retrieval."""
await s3.populate_file_objects([tmp_file])
Expand Down

0 comments on commit 5cec4f8

Please sign in to comment.