kopia lustrzana https://github.com/gaul/s3proxy
rodzic
566575e71a
commit
19e2426220
5
pom.xml
5
pom.xml
|
@ -301,6 +301,11 @@
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||||
|
<artifactId>jackson-dataformat-xml</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-fileupload</groupId>
|
<groupId>commons-fileupload</groupId>
|
||||||
<artifactId>commons-fileupload</artifactId>
|
<artifactId>commons-fileupload</artifactId>
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014-2016 Andrew Gaul <andrew@gaul.org>
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.gaul.s3proxy;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
|
||||||
|
|
||||||
|
/** Represent an Amazon AccessControlPolicy for a container or object. */
|
||||||
|
// CHECKSTYLE:OFF
|
||||||
|
final class AccessControlPolicy {
|
||||||
|
@JacksonXmlProperty(localName = "Owner")
|
||||||
|
Owner owner;
|
||||||
|
@JacksonXmlProperty(localName = "AccessControlList")
|
||||||
|
AccessControlList aclList;
|
||||||
|
|
||||||
|
static final class Owner {
|
||||||
|
@JacksonXmlProperty(localName = "ID")
|
||||||
|
String id;
|
||||||
|
@JacksonXmlProperty(localName = "DisplayName")
|
||||||
|
String displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class AccessControlList {
|
||||||
|
@JacksonXmlProperty(localName = "Grant")
|
||||||
|
@JacksonXmlElementWrapper(useWrapping = false)
|
||||||
|
Collection<Grant> grants;
|
||||||
|
|
||||||
|
static final class Grant {
|
||||||
|
@JacksonXmlProperty(localName = "Grantee")
|
||||||
|
Grantee grantee;
|
||||||
|
@JacksonXmlProperty(localName = "Permission")
|
||||||
|
String permission;
|
||||||
|
|
||||||
|
static final class Grantee {
|
||||||
|
@JacksonXmlProperty(namespace = "xsi", localName = "type",
|
||||||
|
isAttribute = true)
|
||||||
|
String type;
|
||||||
|
@JacksonXmlProperty(localName = "ID")
|
||||||
|
String id;
|
||||||
|
@JacksonXmlProperty(localName = "DisplayName")
|
||||||
|
String displayName;
|
||||||
|
@JacksonXmlProperty(localName = "URI")
|
||||||
|
String uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CHECKSTYLE:ON
|
|
@ -58,6 +58,7 @@ import javax.xml.stream.XMLStreamException;
|
||||||
import javax.xml.stream.XMLStreamReader;
|
import javax.xml.stream.XMLStreamReader;
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
|
@ -841,15 +842,53 @@ final class S3ProxyHandler extends AbstractHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: how to handle XML ACLs?
|
PushbackInputStream pis = new PushbackInputStream(is);
|
||||||
int ch = is.read();
|
int ch = pis.read();
|
||||||
if (ch != -1) {
|
if (ch != -1) {
|
||||||
throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED);
|
pis.unread(ch);
|
||||||
|
AccessControlPolicy policy = new XmlMapper().readValue(
|
||||||
|
pis, AccessControlPolicy.class);
|
||||||
|
access = mapXmlAclsToCannedPolicy(policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
blobStore.setBlobAccess(containerName, blobName, access);
|
blobStore.setBlobAccess(containerName, blobName, access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Map XML ACLs to a canned policy if an exact tranformation exists. */
|
||||||
|
private static BlobAccess mapXmlAclsToCannedPolicy(
|
||||||
|
AccessControlPolicy policy) throws S3Exception {
|
||||||
|
if (!policy.owner.id.equals(FAKE_OWNER_ID)) {
|
||||||
|
throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean ownerFullControl = false;
|
||||||
|
boolean allUsersRead = false;
|
||||||
|
for (AccessControlPolicy.AccessControlList.Grant grant :
|
||||||
|
policy.aclList.grants) {
|
||||||
|
if (grant.grantee.type.equals("CanonicalUser") &&
|
||||||
|
grant.grantee.id.equals(FAKE_OWNER_ID) &&
|
||||||
|
grant.permission.equals("FULL_CONTROL")) {
|
||||||
|
ownerFullControl = true;
|
||||||
|
} else if (grant.grantee.type.equals("Group") &&
|
||||||
|
grant.grantee.uri.equals("http://acs.amazonaws.com/" +
|
||||||
|
"groups/global/AllUsers") &&
|
||||||
|
grant.permission.equals("READ")) {
|
||||||
|
allUsersRead = true;
|
||||||
|
} else {
|
||||||
|
throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ownerFullControl) {
|
||||||
|
if (allUsersRead) {
|
||||||
|
return BlobAccess.PUBLIC_READ;
|
||||||
|
}
|
||||||
|
return BlobAccess.PRIVATE;
|
||||||
|
} else {
|
||||||
|
throw new S3Exception(S3ErrorCode.NOT_IMPLEMENTED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleContainerList(HttpServletResponse response,
|
private void handleContainerList(HttpServletResponse response,
|
||||||
BlobStore blobStore) throws IOException {
|
BlobStore blobStore) throws IOException {
|
||||||
PageSet<? extends StorageMetadata> buckets = blobStore.list();
|
PageSet<? extends StorageMetadata> buckets = blobStore.list();
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="NewlineAtEndOfFile"/>
|
<module name="NewlineAtEndOfFile"/>
|
||||||
|
<module name="SuppressionCommentFilter"/>
|
||||||
<module name="Translation"/>
|
<module name="Translation"/>
|
||||||
<module name="TreeWalker">
|
<module name="TreeWalker">
|
||||||
<property name="cacheFile" value="target/cachefile"/>
|
<property name="cacheFile" value="target/cachefile"/>
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
<module name="EqualsHashCode"/>
|
<module name="EqualsHashCode"/>
|
||||||
<module name="ExplicitInitialization"/>
|
<module name="ExplicitInitialization"/>
|
||||||
<module name="FallThrough"/>
|
<module name="FallThrough"/>
|
||||||
|
<module name="FileContentsHolder"/>
|
||||||
<module name="FinalClass"/>
|
<module name="FinalClass"/>
|
||||||
<module name="GenericWhitespace"/>
|
<module name="GenericWhitespace"/>
|
||||||
<!--
|
<!--
|
||||||
|
|
|
@ -52,11 +52,12 @@ import com.amazonaws.services.s3.model.CopyPartRequest;
|
||||||
import com.amazonaws.services.s3.model.CopyPartResult;
|
import com.amazonaws.services.s3.model.CopyPartResult;
|
||||||
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
|
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
|
||||||
import com.amazonaws.services.s3.model.GetObjectRequest;
|
import com.amazonaws.services.s3.model.GetObjectRequest;
|
||||||
|
import com.amazonaws.services.s3.model.GroupGrantee;
|
||||||
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
|
import com.amazonaws.services.s3.model.InitiateMultipartUploadRequest;
|
||||||
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
|
import com.amazonaws.services.s3.model.InitiateMultipartUploadResult;
|
||||||
import com.amazonaws.services.s3.model.ObjectListing;
|
import com.amazonaws.services.s3.model.ObjectListing;
|
||||||
import com.amazonaws.services.s3.model.ObjectMetadata;
|
import com.amazonaws.services.s3.model.ObjectMetadata;
|
||||||
import com.amazonaws.services.s3.model.Owner;
|
import com.amazonaws.services.s3.model.Permission;
|
||||||
import com.amazonaws.services.s3.model.S3Object;
|
import com.amazonaws.services.s3.model.S3Object;
|
||||||
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
import com.amazonaws.services.s3.model.S3ObjectSummary;
|
||||||
import com.amazonaws.services.s3.model.UploadPartRequest;
|
import com.amazonaws.services.s3.model.UploadPartRequest;
|
||||||
|
@ -363,13 +364,23 @@ public final class S3AwsSdkTest {
|
||||||
metadata.setContentLength(BYTE_SOURCE.size());
|
metadata.setContentLength(BYTE_SOURCE.size());
|
||||||
client.putObject(containerName, blobName, BYTE_SOURCE.openStream(),
|
client.putObject(containerName, blobName, BYTE_SOURCE.openStream(),
|
||||||
metadata);
|
metadata);
|
||||||
|
AccessControlList acl = client.getObjectAcl(containerName, blobName);
|
||||||
|
|
||||||
AccessControlList acl = new AccessControlList();
|
acl.grantPermission(GroupGrantee.AllUsers, Permission.Read);
|
||||||
Owner owner = new Owner();
|
client.setObjectAcl(containerName, blobName, acl);
|
||||||
owner.setId("id");
|
// TODO: work around unimplemented AccessControlList.equals:
|
||||||
owner.setDisplayName("display-name");
|
// https://github.com/aws/aws-sdk-java/pull/609
|
||||||
acl.setOwner(owner);
|
AccessControlList acl2 = client.getObjectAcl(containerName, blobName);
|
||||||
|
assertThat(acl2.getOwner()).isEqualTo(acl.getOwner());
|
||||||
|
assertThat(acl2.getGrantsAsList()).isEqualTo(acl.getGrantsAsList());
|
||||||
|
|
||||||
|
acl.revokeAllPermissions(GroupGrantee.AllUsers);
|
||||||
|
client.setObjectAcl(containerName, blobName, acl);
|
||||||
|
acl2 = client.getObjectAcl(containerName, blobName);
|
||||||
|
assertThat(acl2.getOwner()).isEqualTo(acl.getOwner());
|
||||||
|
assertThat(acl2.getGrantsAsList()).isEqualTo(acl.getGrantsAsList());
|
||||||
|
|
||||||
|
acl.grantPermission(GroupGrantee.AllUsers, Permission.Write);
|
||||||
try {
|
try {
|
||||||
client.setObjectAcl(containerName, blobName, acl);
|
client.setObjectAcl(containerName, blobName, acl);
|
||||||
Fail.failBecauseExceptionWasNotThrown(AmazonS3Exception.class);
|
Fail.failBecauseExceptionWasNotThrown(AmazonS3Exception.class);
|
||||||
|
|
Ładowanie…
Reference in New Issue