Skip to content

Commit

Permalink
feat(storage): add an adapter interface for storage browser (#13576)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Jim Blanchard <[email protected]>
  • Loading branch information
AllanZhengYP and jimblanc authored Jul 15, 2024
1 parent bcd8c9d commit 335315a
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -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,
});
});
});
18 changes: 2 additions & 16 deletions packages/storage/src/storageBrowser/index.ts
Original file line number Diff line number Diff line change
@@ -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';
5 changes: 0 additions & 5 deletions packages/storage/src/storageBrowser/listCallerAccessGrants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<AccessGrant>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import {
CredentialsLocation,
LocationCredentialsHandler,
GetLocationCredentials,
LocationCredentialsStore,
} from '../types';
import { StorageValidationErrorCode } from '../../errors/types/validation';
Expand All @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -33,7 +33,7 @@ const storeRegistry = new WeakMap<
* @internal
*/
export const createStore = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
size?: number,
) => {
const storeSymbol = { value: Symbol('LocationCredentialsStore') };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -35,15 +35,15 @@ const createCacheKey = (location: CredentialsLocation): CacheKey =>
*/
export interface LruLocationCredentialsStore {
capacity: number;
refreshHandler: LocationCredentialsHandler;
refreshHandler: GetLocationCredentials;
values: Map<CacheKey, StoreValue>;
}

/**
* @internal
*/
export const initStore = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
size = CREDENTIALS_STORE_DEFAULT_SIZE,
): LruLocationCredentialsStore => {
assertValidationError(
Expand Down Expand Up @@ -117,7 +117,7 @@ export const fetchNewValue = async (
};

const dispatchRefresh = (
refreshHandler: LocationCredentialsHandler,
refreshHandler: GetLocationCredentials,
value: StoreValue,
onRefreshFailure: () => void,
) => {
Expand Down
27 changes: 0 additions & 27 deletions packages/storage/src/storageBrowser/managedAuthAdapter.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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');
};
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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');
};
Original file line number Diff line number Diff line change
@@ -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,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

export { createManagedAuthConfigAdapter } from './createManagedAuthConfigAdapter';
16 changes: 12 additions & 4 deletions packages/storage/src/storageBrowser/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,19 @@ export interface ListLocationsOutput<T extends LocationAccess> {
nextToken?: string;
}

// Interface for listLocations() handler
export type ListLocations = () => Promise<ListLocationsOutput<LocationAccess>>;
/**
* @internal
*/
export interface ListLocationsInput {
pageSize?: number;
nextToken?: string;
}

export type ListLocations = (
input?: ListLocationsInput,
) => Promise<ListLocationsOutput<LocationAccess>>;

// Interface for getLocationCredentials() handler.
export type LocationCredentialsHandler = (
export type GetLocationCredentials = (
input: CredentialsLocation,
) => Promise<{ credentials: AWSCredentials }>;

Expand Down

0 comments on commit 335315a

Please sign in to comment.