S3: Adding a validation method for s3 notification event name (#7253)

This commit is contained in:
Akira Noda 2024-01-30 03:13:37 +09:00 committed by GitHub
parent d98972ffc8
commit c70658340f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 14 additions and 6 deletions

View File

@ -41,6 +41,7 @@ from moto.s3.exceptions import (
HeadOnDeleteMarker, HeadOnDeleteMarker,
InvalidBucketName, InvalidBucketName,
InvalidNotificationDestination, InvalidNotificationDestination,
InvalidNotificationEvent,
InvalidPart, InvalidPart,
InvalidPublicAccessBlockConfiguration, InvalidPublicAccessBlockConfiguration,
InvalidRequest, InvalidRequest,
@ -821,6 +822,9 @@ class Notification(BaseModel):
random.choice(string.ascii_letters + string.digits) for _ in range(50) random.choice(string.ascii_letters + string.digits) for _ in range(50)
) )
self.arn = arn self.arn = arn
for event_name in events:
if not notifications.S3NotificationEvent.is_event_valid(event_name):
raise InvalidNotificationEvent(event_name)
self.events = events self.events = events
self.filters = filters if filters else {} self.filters = filters if filters else {}

View File

@ -49,6 +49,16 @@ class S3NotificationEvent(str, Enum):
def events(self) -> List[str]: def events(self) -> List[str]:
return sorted([item.value for item in S3NotificationEvent]) return sorted([item.value for item in S3NotificationEvent])
@classmethod
def is_event_valid(self, event_name: str) -> bool:
# Ex) s3:ObjectCreated:Put
if event_name in self.events():
return True
# Ex) event name without `s3:` like ObjectCreated:Put
if event_name in [e[:3] for e in self.events()]:
return True
return False
def _get_s3_event( def _get_s3_event(
event_name: str, bucket: Any, key: Any, notification_id: str event_name: str, bucket: Any, key: Any, notification_id: str

View File

@ -35,7 +35,6 @@ from .exceptions import (
InvalidMaxPartArgument, InvalidMaxPartArgument,
InvalidMaxPartNumberArgument, InvalidMaxPartNumberArgument,
InvalidNotificationARN, InvalidNotificationARN,
InvalidNotificationEvent,
InvalidObjectState, InvalidObjectState,
InvalidPartOrder, InvalidPartOrder,
InvalidRange, InvalidRange,
@ -62,7 +61,6 @@ from .models import (
get_canned_acl, get_canned_acl,
s3_backends, s3_backends,
) )
from .notifications import S3NotificationEvent
from .select_object_content import serialize_select from .select_object_content import serialize_select
from .utils import ( from .utils import (
ARCHIVE_STORAGE_CLASSES, ARCHIVE_STORAGE_CLASSES,
@ -2121,10 +2119,6 @@ class S3Response(BaseResponse):
if not isinstance(n["Event"], list): if not isinstance(n["Event"], list):
n["Event"] = [n["Event"]] n["Event"] = [n["Event"]]
for event in n["Event"]:
if event not in S3NotificationEvent.events():
raise InvalidNotificationEvent(event)
# Parse out the filters: # Parse out the filters:
if n.get("Filter"): if n.get("Filter"):
# Error if S3Key is blank: # Error if S3Key is blank: