Skip to content

Commit

Permalink
chore(release): 0.2.10
Browse files Browse the repository at this point in the history
  • Loading branch information
Maurice Faber committed Aug 30, 2021
2 parents 53d6f57 + 4a28895 commit 6fa0f40
Showing 1 changed file with 79 additions and 65 deletions.
144 changes: 79 additions & 65 deletions src/tasks/keycloak/keycloak.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/camelcase */
import { Issuer } from 'openid-client'
import { Issuer, TokenSet } from 'openid-client'
import {
ClientsApi,
IdentityProvidersApi,
Expand All @@ -8,8 +8,11 @@ import {
ProtocolMappersApi,
RealmsAdminApi,
IdentityProviderMapperRepresentation,
IdentityProviderRepresentation,
ClientScopeRepresentation,
ClientRepresentation,
ProtocolMapperRepresentation,
} from '@redkubes/keycloak-client-node'
import { find } from 'lodash'
import * as realmConfig from './realm-factory'
import {
cleanEnv,
Expand All @@ -36,7 +39,7 @@ async function main(): Promise<void> {
await waitTillAvailable(env.KEYCLOAK_ADDRESS)

let basePath
let token
let token: TokenSet
try {
const keycloakAddress = env.KEYCLOAK_ADDRESS
const keycloakRealm = env.KEYCLOAK_REALM
Expand Down Expand Up @@ -73,106 +76,116 @@ async function main(): Promise<void> {

// Create Client Scopes
const scope = realmConfig.createClientScopes()
const clientScopes = !(await doApiCall(errors, 'Creating openid client scope', () =>
clientScope.realmClientScopesPost(env.KEYCLOAK_REALM, scope),
))
if (clientScopes) {
// @NOTE this PUT operation is almost pointless as it is not updating deep nested properties because of various db constraints

const clientScopes = (await doApiCall(errors, 'Getting openid client scope', () =>
clientScope.realmClientScopesGet(env.KEYCLOAK_REALM),
)) as Array<ClientScopeRepresentation>
const existingScope = clientScopes.find((el) => el.name === scope.name)
if (existingScope) {
await doApiCall(errors, 'Updating openid client scope', async () => {
const currentClientScopes = await clientScope.realmClientScopesGet(env.KEYCLOAK_REALM)
const { id } = ensure(find(currentClientScopes.body, { name: scope.name }))
return clientScope.realmClientScopesIdPut(env.KEYCLOAK_REALM, ensure(id), scope)
// @NOTE this PUT operation is almost pointless as it is not updating deep nested properties because of various db constraints
return clientScope.realmClientScopesIdPut(env.KEYCLOAK_REALM, existingScope.id!, scope)
})
} else {
await doApiCall(errors, 'Creating openid client scope', () =>
clientScope.realmClientScopesPost(env.KEYCLOAK_REALM, scope),
)
}

// Create Roles
const teamRoles = realmConfig.mapTeamsToRoles()
interface RealmRole {
name: string
}
const existingRoles = (await doApiCall(errors, `Getting all roles from realm ${env.KEYCLOAK_REALM}`, async () =>
roles.realmRolesGet(env.KEYCLOAK_REALM),
)) as Array<RealmRole>

await Promise.all(
teamRoles.map(
async (role): Promise<void> => {
const exists = await doApiCall(errors, `Creating role ${role.name}`, async () =>
roles.realmRolesPost(env.KEYCLOAK_REALM, role),
teamRoles.map((role) => {
const exists = existingRoles.some((el) => el.name === role.name!)
if (exists) {
return doApiCall(errors, `Updating role ${role.name!}`, async () =>
roles.realmRolesRoleNamePut(env.KEYCLOAK_REALM, role.name ?? '', role),
)
if (exists)
await doApiCall(errors, `Updating role ${role.name}`, async () =>
roles.realmRolesRoleNamePut(env.KEYCLOAK_REALM, role.name ?? '', role),
)
},
),
}
return doApiCall(errors, `Creating role ${role.name!}`, async () =>
roles.realmRolesPost(env.KEYCLOAK_REALM, role),
)
}),
)

// Create Identity Provider
const idp = await realmConfig.createIdProvider()
const idpExists = await doApiCall(errors, 'Creating identity provider', async () => {
return providers.realmIdentityProviderInstancesPost(env.KEYCLOAK_REALM, idp)
})
if (idpExists) {

const existingProviders = (await doApiCall(errors, 'Geting identity provider', async () => {
return providers.realmIdentityProviderInstancesGet(env.KEYCLOAK_REALM)
})) as Array<IdentityProviderRepresentation>

if (existingProviders.some((el) => el.alias === idp.alias)) {
await doApiCall(errors, 'Updating identity provider', async () => {
return providers.realmIdentityProviderInstancesAliasPut(env.KEYCLOAK_REALM, ensure(idp.alias), idp)
})
} else {
await doApiCall(errors, 'Creating identity provider', async () => {
return providers.realmIdentityProviderInstancesPost(env.KEYCLOAK_REALM, idp)
})
}

// Create Identity Provider Mappers
// @NOTE - PUT involves adding strict required properties not in the factory
const idpMappers = realmConfig.createIdpMappers()
const existingMappers: IdentityProviderMapperRepresentation[] = await doApiCall(
errors,
`Getting mappers`,
() => providers.realmIdentityProviderInstancesAliasMappersGet(env.KEYCLOAK_REALM, env.IDP_ALIAS),
400,
)

const existingMappers = (await doApiCall(errors, `Getting role mappers`, () =>
providers.realmIdentityProviderInstancesAliasMappersGet(env.KEYCLOAK_REALM, env.IDP_ALIAS),
)) as IdentityProviderMapperRepresentation[]

await Promise.all(
idpMappers.map(async (idpMapper) => {
idpMappers.map((idpMapper) => {
const existingMapper: IdentityProviderMapperRepresentation | undefined = (existingMappers || []).find(
(m) => m.name === idpMapper.name,
)
if (existingMapper) {
await doApiCall(
errors,
`Updating mapper ${idpMapper.name}`,
() =>
providers.realmIdentityProviderInstancesAliasMappersIdPut(
env.KEYCLOAK_REALM,
env.IDP_ALIAS,
existingMapper.id!,
{ ...existingMapper, ...idpMapper },
),
400,
)
} else {
await doApiCall(
errors,
`Creating mapper ${idpMapper.name}`,
() => providers.realmIdentityProviderInstancesAliasMappersPost(env.KEYCLOAK_REALM, env.IDP_ALIAS, idpMapper),
400,
return doApiCall(errors, `Updating mapper ${idpMapper.name!}`, () =>
providers.realmIdentityProviderInstancesAliasMappersIdPut(
env.KEYCLOAK_REALM,
env.IDP_ALIAS,
existingMapper.id!,
{ ...existingMapper, ...idpMapper },
),
)
}
return doApiCall(errors, `Creating mapper ${idpMapper.name!}`, () =>
providers.realmIdentityProviderInstancesAliasMappersPost(env.KEYCLOAK_REALM, env.IDP_ALIAS, idpMapper),
)
}),
)

// Create Otomi Client
const client = realmConfig.createClient()
const clientExists = await doApiCall(errors, 'Creating otomi client', () =>
clients.realmClientsPost(env.KEYCLOAK_REALM, client),
)
if (clientExists) {
const allClients = (await doApiCall(errors, 'Getting otomi client', () =>
clients.realmClientsGet(env.KEYCLOAK_REALM),
)) as Array<ClientRepresentation>

if (allClients.some((el) => el.name === client.name)) {
await doApiCall(errors, 'Updating otomi client', () =>
clients.realmClientsIdPut(env.KEYCLOAK_REALM, ensure(client.id), client),
)
} else {
await doApiCall(errors, 'Creating otomi client', () => clients.realmClientsPost(env.KEYCLOAK_REALM, client))
}

// add email claim for client protocolMappers
// @NOTE - PUT involves adding strict required properties not in the factory
await doApiCall(errors, 'creating client email claim', () =>
protocols.realmClientsIdProtocolMappersModelsPost(
env.KEYCLOAK_REALM,
ensure(client.id),
realmConfig.createClientEmailClaimMapper(),
),
)
const allClaims = (await doApiCall(errors, 'Getting client email claim', () =>
protocols.realmClientsIdProtocolMappersModelsGet(env.KEYCLOAK_REALM, ensure(client.id)),
)) as Array<ProtocolMapperRepresentation>
const mapper = realmConfig.createClientEmailClaimMapper()
if (!allClaims.some((el) => el.name === mapper.name)) {
await doApiCall(errors, 'Creating client email claim mapper', () =>
protocols.realmClientsIdProtocolMappersModelsPost(env.KEYCLOAK_REALM, ensure(client.id), mapper),
)
}

// set login theme
await doApiCall(errors, 'adding login theme', () =>
await doApiCall(errors, 'adding theme for login page', () =>
realms.realmPut(env.KEYCLOAK_REALM, realmConfig.createLoginThemeConfig('otomi')),
)

Expand All @@ -181,5 +194,6 @@ async function main(): Promise<void> {

// Run main only on execution, not on import (like tests)
if (typeof require !== 'undefined' && require.main === module) {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
main()
}

0 comments on commit 6fa0f40

Please sign in to comment.