From 335315a3265697b80092325837b4c1fec6cd38a5 Mon Sep 17 00:00:00 2001 From: AllanZhengYP Date: Mon, 15 Jul 2024 11:43:35 -0700 Subject: [PATCH] feat(storage): add an adapter interface for storage browser (#13576) --------- Co-authored-by: Jim Blanchard --- .../createManagedAuthConfigAdapter.test.ts | 72 +++++++++++++++++++ packages/storage/src/storageBrowser/index.ts | 18 +---- .../storageBrowser/listCallerAccessGrants.ts | 5 -- .../locationCredentialsStore/create.ts | 4 +- .../locationCredentialsStore/registry.ts | 4 +- .../locationCredentialsStore/store.ts | 8 +-- .../src/storageBrowser/managedAuthAdapter.ts | 27 ------- .../createListLocationsHandler.ts | 18 +++++ .../createLocationCredentialsHandler.ts | 4 +- .../createManagedAuthConfigAdapter.ts | 52 ++++++++++++++ .../managedAuthConfigAdapter/index.ts | 4 ++ packages/storage/src/storageBrowser/types.ts | 16 +++-- 12 files changed, 170 insertions(+), 62 deletions(-) create mode 100644 packages/storage/__tests__/storageBrowser/managedAuthAdapter/createManagedAuthConfigAdapter.test.ts delete mode 100644 packages/storage/src/storageBrowser/managedAuthAdapter.ts create mode 100644 packages/storage/src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler.ts rename packages/storage/src/storageBrowser/{ => managedAuthConfigAdapter}/createLocationCredentialsHandler.ts (80%) create mode 100644 packages/storage/src/storageBrowser/managedAuthConfigAdapter/createManagedAuthConfigAdapter.ts create mode 100644 packages/storage/src/storageBrowser/managedAuthConfigAdapter/index.ts diff --git a/packages/storage/__tests__/storageBrowser/managedAuthAdapter/createManagedAuthConfigAdapter.test.ts b/packages/storage/__tests__/storageBrowser/managedAuthAdapter/createManagedAuthConfigAdapter.test.ts new file mode 100644 index 00000000000..124fc16cd7a --- /dev/null +++ b/packages/storage/__tests__/storageBrowser/managedAuthAdapter/createManagedAuthConfigAdapter.test.ts @@ -0,0 +1,72 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { createManagedAuthConfigAdapter } from '../../../src/storageBrowser/managedAuthConfigAdapter'; +import { createListLocationsHandler } from '../../../src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler'; +import { createLocationCredentialsHandler } from '../../../src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler'; + +jest.mock( + '../../../src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler', +); +jest.mock( + '../../../src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler', +); + +describe('createManagedAuthConfigAdapter', () => { + const region = 'us-foo-2'; + const accountId = 'XXXXXXXXXXXX'; + const credentialsProvider = jest.fn(); + + beforeEach(() => { + jest + .mocked(createListLocationsHandler) + .mockReturnValue('LIST_LOCATIONS_FN' as any); + jest + .mocked(createLocationCredentialsHandler) + .mockReturnValue('GET_LOCATION_CREDENTIALS_FN' as any); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should pass region to the adapter', () => { + expect(createManagedAuthConfigAdapter({ region } as any)).toMatchObject({ + region, + }); + }); + + it('should create list locations handler', () => { + expect( + createManagedAuthConfigAdapter({ + region, + accountId, + credentialsProvider, + }), + ).toMatchObject({ + listLocations: 'LIST_LOCATIONS_FN', + }); + expect(createListLocationsHandler).toHaveBeenCalledWith({ + region, + accountId, + credentialsProvider, + }); + }); + + it('should create get location credentials handler', () => { + expect( + createManagedAuthConfigAdapter({ + region, + accountId, + credentialsProvider, + }), + ).toMatchObject({ + getLocationCredentials: 'GET_LOCATION_CREDENTIALS_FN', + }); + expect(createLocationCredentialsHandler).toHaveBeenCalledWith({ + region, + accountId, + credentialsProvider, + }); + }); +}); diff --git a/packages/storage/src/storageBrowser/index.ts b/packages/storage/src/storageBrowser/index.ts index 7d36d419558..bde6d9bfe82 100644 --- a/packages/storage/src/storageBrowser/index.ts +++ b/packages/storage/src/storageBrowser/index.ts @@ -1,20 +1,6 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -/** - * NOTE: The APIs exported from this file are ONLY intended for usage by - * Amplify UI. To use location-related features, please use - * @aws-amplify/ui-react-storage - */ - -export { - listCallerAccessGrants, - ListCallerAccessGrantsInput, - ListCallerAccessGrantsOutput, -} from './listCallerAccessGrants'; -export { createLocationCredentialsHandler } from './createLocationCredentialsHandler'; export { createLocationCredentialsStore } from './locationCredentialsStore'; -export { - managedAuthAdapter, - ManagedAuthAdapterInput, -} from './managedAuthAdapter'; +export { createManagedAuthConfigAdapter } from './managedAuthConfigAdapter/createManagedAuthConfigAdapter'; +export { GetLocationCredentials, ListLocations } from './types'; diff --git a/packages/storage/src/storageBrowser/listCallerAccessGrants.ts b/packages/storage/src/storageBrowser/listCallerAccessGrants.ts index cd13e6a5dc5..c55b0ea75e8 100644 --- a/packages/storage/src/storageBrowser/listCallerAccessGrants.ts +++ b/packages/storage/src/storageBrowser/listCallerAccessGrants.ts @@ -7,11 +7,6 @@ export interface ListCallerAccessGrantsInput { accountId: string; credentialsProvider: CredentialsProvider; region: string; - options?: { - nextToken?: string; - // Default to 100; If > 1000, API will make multiple API calls. - pageSize?: number; - }; } export type ListCallerAccessGrantsOutput = ListLocationsOutput; diff --git a/packages/storage/src/storageBrowser/locationCredentialsStore/create.ts b/packages/storage/src/storageBrowser/locationCredentialsStore/create.ts index dc8da21bff5..a54ae32a354 100644 --- a/packages/storage/src/storageBrowser/locationCredentialsStore/create.ts +++ b/packages/storage/src/storageBrowser/locationCredentialsStore/create.ts @@ -3,7 +3,7 @@ import { CredentialsLocation, - LocationCredentialsHandler, + GetLocationCredentials, LocationCredentialsStore, } from '../types'; import { StorageValidationErrorCode } from '../../errors/types/validation'; @@ -17,7 +17,7 @@ import { createStore, getValue, removeStore } from './registry'; import { validateCredentialsProviderLocation } from './validators'; export const createLocationCredentialsStore = (input: { - handler: LocationCredentialsHandler; + handler: GetLocationCredentials; }): LocationCredentialsStore => { const storeSymbol = createStore(input.handler); diff --git a/packages/storage/src/storageBrowser/locationCredentialsStore/registry.ts b/packages/storage/src/storageBrowser/locationCredentialsStore/registry.ts index 6c3d41780f9..54ed8e4db83 100644 --- a/packages/storage/src/storageBrowser/locationCredentialsStore/registry.ts +++ b/packages/storage/src/storageBrowser/locationCredentialsStore/registry.ts @@ -4,7 +4,7 @@ // SPDX-License-Identifier: Apache-2.0 import { AWSCredentials } from '@aws-amplify/core/internals/utils'; -import { CredentialsLocation, LocationCredentialsHandler } from '../types'; +import { CredentialsLocation, GetLocationCredentials } from '../types'; import { assertValidationError } from '../../errors/utils/assertValidationError'; import { StorageValidationErrorCode } from '../../errors/types/validation'; @@ -33,7 +33,7 @@ const storeRegistry = new WeakMap< * @internal */ export const createStore = ( - refreshHandler: LocationCredentialsHandler, + refreshHandler: GetLocationCredentials, size?: number, ) => { const storeSymbol = { value: Symbol('LocationCredentialsStore') }; diff --git a/packages/storage/src/storageBrowser/locationCredentialsStore/store.ts b/packages/storage/src/storageBrowser/locationCredentialsStore/store.ts index ac1901d669b..04e800365c7 100644 --- a/packages/storage/src/storageBrowser/locationCredentialsStore/store.ts +++ b/packages/storage/src/storageBrowser/locationCredentialsStore/store.ts @@ -6,7 +6,7 @@ import { AWSCredentials } from '@aws-amplify/core/internals/utils'; import { Permission } from '../../providers/s3/types/options'; -import { CredentialsLocation, LocationCredentialsHandler } from '../types'; +import { CredentialsLocation, GetLocationCredentials } from '../types'; import { assertValidationError } from '../../errors/utils/assertValidationError'; import { StorageValidationErrorCode } from '../../errors/types/validation'; @@ -35,7 +35,7 @@ const createCacheKey = (location: CredentialsLocation): CacheKey => */ export interface LruLocationCredentialsStore { capacity: number; - refreshHandler: LocationCredentialsHandler; + refreshHandler: GetLocationCredentials; values: Map; } @@ -43,7 +43,7 @@ export interface LruLocationCredentialsStore { * @internal */ export const initStore = ( - refreshHandler: LocationCredentialsHandler, + refreshHandler: GetLocationCredentials, size = CREDENTIALS_STORE_DEFAULT_SIZE, ): LruLocationCredentialsStore => { assertValidationError( @@ -117,7 +117,7 @@ export const fetchNewValue = async ( }; const dispatchRefresh = ( - refreshHandler: LocationCredentialsHandler, + refreshHandler: GetLocationCredentials, value: StoreValue, onRefreshFailure: () => void, ) => { diff --git a/packages/storage/src/storageBrowser/managedAuthAdapter.ts b/packages/storage/src/storageBrowser/managedAuthAdapter.ts deleted file mode 100644 index 9f3214b3158..00000000000 --- a/packages/storage/src/storageBrowser/managedAuthAdapter.ts +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -import { - CredentialsProvider, - ListLocations, - LocationCredentialsHandler, -} from './types'; - -export interface ManagedAuthAdapterInput { - accountId: string; - region: string; - credentialsProvider: CredentialsProvider; -} - -export interface ManagedAuthAdapterOutput { - listLocations: ListLocations; - getLocationCredentials: LocationCredentialsHandler; - region: string; -} - -export const managedAuthAdapter = ( - // eslint-disable-next-line unused-imports/no-unused-vars - input: ManagedAuthAdapterInput, -): ManagedAuthAdapterOutput => { - // TODO(@AllanZhengYP) - throw new Error('Not implemented'); -}; diff --git a/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler.ts b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler.ts new file mode 100644 index 00000000000..c3e9c3c1a4a --- /dev/null +++ b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createListLocationsHandler.ts @@ -0,0 +1,18 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +import { CredentialsProvider, ListLocations } from '../types'; + +export interface CreateListLocationsHandlerInput { + accountId: string; + credentialsProvider: CredentialsProvider; + region: string; +} + +export const createListLocationsHandler = ( + // eslint-disable-next-line unused-imports/no-unused-vars + input: CreateListLocationsHandlerInput, +): ListLocations => { + // TODO(@AllanZhengYP) + throw new Error('Not Implemented'); +}; diff --git a/packages/storage/src/storageBrowser/createLocationCredentialsHandler.ts b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler.ts similarity index 80% rename from packages/storage/src/storageBrowser/createLocationCredentialsHandler.ts rename to packages/storage/src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler.ts index 5da981d71bc..9cded212928 100644 --- a/packages/storage/src/storageBrowser/createLocationCredentialsHandler.ts +++ b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createLocationCredentialsHandler.ts @@ -1,7 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -import { CredentialsProvider, LocationCredentialsHandler } from './types'; +import { CredentialsProvider, GetLocationCredentials } from '../types'; interface CreateLocationCredentialsHandlerInput { accountId: string; @@ -12,7 +12,7 @@ interface CreateLocationCredentialsHandlerInput { export const createLocationCredentialsHandler = ( // eslint-disable-next-line unused-imports/no-unused-vars input: CreateLocationCredentialsHandlerInput, -): LocationCredentialsHandler => { +): GetLocationCredentials => { // TODO(@AllanZhengYP) throw new Error('Not Implemented'); }; diff --git a/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createManagedAuthConfigAdapter.ts b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createManagedAuthConfigAdapter.ts new file mode 100644 index 00000000000..55d334b47c7 --- /dev/null +++ b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/createManagedAuthConfigAdapter.ts @@ -0,0 +1,52 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +import { + CredentialsProvider, + GetLocationCredentials, + ListLocations, +} from '../types'; + +import { createListLocationsHandler } from './createListLocationsHandler'; +import { createLocationCredentialsHandler } from './createLocationCredentialsHandler'; + +interface CreateManagedAuthConfigAdapterInput { + accountId: string; + region: string; + credentialsProvider: CredentialsProvider; +} + +interface AuthConfigAdapter { + listLocations: ListLocations; + getLocationCredentials: GetLocationCredentials; + region: string; +} + +/** + * Create configuration including handlers to call S3 Access Grant APIs to list and get + * credentials for different locations. + * + * @param options - Configuration options for the adapter. + * @returns - An object containing the handlers to call S3 Access Grant APIs and region + */ +export const createManagedAuthConfigAdapter = ({ + credentialsProvider, + region, + accountId, +}: CreateManagedAuthConfigAdapterInput): AuthConfigAdapter => { + const listLocations = createListLocationsHandler({ + credentialsProvider, + accountId, + region, + }); + const getLocationCredentials = createLocationCredentialsHandler({ + credentialsProvider, + accountId, + region, + }); + + return { + listLocations, + getLocationCredentials, + region, + }; +}; diff --git a/packages/storage/src/storageBrowser/managedAuthConfigAdapter/index.ts b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/index.ts new file mode 100644 index 00000000000..4e04b1a2a77 --- /dev/null +++ b/packages/storage/src/storageBrowser/managedAuthConfigAdapter/index.ts @@ -0,0 +1,4 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +export { createManagedAuthConfigAdapter } from './createManagedAuthConfigAdapter'; diff --git a/packages/storage/src/storageBrowser/types.ts b/packages/storage/src/storageBrowser/types.ts index 2525560369f..3f184dcc313 100644 --- a/packages/storage/src/storageBrowser/types.ts +++ b/packages/storage/src/storageBrowser/types.ts @@ -68,11 +68,19 @@ export interface ListLocationsOutput { nextToken?: string; } -// Interface for listLocations() handler -export type ListLocations = () => Promise>; +/** + * @internal + */ +export interface ListLocationsInput { + pageSize?: number; + nextToken?: string; +} + +export type ListLocations = ( + input?: ListLocationsInput, +) => Promise>; -// Interface for getLocationCredentials() handler. -export type LocationCredentialsHandler = ( +export type GetLocationCredentials = ( input: CredentialsLocation, ) => Promise<{ credentials: AWSCredentials }>;