|
| 1 | +import { fromTokenFile } from "@aws-sdk/credential-provider-web-identity"; |
1 | 2 | import { ENV_CONFIG_PATH, ENV_CREDENTIALS_PATH } from "@aws-sdk/shared-ini-file-loader";
|
2 | 3 | import { Credentials } from "@aws-sdk/types";
|
3 | 4 | import { join, sep } from "path";
|
@@ -48,8 +49,11 @@ jest.mock("os", () => {
|
48 | 49 |
|
49 | 50 | return os;
|
50 | 51 | });
|
| 52 | + |
51 | 53 | import { homedir } from "os";
|
52 | 54 |
|
| 55 | +jest.mock("@aws-sdk/credential-provider-web-identity"); |
| 56 | + |
53 | 57 | const DEFAULT_CREDS = {
|
54 | 58 | accessKeyId: "AKIAIOSFODNN7EXAMPLE",
|
55 | 59 | secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
|
@@ -83,6 +87,7 @@ const envAtLoadTime: { [key: string]: string | undefined } = [
|
83 | 87 |
|
84 | 88 | beforeEach(() => {
|
85 | 89 | __clearMatchers();
|
| 90 | + jest.clearAllMocks(); |
86 | 91 | Object.keys(envAtLoadTime).forEach((envKey) => {
|
87 | 92 | delete process.env[envKey];
|
88 | 93 | });
|
@@ -749,6 +754,109 @@ source_profile = default`.trim()
|
749 | 754 | });
|
750 | 755 | });
|
751 | 756 |
|
| 757 | + describe("assume role with web identity", () => { |
| 758 | + it("should call fromTokenFile with data from profile", async () => { |
| 759 | + (fromTokenFile as jest.Mock).mockReturnValueOnce(() => Promise.resolve(FOO_CREDS)); |
| 760 | + const webIdentityTokenFile = "/temp/foo/token"; |
| 761 | + const roleArn = "arn:aws:iam::123456789:role/bar"; |
| 762 | + const roleSessionName = "bazSession"; |
| 763 | + const roleAssumerWithWebIdentity = jest.fn(); |
| 764 | + __addMatcher( |
| 765 | + join(homedir(), ".aws", "credentials"), |
| 766 | + ` |
| 767 | +[foo] |
| 768 | +web_identity_token_file = ${webIdentityTokenFile} |
| 769 | +role_arn = ${roleArn} |
| 770 | +role_session_name = ${roleSessionName}`.trim() |
| 771 | + ); |
| 772 | + |
| 773 | + const provider = fromIni({ |
| 774 | + profile: "foo", |
| 775 | + roleAssumerWithWebIdentity, |
| 776 | + }); |
| 777 | + |
| 778 | + expect(await provider()).toEqual(FOO_CREDS); |
| 779 | + expect(fromTokenFile).toHaveBeenCalledTimes(1); |
| 780 | + expect(fromTokenFile).toHaveBeenCalledWith({ |
| 781 | + webIdentityTokenFile, |
| 782 | + roleArn, |
| 783 | + roleSessionName, |
| 784 | + roleAssumerWithWebIdentity, |
| 785 | + }); |
| 786 | + }); |
| 787 | + |
| 788 | + it("should call fromTokenFile with assume role chaining", async () => { |
| 789 | + (fromTokenFile as jest.Mock).mockReturnValueOnce(() => Promise.resolve(DEFAULT_CREDS)); |
| 790 | + const webIdentityTokenFile = "/temp/foo/token"; |
| 791 | + const roleArn = "arn:aws:iam::123456789:role/bar"; |
| 792 | + const roleSessionName = "bazSession"; |
| 793 | + const roleAssumerWithWebIdentity = jest.fn(); |
| 794 | + |
| 795 | + const fooRoleArn = "arn:aws:iam::123456789:role/foo"; |
| 796 | + const fooSessionName = "fooSession"; |
| 797 | + __addMatcher( |
| 798 | + join(homedir(), ".aws", "credentials"), |
| 799 | + ` |
| 800 | +[bar] |
| 801 | +web_identity_token_file = ${webIdentityTokenFile} |
| 802 | +role_arn = ${roleArn} |
| 803 | +role_session_name = ${roleSessionName} |
| 804 | +
|
| 805 | +[foo] |
| 806 | +role_arn = ${fooRoleArn} |
| 807 | +role_session_name = ${fooSessionName} |
| 808 | +source_profile = bar`.trim() |
| 809 | + ); |
| 810 | + |
| 811 | + const provider = fromIni({ |
| 812 | + profile: "foo", |
| 813 | + roleAssumer(sourceCreds: Credentials, params: AssumeRoleParams): Promise<Credentials> { |
| 814 | + expect(sourceCreds).toEqual(DEFAULT_CREDS); |
| 815 | + expect(params.RoleArn).toEqual(fooRoleArn); |
| 816 | + expect(params.RoleSessionName).toEqual(fooSessionName); |
| 817 | + return Promise.resolve(FOO_CREDS); |
| 818 | + }, |
| 819 | + roleAssumerWithWebIdentity, |
| 820 | + }); |
| 821 | + |
| 822 | + expect(await provider()).toEqual(FOO_CREDS); |
| 823 | + expect(fromTokenFile).toHaveBeenCalledTimes(1); |
| 824 | + expect(fromTokenFile).toHaveBeenCalledWith({ |
| 825 | + webIdentityTokenFile, |
| 826 | + roleArn, |
| 827 | + roleSessionName, |
| 828 | + roleAssumerWithWebIdentity, |
| 829 | + }); |
| 830 | + }); |
| 831 | + |
| 832 | + it("should call fromTokenFile without roleSessionName if not present in profile", async () => { |
| 833 | + (fromTokenFile as jest.Mock).mockReturnValueOnce(() => Promise.resolve(FOO_CREDS)); |
| 834 | + const webIdentityTokenFile = "/temp/foo/token"; |
| 835 | + const roleArn = "arn:aws:iam::123456789:role/bar"; |
| 836 | + const roleAssumerWithWebIdentity = jest.fn(); |
| 837 | + __addMatcher( |
| 838 | + join(homedir(), ".aws", "credentials"), |
| 839 | + ` |
| 840 | +[foo] |
| 841 | +web_identity_token_file = ${webIdentityTokenFile} |
| 842 | +role_arn = ${roleArn}`.trim() |
| 843 | + ); |
| 844 | + |
| 845 | + const provider = fromIni({ |
| 846 | + profile: "foo", |
| 847 | + roleAssumerWithWebIdentity, |
| 848 | + }); |
| 849 | + |
| 850 | + expect(await provider()).toEqual(FOO_CREDS); |
| 851 | + expect(fromTokenFile).toHaveBeenCalledTimes(1); |
| 852 | + expect(fromTokenFile).toHaveBeenCalledWith({ |
| 853 | + webIdentityTokenFile, |
| 854 | + roleArn, |
| 855 | + roleAssumerWithWebIdentity, |
| 856 | + }); |
| 857 | + }); |
| 858 | + }); |
| 859 | + |
752 | 860 | it("should prefer credentials in ~/.aws/credentials to those in ~/.aws/config", async () => {
|
753 | 861 | __addMatcher(
|
754 | 862 | join(homedir(), ".aws", "credentials"),
|
|
0 commit comments