| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  | import time | 
					
						
							|  |  |  | import boto3 | 
					
						
							|  |  |  | import datetime | 
					
						
							|  |  |  | import botocore | 
					
						
							|  |  |  | from moto import mock_s3 | 
					
						
							|  |  |  | from botocore.config import Config | 
					
						
							|  |  |  | from moto.s3.responses import DEFAULT_REGION_NAME | 
					
						
							| 
									
										
										
										
											2022-01-18 14:18:57 -01:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_locked_object(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", config=Config(region_name=DEFAULT_REGION_NAME)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket_name = "locked-bucket-test" | 
					
						
							|  |  |  |     key_name = "file.txt" | 
					
						
							|  |  |  |     seconds_lock = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name, ObjectLockEnabledForBucket=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     until = datetime.datetime.utcnow() + datetime.timedelta(0, seconds_lock) | 
					
						
							|  |  |  |     s3.put_object( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         Body=b"test", | 
					
						
							|  |  |  |         Key=key_name, | 
					
						
							|  |  |  |         ObjectLockMode="COMPLIANCE", | 
					
						
							|  |  |  |         ObjectLockRetainUntilDate=until, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     versions_response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     version_id = versions_response["Versions"][0]["VersionId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted = False | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |         deleted = True | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("AccessDenied") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # cleaning | 
					
						
							|  |  |  |     time.sleep(seconds_lock) | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_fail_locked_object(): | 
					
						
							|  |  |  |     bucket_name = "locked-bucket2" | 
					
						
							|  |  |  |     key_name = "file.txt" | 
					
						
							|  |  |  |     seconds_lock = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3 = boto3.client("s3", config=Config(region_name=DEFAULT_REGION_NAME)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name, ObjectLockEnabledForBucket=False) | 
					
						
							|  |  |  |     until = datetime.datetime.utcnow() + datetime.timedelta(0, seconds_lock) | 
					
						
							|  |  |  |     failed = False | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         s3.put_object( | 
					
						
							|  |  |  |             Bucket=bucket_name, | 
					
						
							|  |  |  |             Body=b"test", | 
					
						
							|  |  |  |             Key=key_name, | 
					
						
							|  |  |  |             ObjectLockMode="COMPLIANCE", | 
					
						
							|  |  |  |             ObjectLockRetainUntilDate=until, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("InvalidRequest") | 
					
						
							|  |  |  |         failed = True | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     failed.should.equal(True) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_object_lock(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", config=Config(region_name=DEFAULT_REGION_NAME)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket_name = "put-lock-bucket-test" | 
					
						
							|  |  |  |     key_name = "file.txt" | 
					
						
							|  |  |  |     seconds_lock = 2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name, ObjectLockEnabledForBucket=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Body=b"test", Key=key_name) | 
					
						
							| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     versions_response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     version_id = versions_response["Versions"][0]["VersionId"] | 
					
						
							|  |  |  |     until = datetime.datetime.utcnow() + datetime.timedelta(0, seconds_lock) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object_retention( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         Key=key_name, | 
					
						
							|  |  |  |         VersionId=version_id, | 
					
						
							|  |  |  |         Retention={"Mode": "COMPLIANCE", "RetainUntilDate": until}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted = False | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |         deleted = True | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("AccessDenied") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # cleaning | 
					
						
							|  |  |  |     time.sleep(seconds_lock) | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_object_legal_hold(): | 
					
						
							|  |  |  |     s3 = boto3.client("s3", config=Config(region_name=DEFAULT_REGION_NAME)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bucket_name = "put-legal-bucket" | 
					
						
							|  |  |  |     key_name = "file.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name, ObjectLockEnabledForBucket=True) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Body=b"test", Key=key_name) | 
					
						
							| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     versions_response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     version_id = versions_response["Versions"][0]["VersionId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.put_object_legal_hold( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         Key=key_name, | 
					
						
							|  |  |  |         VersionId=version_id, | 
					
						
							|  |  |  |         LegalHold={"Status": "ON"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted = False | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |         deleted = True | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("AccessDenied") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # cleaning | 
					
						
							|  |  |  |     s3.put_object_legal_hold( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         Key=key_name, | 
					
						
							|  |  |  |         VersionId=version_id, | 
					
						
							|  |  |  |         LegalHold={"Status": "OFF"}, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |     s3.delete_bucket(Bucket=bucket_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_s3 | 
					
						
							|  |  |  | def test_put_default_lock(): | 
					
						
							|  |  |  |     # do not run this test in aws, it will block the deletion for a whole day | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3 = boto3.client("s3", config=Config(region_name=DEFAULT_REGION_NAME)) | 
					
						
							|  |  |  |     bucket_name = "put-default-lock-bucket" | 
					
						
							|  |  |  |     key_name = "file.txt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     days = 1 | 
					
						
							|  |  |  |     mode = "COMPLIANCE" | 
					
						
							|  |  |  |     enabled = "Enabled" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s3.create_bucket(Bucket=bucket_name, ObjectLockEnabledForBucket=True) | 
					
						
							|  |  |  |     s3.put_object_lock_configuration( | 
					
						
							|  |  |  |         Bucket=bucket_name, | 
					
						
							|  |  |  |         ObjectLockConfiguration={ | 
					
						
							|  |  |  |             "ObjectLockEnabled": enabled, | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             "Rule": {"DefaultRetention": {"Mode": mode, "Days": days}}, | 
					
						
							| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  |         }, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |     s3.put_object(Bucket=bucket_name, Body=b"test", Key=key_name) | 
					
						
							| 
									
										
										
										
											2021-08-17 00:16:59 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     deleted = False | 
					
						
							|  |  |  |     versions_response = s3.list_object_versions(Bucket=bucket_name) | 
					
						
							|  |  |  |     version_id = versions_response["Versions"][0]["VersionId"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     try: | 
					
						
							|  |  |  |         s3.delete_object(Bucket=bucket_name, Key=key_name, VersionId=version_id) | 
					
						
							|  |  |  |         deleted = True | 
					
						
							|  |  |  |     except botocore.client.ClientError as e: | 
					
						
							|  |  |  |         e.response["Error"]["Code"].should.equal("AccessDenied") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     deleted.should.equal(False) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = s3.get_object_lock_configuration(Bucket=bucket_name) | 
					
						
							|  |  |  |     response["ObjectLockConfiguration"]["ObjectLockEnabled"].should.equal(enabled) | 
					
						
							|  |  |  |     response["ObjectLockConfiguration"]["Rule"]["DefaultRetention"][ | 
					
						
							|  |  |  |         "Mode" | 
					
						
							|  |  |  |     ].should.equal(mode) | 
					
						
							|  |  |  |     response["ObjectLockConfiguration"]["Rule"]["DefaultRetention"][ | 
					
						
							|  |  |  |         "Days" | 
					
						
							|  |  |  |     ].should.equal(days) |