Skip to content

Commit

Permalink
feat: update keycloak.ts and add keycloak.test.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
ferruhcihan committed Oct 8, 2024
1 parent 368bc63 commit 2479e86
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 44 deletions.
76 changes: 76 additions & 0 deletions src/operator/keycloak.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { expect } from 'chai'
import sinon from 'sinon'
import { addUserGroups, removeUserGroups } from './keycloak'

describe('Keycloak User Group Management', () => {
let api: any
let existingUser: any
let keycloakRealm: string

beforeEach(() => {
keycloakRealm = 'otomi'
existingUser = { id: 'user-id' }
api = {
users: {
realmUsersIdGroupsGet: sinon.stub(),
realmUsersIdGroupsGroupIdDelete: sinon.stub(),
realmUsersIdGroupsGroupIdPut: sinon.stub(),
},
groups: {
realmGroupsGet: sinon.stub(),
},
}
})

afterEach(() => {
sinon.restore()
})

describe('removeUserGroups', () => {
it('should remove user from groups not in teamGroups', async () => {
const existingUserGroups = [
{ name: 'group1', id: 'group1-id' },
{ name: 'group2', id: 'group2-id' },
]
api.users.realmUsersIdGroupsGet.resolves({ body: existingUserGroups })

await removeUserGroups(api, existingUser, ['group1'])

expect(api.users.realmUsersIdGroupsGroupIdDelete.calledWith(keycloakRealm, 'user-id', 'group2-id')).to.be.true
expect(api.users.realmUsersIdGroupsGroupIdDelete.calledWith(keycloakRealm, 'user-id', 'group1-id')).to.be.false
})

it('should handle errors gracefully', async () => {
api.users.realmUsersIdGroupsGet.rejects(new Error('API Error'))

await removeUserGroups(api, existingUser, ['group1'])

expect(api.users.realmUsersIdGroupsGroupIdDelete.called).to.be.false
})
})

describe('addUserGroups', () => {
it('should add user to groups in teamGroups if not already present', async () => {
const currentKeycloakGroups = [
{ name: 'group1', id: 'group1-id' },
{ name: 'group2', id: 'group2-id' },
]
const existingUserGroups = [{ name: 'group1', id: 'group1-id' }]
api.groups.realmGroupsGet.resolves({ body: currentKeycloakGroups })
api.users.realmUsersIdGroupsGet.resolves({ body: existingUserGroups })

await addUserGroups(api, existingUser, ['group1', 'group2'])

expect(api.users.realmUsersIdGroupsGroupIdPut.calledWith(keycloakRealm, 'user-id', 'group2-id')).to.be.true
expect(api.users.realmUsersIdGroupsGroupIdPut.calledWith(keycloakRealm, 'user-id', 'group1-id')).to.be.false
})

it('should handle errors gracefully', async () => {
api.groups.realmGroupsGet.rejects(new Error('API Error'))

await addUserGroups(api, existingUser, ['group1'])

expect(api.users.realmUsersIdGroupsGroupIdPut.called).to.be.false
})
})
})
74 changes: 30 additions & 44 deletions src/operator/keycloak.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,59 +142,37 @@ async function runKeycloakUpdater(key: string) {
console.info('Missing required keycloak variables for Keycloak setup/reconfiguration')
return
}

async function retryOperation(operation: () => Promise<void>, operationName: string) {
try {
await operation()
} catch (error) {
console.debug(`Error could not ${operationName}`, error)
console.debug('Retrying in 30 seconds')
await new Promise((resolve) => setTimeout(resolve, 30000))
console.log(`Retrying to ${operationName}`)
await runKeycloakUpdater(operationName)
}
}

switch (key) {
case 'addTeam':
try {
await keycloakTeamAdded()
break
} catch (error) {
console.debug('Error could not add team', error)
console.debug('Retrying in 30 seconds')
await new Promise((resolve) => setTimeout(resolve, 30000))
console.log('Retrying to add team')
await runKeycloakUpdater('addTeam')
}
await retryOperation(keycloakTeamAdded, 'add team')
break
case 'removeTeam':
try {
await keycloakTeamDeleted()
break
} catch (error) {
console.debug('Error could not delete team', error)
console.debug('Retrying in 30 seconds')
await new Promise((resolve) => setTimeout(resolve, 30000))
console.log('Retrying to delete team')
await runKeycloakUpdater('removeTeam')
}
await retryOperation(keycloakTeamDeleted, 'delete team')
break
case 'manageUsers':
try {
await manageUsers(env.USERS)
break
} catch (error) {
console.debug('Error could update users', error)
console.debug('Retrying in 30 seconds')
await new Promise((resolve) => setTimeout(resolve, 30000))
console.log('Retrying to update users')
await runKeycloakUpdater('manageUsers')
}
await retryOperation(() => manageUsers(env.USERS), 'update users')
break
case 'updateConfig':
try {
await keycloakConfigMapChanges().then(async () => {
await runKeycloakUpdater('addTeam')
})
await retryOperation(async () => {
await keycloakConfigMapChanges()
await runKeycloakUpdater('addTeam')
if (!JSON.parse(env.FEAT_EXTERNAL_IDP)) {
await runKeycloakUpdater('manageUsers')
}
break
} catch (error) {
console.debug('Error could not update configMap', error)
console.debug('Retrying in 30 seconds')
await new Promise((resolve) => setTimeout(resolve, 30000))
console.log('Retrying to update configMap')
await runKeycloakUpdater('updateConfig')
}
}, 'update configMap')
break
default:
break
Expand Down Expand Up @@ -725,7 +703,11 @@ async function manageGroups(connection: KeycloakConnection) {
}
}

async function removeUserGroups(api: any, existingUser: any, teamGroups: string[]) {
export async function removeUserGroups(
api: { users: UsersApi; groups: GroupsApi },
existingUser: UserRepresentation,
teamGroups: string[],
): Promise<void> {
try {
const { body: existingUserGroups } = await api.users.realmUsersIdGroupsGet(keycloakRealm, existingUser.id as string)

Expand All @@ -741,7 +723,11 @@ async function removeUserGroups(api: any, existingUser: any, teamGroups: string[
}
}

async function addUserGroups(api: any, existingUser: any, teamGroups: string[]) {
export async function addUserGroups(
api: { users: UsersApi; groups: GroupsApi },
existingUser: UserRepresentation,
teamGroups: string[],
): Promise<void> {
try {
const { body: currentKeycloakGroups } = await api.groups.realmGroupsGet(keycloakRealm)
const { body: existingUserGroups } = await api.users.realmUsersIdGroupsGet(keycloakRealm, existingUser.id as string)
Expand Down

0 comments on commit 2479e86

Please sign in to comment.