// tslint:disable:no-unused-expression import * as chai from "chai"; import { KeycloakAdminClient } from "../src/client.js"; import type ClientRepresentation from "../src/defs/clientRepresentation.js"; import type RoleRepresentation from "../src/defs/roleRepresentation.js"; import { credentials } from "./constants.js"; const expect = chai.expect; describe("Roles", () => { let client: KeycloakAdminClient; let currentRole: RoleRepresentation; before(async () => { client = new KeycloakAdminClient(); await client.auth(credentials); }); after(async () => { // delete the currentRole with id await client.roles.delById({ id: currentRole.id!, }); }); it("list roles", async () => { const roles = await client.roles.find(); expect(roles).to.be.ok; }); it("create roles and get by name", async () => { const roleName = "cool-role"; const createdRole = await client.roles.create({ name: roleName, }); expect(createdRole.roleName).to.be.equal(roleName); const role = await client.roles.findOneByName({ name: roleName }); expect(role).to.be.ok; currentRole = role!; }); it("get single roles by id", async () => { const roleId = currentRole.id; const role = await client.roles.findOneById({ id: roleId!, }); expect(role).to.deep.include(currentRole); }); it("update single role by name & by id", async () => { await client.roles.updateByName( { name: currentRole.name! }, { // dont know why if role name not exist in payload, role name will be overriden with empty string // todo: open an issue on keycloak name: "cool-role", description: "cool", }, ); const role = await client.roles.findOneByName({ name: currentRole.name!, }); expect(role).to.include({ description: "cool", }); await client.roles.updateById( { id: currentRole.id! }, { description: "another description", }, ); const roleById = await client.roles.findOneById({ id: currentRole.id!, }); expect(roleById).to.include({ description: "another description", }); }); it("delete single roles by id", async () => { await client.roles.create({ name: "for-delete", }); await client.roles.delByName({ name: "for-delete", }); const roleDelByName = await client.roles.findOneByName({ name: "for-delete", }); expect(roleDelByName).to.be.null; }); it("get users with role by name in realm", async () => { const users = await client.roles.findUsersWithRole({ name: "admin", }); expect(users).to.be.ok; expect(users).to.be.an("array"); }); it.skip("Enable fine grained permissions", async () => { const permission = await client.roles.updatePermission( { id: currentRole.id! }, { enabled: true }, ); expect(permission).to.include({ enabled: true, }); }); it.skip("List fine grained permissions for this role", async () => { const permissions = (await client.roles.listPermissions({ id: currentRole.id!, }))!; expect(permissions.scopePermissions).to.be.an("object"); }); describe("Composite roles", () => { const compositeRoleName = "compositeRole"; let compositeRole: RoleRepresentation; beforeEach(async () => { await client.roles.create({ name: compositeRoleName, }); compositeRole = (await client.roles.findOneByName({ name: compositeRoleName, }))!; await client.roles.createComposite({ roleId: currentRole.id! }, [ compositeRole, ]); }); afterEach(async () => { await client.roles.delByName({ name: compositeRoleName, }); }); it("make the role a composite role by associating some child roles", async () => { const children = await client.roles.getCompositeRoles({ id: currentRole.id!, }); // attributes on the composite role are empty and when fetched not there. // eslint-disable-next-line @typescript-eslint/no-unused-vars const { attributes, ...rest } = compositeRole; expect(children).to.be.eql([rest]); }); it("search for composite roles", async () => { const children = await client.roles.getCompositeRoles({ id: currentRole.id!, search: "not", }); expect(children).to.be.an("array").that.is.length(0); }); it("delete composite roles", async () => { await client.roles.delCompositeRoles({ id: currentRole.id! }, [ compositeRole, ]); const children = await client.roles.getCompositeRoles({ id: currentRole.id!, }); expect(children).to.be.an("array").that.is.empty; }); describe("Get composite roles for client and realm", () => { let createdClient: ClientRepresentation; let clientRole: RoleRepresentation; before(async () => { createdClient = await client.clients.create({ clientId: "test" }); const clientRoleName = "clientRole"; await client.clients.createRole({ id: createdClient.id, name: clientRoleName, }); clientRole = await client.clients.findRole({ id: createdClient.id!, roleName: clientRoleName, }); await client.roles.createComposite({ roleId: currentRole.id! }, [ clientRole, ]); }); after(async () => { await client.clients.del({ id: createdClient.id! }); }); it("get composite role for the realm", async () => { const realmChildren = await client.roles.getCompositeRolesForRealm({ id: currentRole.id!, }); const children = await client.roles.getCompositeRoles({ id: currentRole.id!, }); delete compositeRole.attributes; expect(realmChildren).to.be.eql([compositeRole]); expect(children).to.be.an("array").that.is.length(2); }); it("get composite for the client", async () => { const clientChildren = await client.roles.getCompositeRolesForClient({ id: currentRole.id!, clientId: createdClient.id!, }); delete clientRole.attributes; expect(clientChildren).to.be.eql([clientRole]); }); }); }); });