chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
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 }
|
||||
}
|
||||
Reference in New Issue
Block a user