Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow x-api-key for public rest api #13422

Merged
merged 13 commits into from
Aug 22, 2024
73 changes: 73 additions & 0 deletions packages/api-rest/__tests__/utils/iamAuthApplicable.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { HttpRequest } from '@aws-amplify/core/internals/aws-client-utils';

Check failure on line 4 in packages/api-rest/__tests__/utils/iamAuthApplicable.test.ts

View workflow job for this annotation

GitHub Actions / unit-tests / Unit Test - @aws-amplify/api-rest

There should be at least one empty line between import groups
import {
iamAuthApplicableForGraphQL,
iamAuthApplicableForPublic,
} from '../../src/utils/iamAuthApplicable';

describe('iamAuthApplicable', () => {
const url = new URL('https://url');
const baseRequest: HttpRequest = {
headers: {},
url: url,

Check failure on line 14 in packages/api-rest/__tests__/utils/iamAuthApplicable.test.ts

View workflow job for this annotation

GitHub Actions / unit-tests / Unit Test - @aws-amplify/api-rest

Expected property shorthand
method: 'put',
};

describe('iamAuthApplicableForGraphQL', () => {
it('should return true if there is no authorization header, no x-api-key header, and signingServiceInfo is provided', () => {
const signingServiceInfo = {};
ashika112 marked this conversation as resolved.
Show resolved Hide resolved
expect(iamAuthApplicableForGraphQL(baseRequest, signingServiceInfo)).toBe(
true,
);
});

it('should return false if there is an authorization header', () => {
const request = {
...baseRequest,
headers: { authorization: 'SampleToken' },
};
const signingServiceInfo = {};
expect(iamAuthApplicableForGraphQL(request, signingServiceInfo)).toBe(
false,
);
});

it('should return false if there is an x-api-key header', () => {
const request = { ...baseRequest, headers: { 'x-api-key': 'key' } };
const signingServiceInfo = {};
expect(iamAuthApplicableForGraphQL(request, signingServiceInfo)).toBe(
false,
);
});

it('should return false if signingServiceInfo is not provided', () => {
expect(iamAuthApplicableForGraphQL(baseRequest)).toBe(false);
});
});

describe('iamAuthApplicableForPublic', () => {
it('should return true if there is no authorization header and signingServiceInfo is provided', () => {
const signingServiceInfo = {};
expect(iamAuthApplicableForPublic(baseRequest, signingServiceInfo)).toBe(
true,
);
});

it('should return false if there is an authorization header', () => {
const request = {
...baseRequest,
headers: { authorization: 'SampleToken' },
};
const signingServiceInfo = {};
expect(iamAuthApplicableForPublic(request, signingServiceInfo)).toBe(
false,
);
});

it('should return false if signingServiceInfo is not provided', () => {
expect(iamAuthApplicableForPublic(baseRequest)).toBe(false);
});
});
});
11 changes: 6 additions & 5 deletions packages/api-rest/src/apis/common/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
} from '../../utils';
import { resolveHeaders } from '../../utils/resolveHeaders';
import { RestApiResponse } from '../../types';
import { iamAuthApplicableForGraphQL } from '../../utils/iamAuthApplicable';

type HandlerOptions = Omit<HttpRequest, 'body' | 'headers'> & {
body?: DocumentType | FormData;
Expand All @@ -47,6 +48,10 @@ export const transferHandler = async (
amplify: AmplifyClassV6,
options: HandlerOptions & { abortSignal: AbortSignal },
signingServiceInfo?: SigningServiceInfo,
iamAuthApplicable: (
ashika112 marked this conversation as resolved.
Show resolved Hide resolved
{ headers }: HttpRequest,
signingServiceInfo?: SigningServiceInfo,
) => boolean = iamAuthApplicableForGraphQL,
): Promise<RestApiResponse> => {
const { url, method, headers, body, withCredentials, abortSignal } = options;
const resolvedBody = body
Expand All @@ -69,6 +74,7 @@ export const transferHandler = async (
};

const isIamAuthApplicable = iamAuthApplicable(request, signingServiceInfo);

let response: RestApiResponse;
const credentials = await resolveCredentials(amplify);
if (isIamAuthApplicable && credentials) {
Expand Down Expand Up @@ -97,11 +103,6 @@ export const transferHandler = async (
};
};

const iamAuthApplicable = (
{ headers }: HttpRequest,
signingServiceInfo?: SigningServiceInfo,
) => !headers.authorization && !headers['x-api-key'] && !!signingServiceInfo;

const resolveCredentials = async (
amplify: AmplifyClassV6,
): Promise<AWSCredentials | null> => {
Expand Down
2 changes: 2 additions & 0 deletions packages/api-rest/src/apis/common/publicApis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
parseSigningInfo,
resolveApiUrl,
} from '../../utils';
import { iamAuthApplicableForPublic } from '../../utils/iamAuthApplicable';

import { transferHandler } from './handler';

Expand Down Expand Up @@ -72,6 +73,7 @@ const publicHandler = (
abortSignal,
},
signingServiceInfo,
iamAuthApplicableForPublic,
ashika112 marked this conversation as resolved.
Show resolved Hide resolved
);
});

Expand Down
19 changes: 19 additions & 0 deletions packages/api-rest/src/utils/iamAuthApplicable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

import { HttpRequest } from '@aws-amplify/core/internals/aws-client-utils';

interface SigningServiceInfo {
service?: string;
region?: string;
}

export const iamAuthApplicableForGraphQL = (
ashika112 marked this conversation as resolved.
Show resolved Hide resolved
{ headers }: HttpRequest,
signingServiceInfo?: SigningServiceInfo,
) => !headers.authorization && !headers['x-api-key'] && !!signingServiceInfo;

export const iamAuthApplicableForPublic = (
ashika112 marked this conversation as resolved.
Show resolved Hide resolved
{ headers }: HttpRequest,
signingServiceInfo?: SigningServiceInfo,
) => !headers.authorization && !!signingServiceInfo;
Loading