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>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-xml</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-fileupload</groupId>
|
||||
<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.XMLStreamWriter;
|
||||
|
||||
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
|
@ -841,15 +842,53 @@ final class S3ProxyHandler extends AbstractHandler {
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: how to handle XML ACLs?
|
||||
int ch = is.read();
|
||||
PushbackInputStream pis = new PushbackInputStream(is);
|
||||
int ch = pis.read();
|
||||
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);
|
||||
}
|
||||
|
||||
/** 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,
|
||||
BlobStore blobStore) throws IOException {
|
||||
PageSet<? extends StorageMetadata> buckets = blobStore.list();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/>
|
||||
</module>
|
||||
<module name="NewlineAtEndOfFile"/>
|
||||
<module name="SuppressionCommentFilter"/>
|
||||
<module name="Translation"/>
|
||||
<module name="TreeWalker">
|
||||
<property name="cacheFile" value="target/cachefile"/>
|
||||
|
@ -37,6 +38,7 @@
|
|||
<module name="EqualsHashCode"/>
|
||||
<module name="ExplicitInitialization"/>
|
||||
<module name="FallThrough"/>
|
||||
<module name="FileContentsHolder"/>
|
||||
<module name="FinalClass"/>
|
||||
<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.GeneratePresignedUrlRequest;
|
||||
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.InitiateMultipartUploadResult;
|
||||
import com.amazonaws.services.s3.model.ObjectListing;
|
||||
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.S3ObjectSummary;
|
||||
import com.amazonaws.services.s3.model.UploadPartRequest;
|
||||
|
@ -363,13 +364,23 @@ public final class S3AwsSdkTest {
|
|||
metadata.setContentLength(BYTE_SOURCE.size());
|
||||
client.putObject(containerName, blobName, BYTE_SOURCE.openStream(),
|
||||
metadata);
|
||||
AccessControlList acl = client.getObjectAcl(containerName, blobName);
|
||||
|
||||
AccessControlList acl = new AccessControlList();
|
||||
Owner owner = new Owner();
|
||||
owner.setId("id");
|
||||
owner.setDisplayName("display-name");
|
||||
acl.setOwner(owner);
|
||||
acl.grantPermission(GroupGrantee.AllUsers, Permission.Read);
|
||||
client.setObjectAcl(containerName, blobName, acl);
|
||||
// TODO: work around unimplemented AccessControlList.equals:
|
||||
// https://github.com/aws/aws-sdk-java/pull/609
|
||||
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 {
|
||||
client.setObjectAcl(containerName, blobName, acl);
|
||||
Fail.failBecauseExceptionWasNotThrown(AmazonS3Exception.class);
|
||||
|
|
Ładowanie…
Reference in New Issue