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

feat(experimentalIdentityAndAuth): add @aws.auth#sigv4 integration tests #1012

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/kind-cameras-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@smithy/experimental-identity-and-auth": patch
---

Add `@aws.auth#sigv4` integration tests.
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import {
OnlySigv4AuthCommand,
OnlySigv4AuthOptionalCommand,
SameAsServiceCommand,
Sigv4ServiceClient,
} from "@smithy/identity-and-auth-sigv4-service";
import { AwsCredentialIdentity } from "@smithy/types";
import { requireRequestsFrom } from "@smithy/util-test";

describe("@aws.auth#sigv4 integration tests", () => {
// TODO(experimentalIdentityAndAuth): should match `Sigv4Service` `@aws.auth#sigv4` trait
const MOCK_CREDENTIALS: AwsCredentialIdentity = {
accessKeyId: "MOCK_ACCESS_KEY_ID",
secretAccessKey: "SECRET_ACCESS_KEY",
sessionToken: "SESSION_TOKEN",
};
const MOCK_REGION = "us-east-1";

// Arbitrary mock endpoint (`requireRequestsFrom()` intercepts network requests)
const MOCK_ENDPOINT = "https://foo.bar";

describe("`@aws.auth#sigv4` `region` configuration", () => {
it("Client should throw if `region` is not configured", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
});
requireRequestsFrom(client).toMatch({});
await expect(client.send(new OnlySigv4AuthOptionalCommand({}))).rejects.toThrow(
"expected `region` to be configured for `aws.auth#sigv4`"
);
});

it("Client should NOT throw if `region` is configured", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
});
requireRequestsFrom(client).toMatch({
headers: {
Authorization: (value) => expect(value).toBeUndefined(),
},
});
await client.send(new OnlySigv4AuthOptionalCommand({}));
});
});

describe("Operation requires `@aws.auth#sigv4`", () => {
it("Request is thrown when `credentials` is not configured", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
});
requireRequestsFrom(client).toMatch({});
await expect(client.send(new OnlySigv4AuthCommand({}))).rejects.toThrow(
"HttpAuthScheme `aws.auth#sigv4` did not have an IdentityProvider configured."
);
});

it("Request is signed given configured `credentials`", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
credentials: async () => MOCK_CREDENTIALS,
});
requireRequestsFrom(client).toMatch({});
await client.send(new OnlySigv4AuthCommand({}));
});
});

describe("Operation has `@aws.auth#sigv4` and `@optionalAuth`", () => {
it("Request is NOT thrown and NOT signed when `credentials` is not configured", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
});
requireRequestsFrom(client).toMatch({
headers: {
Authorization: (value) => expect(value).toBeUndefined(),
},
});
await client.send(new OnlySigv4AuthOptionalCommand({}));
});

it("Request is signed given configured `credentials`", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
credentials: async () => MOCK_CREDENTIALS,
});
requireRequestsFrom(client).toMatch({});
await client.send(new OnlySigv4AuthOptionalCommand({}));
});
});

describe("Service has `@aws.auth#sigv4`", () => {
it("Request is thrown when `credentials` is not configured", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
});
requireRequestsFrom(client).toMatch({});
await expect(client.send(new SameAsServiceCommand({}))).rejects.toThrow(
"HttpAuthScheme `aws.auth#sigv4` did not have an IdentityProvider configured."
);
});

it("Request is signed given configured `credentials`", async () => {
const client = new Sigv4ServiceClient({
endpoint: MOCK_ENDPOINT,
region: MOCK_REGION,
credentials: async () => MOCK_CREDENTIALS,
});
requireRequestsFrom(client).toMatch({});
await client.send(new SameAsServiceCommand({}));
});
});
});
9 changes: 9 additions & 0 deletions scripts/build-generated-test-packages.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ const weatherSsdkDir = path.join(
"typescript-ssdk-codegen"
)

// TODO(experimentalIdentityAndAuth): add `@aws.auth#sigv4` client for integration tests
const sigv4ClientDir = path.join(
codegenTestDir,
"identity-and-auth-sigv4",
"typescript-codegen"
);

const nodeModulesDir = path.join(root, "node_modules");

const buildAndCopyToNodeModules = async (packageName, codegenDir, nodeModulesDir) => {
Expand All @@ -52,6 +59,8 @@ const buildAndCopyToNodeModules = async (packageName, codegenDir, nodeModulesDir
try {
await buildAndCopyToNodeModules("weather", weatherClientDir, nodeModulesDir);
await buildAndCopyToNodeModules("weather-ssdk", weatherSsdkDir, nodeModulesDir);
// TODO(experimentalIdentityAndAuth): add `@aws.auth#sigv4` client for integration tests
await buildAndCopyToNodeModules("@smithy/identity-and-auth-sigv4-service", sigv4ClientDir, nodeModulesDir);
} catch (e) {
console.log(e);
process.exit(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
$version: "2.0"

namespace identity.auth.sigv4

use aws.auth#sigv4
use common#fakeProtocol

@fakeProtocol
@sigv4(name: "weather")
service Sigv4Service {
operations: [
OnlySigv4Auth
OnlySigv4AuthOptional
SameAsService
]
}

@http(method: "GET", uri: "/OnlySigv4Auth")
@auth([sigv4])
operation OnlySigv4Auth {}

@http(method: "GET", uri: "/OnlySigv4AuthOptional")
@auth([sigv4])
@optionalAuth
operation OnlySigv4AuthOptional {}

@http(method: "GET", uri: "/SameAsService")
operation SameAsService {}
23 changes: 23 additions & 0 deletions smithy-typescript-codegen-test/smithy-build.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@
}
}
}
},
"identity-and-auth-sigv4": {
"transforms": [
{
"name": "includeServices",
"args": {
"services": ["identity.auth.sigv4#Sigv4Service"]
}
}
],
"plugins": {
"typescript-codegen": {
"service": "identity.auth.sigv4#Sigv4Service",
"targetNamespace": "Sigv4Service",
"package": "@smithy/identity-and-auth-sigv4-service",
"packageVersion": "0.0.1",
"packageJson": {
"license": "Apache-2.0",
"private": true
},
"experimentalIdentityAndAuth": true
}
}
}
},
"plugins": {
Expand Down
Loading