mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-31 22:09:57 +00:00
Fix: Seperate groups / project users additional privileges
This commit is contained in:
backend/src
ee/services
access-approval-request
group-project-user-additional-privilege
project-user-additional-privilege
server/routes
@ -12,27 +12,37 @@ export type TAccessApprovalRequestDALFactory = ReturnType<typeof accessApprovalR
|
||||
export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
const accessApprovalRequestOrm = ormify(db, TableName.AccessApprovalRequest);
|
||||
const projectUserAdditionalPrivilegeOrm = ormify(db, TableName.ProjectUserAdditionalPrivilege);
|
||||
const groupProjectUserAdditionalPrivilegeOrm = ormify(db, TableName.GroupProjectUserAdditionalPrivilege);
|
||||
|
||||
const deleteMany = async (filter: TFindFilter<TAccessApprovalRequests>, tx?: Knex) => {
|
||||
const transaction = tx || (await db.transaction());
|
||||
|
||||
try {
|
||||
const handleDeletion = async (processedTx: Knex) => {
|
||||
const accessApprovalRequests = await accessApprovalRequestOrm.find(filter, { tx: processedTx });
|
||||
const accessApprovalRequests = await accessApprovalRequestOrm.find(filter, { tx: transaction });
|
||||
|
||||
await projectUserAdditionalPrivilegeOrm.delete(
|
||||
{
|
||||
$in: {
|
||||
id: accessApprovalRequests.filter((req) => !!req.privilegeId).map((req) => req.privilegeId!)
|
||||
}
|
||||
},
|
||||
processedTx
|
||||
);
|
||||
await projectUserAdditionalPrivilegeOrm.delete(
|
||||
{
|
||||
$in: {
|
||||
id: accessApprovalRequests
|
||||
.filter((req) => Boolean(req.projectUserPrivilegeId))
|
||||
.map((req) => req.projectUserPrivilegeId!)
|
||||
}
|
||||
},
|
||||
transaction
|
||||
);
|
||||
|
||||
return accessApprovalRequestOrm.delete(filter, processedTx);
|
||||
};
|
||||
await groupProjectUserAdditionalPrivilegeOrm.delete(
|
||||
{
|
||||
$in: {
|
||||
id: accessApprovalRequests
|
||||
.filter((req) => Boolean(req.groupProjectUserPrivilegeId))
|
||||
.map((req) => req.groupProjectUserPrivilegeId!)
|
||||
}
|
||||
},
|
||||
transaction
|
||||
);
|
||||
|
||||
if (tx) return await handleDeletion(tx);
|
||||
|
||||
return await db.transaction(handleDeletion);
|
||||
return await accessApprovalRequestOrm.delete(filter, transaction);
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "DeleteManyAccessApprovalRequest" });
|
||||
}
|
||||
@ -45,9 +55,14 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
|
||||
.leftJoin(
|
||||
TableName.ProjectUserAdditionalPrivilege,
|
||||
`${TableName.AccessApprovalRequest}.privilegeId`,
|
||||
`${TableName.AccessApprovalRequest}.projectUserPrivilegeId`,
|
||||
`${TableName.ProjectUserAdditionalPrivilege}.id`
|
||||
)
|
||||
.leftJoin(
|
||||
TableName.GroupProjectUserAdditionalPrivilege,
|
||||
`${TableName.AccessApprovalRequest}.groupProjectUserPrivilegeId`,
|
||||
`${TableName.GroupProjectUserAdditionalPrivilege}.id`
|
||||
)
|
||||
.leftJoin(
|
||||
TableName.AccessApprovalPolicy,
|
||||
`${TableName.AccessApprovalRequest}.policyId`,
|
||||
@ -89,32 +104,81 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
db.ref("status").withSchema(TableName.AccessApprovalRequestReviewer).as("reviewerStatus")
|
||||
)
|
||||
|
||||
// Project user additional privilege
|
||||
.select(
|
||||
db
|
||||
.ref("projectMembershipId")
|
||||
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||
.as("privilegeProjectMembershipId"),
|
||||
.as("projectPrivilegeProjectMembershipId"),
|
||||
|
||||
db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("projectPrivilegeIsTemporary"),
|
||||
|
||||
db
|
||||
.ref("groupMembershipId")
|
||||
.ref("temporaryMode")
|
||||
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||
.as("privilegeGroupMembershipId"),
|
||||
db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeIsTemporary"),
|
||||
db.ref("temporaryMode").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryMode"),
|
||||
db.ref("temporaryRange").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegeTemporaryRange"),
|
||||
.as("projectPrivilegeTemporaryMode"),
|
||||
|
||||
db
|
||||
.ref("temporaryRange")
|
||||
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||
.as("projectPrivilegeTemporaryRange"),
|
||||
|
||||
db
|
||||
.ref("temporaryAccessStartTime")
|
||||
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||
.as("privilegeTemporaryAccessStartTime"),
|
||||
.as("projectPrivilegeTemporaryAccessStartTime"),
|
||||
|
||||
db
|
||||
.ref("temporaryAccessEndTime")
|
||||
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||
.as("privilegeTemporaryAccessEndTime"),
|
||||
.as("projectPrivilegeTemporaryAccessEndTime"),
|
||||
|
||||
db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("privilegePermissions")
|
||||
db.ref("permissions").withSchema(TableName.ProjectUserAdditionalPrivilege).as("projectPrivilegePermissions")
|
||||
)
|
||||
// Group project user additional privilege
|
||||
.select(
|
||||
db
|
||||
.ref("groupProjectMembershipId")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeGroupProjectMembershipId"),
|
||||
|
||||
db
|
||||
.ref("requestedByUserId")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeRequestedByUserId"),
|
||||
|
||||
db
|
||||
.ref("isTemporary")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeIsTemporary"),
|
||||
|
||||
db
|
||||
.ref("temporaryMode")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeTemporaryMode"),
|
||||
|
||||
db
|
||||
.ref("temporaryRange")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeTemporaryRange"),
|
||||
|
||||
db
|
||||
.ref("temporaryAccessStartTime")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeTemporaryAccessStartTime"),
|
||||
|
||||
db
|
||||
.ref("temporaryAccessEndTime")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegeTemporaryAccessEndTime"),
|
||||
db
|
||||
.ref("permissions")
|
||||
.withSchema(TableName.GroupProjectUserAdditionalPrivilege)
|
||||
.as("groupPrivilegePermissions")
|
||||
)
|
||||
.orderBy(`${TableName.AccessApprovalRequest}.createdAt`, "desc");
|
||||
|
||||
const formattedDocs = sqlNestRelationships({
|
||||
const projectUserFormattedDocs = sqlNestRelationships({
|
||||
data: docs,
|
||||
key: "id",
|
||||
parentMapper: (doc) => ({
|
||||
@ -129,20 +193,34 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
secretPath: doc.policySecretPath,
|
||||
envId: doc.policyEnvId
|
||||
},
|
||||
privilege: doc.privilegeId
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
privilege: doc.projectUserPrivilegeId
|
||||
? {
|
||||
projectMembershipId: doc.privilegeGroupMembershipId,
|
||||
groupMembershipId: doc.privilegeGroupMembershipId,
|
||||
isTemporary: doc.privilegeIsTemporary,
|
||||
temporaryMode: doc.privilegeTemporaryMode,
|
||||
temporaryRange: doc.privilegeTemporaryRange,
|
||||
temporaryAccessStartTime: doc.privilegeTemporaryAccessStartTime,
|
||||
temporaryAccessEndTime: doc.privilegeTemporaryAccessEndTime,
|
||||
permissions: doc.privilegePermissions
|
||||
projectMembershipId: doc.projectMembershipId,
|
||||
groupMembershipId: null,
|
||||
requestedByUserId: null,
|
||||
isTemporary: doc.projectPrivilegeIsTemporary,
|
||||
temporaryMode: doc.projectPrivilegeTemporaryMode,
|
||||
temporaryRange: doc.projectPrivilegeTemporaryRange,
|
||||
temporaryAccessStartTime: doc.projectPrivilegeTemporaryAccessStartTime,
|
||||
temporaryAccessEndTime: doc.projectPrivilegeTemporaryAccessEndTime,
|
||||
permissions: doc.projectPrivilegePermissions
|
||||
}
|
||||
: null,
|
||||
: doc.groupProjectUserPrivilegeId
|
||||
? {
|
||||
groupMembershipId: doc.groupPrivilegeGroupProjectMembershipId,
|
||||
requestedByUserId: doc.groupPrivilegeRequestedByUserId,
|
||||
projectMembershipId: null,
|
||||
isTemporary: doc.groupPrivilegeIsTemporary,
|
||||
temporaryMode: doc.groupPrivilegeTemporaryMode,
|
||||
temporaryRange: doc.groupPrivilegeTemporaryRange,
|
||||
temporaryAccessStartTime: doc.groupPrivilegeTemporaryAccessStartTime,
|
||||
temporaryAccessEndTime: doc.groupPrivilegeTemporaryAccessEndTime,
|
||||
permissions: doc.groupPrivilegePermissions
|
||||
}
|
||||
: null,
|
||||
|
||||
isApproved: !!doc.privilegeId
|
||||
isApproved: !!doc.projectUserPrivilegeId
|
||||
}),
|
||||
childrenMapper: [
|
||||
{
|
||||
@ -155,9 +233,9 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
]
|
||||
});
|
||||
|
||||
if (!formattedDocs) return [];
|
||||
if (!projectUserFormattedDocs) return [];
|
||||
|
||||
return formattedDocs.map((doc) => ({
|
||||
return projectUserFormattedDocs.map((doc) => ({
|
||||
...doc,
|
||||
policy: { ...doc.policy, approvers: doc.approvers }
|
||||
}));
|
||||
@ -247,12 +325,6 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
`${TableName.AccessApprovalPolicy}.id`
|
||||
)
|
||||
.leftJoin(TableName.Environment, `${TableName.AccessApprovalPolicy}.envId`, `${TableName.Environment}.id`)
|
||||
.leftJoin(
|
||||
TableName.ProjectUserAdditionalPrivilege,
|
||||
`${TableName.AccessApprovalRequest}.privilegeId`,
|
||||
`${TableName.ProjectUserAdditionalPrivilege}.id`
|
||||
)
|
||||
|
||||
.leftJoin(
|
||||
TableName.AccessApprovalRequestReviewer,
|
||||
`${TableName.AccessApprovalRequest}.id`,
|
||||
@ -282,12 +354,18 @@ export const accessApprovalRequestDALFactory = (db: TDbClient) => {
|
||||
|
||||
// an approval is pending if there is no reviewer rejections and no privilege ID is set
|
||||
const pendingApprovals = formattedRequests.filter(
|
||||
(req) => !req.privilegeId && !req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
|
||||
(req) =>
|
||||
!req.projectUserPrivilegeId &&
|
||||
!req.groupProjectUserPrivilegeId &&
|
||||
!req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
|
||||
);
|
||||
|
||||
// an approval is finalized if there are any rejections or a privilege ID is set
|
||||
const finalizedApprovals = formattedRequests.filter(
|
||||
(req) => req.privilegeId || req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
|
||||
(req) =>
|
||||
req.projectUserPrivilegeId ||
|
||||
req.groupProjectUserPrivilegeId ||
|
||||
req.reviewers.some((r) => r.status === ApprovalStatus.REJECTED)
|
||||
);
|
||||
|
||||
return { pendingCount: pendingApprovals.length, finalizedCount: finalizedApprovals.length };
|
||||
|
@ -2,11 +2,10 @@ import { ForbiddenError } from "@casl/ability";
|
||||
import slugify from "@sindresorhus/slugify";
|
||||
import ms from "ms";
|
||||
|
||||
import { ProjectMembershipRole } from "@app/db/schemas";
|
||||
import { ProjectMembershipRole, TProjectUserAdditionalPrivilege } from "@app/db/schemas";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { TGroupProjectDALFactory } from "@app/services/group-project/group-project-dal";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "@app/services/project-env/project-env-dal";
|
||||
import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal";
|
||||
@ -16,7 +15,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||
import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-policy/access-approval-policy-approver-dal";
|
||||
import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal";
|
||||
import { verifyApprovers } from "../access-approval-policy/access-approval-policy-fns";
|
||||
import { TUserGroupMembershipDALFactory } from "../group/user-group-membership-dal";
|
||||
import { TGroupProjectUserAdditionalPrivilegeDALFactory } from "../group-project-user-additional-privilege/group-project-user-additional-privilege-dal";
|
||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission";
|
||||
import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal";
|
||||
@ -33,14 +32,13 @@ import {
|
||||
TReviewAccessRequestDTO
|
||||
} from "./access-approval-request-types";
|
||||
|
||||
type TSecretApprovalRequestServiceFactoryDep = {
|
||||
type TAccessApprovalRequestServiceFactoryDep = {
|
||||
additionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "create" | "findById" | "deleteById">;
|
||||
groupAdditionalPrivilegeDAL: TGroupProjectUserAdditionalPrivilegeDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
accessApprovalPolicyApproverDAL: Pick<TAccessApprovalPolicyApproverDALFactory, "find">;
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne">;
|
||||
projectDAL: Pick<TProjectDALFactory, "checkProjectUpgradeStatus" | "findProjectBySlug">;
|
||||
userGroupMembershipDAL: Pick<TUserGroupMembershipDALFactory, "findOne">;
|
||||
groupProjectDAL: Pick<TGroupProjectDALFactory, "findOne">;
|
||||
accessApprovalRequestDAL: Pick<
|
||||
TAccessApprovalRequestDALFactory,
|
||||
| "create"
|
||||
@ -73,16 +71,15 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
projectEnvDAL,
|
||||
permissionService,
|
||||
accessApprovalRequestDAL,
|
||||
groupAdditionalPrivilegeDAL,
|
||||
accessApprovalRequestReviewerDAL,
|
||||
userGroupMembershipDAL,
|
||||
groupProjectDAL,
|
||||
projectMembershipDAL,
|
||||
accessApprovalPolicyDAL,
|
||||
accessApprovalPolicyApproverDAL,
|
||||
additionalPrivilegeDAL,
|
||||
smtpService,
|
||||
userDAL
|
||||
}: TSecretApprovalRequestServiceFactoryDep) => {
|
||||
}: TAccessApprovalRequestServiceFactoryDep) => {
|
||||
const createAccessApprovalRequest = async ({
|
||||
isTemporary,
|
||||
temporaryRange,
|
||||
@ -146,12 +143,21 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
|
||||
if (duplicateRequests?.length > 0) {
|
||||
for await (const duplicateRequest of duplicateRequests) {
|
||||
if (duplicateRequest.privilegeId) {
|
||||
const privilege = await additionalPrivilegeDAL.findById(duplicateRequest.privilegeId);
|
||||
let foundPrivilege: Pick<
|
||||
TProjectUserAdditionalPrivilege,
|
||||
"temporaryAccessEndTime" | "isTemporary" | "id"
|
||||
> | null = null;
|
||||
|
||||
const isExpired = new Date() > new Date(privilege.temporaryAccessEndTime || ("" as string));
|
||||
if (duplicateRequest.projectUserPrivilegeId) {
|
||||
foundPrivilege = await additionalPrivilegeDAL.findById(duplicateRequest.projectUserPrivilegeId);
|
||||
} else if (duplicateRequest.groupProjectUserPrivilegeId) {
|
||||
foundPrivilege = await groupAdditionalPrivilegeDAL.findById(duplicateRequest.groupProjectUserPrivilegeId);
|
||||
}
|
||||
|
||||
if (!isExpired || !privilege.isTemporary) {
|
||||
if (foundPrivilege) {
|
||||
const isExpired = new Date() > new Date(foundPrivilege.temporaryAccessEndTime || ("" as string));
|
||||
|
||||
if (!isExpired || !foundPrivilege.isTemporary) {
|
||||
throw new BadRequestError({ message: "You already have an active privilege with the same criteria" });
|
||||
}
|
||||
} else {
|
||||
@ -241,7 +247,7 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
|
||||
const accessApprovalRequest = await accessApprovalRequestDAL.findById(requestId);
|
||||
|
||||
if (!accessApprovalRequest?.privilegeId) {
|
||||
if (!accessApprovalRequest?.projectUserPrivilegeId && !accessApprovalRequest?.groupProjectUserPrivilegeId) {
|
||||
throw new BadRequestError({ message: "Access request must be approved to be deleted" });
|
||||
}
|
||||
|
||||
@ -258,7 +264,11 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
throw new UnauthorizedError({ message: "Only policy approvers can delete access requests" });
|
||||
}
|
||||
|
||||
await additionalPrivilegeDAL.deleteById(accessApprovalRequest.privilegeId);
|
||||
if (accessApprovalRequest.projectUserPrivilegeId) {
|
||||
await additionalPrivilegeDAL.deleteById(accessApprovalRequest.projectUserPrivilegeId);
|
||||
} else if (accessApprovalRequest.groupProjectUserPrivilegeId) {
|
||||
await groupAdditionalPrivilegeDAL.deleteById(accessApprovalRequest.groupProjectUserPrivilegeId);
|
||||
}
|
||||
|
||||
return { request: accessApprovalRequest };
|
||||
};
|
||||
@ -368,7 +378,8 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
throw new BadRequestError({ message: "Temporary range is required for temporary access" });
|
||||
}
|
||||
|
||||
let privilegeId: string | null = null;
|
||||
let projectUserPrivilegeId: string | null = null;
|
||||
let groupProjectMembershipId: string | null = null;
|
||||
|
||||
if (!accessApprovalRequest.groupMembershipId && !accessApprovalRequest.projectMembershipId) {
|
||||
throw new BadRequestError({ message: "Project membership or group membership is required" });
|
||||
@ -376,57 +387,83 @@ export const accessApprovalRequestServiceFactory = ({
|
||||
|
||||
// Permanent access
|
||||
if (!accessApprovalRequest.isTemporary && !accessApprovalRequest.temporaryRange) {
|
||||
let groupUserMembershipId: string | null = null;
|
||||
|
||||
if (accessApprovalRequest.groupMembershipId) {
|
||||
const groupProjectMembership = await groupProjectDAL.findOne({
|
||||
id: accessApprovalRequest.groupMembershipId
|
||||
});
|
||||
if (!groupProjectMembership) throw new BadRequestError({ message: "Group not found" });
|
||||
// Group user privilege
|
||||
const groupProjectUserAdditionalPrivilege = await groupAdditionalPrivilegeDAL.create(
|
||||
{
|
||||
groupProjectMembershipId: accessApprovalRequest.groupMembershipId,
|
||||
requestedByUserId: accessApprovalRequest.requestedByUserId,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions)
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
const userGroupMembershipId = await userGroupMembershipDAL.findOne({
|
||||
groupId: groupProjectMembership.groupId
|
||||
});
|
||||
if (!userGroupMembershipId) throw new BadRequestError({ message: "User group membership not found" });
|
||||
|
||||
groupUserMembershipId = userGroupMembershipId.id;
|
||||
groupProjectMembershipId = groupProjectUserAdditionalPrivilege.id;
|
||||
} else {
|
||||
// Project user privilege
|
||||
const privilege = await additionalPrivilegeDAL.create(
|
||||
{
|
||||
projectMembershipId: accessApprovalRequest.projectMembershipId!,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions)
|
||||
},
|
||||
tx
|
||||
);
|
||||
projectUserPrivilegeId = privilege.id;
|
||||
}
|
||||
|
||||
const privilege = await additionalPrivilegeDAL.create(
|
||||
{
|
||||
groupMembershipId: groupUserMembershipId || null,
|
||||
projectMembershipId: accessApprovalRequest.projectMembershipId || null,
|
||||
groupProjectId: accessApprovalRequest.groupMembershipId ? accessApprovalRequest.projectId : null,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions)
|
||||
},
|
||||
tx
|
||||
);
|
||||
privilegeId = privilege.id;
|
||||
} else {
|
||||
// Temporary access
|
||||
const relativeTempAllocatedTimeInMs = ms(accessApprovalRequest.temporaryRange!);
|
||||
const startTime = new Date();
|
||||
|
||||
const privilege = await additionalPrivilegeDAL.create(
|
||||
{
|
||||
projectMembershipId: accessApprovalRequest.projectMembershipId || null,
|
||||
groupMembershipId: accessApprovalRequest.groupMembershipId || null,
|
||||
groupProjectId: accessApprovalRequest.groupMembershipId ? accessApprovalRequest.projectId : null,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions),
|
||||
isTemporary: true,
|
||||
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
|
||||
temporaryRange: accessApprovalRequest.temporaryRange!,
|
||||
temporaryAccessStartTime: startTime,
|
||||
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
|
||||
},
|
||||
tx
|
||||
);
|
||||
privilegeId = privilege.id;
|
||||
if (accessApprovalRequest.groupMembershipId) {
|
||||
// Group user privilege
|
||||
const groupProjectUserAdditionalPrivilege = await groupAdditionalPrivilegeDAL.create(
|
||||
{
|
||||
groupProjectMembershipId: accessApprovalRequest.groupMembershipId,
|
||||
requestedByUserId: accessApprovalRequest.requestedByUserId,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions),
|
||||
isTemporary: true,
|
||||
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
|
||||
temporaryRange: accessApprovalRequest.temporaryRange!,
|
||||
temporaryAccessStartTime: startTime,
|
||||
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
|
||||
},
|
||||
tx
|
||||
);
|
||||
|
||||
groupProjectMembershipId = groupProjectUserAdditionalPrivilege.id;
|
||||
} else {
|
||||
const privilege = await additionalPrivilegeDAL.create(
|
||||
{
|
||||
projectMembershipId: accessApprovalRequest.projectMembershipId!,
|
||||
slug: `requested-privilege-${slugify(alphaNumericNanoId(12))}`,
|
||||
permissions: JSON.stringify(accessApprovalRequest.permissions),
|
||||
isTemporary: true,
|
||||
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
|
||||
temporaryRange: accessApprovalRequest.temporaryRange!,
|
||||
temporaryAccessStartTime: startTime,
|
||||
temporaryAccessEndTime: new Date(new Date(startTime).getTime() + relativeTempAllocatedTimeInMs)
|
||||
},
|
||||
tx
|
||||
);
|
||||
projectUserPrivilegeId = privilege.id;
|
||||
}
|
||||
}
|
||||
|
||||
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { privilegeId }, tx);
|
||||
if (projectUserPrivilegeId) {
|
||||
await accessApprovalRequestDAL.updateById(accessApprovalRequest.id, { projectUserPrivilegeId }, tx);
|
||||
} else if (groupProjectMembershipId) {
|
||||
await accessApprovalRequestDAL.updateById(
|
||||
accessApprovalRequest.id,
|
||||
{ groupProjectUserPrivilegeId: groupProjectMembershipId },
|
||||
tx
|
||||
);
|
||||
} else {
|
||||
throw new BadRequestError({ message: "No privilege was created" });
|
||||
}
|
||||
}
|
||||
|
||||
return newReview;
|
||||
|
12
backend/src/ee/services/group-project-user-additional-privilege/group-project-user-additional-privilege-dal.ts
Normal file
12
backend/src/ee/services/group-project-user-additional-privilege/group-project-user-additional-privilege-dal.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { ormify } from "@app/lib/knex";
|
||||
|
||||
export type TGroupProjectUserAdditionalPrivilegeDALFactory = ReturnType<
|
||||
typeof groupProjectUserAdditionalPrivilegeDALFactory
|
||||
>;
|
||||
|
||||
export const groupProjectUserAdditionalPrivilegeDALFactory = (db: TDbClient) => {
|
||||
const orm = ormify(db, TableName.GroupProjectUserAdditionalPrivilege);
|
||||
return orm;
|
||||
};
|
@ -59,8 +59,6 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
||||
if (!dto.isTemporary) {
|
||||
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
|
||||
projectMembershipId,
|
||||
groupMembershipId: null,
|
||||
groupProjectId: null,
|
||||
slug,
|
||||
permissions: customPermission
|
||||
});
|
||||
@ -70,8 +68,6 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
|
||||
const relativeTempAllocatedTimeInMs = ms(dto.temporaryRange);
|
||||
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
|
||||
projectMembershipId,
|
||||
groupMembershipId: null,
|
||||
groupProjectId: null,
|
||||
slug,
|
||||
permissions: customPermission,
|
||||
isTemporary: true,
|
||||
|
@ -22,6 +22,7 @@ import { dynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secre
|
||||
import { groupDALFactory } from "@app/ee/services/group/group-dal";
|
||||
import { groupServiceFactory } from "@app/ee/services/group/group-service";
|
||||
import { userGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||
import { groupProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/group-project-user-additional-privilege/group-project-user-additional-privilege-dal";
|
||||
import { identityProjectAdditionalPrivilegeDALFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-dal";
|
||||
import { identityProjectAdditionalPrivilegeServiceFactory } from "@app/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service";
|
||||
import { ldapConfigDALFactory } from "@app/ee/services/ldap-config/ldap-config-dal";
|
||||
@ -217,6 +218,8 @@ export const registerRoutes = async (
|
||||
const accessApprovalPolicyApproverDAL = accessApprovalPolicyApproverDALFactory(db);
|
||||
const accessApprovalRequestReviewerDAL = accessApprovalRequestReviewerDALFactory(db);
|
||||
|
||||
const groupProjectUserAdditionalPrivilegeDAL = groupProjectUserAdditionalPrivilegeDALFactory(db);
|
||||
|
||||
const sapApproverDAL = secretApprovalPolicyApproverDALFactory(db);
|
||||
const secretApprovalPolicyDAL = secretApprovalPolicyDALFactory(db);
|
||||
const secretApprovalRequestDAL = secretApprovalRequestDALFactory(db);
|
||||
@ -618,11 +621,10 @@ export const registerRoutes = async (
|
||||
permissionService,
|
||||
accessApprovalRequestReviewerDAL,
|
||||
additionalPrivilegeDAL: projectUserAdditionalPrivilegeDAL,
|
||||
groupAdditionalPrivilegeDAL: groupProjectUserAdditionalPrivilegeDAL,
|
||||
projectMembershipDAL,
|
||||
accessApprovalPolicyDAL,
|
||||
accessApprovalRequestDAL,
|
||||
groupProjectDAL,
|
||||
userGroupMembershipDAL,
|
||||
projectEnvDAL,
|
||||
userDAL,
|
||||
smtpService,
|
||||
|
Reference in New Issue
Block a user