Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/rbac_with_domains_policy2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
p, admin, domain1, data1, read
p, admin, domain1, data1, write
p, admin, domain2, data2, read
p, admin, domain2, data2, write
p, user, domain3, data2, read
g, alice, admin, domain1
g, alice, admin, domain2
g, bob, admin, domain2
g, bob, user, domain3
24 changes: 24 additions & 0 deletions src/enforcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,30 @@ export class Enforcer extends ManagementEnforcer {

return res.filter((n) => !inherits.some((m) => n === m));
}

/**
* getDomainsForUser gets all domains that a user has.
*/
public async getDomainsForUser(user: string): Promise<string[]> {
const domains: string[] = [];
for (const rm of this.rmMap.values()) {
const domain = await rm.getDomains(user);
domains.push(...domain);
}
return domains;
}

/**
* getAllDomains gets all domains.
*/
public async getAllDomains(): Promise<string[]> {
const domains: string[] = [];
for (const rm of this.rmMap.values()) {
const domain = await rm.getAllDomains();
domains.push(...domain);
}
return arrayRemoveDuplicates(domains);
}
}

export async function newEnforcerWithClass<T extends Enforcer>(enforcer: new () => T, ...params: any[]): Promise<T> {
Expand Down
44 changes: 44 additions & 0 deletions src/rbac/defaultRoleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,4 +352,48 @@ export class DefaultRoleManager implements RoleManager {
});
}
}

/**
* getDomains gets domains that a user has.
*/
public async getDomains(name: string): Promise<string[]> {
const domains: string[] = [];
this.allDomains.forEach((roles, domain) => {
// Skip the default domain if there are other domains
if (domain === DEFAULT_DOMAIN && this.allDomains.size > 1) {
return;
}
const role = roles.get(name);
if (role) {
// Check if role has any roles it inherits OR if any other role inherits from it
const hasRoles = role.getRoles().length > 0;
const hasUsers = this.hasUserForRole(roles, name);
if (hasRoles || hasUsers) {
domains.push(domain);
}
}
});
return domains;
}

/**
* getAllDomains gets all domains.
*/
public async getAllDomains(): Promise<string[]> {
const domains = Array.from(this.allDomains.keys());
// Filter out the default domain if there are other domains
if (domains.length > 1) {
return domains.filter((d) => d !== DEFAULT_DOMAIN);
}
return domains;
}

private hasUserForRole(roles: Roles, name: string): boolean {
for (const role of roles.values()) {
if (role.hasDirectRole(name)) {
return true;
}
}
return false;
}
}
4 changes: 4 additions & 0 deletions src/rbac/roleManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,8 @@ export interface RoleManager {
getUsers(name: string, ...domain: string[]): Promise<string[]>;
// PrintRoles prints all the roles to log.
printRoles(): Promise<void>;
// GetDomains gets domains that a user has
getDomains(name: string): Promise<string[]>;
// GetAllDomains gets all domains
getAllDomains(): Promise<string[]>;
}
23 changes: 23 additions & 0 deletions test/rbacwDomainAPI.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,26 @@ test('test getUsersForRoleInDomain', async () => {
expect(await e.getUsersForRoleInDomain('superadmin', 'domain1')).toEqual([]);
expect(await e.getUsersForRoleInDomain('superadmin', 'domain2')).toEqual([]);
});

test('test getDomainsForUser', async () => {
const e = await newEnforcer('examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy2.csv');

let myRes = await e.getDomainsForUser('alice');
myRes.sort();
expect(myRes).toEqual(['domain1', 'domain2']);

myRes = await e.getDomainsForUser('bob');
myRes.sort();
expect(myRes).toEqual(['domain2', 'domain3']);

myRes = await e.getDomainsForUser('user');
expect(myRes).toEqual(['domain3']);
});

test('test getAllDomains', async () => {
const e = await newEnforcer('examples/rbac_with_domains_model.conf', 'examples/rbac_with_domains_policy.csv');

const myRes = await e.getAllDomains();
myRes.sort();
expect(myRes).toEqual(['domain1', 'domain2']);
});