Skip to content

Commit

Permalink
feat(storage): set allowedByApp to listCallerAccessGrants (#13934)
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanZhengYP authored Oct 17, 2024
1 parent 5145064 commit 05ef3d8
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 46 deletions.
7 changes: 7 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ import tsParser from '@typescript-eslint/parser';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';

import customClientDtsBundlerConfig from './scripts/dts-bundler/dts-bundler.config.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
const customClientDtsFiles = customClientDtsBundlerConfig.entries
.map(clientBundlerConfig => clientBundlerConfig.outFile)
.filter(outFile => outFile?.length > 0)
.map(outFile => outFile.replace(__dirname + path.sep, '')) // Convert absolute path to relative path

export default [
{
Expand All @@ -39,6 +45,7 @@ export default [
'packages/interactions/__tests__',
'packages/predictions/__tests__',
'packages/pubsub/__tests__',
...customClientDtsFiles,
],
},
...fixupConfigRules(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ describe('listCallerAccessGrants', () => {
AccountId: mockAccountId,
NextToken: mockNextToken,
MaxResults: mockPageSize,
AllowedByApplication: true,
}),
);
const inputCredentialsProvider = jest.mocked(listCallerAccessGrantsClient)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ const listCallerAccessGrantsHappyCaseSingleGrant: ApiFunctionalTestCase<
GrantScope: 's3://my-bucket/path/to/',
MaxResults: 50,
NextToken: 'mockToken',
AllowedByApplication: true,
},
expect.objectContaining({
url: expect.objectContaining({
href: 'https://accountid.s3-control.us-east-1.amazonaws.com/v20180820/accessgrantsinstance/caller/grants?grantscope=s3%3A%2F%2Fmy-bucket%2Fpath%2Fto%2F&maxResults=50&nextToken=mockToken',
href: 'https://accountid.s3-control.us-east-1.amazonaws.com/v20180820/accessgrantsinstance/caller/grants?grantscope=s3%3A%2F%2Fmy-bucket%2Fpath%2Fto%2F&maxResults=50&nextToken=mockToken&allowedByApplication=true',
}),
method: 'GET',
headers: expect.objectContaining({
Expand Down Expand Up @@ -83,10 +84,11 @@ const listCallerAccessGrantsHappyCaseMultipleGrants: ApiFunctionalTestCase<
GrantScope: 's3://my-bucket/path/to/',
MaxResults: 50,
NextToken: 'mockToken',
AllowedByApplication: true,
},
expect.objectContaining({
url: expect.objectContaining({
href: 'https://accountid.s3-control.us-east-1.amazonaws.com/v20180820/accessgrantsinstance/caller/grants?grantscope=s3%3A%2F%2Fmy-bucket%2Fpath%2Fto%2F&maxResults=50&nextToken=mockToken',
href: 'https://accountid.s3-control.us-east-1.amazonaws.com/v20180820/accessgrantsinstance/caller/grants?grantscope=s3%3A%2F%2Fmy-bucket%2Fpath%2Fto%2F&maxResults=50&nextToken=mockToken&allowedByApplication=true',
}),
method: 'GET',
headers: expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export const listCallerAccessGrants = async (
AccountId: accountId,
NextToken: nextToken,
MaxResults: pageSize ?? MAX_PAGE_SIZE,
AllowedByApplication: true,
},
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ import type {
} from './types';
import { defaultConfig, parseXmlError } from './base';

export type ListCallerAccessGrantsInput = ListCallerAccessGrantsCommandInput;
export type ListCallerAccessGrantsInput = Pick<
ListCallerAccessGrantsCommandInput,
| 'AccountId'
| 'AllowedByApplication'
| 'GrantScope'
| 'NextToken'
| 'MaxResults'
>;

export type ListCallerAccessGrantsOutput = ListCallerAccessGrantsCommandOutput;

Expand All @@ -44,11 +51,12 @@ const listCallerAccessGrantsSerializer = (
grantscope: input.GrantScope,
maxResults: input.MaxResults,
nextToken: input.NextToken,
allowedByApplication: input.AllowedByApplication,
});
const url = new AmplifyUrl(endpoint.url.toString());
url.search = new AmplifyUrlSearchParams(query).toString();

// Ref: NA
// Ref: https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_ListCallerAccessGrants.html
url.pathname = '/v20180820/accessgrantsinstance/caller/grants';

return {
Expand Down
98 changes: 64 additions & 34 deletions packages/storage/src/providers/s3/utils/client/s3control/types.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

/*
This file contains manually curated AWS service types that are not yet available via the AWS SDK and the `dts-bundler`
script. Once these APIs have been released to the AWS SDK, this file can be removed in favor of the `dts-bundler`
types.
These types were harvested from Trebuchet.
@TODO(jimblanc) Unify types & integrate with `dts-bundler`
*/
/**
* Generated by scripts/dts-bundler/README.md
*/

import { MetadataBearer as __MetadataBearer } from '@aws-sdk/types';

Expand Down Expand Up @@ -44,33 +38,20 @@ export interface Credentials {
/**
* <p>The Amazon Web Services STS temporary credential that S3 Access Grants vends to grantees and client applications. </p>
* @public
* @public
*
* The input for {@link ListCallerAccessGrantsCommand}.
* @public
*
* The input for {@link ListCallerAccessGrantsCommand}.
*/
SessionToken?: string;
/**
* <p>The expiration date and time of the temporary credential that S3 Access Grants vends to grantees and client applications. </p>
* @public
* @public
*
* The output of {@link ListCallerAccessGrantsCommand}.
* @public
*
* The output of {@link ListCallerAccessGrantsCommand}.
*/
Expiration?: Date;
}

/**
* @public
*
* The input for {@link GetDataAccessCommand}.
*/
export type GetDataAccessCommandInput = GetDataAccessRequest;
export interface GetDataAccessCommandInput extends GetDataAccessRequest {}
/**
* @public
*
Expand All @@ -79,23 +60,20 @@ export type GetDataAccessCommandInput = GetDataAccessRequest;
export interface GetDataAccessCommandOutput
extends GetDataAccessResult,
__MetadataBearer {}

/**
* @public
*/
export interface GetDataAccessRequest {
/**
* <p>The ID of the Amazon Web Services account that is making this request.</p>
* <p>The Amazon Web Services account ID of the S3 Access Grants instance.</p>
* @public
*/
AccountId?: string;

/**
* <p>The S3 URI path of the data to which you are requesting temporary access credentials. If the requesting account has an access grant for this data, S3 Access Grants vends temporary access credentials in the response.</p>
* @public
*/
Target: string | undefined;

/**
* <p>The type of permission granted to your S3 data, which can be set to one of the following values:</p>
* <ul>
Expand All @@ -115,13 +93,11 @@ export interface GetDataAccessRequest {
* @public
*/
Permission: Permission | undefined;

/**
* <p>The session duration, in seconds, of the temporary access credential that S3 Access Grants vends to the grantee or client application. The default value is 1 hour, but the grantee can specify a range from 900 seconds (15 minutes) up to 43200 seconds (12 hours). If the grantee requests a value higher than this maximum, the operation fails. </p>
* @public
*/
DurationSeconds?: number;

/**
* <p>The scope of the temporary access credential that S3 Access Grants vends to the grantee or client application. </p>
* <ul>
Expand All @@ -137,14 +113,12 @@ export interface GetDataAccessRequest {
* @public
*/
Privilege?: Privilege;

/**
* <p>The type of <code>Target</code>. The only possible value is <code>Object</code>. Pass this value if the target data that you would like to access is a path to an object. Do not pass this value if the target data is a bucket or a bucket and a prefix. </p>
* @public
*/
TargetType?: S3PrefixType;
}

/**
* @public
*/
Expand All @@ -154,20 +128,19 @@ export interface GetDataAccessResult {
* @public
*/
Credentials?: Credentials;

/**
* <p>The S3 URI path of the data to which you are being granted temporary access credentials. </p>
* @public
*/
MatchedGrantTarget?: string;
}

/**
* @public
*
* The input for {@link ListCallerAccessGrantsCommand}.
*/
export type ListCallerAccessGrantsCommandInput = ListCallerAccessGrantsRequest;
export interface ListCallerAccessGrantsCommandInput
extends ListCallerAccessGrantsRequest {}
/**
* @public
*
Expand All @@ -177,27 +150,84 @@ export interface ListCallerAccessGrantsCommandOutput
extends ListCallerAccessGrantsResult,
__MetadataBearer {}
/**
* <p>Part of <code>ListCallerAccessGrantsResult</code>. Each entry includes the
* permission level (READ, WRITE, or READWRITE) and the grant scope of the access grant. If the grant also includes an application ARN, the grantee can only access the S3 data through this application.</p>
* @public
*/
export interface ListCallerAccessGrantsEntry {
/**
* <p>The type of permission granted, which can be one of the following values:</p>
* <ul>
* <li>
* <p>
* <code>READ</code> - Grants read-only access to the S3 data.</p>
* </li>
* <li>
* <p>
* <code>WRITE</code> - Grants write-only access to the S3 data.</p>
* </li>
* <li>
* <p>
* <code>READWRITE</code> - Grants both read and write access to the S3 data.</p>
* </li>
* </ul>
* @public
*/
Permission?: Permission;
/**
* <p>The S3 path of the data to which you have been granted access. </p>
* @public
*/
GrantScope?: string;
/**
* <p>The Amazon Resource Name (ARN) of an Amazon Web Services IAM Identity Center application associated with your Identity Center instance. If the grant includes an application ARN, the grantee can only access the S3 data through this application. </p>
* @public
*/
ApplicationArn?: string;
}
/**
* @public
*/
export interface ListCallerAccessGrantsRequest {
/**
* <p>The Amazon Web Services account ID of the S3 Access Grants instance.</p>
* @public
*/
AccountId?: string;
/**
* <p>The S3 path of the data that you would like to access. Must start with <code>s3://</code>. You can optionally pass only the beginning characters of a path, and S3 Access Grants will search for all applicable grants for the path fragment. </p>
* @public
*/
GrantScope?: string;
/**
* <p>A pagination token to request the next page of results. Pass this value into a subsequent <code>List Caller Access Grants</code> request in order to retrieve the next page of results.</p>
* @public
*/
NextToken?: string;
/**
* <p>The maximum number of access grants that you would like returned in the <code>List Caller Access Grants</code> response. If the results include the pagination token <code>NextToken</code>, make another call using the <code>NextToken</code> to determine if there are more results.</p>
* @public
*/
MaxResults?: number;
/**
* <p>If this optional parameter is passed in the request, a filter is applied to the results. The results will include only the access grants for the caller's Identity Center application or for any other applications (<code>ALL</code>).</p>
* @public
*/
AllowedByApplication?: boolean;
}
/**
* @public
*/
export interface ListCallerAccessGrantsResult {
/**
* <p>A pagination token that you can use to request the next page of results. Pass this value into a subsequent <code>List Caller Access Grants</code> request in order to retrieve the next page of results.</p>
* @public
*/
NextToken?: string;
/**
* <p>A list of the caller's access grants that were created using S3 Access Grants and that grant the caller access to the S3 data of the Amazon Web Services account ID that was specified in the request. </p>
* @public
*/
CallerAccessGrantsList?: ListCallerAccessGrantsEntry[];
}
/**
Expand Down
36 changes: 29 additions & 7 deletions scripts/dts-bundler/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
This project is used to rollup the TS types from the AWS SDK into the custom AWS clients. You can regenerate them
by running the `build` script in this project, and commit the generated file changes.
## What is this package?

To update the generated types files, you need to:
Amplify JS uses custom AWS API clients in limited scope. These API handlers' types are compatible with those of
AWS SDK, and trimmed to the parameters used by the Amplify library.

1. Update existing `*.d.ts` files in this folder or add new ones.
1. If new `*.d.ts` file is added, update the `dts-bundler.config.js` with additional entries.
This package is used to rollup the TS types from the AWS SDK into the custom AWS clients. You can regenerate them
by running the `build` script in this project, then review & commit the generated file changes.

## How to update the custom AWS clients types?

Since custom AWS clients are used in limited scope, in most cases you don't need to add any new services. Instead, you
may need to update the SDK versions or exporting additional types. Here's the steps:

1. Make sure the `package.json` dev dependencies entry contains the AWS SDK service client you are working with and
more importantly the version is upgraded to that supports the feature you are working with.
1. Open the `*.d.ts` file for the AWS client you need to upgrade, and make sure the interfaces you need are exported.
1. Open the `dts-bundler.config.js` file and make sure the entry to the `*.d.ts` file you are working with exists and
the `outFile` path is expected.
* You need to update the `libraries.inlinedLibraries` to include the AWS SDK service client package to bundle
the TS interfaces there.
1. Run the generating script `yarn && yarn build`. The generated files will be shown in the console.
1. Inspect generated files and make sure headers are not changed.
1. Commit the changes
* If you only want to work with a single AWS service instead of changing all the definitions for all the services,
you can comment out other service entries from the `dts-bundler.config.js`.
1. Inspect the bundled TypeScript definition file in the `outFile` path. To better compare the diffs, you need to
re-format the generated code.
* You need to make sure any license headers and previous notes are not changed.
* The bundled TypeScript definition file may import more types transitive dependencies of AWS SDK package. In this
case you may need to tweak the `libraries.inlinedLibraries` config until all the necessary dependency types are
bundled.
* You need to make sure the imported packages of the bundle file(e.g. `@aws-sdk/types`) are also added to the
Amplify library's **runtime dependency**.
* You **must** make sure the documented manual changes are re-applied to the newly generated bundle file.
8 changes: 8 additions & 0 deletions scripts/dts-bundler/dts-bundler.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ const config = {
},
output: outputConfig,
},
{
filePath: './s3-control.d.ts',
outFile: join(storagePackageSrcClientsPath, 'client', 's3control', 'types.ts'),
libraries: {
inlinedLibraries: ['@aws-sdk/client-s3-control'],
},
output: outputConfig,
},
{
filePath: './cognito-identity-provider.d.ts',
outFile: join(
Expand Down
4 changes: 3 additions & 1 deletion scripts/dts-bundler/package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
{
"name": "api-extract-aws-clients",
"private": true,
"devDependencies": {
"@aws-sdk/client-pinpoint": "3.335.1",
"@aws-sdk/client-cognito-identity": "3.335.0",
"@aws-sdk/client-cognito-identity-provider": "3.386.0",
"@aws-sdk/client-s3": "3.335.0",
"@aws-sdk/client-s3": "3.673.0",
"@aws-sdk/client-s3-control": "3.670.0",
"dts-bundle-generator": "^8.0.1"
},
"scripts": {
Expand Down
13 changes: 13 additions & 0 deletions scripts/dts-bundler/s3-control.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 05ef3d8

Please sign in to comment.