forked from awsdocs/aws-doc-sdk-examples
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
830 additions
and
458 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
javav2/example_code/s3/src/main/java/com/example/s3/DoesBucketExist.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
package com.example.s3; | ||
// snippet-start:[s3.java2.does-bucket-exist-main] | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import software.amazon.awssdk.awscore.exception.AwsServiceException; | ||
import software.amazon.awssdk.http.HttpStatusCode; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.utils.Validate; | ||
|
||
public class DoesBucketExist { | ||
private static final Logger logger = LoggerFactory.getLogger(DoesBucketExist.class); | ||
|
||
public static void main(String[] args) { | ||
DoesBucketExist doesBucketExist = new DoesBucketExist(); | ||
|
||
final S3Client s3SyncClient = S3Client.builder().build(); | ||
final String bucketName = "amzn-s3-demo-bucket"; // Change to the bucket name that you want to check. | ||
|
||
boolean exists = doesBucketExist.doesBucketExist(bucketName, s3SyncClient); | ||
logger.info("Bucket exists: {}", exists); | ||
} | ||
|
||
/** | ||
* Checks if the specified bucket exists. Amazon S3 buckets are named in a global namespace; use this method to | ||
* determine if a specified bucket name already exists, and therefore can't be used to create a new bucket. | ||
* <p> | ||
* Internally this method uses the <a | ||
* href="https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getBucketAcl(java.util.function.Consumer)">S3Client.getBucketAcl(String)</a> | ||
* operation to determine whether the bucket exists. | ||
* <p> | ||
* This method is equivalent to the AWS SDK for Java V1's <a | ||
* href="https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/AmazonS3Client.html#doesBucketExistV2-java.lang.String-">AmazonS3Client#doesBucketExistV2(String)</a>. | ||
* | ||
* @param bucketName The name of the bucket to check. | ||
* @param s3SyncClient An <code>S3Client</code> instance. The method checks for the bucket in the AWS Region | ||
* configured on the instance. | ||
* @return The value true if the specified bucket exists in Amazon S3; the value false if there is no bucket in | ||
* Amazon S3 with that name. | ||
*/ | ||
public boolean doesBucketExist(String bucketName, S3Client s3SyncClient) { | ||
try { | ||
Validate.notEmpty(bucketName, "The bucket name must not be null or an empty string.", ""); | ||
s3SyncClient.getBucketAcl(r -> r.bucket(bucketName)); | ||
return true; | ||
} catch (AwsServiceException ase) { | ||
// A redirect error or an AccessDenied exception means the bucket exists but it's not in this region | ||
// or we don't have permissions to it. | ||
if ((ase.statusCode() == HttpStatusCode.MOVED_PERMANENTLY) || "AccessDenied".equals(ase.awsErrorDetails().errorCode())) { | ||
return true; | ||
} | ||
if (ase.statusCode() == HttpStatusCode.NOT_FOUND) { | ||
return false; | ||
} | ||
throw ase; | ||
} | ||
} | ||
} | ||
// snippet-end:[s3.java2.does-bucket-exist-main] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> | ||
<AccessControlList> | ||
<Grant> | ||
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser"> | ||
<DisplayName>owner</DisplayName> | ||
<ID>dad784318ac45facc6a8c74b9b44f18afd317c85fa8776eeb2b000c8942bc8d9</ID> | ||
</Grantee> | ||
<Permission>FULL_CONTROL</Permission> | ||
</Grant> | ||
<Grant> | ||
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group"> | ||
<DisplayName>my-grantee</DisplayName> | ||
<URI>http://acs.amazonaws.com/groups/global/AuthenticatedUsers</URI> | ||
</Grantee> | ||
<Permission>READ_ACP</Permission> | ||
</Grant> | ||
</AccessControlList> | ||
<Owner> | ||
<ID>dad784318ac45facc6a8c74b9b44f18afd317c85fa8776eeb2b000c8942bc8d9</ID> | ||
</Owner> | ||
</AccessControlPolicy> |
162 changes: 162 additions & 0 deletions
162
javav2/example_code/s3/src/test/java/com/example/s3/DoesBucketExistTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
package com.example.s3; | ||
// | ||
|
||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.api.Test; | ||
import software.amazon.awssdk.policybuilder.iam.IamConditionKey; | ||
import software.amazon.awssdk.policybuilder.iam.IamConditionOperator; | ||
import software.amazon.awssdk.policybuilder.iam.IamEffect; | ||
import software.amazon.awssdk.policybuilder.iam.IamPolicy; | ||
import software.amazon.awssdk.policybuilder.iam.IamPrincipalType; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.iam.IamClient; | ||
import software.amazon.awssdk.services.iam.model.PutRolePolicyResponse; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.services.sts.StsClient; | ||
import software.amazon.awssdk.services.sts.auth.StsAssumeRoleCredentialsProvider; | ||
|
||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertFalse; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
class DoesBucketExistTest { | ||
private static final String ROLE_NAME = "minimal-s3-perms-role"; | ||
private static final String POLICY_NAME = "minimum-s3-ability-policy"; | ||
private static final IamClient iamClient = IamClient.builder().build(); | ||
|
||
@Test | ||
@Tag("IntegrationTest") | ||
void doesBucketExist_exists_but_not_in_client_region_should_return_true() { | ||
|
||
S3Client usWestS3Client = S3Client.builder().region(Region.US_WEST_2).build(); | ||
final String bucketName = "my-us-west2-bucket-" + UUID.randomUUID(); | ||
createBucket(usWestS3Client, bucketName); | ||
|
||
DoesBucketExist doesBucketExist = new DoesBucketExist(); | ||
S3Client euCentralS3Client = S3Client.builder().region(Region.EU_CENTRAL_1).build(); | ||
boolean exists = doesBucketExist.doesBucketExist(bucketName, euCentralS3Client); | ||
assertTrue(exists); | ||
|
||
deleteBucket(usWestS3Client, bucketName); | ||
} | ||
|
||
@Test | ||
@Tag("IntegrationTest") | ||
void doesBucketExist_does_not_exist_should_return_false() { | ||
|
||
DoesBucketExist doesBucketExist = new DoesBucketExist(); | ||
final String bucketName = "xx-xx-xxxx-xxxx" + UUID.randomUUID(); | ||
|
||
boolean exists = doesBucketExist.doesBucketExist(bucketName, S3Client.create()); | ||
assertFalse(exists); | ||
} | ||
|
||
@Test | ||
@Tag("IntegrationTest") | ||
void doesBucketExist_returns_true_when_bucket_exists_but_caller_does_not_have_permission() { | ||
StsClient stsClient = StsClient.create(); | ||
createAssumableRole(stsClient); | ||
|
||
S3Client s3Client = S3Client.create(); | ||
final String bucketName = "my-bucket-" + UUID.randomUUID(); | ||
createBucket(s3Client, bucketName); | ||
|
||
try { | ||
|
||
String roleArn = iamClient.getRole(b -> b.roleName(ROLE_NAME)).role().arn(); | ||
|
||
S3Client s3ClientWithoutPermission = S3Client.builder() | ||
.credentialsProvider(StsAssumeRoleCredentialsProvider.builder() | ||
.stsClient(stsClient) | ||
.refreshRequest(arr -> arr | ||
.roleArn(roleArn) | ||
.roleSessionName("test-session")) | ||
.build()) | ||
.build(); | ||
DoesBucketExist doesBucketExist = new DoesBucketExist(); | ||
boolean existsButNoAccess = doesBucketExist.doesBucketExist(bucketName, s3ClientWithoutPermission); | ||
assertTrue(existsButNoAccess); | ||
|
||
boolean exists = doesBucketExist.doesBucketExist("non-existent-bucket" + UUID.randomUUID(), s3ClientWithoutPermission); | ||
assertFalse(exists); | ||
} finally { | ||
deleteBucket(s3Client, bucketName); | ||
deleteRole(); | ||
|
||
} | ||
} | ||
|
||
private static void createBucket(S3Client s3Client, String bucketName) { | ||
s3Client.createBucket(b -> b.bucket(bucketName)); | ||
s3Client.waiter().waitUntilBucketExists(b -> b.bucket(bucketName)); | ||
} | ||
|
||
private static void deleteBucket(S3Client s3Client, String bucketName) { | ||
s3Client.deleteBucket(b -> b.bucket(bucketName)); | ||
s3Client.waiter().waitUntilBucketNotExists(b -> b.bucket(bucketName)); | ||
} | ||
|
||
|
||
private static void createAssumableRole(StsClient stsClient) { | ||
final String accountID = stsClient.getCallerIdentity().account(); | ||
|
||
IamPolicy trustIamPolicyForAnyoneInSameAccount = IamPolicy.builder() | ||
.addStatement(statement -> statement | ||
.effect(IamEffect.ALLOW) | ||
.addPrincipal(principal -> principal | ||
.type(IamPrincipalType.AWS) | ||
.id("arn:aws:iam::" + accountID + ":root") | ||
) | ||
.addAction("sts:AssumeRole") | ||
.addConditions(IamConditionOperator.STRING_EQUALS, | ||
IamConditionKey.create("aws:PrincipalType"), | ||
List.of("User", "AssumedRole") | ||
).addConditions(IamConditionOperator.STRING_LIKE, | ||
"aws:userId", | ||
List.of("AIDAX*", "AROA*:*", "AIDA*:*")) | ||
) | ||
.build(); | ||
|
||
iamClient.createRole(crb -> crb | ||
.roleName(ROLE_NAME) | ||
.assumeRolePolicyDocument(trustIamPolicyForAnyoneInSameAccount.toJson()) | ||
); | ||
|
||
IamPolicy getBucketLocationOnlyPolicy = IamPolicy.builder() | ||
.addStatement(statement -> statement | ||
.effect(IamEffect.ALLOW) | ||
.addAction("s3:GetBucketLocation") | ||
.addResource("arn:aws:s3:::*") | ||
) | ||
.build(); | ||
|
||
iamClient.putRolePolicy(prprb -> prprb | ||
.roleName(ROLE_NAME) | ||
.policyName(POLICY_NAME) | ||
.policyDocument(getBucketLocationOnlyPolicy.toJson())); | ||
|
||
// Add a delay for the role to propagate. | ||
try { | ||
Thread.sleep(8000); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
|
||
} | ||
|
||
private static void deleteRole(){ | ||
|
||
iamClient.deleteRolePolicy(drbrb -> drbrb | ||
.roleName(ROLE_NAME) | ||
.policyName(POLICY_NAME)); | ||
|
||
iamClient.deleteRole(drb -> drb | ||
.roleName(ROLE_NAME) | ||
); | ||
} | ||
} | ||
|
Oops, something went wrong.