feat: changed backend-pg to backend

This commit is contained in:
Akhil Mohan
2024-01-27 19:14:33 +05:30
parent d13eafcef7
commit 66d258f02b
792 changed files with 40298 additions and 40607 deletions
@@ -0,0 +1,74 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { ormify, selectAllTableCols } from "@app/lib/knex";
export type TIdentityProjectDALFactory = ReturnType<typeof identityProjectDALFactory>;
export const identityProjectDALFactory = (db: TDbClient) => {
const identityProjectOrm = ormify(db, TableName.IdentityProjectMembership);
const findByProjectId = async (projectId: string, tx?: Knex) => {
try {
const docs = await (tx || db)(TableName.IdentityProjectMembership)
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
.join(
TableName.Identity,
`${TableName.IdentityProjectMembership}.identityId`,
`${TableName.Identity}.id`
)
.leftJoin(
TableName.ProjectRoles,
`${TableName.IdentityProjectMembership}.roleId`,
`${TableName.ProjectRoles}.id`
)
.select(selectAllTableCols(TableName.IdentityProjectMembership))
// cr stands for custom role
.select(db.ref("id").as("crId").withSchema(TableName.ProjectRoles))
.select(db.ref("name").as("crName").withSchema(TableName.ProjectRoles))
.select(db.ref("slug").as("crSlug").withSchema(TableName.ProjectRoles))
.select(db.ref("description").as("crDescription").withSchema(TableName.ProjectRoles))
.select(db.ref("permissions").as("crPermission").withSchema(TableName.ProjectRoles))
.select(db.ref("permissions").as("crPermission").withSchema(TableName.ProjectRoles))
.select(db.ref("id").as("identityId").withSchema(TableName.Identity))
.select(db.ref("name").as("identityName").withSchema(TableName.Identity))
.select(db.ref("authMethod").as("identityAuthMethod").withSchema(TableName.Identity));
return docs.map(
({
crId,
crDescription,
crSlug,
crPermission,
crName,
identityId,
identityName,
identityAuthMethod,
...el
}) => ({
...el,
identityId,
identity: {
id: identityId,
name: identityName,
authMethod: identityAuthMethod
},
customRole: el.roleId
? {
id: crId,
name: crName,
slug: crSlug,
permissions: crPermission,
description: crDescription
}
: undefined
})
);
} catch (error) {
throw new DatabaseError({ error, name: "FindByProjectId" });
}
};
return { ...identityProjectOrm, findByProjectId };
};
@@ -0,0 +1,187 @@
import { ForbiddenError } from "@casl/ability";
import { ProjectMembershipRole, TProjectRoles } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import {
ProjectPermissionActions,
ProjectPermissionSub
} from "@app/ee/services/permission/project-permission";
import { isAtLeastAsPrivileged } from "@app/lib/casl";
import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors";
import { ActorType } from "../auth/auth-type";
import { TIdentityOrgDALFactory } from "../identity/identity-org-dal";
import { TProjectDALFactory } from "../project/project-dal";
import { TIdentityProjectDALFactory } from "./identity-project-dal";
import {
TCreateProjectIdentityDTO,
TDeleteProjectIdentityDTO,
TListProjectIdentityDTO,
TUpdateProjectIdentityDTO
} from "./identity-project-types";
type TIdentityProjectServiceFactoryDep = {
identityProjectDAL: TIdentityProjectDALFactory;
projectDAL: Pick<TProjectDALFactory, "findById">;
identityOrgMembershipDAL: Pick<TIdentityOrgDALFactory, "findOne">;
permissionService: Pick<
TPermissionServiceFactory,
"getProjectPermission" | "getProjectPermissionByRole"
>;
};
export type TIdentityProjectServiceFactory = ReturnType<typeof identityProjectServiceFactory>;
export const identityProjectServiceFactory = ({
identityProjectDAL,
permissionService,
identityOrgMembershipDAL,
projectDAL
}: TIdentityProjectServiceFactoryDep) => {
const createProjectIdentity = async ({
identityId,
actor,
actorId,
projectId,
role
}: TCreateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create,
ProjectPermissionSub.Identity
);
const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (existingIdentity)
throw new BadRequestError({
message: `Identity with id ${identityId} already exists in project with id ${projectId}`
});
const project = await projectDAL.findById(projectId);
const identityOrgMembership = await identityOrgMembershipDAL.findOne({
identityId,
orgId: project.orgId
});
if (!identityOrgMembership)
throw new BadRequestError({
message: `Failed to find identity with id ${identityId}`
});
const { permission: rolePermission, role: customRole } =
await permissionService.getProjectPermissionByRole(role, project.id);
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
if (!hasPriviledge)
throw new ForbiddenRequestError({
message: "Failed to add identity to project with more privileged role"
});
const isCustomRole = Boolean(customRole);
const projectIdentity = await identityProjectDAL.create({
identityId,
projectId: project.id,
role: isCustomRole ? ProjectMembershipRole.Custom : role,
roleId: customRole?.id
});
return projectIdentity;
};
const updateProjectIdentity = async ({
projectId,
identityId,
role,
actor,
actorId
}: TUpdateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit,
ProjectPermissionSub.Identity
);
const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId });
if (!projectIdentity)
throw new BadRequestError({
message: `Identity with id ${identityId} doesn't exists in project with id ${projectId}`
});
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
projectIdentity.identityId,
projectIdentity.projectId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to delete more privileged identity" });
let customRole: TProjectRoles | undefined;
if (role) {
const { permission: rolePermission, role: customOrgRole } =
await permissionService.getProjectPermissionByRole(role, projectIdentity.projectId);
const isCustomRole = Boolean(customOrgRole);
const hasRequiredNewRolePermission = isAtLeastAsPrivileged(permission, rolePermission);
if (!hasRequiredNewRolePermission)
throw new BadRequestError({ message: "Failed to create a more privileged identity" });
if (isCustomRole) customRole = customOrgRole;
}
const [updatedProjectIdentity] = await identityProjectDAL.update(
{ projectId, identityId: projectIdentity.identityId },
{
role: customRole ? ProjectMembershipRole.Custom : role,
roleId: customRole ? customRole.id : null
}
);
return updatedProjectIdentity;
};
const deleteProjectIdentity = async ({
identityId,
actorId,
actor,
projectId
}: TDeleteProjectIdentityDTO) => {
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
if (!identityProjectMembership)
throw new BadRequestError({ message: `Failed to find identity with id ${identityId}` });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
identityProjectMembership.projectId
);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete,
ProjectPermissionSub.Identity
);
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
identityId,
identityProjectMembership.projectId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to delete more privileged identity" });
const [deletedIdentity] = await identityProjectDAL.delete({ identityId });
return deletedIdentity;
};
const listProjectIdentities = async ({ projectId, actor, actorId }: TListProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId);
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read,
ProjectPermissionSub.Identity
);
const identityMemberhips = await identityProjectDAL.findByProjectId(projectId);
return identityMemberhips;
};
return {
createProjectIdentity,
updateProjectIdentity,
deleteProjectIdentity,
listProjectIdentities
};
};
@@ -0,0 +1,17 @@
import { TProjectPermission } from "@app/lib/types";
export type TCreateProjectIdentityDTO = {
identityId: string;
role: string;
} & TProjectPermission;
export type TUpdateProjectIdentityDTO = {
role: string;
identityId: string;
} & TProjectPermission;
export type TDeleteProjectIdentityDTO = {
identityId: string;
} & TProjectPermission;
export type TListProjectIdentityDTO = TProjectPermission;