d25d482dc2
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
305 lines
9.3 KiB
TypeScript
305 lines
9.3 KiB
TypeScript
import {
|
|
DescribeGroupCommand,
|
|
DescribeUserCommand,
|
|
GetGroupIdCommand,
|
|
GetUserIdCommand,
|
|
IdentitystoreClient,
|
|
ListGroupsCommand,
|
|
} from '@aws-sdk/client-identitystore'
|
|
import {
|
|
DescribeAccountCommand,
|
|
ListAccountsCommand,
|
|
OrganizationsClient,
|
|
} from '@aws-sdk/client-organizations'
|
|
import {
|
|
type AccountAssignmentOperationStatus,
|
|
DescribeAccountAssignmentCreationStatusCommand,
|
|
DescribeAccountAssignmentDeletionStatusCommand,
|
|
DescribePermissionSetCommand,
|
|
ListAccountAssignmentsForPrincipalCommand,
|
|
ListInstancesCommand,
|
|
ListPermissionSetsCommand,
|
|
type PrincipalType,
|
|
SSOAdminClient,
|
|
} from '@aws-sdk/client-sso-admin'
|
|
import type { IdentityCenterConnectionConfig } from '@/tools/identity_center/types'
|
|
|
|
export function createSSOAdminClient(config: IdentityCenterConnectionConfig): SSOAdminClient {
|
|
return new SSOAdminClient({
|
|
region: config.region,
|
|
credentials: {
|
|
accessKeyId: config.accessKeyId,
|
|
secretAccessKey: config.secretAccessKey,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function createIdentityStoreClient(
|
|
config: IdentityCenterConnectionConfig
|
|
): IdentitystoreClient {
|
|
return new IdentitystoreClient({
|
|
region: config.region,
|
|
credentials: {
|
|
accessKeyId: config.accessKeyId,
|
|
secretAccessKey: config.secretAccessKey,
|
|
},
|
|
})
|
|
}
|
|
|
|
export function createOrganizationsClient(config: IdentityCenterConnectionConfig) {
|
|
return new OrganizationsClient({
|
|
region: 'us-east-1', // Organizations API only available in us-east-1
|
|
credentials: {
|
|
accessKeyId: config.accessKeyId,
|
|
secretAccessKey: config.secretAccessKey,
|
|
},
|
|
})
|
|
}
|
|
|
|
export async function listInstances(
|
|
client: SSOAdminClient,
|
|
maxResults?: number | null,
|
|
nextToken?: string | null
|
|
) {
|
|
const command = new ListInstancesCommand({
|
|
...(maxResults ? { MaxResults: maxResults } : {}),
|
|
...(nextToken ? { NextToken: nextToken } : {}),
|
|
})
|
|
const response = await client.send(command)
|
|
const instances = (response.Instances ?? []).map((instance) => ({
|
|
instanceArn: instance.InstanceArn ?? '',
|
|
identityStoreId: instance.IdentityStoreId ?? '',
|
|
name: instance.Name ?? null,
|
|
status: instance.Status ?? '',
|
|
statusReason: instance.StatusReason ?? null,
|
|
ownerAccountId: instance.OwnerAccountId ?? null,
|
|
createdDate: instance.CreatedDate?.toISOString() ?? null,
|
|
}))
|
|
return { instances, nextToken: response.NextToken ?? null, count: instances.length }
|
|
}
|
|
|
|
export async function listAccounts(
|
|
client: OrganizationsClient,
|
|
maxResults?: number | null,
|
|
nextToken?: string | null
|
|
) {
|
|
const command = new ListAccountsCommand({
|
|
...(maxResults ? { MaxResults: maxResults } : {}),
|
|
...(nextToken ? { NextToken: nextToken } : {}),
|
|
})
|
|
const response = await client.send(command)
|
|
const accounts = (response.Accounts ?? []).map((account) => ({
|
|
id: account.Id ?? '',
|
|
arn: account.Arn ?? '',
|
|
name: account.Name ?? '',
|
|
email: account.Email ?? '',
|
|
status: account.State ?? '',
|
|
joinedTimestamp: account.JoinedTimestamp?.toISOString() ?? null,
|
|
}))
|
|
return { accounts, nextToken: response.NextToken ?? null, count: accounts.length }
|
|
}
|
|
|
|
export async function listPermissionSets(
|
|
client: SSOAdminClient,
|
|
instanceArn: string,
|
|
maxResults?: number | null,
|
|
nextToken?: string | null
|
|
) {
|
|
const listCommand = new ListPermissionSetsCommand({
|
|
InstanceArn: instanceArn,
|
|
...(maxResults ? { MaxResults: maxResults } : {}),
|
|
...(nextToken ? { NextToken: nextToken } : {}),
|
|
})
|
|
const listResponse = await client.send(listCommand)
|
|
const permissionSetArns = listResponse.PermissionSets ?? []
|
|
|
|
const permissionSets = await Promise.all(
|
|
permissionSetArns.map(async (arn) => {
|
|
const describeCommand = new DescribePermissionSetCommand({
|
|
InstanceArn: instanceArn,
|
|
PermissionSetArn: arn,
|
|
})
|
|
const describeResponse = await client.send(describeCommand)
|
|
const ps = describeResponse.PermissionSet
|
|
return {
|
|
permissionSetArn: ps?.PermissionSetArn ?? arn,
|
|
name: ps?.Name ?? '',
|
|
description: ps?.Description ?? null,
|
|
sessionDuration: ps?.SessionDuration ?? null,
|
|
createdDate: ps?.CreatedDate?.toISOString() ?? null,
|
|
}
|
|
})
|
|
)
|
|
|
|
return {
|
|
permissionSets,
|
|
nextToken: listResponse.NextToken ?? null,
|
|
count: permissionSets.length,
|
|
}
|
|
}
|
|
|
|
export async function getUserByEmail(
|
|
ssoClient: IdentitystoreClient,
|
|
identityStoreId: string,
|
|
email: string
|
|
) {
|
|
const getUserIdCommand = new GetUserIdCommand({
|
|
IdentityStoreId: identityStoreId,
|
|
AlternateIdentifier: {
|
|
UniqueAttribute: {
|
|
AttributePath: 'emails.value',
|
|
AttributeValue: email,
|
|
},
|
|
},
|
|
})
|
|
const getUserIdResponse = await ssoClient.send(getUserIdCommand)
|
|
const userId = getUserIdResponse.UserId ?? ''
|
|
|
|
const describeCommand = new DescribeUserCommand({
|
|
IdentityStoreId: identityStoreId,
|
|
UserId: userId,
|
|
})
|
|
const describeResponse = await ssoClient.send(describeCommand)
|
|
|
|
const primaryEmail =
|
|
describeResponse.Emails?.find((e) => e.Primary)?.Value ??
|
|
describeResponse.Emails?.[0]?.Value ??
|
|
null
|
|
|
|
return {
|
|
userId,
|
|
userName: describeResponse.UserName ?? '',
|
|
displayName: describeResponse.DisplayName ?? null,
|
|
email: primaryEmail,
|
|
}
|
|
}
|
|
|
|
export function mapAssignmentStatus(status: AccountAssignmentOperationStatus) {
|
|
return {
|
|
status: status.Status ?? '',
|
|
requestId: status.RequestId ?? '',
|
|
accountId: status.TargetId ?? null,
|
|
permissionSetArn: status.PermissionSetArn ?? null,
|
|
principalType: status.PrincipalType ?? null,
|
|
principalId: status.PrincipalId ?? null,
|
|
failureReason: status.FailureReason ?? null,
|
|
createdDate: status.CreatedDate?.toISOString() ?? null,
|
|
}
|
|
}
|
|
|
|
export async function checkAssignmentCreationStatus(
|
|
client: SSOAdminClient,
|
|
instanceArn: string,
|
|
requestId: string
|
|
) {
|
|
const command = new DescribeAccountAssignmentCreationStatusCommand({
|
|
InstanceArn: instanceArn,
|
|
AccountAssignmentCreationRequestId: requestId,
|
|
})
|
|
const response = await client.send(command)
|
|
return mapAssignmentStatus(response.AccountAssignmentCreationStatus ?? {})
|
|
}
|
|
|
|
export async function checkAssignmentDeletionStatus(
|
|
client: SSOAdminClient,
|
|
instanceArn: string,
|
|
requestId: string
|
|
) {
|
|
const command = new DescribeAccountAssignmentDeletionStatusCommand({
|
|
InstanceArn: instanceArn,
|
|
AccountAssignmentDeletionRequestId: requestId,
|
|
})
|
|
const response = await client.send(command)
|
|
return mapAssignmentStatus(response.AccountAssignmentDeletionStatus ?? {})
|
|
}
|
|
|
|
export async function listGroups(
|
|
client: IdentitystoreClient,
|
|
identityStoreId: string,
|
|
maxResults?: number | null,
|
|
nextToken?: string | null
|
|
) {
|
|
const command = new ListGroupsCommand({
|
|
IdentityStoreId: identityStoreId,
|
|
...(maxResults ? { MaxResults: maxResults } : {}),
|
|
...(nextToken ? { NextToken: nextToken } : {}),
|
|
})
|
|
const response = await client.send(command)
|
|
const groups = (response.Groups ?? []).map((group) => ({
|
|
groupId: group.GroupId ?? '',
|
|
displayName: group.DisplayName ?? null,
|
|
description: group.Description ?? null,
|
|
externalIds: group.ExternalIds?.map((e) => ({ issuer: e.Issuer ?? '', id: e.Id ?? '' })) ?? [],
|
|
}))
|
|
return { groups, nextToken: response.NextToken ?? null, count: groups.length }
|
|
}
|
|
|
|
export async function getGroupByDisplayName(
|
|
client: IdentitystoreClient,
|
|
identityStoreId: string,
|
|
displayName: string
|
|
) {
|
|
const getGroupIdCommand = new GetGroupIdCommand({
|
|
IdentityStoreId: identityStoreId,
|
|
AlternateIdentifier: {
|
|
UniqueAttribute: {
|
|
AttributePath: 'displayName',
|
|
AttributeValue: displayName,
|
|
},
|
|
},
|
|
})
|
|
const getGroupIdResponse = await client.send(getGroupIdCommand)
|
|
const groupId = getGroupIdResponse.GroupId ?? ''
|
|
|
|
const describeCommand = new DescribeGroupCommand({
|
|
IdentityStoreId: identityStoreId,
|
|
GroupId: groupId,
|
|
})
|
|
const describeResponse = await client.send(describeCommand)
|
|
|
|
return {
|
|
groupId,
|
|
displayName: describeResponse.DisplayName ?? null,
|
|
description: describeResponse.Description ?? null,
|
|
}
|
|
}
|
|
|
|
export async function describeAccount(client: OrganizationsClient, accountId: string) {
|
|
const command = new DescribeAccountCommand({ AccountId: accountId })
|
|
const response = await client.send(command)
|
|
const account = response.Account
|
|
return {
|
|
id: account?.Id ?? '',
|
|
arn: account?.Arn ?? '',
|
|
name: account?.Name ?? '',
|
|
email: account?.Email ?? '',
|
|
status: account?.State ?? '',
|
|
joinedTimestamp: account?.JoinedTimestamp?.toISOString() ?? null,
|
|
}
|
|
}
|
|
|
|
export async function listAccountAssignmentsForPrincipal(
|
|
client: SSOAdminClient,
|
|
instanceArn: string,
|
|
principalId: string,
|
|
principalType: string,
|
|
maxResults?: number | null,
|
|
nextToken?: string | null
|
|
) {
|
|
const command = new ListAccountAssignmentsForPrincipalCommand({
|
|
InstanceArn: instanceArn,
|
|
PrincipalId: principalId,
|
|
PrincipalType: principalType as PrincipalType,
|
|
...(maxResults ? { MaxResults: maxResults } : {}),
|
|
...(nextToken ? { NextToken: nextToken } : {}),
|
|
})
|
|
const response = await client.send(command)
|
|
const assignments = (response.AccountAssignments ?? []).map((a) => ({
|
|
accountId: a.AccountId ?? '',
|
|
permissionSetArn: a.PermissionSetArn ?? '',
|
|
principalType: a.PrincipalType ?? '',
|
|
principalId: a.PrincipalId ?? '',
|
|
}))
|
|
return { assignments, nextToken: response.NextToken ?? null, count: assignments.length }
|
|
}
|