src/iam/policy/policy.service.ts
Properties |
|
Methods |
|
constructor(prismaService: PrismaService, keycloakProvider: KeycloakProvider)
|
|||||||||
|
Defined in src/iam/policy/policy.service.ts:14
|
|||||||||
|
Parameters :
|
| Async addResourceEntry | ||||||||||||
addResourceEntry(resourceType: string, resourceId: any)
|
||||||||||||
|
Defined in src/iam/policy/policy.service.ts:202
|
||||||||||||
|
this function adds entry to resource table
Parameters :
Returns :
Promise<object>
created resource object |
| checkPermission | ||||||||||
checkPermission(permission, projectId, resource, action)
|
||||||||||
|
Defined in src/iam/policy/policy.service.ts:239
|
||||||||||
|
function to check permissions
Parameters :
Returns :
any
|
| Async createPolicy | ||||||
createPolicy(policy: Policy)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:21
|
||||||
|
Parameters :
Returns :
Promise<Policy>
|
| Async deletePolicy | ||||||
deletePolicy(where: Prisma.PolicyWhereUniqueInput)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:31
|
||||||
|
Parameters :
Returns :
Promise<Policy>
|
| Async getCredentials | ||||||
getCredentials(username: string)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:45
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getOrCreateUser |
getOrCreateUser(username: string, email: string)
|
|
Defined in src/iam/policy/policy.service.ts:41
|
|
Returns :
unknown
|
| Async getTuroPermissions | ||||||
getTuroPermissions(userId: string)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:262
|
||||||
|
this function gets turo permissions
Parameters :
Returns :
Promise<object>
|
| Async getUserPermissions | ||||||
getUserPermissions(userId: string)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:164
|
||||||
|
this function gets permissions for user according to policies defined
Parameters :
Returns :
Promise<object>
|
| Async getUserPolicies | ||||||
getUserPolicies(userId: string)
|
||||||
|
Defined in src/iam/policy/policy.service.ts:57
|
||||||
|
this function to get policies applicable to user
Parameters :
Returns :
Promise<object>
|
| Async removeResourceEntry | ||||||||||||
removeResourceEntry(resourceType: string, resourceId: any)
|
||||||||||||
|
Defined in src/iam/policy/policy.service.ts:220
|
||||||||||||
|
this function uses delete many to delete entry from resource table as prisma delete expects unique id in where clause
Parameters :
Returns :
Promise<object>
deleted resource entry object |
| policies |
Type : object
|
Default value : {}
|
|
Defined in src/iam/policy/policy.service.ts:14
|
| Private PROJECT_PUBLIC_ROLE_NAME |
Default value : Roles.PROJECT_READONLY
|
|
Defined in src/iam/policy/policy.service.ts:10
|
| Private TURO_ADMIN_ROLE_NAME |
Default value : Roles.TURO_ADMIN
|
|
Defined in src/iam/policy/policy.service.ts:12
|
| Private TURO_READONLY_ROLE_NAME |
Default value : Roles.TURO_READONLY
|
|
Defined in src/iam/policy/policy.service.ts:11
|
import { Injectable, InternalServerErrorException } from "@nestjs/common";
import { Prisma } from "@prisma/client";
import { PrismaService } from "../../common/prisma/prisma.service";
import { Policy } from "./types/policy.interface";
import { KeycloakProvider } from "../../providers/keycloak/keycloak.provider";
import { Roles } from "../role/entity/role.entity";
@Injectable()
export class PolicyService {
private PROJECT_PUBLIC_ROLE_NAME = Roles.PROJECT_READONLY;
private TURO_READONLY_ROLE_NAME = Roles.TURO_READONLY;
private TURO_ADMIN_ROLE_NAME = Roles.TURO_ADMIN;
policies = {};
constructor(
private readonly prismaService: PrismaService,
private readonly keycloakProvider: KeycloakProvider,
) {}
async createPolicy(policy: Policy): Promise<Policy> {
try {
return (await this.prismaService.policy.create({
data: policy,
})) as unknown as Policy;
} catch (error) {
throw new InternalServerErrorException(error.message);
}
}
async deletePolicy(where: Prisma.PolicyWhereUniqueInput): Promise<Policy> {
try {
return (await this.prismaService.policy.delete({
where,
})) as unknown as Policy;
} catch (error) {
throw new InternalServerErrorException(error.message);
}
}
async getOrCreateUser(username: string, email: string) {
return await this.keycloakProvider.getOrCreateUser(username, email);
}
async getCredentials(username: string) {
return await this.keycloakProvider.getCredentials(
KeycloakProvider.turoServicesClientId,
username,
);
}
/**
* this function to get policies applicable to user
* @param userId
* @returns {Promise<object>}
*/
async getUserPolicies(userId: string): Promise<object> {
const _userId = userId.toLowerCase();
const projectPolicyMap = {};
const userTuroRoles = await this.prismaService.userTuroRole.findMany({
where: {
userId: _userId,
},
});
const userBURoles = await this.prismaService.userBURole.findMany({
where: {
userId: _userId,
},
include: {
bu: {
include: {
projects: true,
},
},
},
});
const userProjectRoles = await this.prismaService.userProjectRole.findMany({
where: {
userId: _userId,
},
});
const userProjects = userProjectRoles.map((role) => role.projectId);
// get public projects ie not already in user projects
const publicProjects = await this.prismaService.project.findMany({
where: {
id: {
notIn: userProjects,
},
isPublic: true,
},
});
const publicRole = await this.prismaService.role.findUnique({
where: {
name: this.PROJECT_PUBLIC_ROLE_NAME,
},
});
publicProjects.forEach((project) => {
userProjectRoles.push({
id: null, //placeholder
projectId: project.id,
userId: _userId,
roleId: publicRole.id,
});
});
userBURoles.forEach((buRole) => {
buRole.bu.projects.forEach((project) => {
userProjectRoles.push({
id: null, // placeholder
roleId: buRole.roleId,
projectId: project.id,
userId: buRole.userId,
});
});
});
userTuroRoles.forEach((turoRole) => {
userProjectRoles.push({
id: null, // placeholder
roleId: turoRole.roleId,
projectId: 0,
userId: turoRole.userId,
});
});
const promises = userProjectRoles.map((userProjectRole) => {
return new Promise<void>(async (resolve) => {
const policies = await this.prismaService.policy.findMany({
where: {
roles: {
some: {
roleId: userProjectRole.roleId,
},
},
},
});
if (userProjectRole.projectId in projectPolicyMap) {
projectPolicyMap[userProjectRole.projectId].push(...policies);
} else {
projectPolicyMap[userProjectRole.projectId] = policies;
}
resolve();
});
});
await Promise.all(promises);
return projectPolicyMap;
}
/**
* this function gets permissions for user
* according to policies defined
* @param userId
* @returns {Promise<object>}
*/
async getUserPermissions(userId: string): Promise<object> {
const _userId = userId.toLowerCase();
const projectPolicyMap = await this.getUserPolicies(_userId);
const permissionsMap = {};
for (const projectId in projectPolicyMap) {
projectPolicyMap[projectId].forEach((policy) => {
policy["statements"].forEach((statement) => {
if (
permissionsMap[projectId] &&
statement["resource"] in permissionsMap[projectId]
) {
permissionsMap[projectId][statement["resource"]][
statement["action"]
] = true;
} else if (permissionsMap[projectId]) {
permissionsMap[projectId][statement["resource"]] = {
[statement["action"]]: true,
};
} else {
permissionsMap[projectId] = {
[statement["resource"]]: {
[statement["action"]]: true,
},
};
}
});
});
}
return permissionsMap;
}
/**
* this function adds entry to resource table
* @param resourceType eg: project, model, cost, etc.
* @param resourceId eg: 1, 2,etc.
* @returns created resource object
*/
async addResourceEntry(
resourceType: string,
resourceId: any,
): Promise<object> {
return this.prismaService.resource.create({
data: {
name: `turo:${resourceType}:${resourceId}`,
},
});
}
/**
* this function uses delete many to delete entry from resource
* table as prisma delete expects unique id in where clause
* @param resourceType eg: project, model, cost, etc.
* @param resourceId eg: 1, 2,etc.
* @returns deleted resource entry object
*/
async removeResourceEntry(
resourceType: string,
resourceId: any,
): Promise<object> {
return this.prismaService.resource.deleteMany({
where: {
name: `turo:${resourceType}:${resourceId}`,
},
});
}
/**
* function to check permissions
* @param permission
* @param projectId
* @param resource
* @param action
* @returns
*/
checkPermission(permission, projectId, resource, action) {
const projectPermission = permission[projectId];
const globalPermission = permission["0"];
const allowedPermissionList = [
globalPermission?.["*"]?.["*"],
globalPermission?.["*"]?.[action],
globalPermission?.[resource]?.["*"],
globalPermission?.[resource]?.[action],
projectPermission?.["*"]?.["*"],
projectPermission?.["*"]?.[action],
projectPermission?.[resource]?.["*"],
projectPermission?.[resource]?.[action],
];
return allowedPermissionList.some((permission) => permission == true);
}
/**
* this function gets turo permissions
* @param userId
* @returns {Promise<object>}
*/
async getTuroPermissions(userId: string): Promise<object> {
// fetch all user roles
const _userId = userId.toLowerCase();
const userRoles = await this.prismaService.userTuroRole.findMany({
where: {
userId: _userId,
},
include: {
role: true,
},
});
// check if user is turo admin
const isTuroAdmin = userRoles.some(
(role) => role.role.name === this.TURO_ADMIN_ROLE_NAME,
);
// check if user is turo readonly
const isTuroReadOnly = userRoles.some(
(role) => role.role.name === this.TURO_READONLY_ROLE_NAME,
);
return {
isTuroAdmin,
isTuroReadOnly,
};
}
}