-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
revert(iam): oidc provider retrieves leaf certificate instead of root…
- Loading branch information
Showing
100 changed files
with
1,428 additions
and
866 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+0 Bytes
(100%)
...er.js.snapshot/asset.4288ebb3652acdf2d828b7db7ca44a7162a401ace50ebb4026e84b18a02a06ee.zip
Binary file not shown.
File renamed without changes.
4 changes: 4 additions & 0 deletions
4
...snapshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/diff.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export declare function arrayDiff(oldValues: string[], newValues: string[]): { | ||
adds: string[]; | ||
deletes: string[]; | ||
}; |
File renamed without changes.
17 changes: 17 additions & 0 deletions
17
...s.snapshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/diff.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
export function arrayDiff(oldValues: string[], newValues: string[]) { | ||
const deletes = new Set(oldValues); | ||
const adds = new Set<string>(); | ||
|
||
for (const v of new Set(newValues)) { | ||
if (deletes.has(v)) { | ||
deletes.delete(v); | ||
} else { | ||
adds.add(v); | ||
} | ||
} | ||
|
||
return { | ||
adds: Array.from(adds), | ||
deletes: Array.from(deletes), | ||
}; | ||
} |
24 changes: 24 additions & 0 deletions
24
...shot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/external.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import * as aws from 'aws-sdk'; | ||
declare function defaultLogger(fmt: string, ...args: any[]): void; | ||
/** | ||
* Downloads the CA thumbprint from the issuer URL | ||
*/ | ||
declare function downloadThumbprint(issuerUrl: string): Promise<string>; | ||
export declare const external: { | ||
downloadThumbprint: typeof downloadThumbprint; | ||
log: typeof defaultLogger; | ||
createOpenIDConnectProvider: (req: aws.IAM.CreateOpenIDConnectProviderRequest) => Promise<import("aws-sdk/lib/request").PromiseResult<aws.IAM.CreateOpenIDConnectProviderResponse, aws.AWSError>>; | ||
deleteOpenIDConnectProvider: (req: aws.IAM.DeleteOpenIDConnectProviderRequest) => Promise<{ | ||
$response: aws.Response<{}, aws.AWSError>; | ||
}>; | ||
updateOpenIDConnectProviderThumbprint: (req: aws.IAM.UpdateOpenIDConnectProviderThumbprintRequest) => Promise<{ | ||
$response: aws.Response<{}, aws.AWSError>; | ||
}>; | ||
addClientIDToOpenIDConnectProvider: (req: aws.IAM.AddClientIDToOpenIDConnectProviderRequest) => Promise<{ | ||
$response: aws.Response<{}, aws.AWSError>; | ||
}>; | ||
removeClientIDFromOpenIDConnectProvider: (req: aws.IAM.RemoveClientIDFromOpenIDConnectProviderRequest) => Promise<{ | ||
$response: aws.Response<{}, aws.AWSError>; | ||
}>; | ||
}; | ||
export {}; |
53 changes: 53 additions & 0 deletions
53
...apshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/external.js
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
53 changes: 53 additions & 0 deletions
53
...apshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/external.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* istanbul ignore file */ | ||
|
||
import * as tls from 'tls'; | ||
import * as url from 'url'; | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import * as aws from 'aws-sdk'; | ||
|
||
let client: aws.IAM; | ||
|
||
function iam() { | ||
if (!client) { client = new aws.IAM(); } | ||
return client; | ||
} | ||
|
||
function defaultLogger(fmt: string, ...args: any[]) { | ||
// eslint-disable-next-line no-console | ||
console.log(fmt, ...args); | ||
} | ||
|
||
/** | ||
* Downloads the CA thumbprint from the issuer URL | ||
*/ | ||
async function downloadThumbprint(issuerUrl: string) { | ||
external.log(`downloading certificate authority thumbprint for ${issuerUrl}`); | ||
return new Promise<string>((ok, ko) => { | ||
const purl = url.parse(issuerUrl); | ||
const port = purl.port ? parseInt(purl.port, 10) : 443; | ||
if (!purl.host) { | ||
return ko(new Error(`unable to determine host from issuer url ${issuerUrl}`)); | ||
} | ||
const socket = tls.connect(port, purl.host, { rejectUnauthorized: false, servername: purl.host }); | ||
socket.once('error', ko); | ||
socket.once('secureConnect', () => { | ||
const cert = socket.getPeerCertificate(); | ||
socket.end(); | ||
const thumbprint = cert.fingerprint.split(':').join(''); | ||
external.log(`certificate authority thumbprint for ${issuerUrl} is ${thumbprint}`); | ||
ok(thumbprint); | ||
}); | ||
}); | ||
} | ||
|
||
// allows unit test to replace with mocks | ||
/* eslint-disable max-len */ | ||
export const external = { | ||
downloadThumbprint, | ||
log: defaultLogger, | ||
createOpenIDConnectProvider: (req: aws.IAM.CreateOpenIDConnectProviderRequest) => iam().createOpenIDConnectProvider(req).promise(), | ||
deleteOpenIDConnectProvider: (req: aws.IAM.DeleteOpenIDConnectProviderRequest) => iam().deleteOpenIDConnectProvider(req).promise(), | ||
updateOpenIDConnectProviderThumbprint: (req: aws.IAM.UpdateOpenIDConnectProviderThumbprintRequest) => iam().updateOpenIDConnectProviderThumbprint(req).promise(), | ||
addClientIDToOpenIDConnectProvider: (req: aws.IAM.AddClientIDToOpenIDConnectProviderRequest) => iam().addClientIDToOpenIDConnectProvider(req).promise(), | ||
removeClientIDFromOpenIDConnectProvider: (req: aws.IAM.RemoveClientIDFromOpenIDConnectProviderRequest) => iam().removeClientIDFromOpenIDConnectProvider(req).promise(), | ||
}; |
3 changes: 3 additions & 0 deletions
3
...napshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/index.d.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export declare function handler(event: AWSLambda.CloudFormationCustomResourceEvent): Promise<void | { | ||
PhysicalResourceId: string | undefined; | ||
}>; |
File renamed without changes.
89 changes: 89 additions & 0 deletions
89
....snapshot/asset.42973d1d89f4a393a64981f78d088964ba13e63a3aab4478cd74109c77cf9174/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { arrayDiff } from './diff'; | ||
import { external } from './external'; | ||
|
||
export async function handler(event: AWSLambda.CloudFormationCustomResourceEvent) { | ||
if (event.RequestType === 'Create') { return onCreate(event); } | ||
if (event.RequestType === 'Update') { return onUpdate(event); } | ||
if (event.RequestType === 'Delete') { return onDelete(event); } | ||
throw new Error('invalid request type'); | ||
} | ||
|
||
async function onCreate(event: AWSLambda.CloudFormationCustomResourceCreateEvent) { | ||
const issuerUrl = event.ResourceProperties.Url; | ||
const thumbprints: string[] = (event.ResourceProperties.ThumbprintList ?? []).sort(); // keep sorted for UPDATE | ||
const clients: string[] = (event.ResourceProperties.ClientIDList ?? []).sort(); | ||
|
||
if (thumbprints.length === 0) { | ||
thumbprints.push(await external.downloadThumbprint(issuerUrl)); | ||
} | ||
|
||
const resp = await external.createOpenIDConnectProvider({ | ||
Url: issuerUrl, | ||
ClientIDList: clients, | ||
ThumbprintList: thumbprints, | ||
}); | ||
|
||
return { | ||
PhysicalResourceId: resp.OpenIDConnectProviderArn, | ||
}; | ||
} | ||
|
||
async function onUpdate(event: AWSLambda.CloudFormationCustomResourceUpdateEvent) { | ||
const issuerUrl = event.ResourceProperties.Url; | ||
const thumbprints: string[] = (event.ResourceProperties.ThumbprintList ?? []).sort(); // keep sorted for UPDATE | ||
const clients: string[] = (event.ResourceProperties.ClientIDList ?? []).sort(); | ||
|
||
// determine which update we are talking about. | ||
const oldIssuerUrl = event.OldResourceProperties.Url; | ||
|
||
// if this is a URL update, then we basically create a new resource and cfn will delete the old one | ||
// since the physical resource ID will change. | ||
if (oldIssuerUrl !== issuerUrl) { | ||
return onCreate({ ...event, RequestType: 'Create' }); | ||
} | ||
|
||
const providerArn = event.PhysicalResourceId; | ||
|
||
// if thumbprints changed, we can update in-place, but bear in mind that if the new thumbprint list | ||
// is empty, we will grab it from the server like we do in CREATE | ||
const oldThumbprints = (event.OldResourceProperties.ThumbprintList || []).sort(); | ||
if (JSON.stringify(oldThumbprints) !== JSON.stringify(thumbprints)) { | ||
const thumbprintList = thumbprints.length > 0 ? thumbprints : [await external.downloadThumbprint(issuerUrl)]; | ||
external.log('updating thumbprint list from', oldThumbprints, 'to', thumbprints); | ||
await external.updateOpenIDConnectProviderThumbprint({ | ||
OpenIDConnectProviderArn: providerArn, | ||
ThumbprintList: thumbprintList, | ||
}); | ||
|
||
// don't return, we might have more updates... | ||
} | ||
|
||
// if client ID list has changed, determine "diff" because the API is add/remove | ||
const oldClients: string[] = (event.OldResourceProperties.ClientIDList || []).sort(); | ||
const diff = arrayDiff(oldClients, clients); | ||
external.log(`client ID diff: ${JSON.stringify(diff)}`); | ||
|
||
for (const addClient of diff.adds) { | ||
external.log(`adding client id "${addClient}" to provider ${providerArn}`); | ||
await external.addClientIDToOpenIDConnectProvider({ | ||
OpenIDConnectProviderArn: providerArn, | ||
ClientID: addClient, | ||
}); | ||
} | ||
|
||
for (const deleteClient of diff.deletes) { | ||
external.log(`removing client id "${deleteClient}" from provider ${providerArn}`); | ||
await external.removeClientIDFromOpenIDConnectProvider({ | ||
OpenIDConnectProviderArn: providerArn, | ||
ClientID: deleteClient, | ||
}); | ||
} | ||
|
||
return; | ||
} | ||
|
||
async function onDelete(deleteEvent: AWSLambda.CloudFormationCustomResourceDeleteEvent) { | ||
await external.deleteOpenIDConnectProvider({ | ||
OpenIDConnectProviderArn: deleteEvent.PhysicalResourceId, | ||
}); | ||
} |
Oops, something went wrong.