// tslint:disable:no-unused-expression import { faker } from "@faker-js/faker"; import * as chai from "chai"; import { omit, pick } from "lodash-es"; import { KeycloakAdminClient } from "../src/client.js"; import type ClientRepresentation from "../src/defs/clientRepresentation.js"; import type GroupRepresentation from "../src/defs/groupRepresentation.js"; import type PolicyRepresentation from "../src/defs/policyRepresentation.js"; import { DecisionStrategy, Logic } from "../src/defs/policyRepresentation.js"; import type UserRepresentation from "../src/defs/userRepresentation.js"; import { credentials } from "./constants.js"; const expect = chai.expect; describe("Group user integration", () => { let kcAdminClient: KeycloakAdminClient; let currentGroup: GroupRepresentation; let currentUser: UserRepresentation; let managementClient: ClientRepresentation; let currentUserPolicy: PolicyRepresentation; let currentPolicy: PolicyRepresentation; before(async () => { const groupName = faker.internet.userName(); kcAdminClient = new KeycloakAdminClient(); await kcAdminClient.auth(credentials); // create group const group = await kcAdminClient.groups.create({ name: groupName, }); currentGroup = (await kcAdminClient.groups.findOne({ id: group.id }))!; // create user const username = faker.internet.userName(); const user = await kcAdminClient.users.create({ username, email: "test@keycloak.org", enabled: true, }); currentUser = (await kcAdminClient.users.findOne({ id: user.id }))!; }); after(async () => { await kcAdminClient.groups.del({ id: currentGroup.id!, }); await kcAdminClient.users.del({ id: currentUser.id!, }); }); it("should list user's group and expect empty", async () => { const groups = await kcAdminClient.users.listGroups({ id: currentUser.id!, }); expect(groups).to.be.eql([]); }); it("should add user to group", async () => { await kcAdminClient.users.addToGroup({ id: currentUser.id!, groupId: currentGroup.id!, }); const groups = await kcAdminClient.users.listGroups({ id: currentUser.id!, }); // expect id,name,path to be the same expect(groups[0]).to.be.eql(pick(currentGroup, ["id", "name", "path"])); }); it("should list members using group api", async () => { const members = await kcAdminClient.groups.listMembers({ id: currentGroup.id!, }); // access will not returned from member api expect(members[0]).to.be.eql(omit(currentUser, ["access"])); }); it("should remove user from group", async () => { await kcAdminClient.users.delFromGroup({ id: currentUser.id!, groupId: currentGroup.id!, }); const groups = await kcAdminClient.users.listGroups({ id: currentUser.id!, }); expect(groups).to.be.eql([]); }); /** * Authorization permissions */ describe.skip("authorization permissions", () => { before(async () => { const clients = await kcAdminClient.clients.find(); managementClient = clients.find( (client) => client.clientId === "master-realm", )!; }); after(async () => { await kcAdminClient.clients.delPolicy({ id: managementClient.id!, policyId: currentUserPolicy.id!, }); }); it("Enable permissions", async () => { const permission = await kcAdminClient.groups.updatePermission( { id: currentGroup.id! }, { enabled: true }, ); expect(permission).to.include({ enabled: true, }); }); it("list of users in policy management", async () => { const userPolicyData: PolicyRepresentation = { type: "user", logic: Logic.POSITIVE, decisionStrategy: DecisionStrategy.UNANIMOUS, name: `policy.manager.${currentGroup.id}`, users: [currentUser.id!], }; currentUserPolicy = await kcAdminClient.clients.createPolicy( { id: managementClient.id!, type: userPolicyData.type! }, userPolicyData, ); expect(currentUserPolicy).to.include({ type: "user", logic: Logic.POSITIVE, decisionStrategy: DecisionStrategy.UNANIMOUS, name: `policy.manager.${currentGroup.id}`, }); }); it("list the roles available for this group", async () => { const permissions = (await kcAdminClient.groups.listPermissions({ id: currentGroup.id!, }))!; expect(permissions.scopePermissions).to.be.an("object"); const scopes = (await kcAdminClient.clients.listScopesByResource({ id: managementClient.id!, resourceName: permissions.resource!, }))!; const policies = await kcAdminClient.clients.listPolicies({ id: managementClient.id, resource: permissions.resource, max: 2, }); expect(policies).to.have.length(2); expect(scopes).to.have.length(5); // Search for the id of the management role const roleId = scopes.find((scope) => scope.name === "manage")!.id; const userPolicy = await kcAdminClient.clients.findPolicyByName({ id: managementClient.id!, name: `policy.manager.${currentGroup.id}`, }); expect(userPolicy).to.deep.include({ name: `policy.manager.${currentGroup.id}`, }); // Update of the role with the above modifications const policyData: PolicyRepresentation = { id: permissions.scopePermissions!.manage!, name: `manage.permission.group.${currentGroup.id}`, type: "scope", logic: Logic.POSITIVE, decisionStrategy: DecisionStrategy.UNANIMOUS, resources: [permissions.resource!], scopes: [roleId], policies: [userPolicy.id!], }; await kcAdminClient.clients.updatePermission( { id: managementClient.id!, permissionId: permissions.scopePermissions!.manage, type: "scope", }, policyData, ); currentPolicy = (await kcAdminClient.clients.findOnePermission({ id: managementClient.id!, permissionId: permissions.scopePermissions!.manage, type: "scope", }))!; expect(currentPolicy).to.deep.include({ id: permissions.scopePermissions!.manage, name: `manage.permission.group.${currentGroup.id}`, type: "scope", logic: Logic.POSITIVE, decisionStrategy: DecisionStrategy.UNANIMOUS, }); }); }); });