Skip to content

Commit d4ae62c

Browse files
committed
feat: add methods to retrieve domains for users and roles (#524)
1 parent ab064e0 commit d4ae62c

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
p, admin, domain1, data1, read
2+
p, admin, domain1, data1, write
3+
p, admin, domain2, data2, read
4+
p, admin, domain2, data2, write
5+
p, user, domain3, data2, read
6+
g, alice, admin, domain1
7+
g, alice, admin, domain2
8+
g, bob, admin, domain2
9+
g, bob, user, domain3

src/enforcer.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,30 @@ export class Enforcer extends ManagementEnforcer {
464464

465465
return res.filter((n) => !inherits.some((m) => n === m));
466466
}
467+
468+
/**
469+
* getDomainsForUser gets all domains that a user has.
470+
*/
471+
public async getDomainsForUser(user: string): Promise<string[]> {
472+
const domains: string[] = [];
473+
for (const rm of this.rmMap.values()) {
474+
const domain = await rm.getDomains(user);
475+
domains.push(...domain);
476+
}
477+
return domains;
478+
}
479+
480+
/**
481+
* getAllDomains gets all domains.
482+
*/
483+
public async getAllDomains(): Promise<string[]> {
484+
const domains: string[] = [];
485+
for (const rm of this.rmMap.values()) {
486+
const domain = await rm.getAllDomains();
487+
domains.push(...domain);
488+
}
489+
return arrayRemoveDuplicates(domains);
490+
}
467491
}
468492

469493
export async function newEnforcerWithClass<T extends Enforcer>(enforcer: new () => T, ...params: any[]): Promise<T> {

src/rbac/defaultRoleManager.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,4 +352,48 @@ export class DefaultRoleManager implements RoleManager {
352352
});
353353
}
354354
}
355+
356+
/**
357+
* getDomains gets domains that a user has.
358+
*/
359+
public async getDomains(name: string): Promise<string[]> {
360+
const domains: string[] = [];
361+
this.allDomains.forEach((roles, domain) => {
362+
// Skip the default domain if there are other domains
363+
if (domain === DEFAULT_DOMAIN && this.allDomains.size > 1) {
364+
return;
365+
}
366+
const role = roles.get(name);
367+
if (role) {
368+
// Check if role has any roles it inherits OR if any other role inherits from it
369+
const hasRoles = role.getRoles().length > 0;
370+
const hasUsers = this.hasUserForRole(roles, name);
371+
if (hasRoles || hasUsers) {
372+
domains.push(domain);
373+
}
374+
}
375+
});
376+
return domains;
377+
}
378+
379+
/**
380+
* getAllDomains gets all domains.
381+
*/
382+
public async getAllDomains(): Promise<string[]> {
383+
const domains = Array.from(this.allDomains.keys());
384+
// Filter out the default domain if there are other domains
385+
if (domains.length > 1) {
386+
return domains.filter((d) => d !== DEFAULT_DOMAIN);
387+
}
388+
return domains;
389+
}
390+
391+
private hasUserForRole(roles: Roles, name: string): boolean {
392+
for (const role of roles.values()) {
393+
if (role.hasDirectRole(name)) {
394+
return true;
395+
}
396+
}
397+
return false;
398+
}
355399
}

src/rbac/roleManager.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,8 @@ export interface RoleManager {
3636
getUsers(name: string, ...domain: string[]): Promise<string[]>;
3737
// PrintRoles prints all the roles to log.
3838
printRoles(): Promise<void>;
39+
// GetDomains gets domains that a user has
40+
getDomains(name: string): Promise<string[]>;
41+
// GetAllDomains gets all domains
42+
getAllDomains(): Promise<string[]>;
3943
}

test/rbacwDomainAPI.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,26 @@ test('test getUsersForRoleInDomain', async () => {
2929
expect(await e.getUsersForRoleInDomain('superadmin', 'domain1')).toEqual([]);
3030
expect(await e.getUsersForRoleInDomain('superadmin', 'domain2')).toEqual([]);
3131
});
32+
33+
test('test getDomainsForUser', async () => {
34+
const e = await newEnforcer('examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy2.csv');
35+
36+
let myRes = await e.getDomainsForUser('alice');
37+
myRes.sort();
38+
expect(myRes).toEqual(['domain1', 'domain2']);
39+
40+
myRes = await e.getDomainsForUser('bob');
41+
myRes.sort();
42+
expect(myRes).toEqual(['domain2', 'domain3']);
43+
44+
myRes = await e.getDomainsForUser('user');
45+
expect(myRes).toEqual(['domain3']);
46+
});
47+
48+
test('test getAllDomains', async () => {
49+
const e = await newEnforcer('examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy.csv');
50+
51+
const myRes = await e.getAllDomains();
52+
myRes.sort();
53+
expect(myRes).toEqual(['domain1', 'domain2']);
54+
});

0 commit comments

Comments
 (0)