Skip to content

Commit

Permalink
Store ACLs with ObjectMetadata
Browse files Browse the repository at this point in the history
This is a step to storing versions, as ACLs are stored by version in S3.
  • Loading branch information
afranken committed May 30, 2024
1 parent 12efb2f commit 56972ed
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.adobe.testing.s3mock.dto.Tag;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -54,7 +53,6 @@
public class ObjectStore extends StoreBase {
private static final Logger LOG = LoggerFactory.getLogger(ObjectStore.class);
private static final String META_FILE = "objectMetadata.json";
private static final String ACL_FILE = "objectAcl.json";
private static final String DATA_FILE = "binaryData";

/**
Expand Down Expand Up @@ -132,7 +130,8 @@ public S3ObjectMetadata storeS3ObjectMetadata(BucketMetadata bucket,
encryptionHeaders,
checksumAlgorithm,
checksum,
storageClass
storageClass,
null
);
writeMetafile(bucket, s3ObjectMetadata);
return s3ObjectMetadata;
Expand Down Expand Up @@ -173,7 +172,8 @@ public void storeObjectTags(BucketMetadata bucket, UUID id, List<Tag> tags) {
s3ObjectMetadata.encryptionHeaders(),
s3ObjectMetadata.checksumAlgorithm(),
s3ObjectMetadata.checksum(),
s3ObjectMetadata.storageClass()
s3ObjectMetadata.storageClass(),
s3ObjectMetadata.policy()
));
}
}
Expand Down Expand Up @@ -206,7 +206,8 @@ public void storeLegalHold(BucketMetadata bucket, UUID id, LegalHold legalHold)
s3ObjectMetadata.encryptionHeaders(),
s3ObjectMetadata.checksumAlgorithm(),
s3ObjectMetadata.checksum(),
s3ObjectMetadata.storageClass()
s3ObjectMetadata.storageClass(),
s3ObjectMetadata.policy()
));
}
}
Expand All @@ -219,16 +220,38 @@ public void storeLegalHold(BucketMetadata bucket, UUID id, LegalHold legalHold)
* @param policy the ACL.
*/
public void storeAcl(BucketMetadata bucket, UUID id, AccessControlPolicy policy) {
writeAclFile(bucket, id, policy);
synchronized (lockStore.get(id)) {
var s3ObjectMetadata = getS3ObjectMetadata(bucket, id);
writeMetafile(bucket, new S3ObjectMetadata(
s3ObjectMetadata.id(),
s3ObjectMetadata.key(),
s3ObjectMetadata.size(),
s3ObjectMetadata.modificationDate(),
s3ObjectMetadata.etag(),
s3ObjectMetadata.contentType(),
s3ObjectMetadata.lastModified(),
s3ObjectMetadata.dataPath(),
s3ObjectMetadata.userMetadata(),
s3ObjectMetadata.tags(),
s3ObjectMetadata.legalHold(),
s3ObjectMetadata.retention(),
s3ObjectMetadata.owner(),
s3ObjectMetadata.storeHeaders(),
s3ObjectMetadata.encryptionHeaders(),
s3ObjectMetadata.checksumAlgorithm(),
s3ObjectMetadata.checksum(),
s3ObjectMetadata.storageClass(),
policy
)
);
}
}

public AccessControlPolicy readAcl(BucketMetadata bucket, UUID id) {
var policy = readAclFile(bucket, id);
if (policy == null) {
var s3ObjectMetadata = getS3ObjectMetadata(bucket, id);
return privateCannedAcl(s3ObjectMetadata.owner());
}
return policy;
var s3ObjectMetadata = getS3ObjectMetadata(bucket, id);
return s3ObjectMetadata.policy() == null
? privateCannedAcl(s3ObjectMetadata.owner())
: s3ObjectMetadata.policy();
}

/**
Expand Down Expand Up @@ -259,7 +282,8 @@ public void storeRetention(BucketMetadata bucket, UUID id, Retention retention)
s3ObjectMetadata.encryptionHeaders(),
s3ObjectMetadata.checksumAlgorithm(),
s3ObjectMetadata.checksum(),
s3ObjectMetadata.storageClass()
s3ObjectMetadata.storageClass(),
s3ObjectMetadata.policy()
));
}
}
Expand Down Expand Up @@ -370,7 +394,8 @@ public CopyObjectResult pretendToCopyS3Object(BucketMetadata sourceBucket,
? sourceObject.encryptionHeaders() : encryptionHeaders,
sourceObject.checksumAlgorithm(),
sourceObject.checksum(),
storageClass != null ? storageClass : sourceObject.storageClass()
storageClass != null ? storageClass : sourceObject.storageClass(),
sourceObject.policy()
));
return new CopyObjectResult(sourceObject.modificationDate(), sourceObject.etag());
}
Expand Down Expand Up @@ -449,10 +474,6 @@ private Path getMetaFilePath(BucketMetadata bucket, UUID id) {
return Paths.get(getObjectFolderPath(bucket, id).toString(), META_FILE);
}

private Path getAclFilePath(BucketMetadata bucket, UUID id) {
return Paths.get(getObjectFolderPath(bucket, id).toString(), ACL_FILE);
}

private Path getDataFilePath(BucketMetadata bucket, UUID id) {
return Paths.get(getObjectFolderPath(bucket, id).toString(), DATA_FILE);
}
Expand All @@ -471,33 +492,4 @@ private void writeMetafile(BucketMetadata bucket, S3ObjectMetadata s3ObjectMetad
throw new IllegalStateException("Could not write object metadata-file " + id, e);
}
}

private AccessControlPolicy readAclFile(BucketMetadata bucket, UUID id) {
try {
synchronized (lockStore.get(id)) {
var aclFile = getAclFilePath(bucket, id).toFile();
if (!aclFile.exists()) {
return null;
}
var toDeserialize = FileUtils.readFileToString(aclFile, Charset.defaultCharset());
return objectMapper.readValue(toDeserialize, AccessControlPolicy.class);
}
} catch (IOException e) {
throw new IllegalStateException("Could not read object acl-file " + id, e);
}
}

private void writeAclFile(BucketMetadata bucket, UUID id, AccessControlPolicy policy) {
try {
synchronized (lockStore.get(id)) {
var aclFile = getAclFilePath(bucket, id).toFile();
if (!retainFilesOnExit) {
aclFile.deleteOnExit();
}
FileUtils.write(aclFile, objectMapper.writeValueAsString(policy), Charset.defaultCharset());
}
} catch (IOException e) {
throw new IllegalStateException("Could not write object acl-file " + id, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import static com.adobe.testing.s3mock.util.EtagUtil.normalizeEtag;

import com.adobe.testing.s3mock.dto.AccessControlPolicy;
import com.adobe.testing.s3mock.dto.ChecksumAlgorithm;
import com.adobe.testing.s3mock.dto.LegalHold;
import com.adobe.testing.s3mock.dto.Owner;
Expand Down Expand Up @@ -54,7 +55,8 @@ public record S3ObjectMetadata(
Map<String, String> encryptionHeaders,
ChecksumAlgorithm checksumAlgorithm,
String checksum,
StorageClass storageClass
StorageClass storageClass,
AccessControlPolicy policy
) {

public S3ObjectMetadata {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,7 @@ internal class ObjectControllerTest : BaseControllerTest() {
encryptionHeaders(encryption, encryptionKey),
null,
null,
null,
null
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ internal class TaggingHeaderConverterTest {
}

private fun tag(i: Int): String {
return String.format("tag%d=value%d", i, i)
return "tag$i=value$i"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ internal abstract class ServiceTestBase {
null,
null,
null,
StorageClass.STANDARD
StorageClass.STANDARD,
null
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ internal class HeaderUtilTest {
null,
null,
null,
StorageClass.STANDARD
StorageClass.STANDARD,
null
)
}

Expand Down

0 comments on commit 56972ed

Please sign in to comment.