feat: battle of ts - unlimited edition

This commit is contained in:
=
2025-10-10 00:09:46 +05:30
parent fd98465dec
commit 44c9575a3d
38 changed files with 492 additions and 498 deletions
@@ -1,6 +1,7 @@
import slugify from "@sindresorhus/slugify";
import { z } from "zod";
import { AccessScope, TemporaryPermissionMode } from "@app/db/schemas";
import { backfillPermissionV1SchemaToV2Schema } from "@app/ee/services/permission/project-permission";
import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs";
import { UnauthorizedError } from "@app/lib/errors";
@@ -14,8 +15,7 @@ import {
ProjectSpecificPrivilegePermissionSchema,
SanitizedIdentityPrivilegeSchema
} from "@app/server/routes/sanitizedSchemas";
import { AuthMode } from "@app/services/auth/auth-type";
import { AccessScope, MembershipActors, TemporaryPermissionMode } from "@app/db/schemas";
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -78,7 +78,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
data: {
actorId: req.body.identityId,
actorType: MembershipActors.Identity,
actorType: ActorType.IDENTITY,
...req.body,
isTemporary: false,
name: req.body.slug || slugify(alphaNumericNanoId(8)),
@@ -92,7 +92,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.body.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -172,7 +172,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
data: {
actorId: req.body.identityId,
actorType: MembershipActors.Identity,
actorType: ActorType.IDENTITY,
...req.body,
isTemporary: true,
name: req.body.slug || slugify(alphaNumericNanoId(8)),
@@ -186,7 +186,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.body.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -262,15 +262,9 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
slug: req.body.projectSlug
});
const { membershipId } = await server.services.convertor.identityIdToMembershipId(
req.body.identityId,
AccessScope.Project,
projectId
);
const { privilegeId } = await server.services.convertor.additionalPrivilegeNameToId(
const { privilege: privilegeDoc } = await server.services.convertor.additionalPrivilegeNameToDoc(
req.body.privilegeSlug,
membershipId
projectId
);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.updateAdditionalPrivilege({
@@ -282,8 +276,8 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
selector: {
actorId: req.body.identityId,
actorType: MembershipActors.Identity,
id: privilegeId
actorType: ActorType.IDENTITY,
id: privilegeDoc.id
},
data: {
...req.body,
@@ -305,7 +299,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.body.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -346,15 +340,9 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
slug: req.body.projectSlug
});
const { membershipId } = await server.services.convertor.identityIdToMembershipId(
req.body.identityId,
AccessScope.Project,
projectId
);
const { privilegeId } = await server.services.convertor.additionalPrivilegeNameToId(
const { privilegeId } = await server.services.convertor.additionalPrivilegeNameToDoc(
req.body.privilegeSlug,
membershipId
projectId
);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.deleteAdditionalPrivilege({
@@ -366,7 +354,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
selector: {
actorId: req.body.identityId,
actorType: MembershipActors.Identity,
actorType: ActorType.IDENTITY,
id: privilegeId
}
});
@@ -375,7 +363,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.body.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -418,15 +406,9 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
slug: req.query.projectSlug
});
const { membershipId } = await server.services.convertor.identityIdToMembershipId(
req.query.identityId,
AccessScope.Project,
projectId
);
const { privilegeId } = await server.services.convertor.additionalPrivilegeNameToId(
const { privilegeId } = await server.services.convertor.additionalPrivilegeNameToDoc(
req.params.privilegeSlug,
membershipId
projectId
);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.getAdditionalPrivilegeById({
@@ -438,7 +420,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
selector: {
actorId: req.query.identityId,
actorType: MembershipActors.Identity,
actorType: ActorType.IDENTITY,
id: privilegeId
}
});
@@ -447,7 +429,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.query.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -496,7 +478,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
selector: {
actorId: req.query.identityId,
actorType: MembershipActors.Identity
actorType: ActorType.IDENTITY
}
});
@@ -504,7 +486,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privileges: privileges.map((privilege) => ({
...privilege,
identityId: req.query.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}))
@@ -1,17 +1,18 @@
import slugify from "@sindresorhus/slugify";
import { z } from "zod";
import { AccessScope, MembershipActors, TemporaryPermissionMode } from "@app/db/schemas";
import { AccessScope, TemporaryPermissionMode } from "@app/db/schemas";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { PROJECT_USER_ADDITIONAL_PRIVILEGE } from "@app/lib/api-docs";
import { NotFoundError } from "@app/lib/errors";
import { ms } from "@app/lib/ms";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { SanitizedUserProjectAdditionalPrivilegeSchema } from "@app/server/routes/sanitizedSchema/user-additional-privilege";
import { AuthMode } from "@app/services/auth/auth-type";
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -70,7 +71,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
data: {
actorId: userId,
actorType: MembershipActors.User,
actorType: ActorType.USER,
...req.body.type,
name: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: req.body.permissions
@@ -127,17 +128,15 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.privilegeId,
AccessScope.Project,
req.permission.orgId
);
const data = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.privilegeId);
if (!data.privilege.actorUserId)
throw new NotFoundError({ message: `Privilege with id ${req.params.privilegeId} not found` });
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.updateAdditionalPrivilege({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: data.privilege.projectId as string,
orgId: req.permission.orgId
},
data: {
@@ -151,16 +150,16 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
selector: {
id: req.params.privilegeId,
actorId: membership.actorUserId as string,
actorType: MembershipActors.User
actorId: data.privilege.actorUserId,
actorType: ActorType.USER
}
});
return {
privilege: {
...privilege,
userId: membership.actorUserId as string,
projectId: membership.scopeProjectId as string,
userId: data.privilege.actorUserId,
projectId: data.privilege.projectId as string,
slug: privilege.name
}
};
@@ -185,31 +184,29 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.privilegeId,
AccessScope.Project,
req.permission.orgId
);
const data = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.privilegeId);
if (!data.privilege.actorUserId)
throw new NotFoundError({ message: `Privilege with id ${req.params.privilegeId} not found` });
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.deleteAdditionalPrivilege({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: data.privilege.projectId as string,
orgId: req.permission.orgId
},
selector: {
id: req.params.privilegeId,
actorId: membership.actorUserId as string,
actorType: MembershipActors.User
actorId: data.privilege.actorUserId,
actorType: ActorType.USER
}
});
return {
privilege: {
...privilege,
userId: membership.actorUserId as string,
projectId: membership.scopeProjectId as string,
userId: data.privilege.actorUserId,
projectId: data.privilege.projectId as string,
slug: privilege.name
}
};
@@ -249,7 +246,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
selector: {
actorId: userId,
actorType: MembershipActors.User
actorType: ActorType.USER
}
});
@@ -282,31 +279,29 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
},
onRequest: verifyAuth([AuthMode.JWT]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.privilegeId,
AccessScope.Project,
req.permission.orgId
);
const data = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.privilegeId);
if (!data.privilege.actorUserId)
throw new NotFoundError({ message: `Privilege with id ${req.params.privilegeId} not found` });
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.getAdditionalPrivilegeById({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: data.privilege.projectId as string,
orgId: req.permission.orgId
},
selector: {
id: req.params.privilegeId,
actorId: membership.actorUserId as string,
actorType: MembershipActors.User
actorId: data.privilege.actorUserId,
actorType: ActorType.USER
}
});
return {
privilege: {
...privilege,
userId: membership.actorUserId as string,
projectId: membership.scopeProjectId as string,
userId: data.privilege.actorUserId,
projectId: data.privilege.projectId as string,
slug: privilege.name
}
};
@@ -1,7 +1,7 @@
import slugify from "@sindresorhus/slugify";
import { z } from "zod";
import { AccessScope, MembershipActors, TemporaryPermissionMode } from "@app/db/schemas";
import { AccessScope, TemporaryPermissionMode } from "@app/db/schemas";
import { checkForInvalidPermissionCombination } from "@app/ee/services/permission/permission-fns";
import { ProjectPermissionV2Schema } from "@app/ee/services/permission/project-permission";
import { ApiDocsTags, IDENTITY_ADDITIONAL_PRIVILEGE_V2 } from "@app/lib/api-docs";
@@ -11,7 +11,7 @@ import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { slugSchema } from "@app/server/lib/schemas";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { SanitizedIdentityPrivilegeSchema } from "@app/server/routes/sanitizedSchema/identitiy-additional-privilege";
import { AuthMode } from "@app/services/auth/auth-type";
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -73,7 +73,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
data: {
actorId: req.body.identityId,
actorType: MembershipActors.Identity,
actorType: ActorType.IDENTITY,
...req.body.type,
name: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: req.body.permissions
@@ -84,7 +84,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.body.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId: req.body.projectId,
slug: privilege.name
}
@@ -142,23 +142,19 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.id,
AccessScope.Project,
req.permission.orgId
);
const { privilege: privilegeDoc } = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.id);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.updateAdditionalPrivilege({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: privilegeDoc.projectId as string,
orgId: req.permission.orgId
},
selector: {
id: req.params.id,
actorId: membership.actorIdentityId as string,
actorType: MembershipActors.Identity
actorId: privilegeDoc.actorIdentityId as string,
actorType: ActorType.IDENTITY
},
data: {
...req.body,
@@ -170,9 +166,9 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
return {
privilege: {
...privilege,
identityId: membership.actorIdentityId as string,
projectMembershipId: privilege.membershipId,
projectId: membership.scopeProjectId as string,
identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "",
projectId: privilegeDoc.projectId as string,
slug: privilege.name
}
};
@@ -205,32 +201,28 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.id,
AccessScope.Project,
req.permission.orgId
);
const { privilege: privilegeDoc } = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.id);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.deleteAdditionalPrivilege({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: privilegeDoc.projectId as string,
orgId: req.permission.orgId
},
selector: {
id: req.params.id,
actorId: membership.actorIdentityId as string,
actorType: MembershipActors.Identity
actorId: privilegeDoc.actorIdentityId as string,
actorType: ActorType.IDENTITY
}
});
return {
privilege: {
...privilege,
identityId: membership.actorIdentityId as string,
projectMembershipId: privilege.membershipId,
projectId: membership.scopeProjectId as string,
identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "",
projectId: privilegeDoc.projectId as string,
slug: privilege.name
}
};
@@ -263,32 +255,28 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => {
const { membership } = await server.services.convertor.additionalPrivilegeIdToMembershipId(
req.params.id,
AccessScope.Project,
req.permission.orgId
);
const { privilege: privilegeDoc } = await server.services.convertor.additionalPrivilegeIdToDoc(req.params.id);
const { additionalPrivilege: privilege } = await server.services.additionalPrivilege.getAdditionalPrivilegeById({
permission: req.permission,
scopeData: {
scope: AccessScope.Project,
projectId: membership.scopeProjectId as string,
projectId: privilegeDoc.projectId as string,
orgId: req.permission.orgId
},
selector: {
id: req.params.id,
actorId: membership.actorIdentityId as string,
actorType: MembershipActors.Identity
actorId: privilegeDoc.actorIdentityId as string,
actorType: ActorType.IDENTITY
}
});
return {
privilege: {
...privilege,
identityId: membership.actorIdentityId as string,
projectMembershipId: privilege.membershipId,
projectId: membership.scopeProjectId as string,
identityId: privilegeDoc.actorIdentityId as string,
projectMembershipId: "",
projectId: privilegeDoc.projectId as string,
slug: privilege.name
}
};
@@ -341,7 +329,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
selector: {
name: req.params.privilegeSlug,
actorId: req.query.identityId,
actorType: MembershipActors.Identity
actorType: ActorType.IDENTITY
}
}
);
@@ -350,7 +338,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privilege: {
...privilege,
identityId: req.query.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId,
slug: privilege.name
}
@@ -394,7 +382,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
},
selector: {
actorId: req.query.identityId,
actorType: MembershipActors.Identity
actorType: ActorType.IDENTITY
}
});
@@ -402,7 +390,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
privileges: privileges.map((privilege) => ({
...privilege,
identityId: req.query.identityId,
projectMembershipId: privilege.membershipId,
projectMembershipId: "",
projectId: req.query.projectId,
slug: privilege.name
}))
@@ -1,21 +1,18 @@
import { ForbiddenError } from "@casl/ability";
import { ActionProjectType } from "@app/db/schemas";
import { AccessScope, ActionProjectType } from "@app/db/schemas";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { BadRequestError, NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
import { TOrgMembershipDALFactory } from "@app/services/org-membership/org-membership-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";
import { TUserDALFactory } from "@app/services/user/user-dal";
import { TAccessApprovalRequestDALFactory } from "../access-approval-request/access-approval-request-dal";
import { TAccessApprovalRequestReviewerDALFactory } from "../access-approval-request/access-approval-request-reviewer-dal";
import { ApprovalStatus } from "../access-approval-request/access-approval-request-types";
import { TGroupDALFactory } from "../group/group-dal";
import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal";
import {
TAccessApprovalPolicyApproverDALFactory,
TAccessApprovalPolicyBypasserDALFactory
@@ -31,6 +28,8 @@ import {
TListAccessApprovalPoliciesDTO,
TUpdateAccessApprovalPolicy
} from "./access-approval-policy-types";
import { TMembershipUserDALFactory } from "@app/services/membership-user/membership-user-dal";
import { TAdditionalPrivilegeDALFactory } from "@app/services/additional-privilege/additional-privilege-dal";
type TAccessApprovalPolicyServiceFactoryDep = {
projectDAL: TProjectDALFactory;
@@ -39,14 +38,13 @@ type TAccessApprovalPolicyServiceFactoryDep = {
projectEnvDAL: Pick<TProjectEnvDALFactory, "find" | "findOne">;
accessApprovalPolicyApproverDAL: TAccessApprovalPolicyApproverDALFactory;
accessApprovalPolicyBypasserDAL: TAccessApprovalPolicyBypasserDALFactory;
projectMembershipDAL: Pick<TProjectMembershipDALFactory, "find">;
groupDAL: TGroupDALFactory;
userDAL: Pick<TUserDALFactory, "find">;
accessApprovalRequestDAL: Pick<TAccessApprovalRequestDALFactory, "update" | "find" | "resetReviewByPolicyId">;
additionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "delete">;
additionalPrivilegeDAL: Pick<TAdditionalPrivilegeDALFactory, "delete">;
accessApprovalRequestReviewerDAL: Pick<TAccessApprovalRequestReviewerDALFactory, "update" | "delete">;
orgMembershipDAL: Pick<TOrgMembershipDALFactory, "find">;
accessApprovalPolicyEnvironmentDAL: TAccessApprovalPolicyEnvironmentDALFactory;
membershipUserDAL: TMembershipUserDALFactory;
};
export const accessApprovalPolicyServiceFactory = ({
@@ -62,7 +60,7 @@ export const accessApprovalPolicyServiceFactory = ({
accessApprovalRequestDAL,
additionalPrivilegeDAL,
accessApprovalRequestReviewerDAL,
orgMembershipDAL
membershipUserDAL
}: TAccessApprovalPolicyServiceFactoryDep): TAccessApprovalPolicyServiceFactory => {
const $policyExists = async ({
envId,
@@ -424,13 +422,14 @@ export const accessApprovalPolicyServiceFactory = ({
// Validate user bypassers
if (bypasserUserIds.length > 0) {
const orgMemberships = await orgMembershipDAL.find({
$in: { userId: bypasserUserIds },
orgId: actorOrgId
const orgMemberships = await membershipUserDAL.find({
$in: { actorUserId: bypasserUserIds },
scopeOrgId: actorOrgId,
scope: AccessScope.Organization
});
if (orgMemberships.length !== bypasserUserIds.length) {
const foundUserIdsInOrg = new Set(orgMemberships.map((mem) => mem.userId));
const foundUserIdsInOrg = new Set(orgMemberships.map((mem) => mem.actorUserId as string));
const missingUserIds = bypasserUserIds.filter((id) => !foundUserIdsInOrg.has(id));
throw new BadRequestError({
message: `One or more specified bypasser users are not part of the organization or do not exist. Invalid or non-member user IDs: ${missingUserIds.join(", ")}`
@@ -26,16 +26,15 @@ import { TAccessApprovalPolicyApproverDALFactory } from "../access-approval-poli
import { TAccessApprovalPolicyDALFactory } from "../access-approval-policy/access-approval-policy-dal";
import { TGroupDALFactory } from "../group/group-dal";
import { TPermissionServiceFactory } from "../permission/permission-service-types";
import { TProjectUserAdditionalPrivilegeDALFactory } from "../project-user-additional-privilege/project-user-additional-privilege-dal";
import { ProjectUserAdditionalPrivilegeTemporaryMode } from "../project-user-additional-privilege/project-user-additional-privilege-types";
import { TAccessApprovalRequestDALFactory } from "./access-approval-request-dal";
import { verifyRequestedPermissions } from "./access-approval-request-fns";
import { TAccessApprovalRequestReviewerDALFactory } from "./access-approval-request-reviewer-dal";
import { ApprovalStatus, TAccessApprovalRequestServiceFactory } from "./access-approval-request-types";
import { TAdditionalPrivilegeDALFactory } from "@app/services/additional-privilege/additional-privilege-dal";
type TSecretApprovalRequestServiceFactoryDep = {
additionalPrivilegeDAL: Pick<TProjectUserAdditionalPrivilegeDALFactory, "create" | "findById">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "invalidateProjectPermissionCache">;
additionalPrivilegeDAL: Pick<TAdditionalPrivilegeDALFactory, "create" | "findById">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
accessApprovalPolicyApproverDAL: Pick<TAccessApprovalPolicyApproverDALFactory, "find">;
projectEnvDAL: Pick<TProjectEnvDALFactory, "findOne">;
projectDAL: Pick<
@@ -1,7 +1,7 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { GatewaysV2Schema, TableName, TGatewaysV2 } from "@app/db/schemas";
import { AccessScope, GatewaysV2Schema, TableName, TGatewaysV2 } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { buildFindFilter, ormify, selectAllTableCols, TFindFilter, TFindOpt } from "@app/lib/knex";
@@ -16,11 +16,6 @@ export const gatewayV2DalFactory = (db: TDbClient) => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
.where(buildFindFilter(filter, TableName.GatewayV2))
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.GatewayV2}.identityId`)
.join(
TableName.IdentityOrgMembership,
`${TableName.IdentityOrgMembership}.identityId`,
`${TableName.GatewayV2}.identityId`
)
.select(selectAllTableCols(TableName.GatewayV2))
.select(db.ref("name").withSchema(TableName.Identity).as("identityName"));
+7 -10
View File
@@ -1,5 +1,5 @@
import { TDbClient } from "@app/db";
import { GatewaysSchema, TableName, TGateways } from "@app/db/schemas";
import { AccessScope, GatewaysSchema, TableName, TGateways } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { buildFindFilter, ormify, selectAllTableCols, TFindFilter, TFindOpt } from "@app/lib/knex";
@@ -17,17 +17,14 @@ export const gatewayDALFactory = (db: TDbClient) => {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
.where(buildFindFilter(filter, TableName.Gateway, ["orgId"]))
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.Gateway}.identityId`)
.join(
TableName.IdentityOrgMembership,
`${TableName.IdentityOrgMembership}.identityId`,
`${TableName.Gateway}.identityId`
)
.join(TableName.Membership, `${TableName.Membership}.actorIdentityId`, `${TableName.Gateway}.identityId`)
.select(selectAllTableCols(TableName.Gateway))
.select(db.ref("orgId").withSchema(TableName.IdentityOrgMembership).as("identityOrgId"))
.select(db.ref("name").withSchema(TableName.Identity).as("identityName"));
.select(db.ref("scopeOrgId").withSchema(TableName.IdentityOrgMembership).as("identityOrgId"))
.select(db.ref("name").withSchema(TableName.Identity).as("identityName"))
.where(`${TableName.Membership}.scope`, AccessScope.Organization);
if (filter.orgId) {
void query.where(`${TableName.IdentityOrgMembership}.orgId`, filter.orgId);
void query.where(`${TableName.Membership}.scopeOrgId`, filter.orgId);
}
if (limit) void query.limit(limit);
if (offset) void query.offset(offset);
@@ -39,7 +36,7 @@ export const gatewayDALFactory = (db: TDbClient) => {
return docs.map((el) => ({
...GatewaysSchema.parse(el),
orgId: el.identityOrgId as string, // todo(daniel): figure out why typescript is not inferring this as a string
orgId: el.identityOrgId,
identity: { id: el.identityId, name: el.identityName }
}));
} catch (error) {
+13 -6
View File
@@ -36,14 +36,21 @@ export const groupDALFactory = (db: TDbClient) => {
try {
const docs = await (tx || db.replicaNode())(TableName.Groups)
.where(`${TableName.Groups}.orgId`, orgId)
.leftJoin(TableName.OrgRoles, `${TableName.Groups}.roleId`, `${TableName.OrgRoles}.id`)
.where(`${TableName.Membership}.scopeOrgId`, orgId)
.where(`${TableName.Membership}.scope`, AccessScope.Organization)
.join(TableName.Membership, `${TableName.Groups}.id`, `${TableName.Membership}.actorGroupId`)
.join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
.join(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
.select(selectAllTableCols(TableName.Groups))
// cr stands for custom role
.select(db.ref("id").as("crId").withSchema(TableName.OrgRoles))
.select(db.ref("name").as("crName").withSchema(TableName.OrgRoles))
.select(db.ref("slug").as("crSlug").withSchema(TableName.OrgRoles))
.select(db.ref("description").as("crDescription").withSchema(TableName.OrgRoles))
.select(db.ref("permissions").as("crPermission").withSchema(TableName.OrgRoles));
.select(db.ref("id").as("crId").withSchema(TableName.Role))
.select(db.ref("name").as("crName").withSchema(TableName.Role))
.select(db.ref("role").withSchema(TableName.MembershipRole))
.select(db.ref("customRoleId").as("roleId").withSchema(TableName.MembershipRole))
.select(db.ref("slug").as("crSlug").withSchema(TableName.Role))
.select(db.ref("description").as("crDescription").withSchema(TableName.Role))
.select(db.ref("permissions").as("crPermission").withSchema(TableName.Role));
return docs.map(({ crId, crDescription, crSlug, crPermission, crName, ...el }) => ({
...el,
customRole: el.roleId
@@ -9,8 +9,7 @@ import {
MembershipsSchema,
TableName,
TMemberships,
TProjectRoles,
TProjects
TProjectRoles
} from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { selectAllTableCols, sqlNestRelationships } from "@app/lib/knex";
@@ -204,11 +203,19 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
.replicaNode()(TableName.Membership)
.join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`)
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
.leftJoin(
TableName.AdditionalPrivilege,
`${TableName.Membership}.id`,
`${TableName.AdditionalPrivilege}.membershipId`
)
.leftJoin(TableName.AdditionalPrivilege, (qb) => {
if (actorType === ActorType.IDENTITY) {
qb.on(`${TableName.Membership}.actorIdentityId`, `${TableName.AdditionalPrivilege}.actorIdentityId`).andOn(
`${TableName.Membership}.scopeOrgId`,
`${TableName.AdditionalPrivilege}.orgId`
);
} else {
qb.on(`${TableName.Membership}.actorUserId`, `${TableName.AdditionalPrivilege}.actorUserId`).andOn(
`${TableName.Membership}.scopeOrgId`,
`${TableName.AdditionalPrivilege}.orgId`
);
}
})
.leftJoin(TableName.IdentityMetadata, (queryBuilder) => {
if (actorType === ActorType.USER) {
void queryBuilder
@@ -366,22 +373,20 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
) => {
try {
const docs = await db
.replicaNode()(TableName.GroupProjectMembership)
.join(TableName.Groups, `${TableName.Groups}.id`, `${TableName.GroupProjectMembership}.groupId`)
.join(
TableName.GroupProjectMembershipRole,
`${TableName.GroupProjectMembershipRole}.projectMembershipId`,
`${TableName.GroupProjectMembership}.id`
)
.replicaNode()(TableName.Membership)
.whereNotNull(`${TableName.Membership}.actorGroupId`)
.where(`${TableName.Membership}.scope`, AccessScope.Project)
.join(TableName.Groups, `${TableName.Groups}.id`, `${TableName.Membership}.actorGroupId`)
.join(TableName.MembershipRole, `${TableName.MembershipRole}.membershipId`, `${TableName.Membership}.id`)
.leftJoin<TProjectRoles>(
{ groupCustomRoles: TableName.ProjectRoles },
`${TableName.GroupProjectMembershipRole}.customRoleId`,
{ groupCustomRoles: TableName.Role },
`${TableName.MembershipRole}.customRoleId`,
`groupCustomRoles.id`
)
.where(`${TableName.GroupProjectMembership}.projectId`, "=", projectId)
.where(`${TableName.Membership}.scopeProjectId`, "=", projectId)
.where((bd) => {
if (filterGroupId) {
void bd.where(`${TableName.GroupProjectMembership}.groupId`, "=", filterGroupId);
void bd.where(`${TableName.Membership}.actorGroupId`, "=", filterGroupId);
}
})
.select(
@@ -390,31 +395,19 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
db.ref("name").withSchema(TableName.Groups).as("groupName"),
db.ref("slug").withSchema("groupCustomRoles").as("groupProjectMembershipRoleCustomRoleSlug"),
db.ref("permissions").withSchema("groupCustomRoles").as("groupProjectMembershipRolePermission"),
db.ref("id").withSchema(TableName.GroupProjectMembershipRole).as("groupProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.GroupProjectMembershipRole).as("groupProjectMembershipRole"),
db
.ref("customRoleId")
.withSchema(TableName.GroupProjectMembershipRole)
.as("groupProjectMembershipRoleCustomRoleId"),
db
.ref("isTemporary")
.withSchema(TableName.GroupProjectMembershipRole)
.as("groupProjectMembershipRoleIsTemporary"),
db
.ref("temporaryMode")
.withSchema(TableName.GroupProjectMembershipRole)
.as("groupProjectMembershipRoleTemporaryMode"),
db
.ref("temporaryRange")
.withSchema(TableName.GroupProjectMembershipRole)
.as("groupProjectMembershipRoleTemporaryRange"),
db.ref("id").withSchema(TableName.MembershipRole).as("groupProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.MembershipRole).as("groupProjectMembershipRole"),
db.ref("customRoleId").withSchema(TableName.MembershipRole).as("groupProjectMembershipRoleCustomRoleId"),
db.ref("isTemporary").withSchema(TableName.MembershipRole).as("groupProjectMembershipRoleIsTemporary"),
db.ref("temporaryMode").withSchema(TableName.MembershipRole).as("groupProjectMembershipRoleTemporaryMode"),
db.ref("temporaryRange").withSchema(TableName.MembershipRole).as("groupProjectMembershipRoleTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("groupProjectMembershipRoleTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("groupProjectMembershipRoleTemporaryAccessEndTime")
);
@@ -476,175 +469,124 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
}
};
const getProjectUserPermissions: TPermissionDALFactory["getProjectUserPermissions"] = async (projectId: string) => {
// TODO(simp): this query is wrong and fix it
const getProjectUserPermissions: TPermissionDALFactory["getProjectUserPermissions"] = async (
projectId: string,
orgId: string
) => {
try {
const userGroupSubquery = db(TableName.Groups)
.leftJoin(TableName.UserGroupMembership, `${TableName.UserGroupMembership}.groupId`, `${TableName.Groups}.id`)
.where(`${TableName.Groups}.orgId`, orgId)
.select(db.ref("id").withSchema(TableName.Groups));
const docs = await db
.replicaNode()(TableName.Users)
.where("isGhost", "=", false)
.leftJoin(TableName.GroupProjectMembership, (queryBuilder) => {
void queryBuilder.on(`${TableName.GroupProjectMembership}.projectId`, db.raw("?", [projectId]));
.replicaNode()(TableName.Membership)
.join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`)
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
.leftJoin(TableName.AdditionalPrivilege, (qb) => {
qb.on(`${TableName.Membership}.actorUserId`, `${TableName.AdditionalPrivilege}.actorUserId`).andOn(
`${TableName.Membership}.scopeOrgId`,
`${TableName.AdditionalPrivilege}.orgId`
);
})
.leftJoin(
TableName.GroupProjectMembershipRole,
`${TableName.GroupProjectMembershipRole}.projectMembershipId`,
`${TableName.GroupProjectMembership}.id`
)
.leftJoin<TProjectRoles>(
{ groupCustomRoles: TableName.ProjectRoles },
`${TableName.GroupProjectMembershipRole}.customRoleId`,
`groupCustomRoles.id`
)
.join(TableName.ProjectMembership, (queryBuilder) => {
void queryBuilder
.on(`${TableName.ProjectMembership}.projectId`, db.raw("?", [projectId]))
.andOn(`${TableName.ProjectMembership}.userId`, `${TableName.Users}.id`);
})
.leftJoin(
TableName.ProjectUserMembershipRole,
`${TableName.ProjectUserMembershipRole}.projectMembershipId`,
`${TableName.ProjectMembership}.id`
)
.leftJoin(
TableName.ProjectRoles,
`${TableName.ProjectUserMembershipRole}.customRoleId`,
`${TableName.ProjectRoles}.id`
)
.leftJoin(TableName.ProjectUserAdditionalPrivilege, (queryBuilder) => {
void queryBuilder
.on(`${TableName.ProjectUserAdditionalPrivilege}.projectId`, db.raw("?", [projectId]))
.andOn(`${TableName.ProjectUserAdditionalPrivilege}.userId`, `${TableName.Users}.id`);
})
.join<TProjects>(TableName.Project, `${TableName.Project}.id`, db.raw("?", [projectId]))
.join(TableName.Organization, `${TableName.Project}.orgId`, `${TableName.Organization}.id`)
.leftJoin(TableName.IdentityMetadata, (queryBuilder) => {
void queryBuilder
.on(`${TableName.Users}.id`, `${TableName.IdentityMetadata}.userId`)
.andOn(`${TableName.Organization}.id`, `${TableName.IdentityMetadata}.orgId`);
.on(`${TableName.Membership}.actorUserId`, `${TableName.IdentityMetadata}.userId`)
.andOn(`${TableName.Membership}.scopeOrgId`, `${TableName.IdentityMetadata}.orgId`);
})
.leftJoin(
TableName.UserGroupMembership,
`${TableName.UserGroupMembership}.groupId`,
`${TableName.Membership}.actorGroupId`
)
.leftJoin(TableName.Users, (qb) => {
qb.on(`${TableName.Users}.id`, `${TableName.Membership}.actorUserId`).orOn(
`${TableName.Users}.id`,
`${TableName.UserGroupMembership}.groupId`
);
})
.where(`${TableName.Membership}.scopeOrgId`, orgId)
.where(`${TableName.Membership}.scope`, AccessScope.Project)
.where(`${TableName.Membership}.scopeProjectId`, projectId)
.select(
db.ref("id").withSchema(TableName.Users).as("userId"),
db.ref("username").withSchema(TableName.Users).as("username"),
// groups specific
db.ref("id").withSchema(TableName.GroupProjectMembership).as("groupMembershipId"),
db.ref("createdAt").withSchema(TableName.GroupProjectMembership).as("groupMembershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.GroupProjectMembership).as("groupMembershipUpdatedAt"),
db.ref("slug").withSchema("groupCustomRoles").as("userGroupProjectMembershipRoleCustomRoleSlug"),
db.ref("permissions").withSchema("groupCustomRoles").as("userGroupProjectMembershipRolePermission"),
db.ref("id").withSchema(TableName.GroupProjectMembershipRole).as("userGroupProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.GroupProjectMembershipRole).as("userGroupProjectMembershipRole"),
db
.ref("customRoleId")
.withSchema(TableName.GroupProjectMembershipRole)
.as("userGroupProjectMembershipRoleCustomRoleId"),
db
.ref("isTemporary")
.withSchema(TableName.GroupProjectMembershipRole)
.as("userGroupProjectMembershipRoleIsTemporary"),
db.ref("id").withSchema(TableName.MembershipRole).as("userGroupProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.MembershipRole).as("userGroupProjectMembershipRole"),
db.ref("customRoleId").withSchema(TableName.MembershipRole).as("userGroupProjectMembershipRoleCustomRoleId"),
db.ref("isTemporary").withSchema(TableName.MembershipRole).as("userGroupProjectMembershipRoleIsTemporary"),
db
.ref("temporaryMode")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("userGroupProjectMembershipRoleTemporaryMode"),
db
.ref("temporaryRange")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("userGroupProjectMembershipRoleTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("userGroupProjectMembershipRoleTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.GroupProjectMembershipRole)
.withSchema(TableName.MembershipRole)
.as("userGroupProjectMembershipRoleTemporaryAccessEndTime"),
// user specific
db.ref("id").withSchema(TableName.ProjectMembership).as("membershipId"),
db.ref("createdAt").withSchema(TableName.ProjectMembership).as("membershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.ProjectMembership).as("membershipUpdatedAt"),
db.ref("slug").withSchema(TableName.ProjectRoles).as("userProjectMembershipRoleCustomRoleSlug"),
db.ref("permissions").withSchema(TableName.ProjectRoles).as("userProjectCustomRolePermission"),
db.ref("id").withSchema(TableName.ProjectUserMembershipRole).as("userProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.ProjectUserMembershipRole).as("userProjectMembershipRole"),
db
.ref("temporaryMode")
.withSchema(TableName.ProjectUserMembershipRole)
.as("userProjectMembershipRoleTemporaryMode"),
db
.ref("isTemporary")
.withSchema(TableName.ProjectUserMembershipRole)
.as("userProjectMembershipRoleIsTemporary"),
db
.ref("temporaryRange")
.withSchema(TableName.ProjectUserMembershipRole)
.as("userProjectMembershipRoleTemporaryRange"),
db.ref("id").withSchema(TableName.Membership).as("membershipId"),
db.ref("createdAt").withSchema(TableName.Membership).as("membershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.Membership).as("membershipUpdatedAt"),
db.ref("slug").withSchema(TableName.Role).as("userProjectMembershipRoleCustomRoleSlug"),
db.ref("permissions").withSchema(TableName.Role).as("userProjectCustomRolePermission"),
db.ref("id").withSchema(TableName.Role).as("userProjectMembershipRoleId"),
db.ref("role").withSchema(TableName.Role).as("userProjectMembershipRole"),
db.ref("temporaryMode").withSchema(TableName.Role).as("userProjectMembershipRoleTemporaryMode"),
db.ref("isTemporary").withSchema(TableName.Role).as("userProjectMembershipRoleIsTemporary"),
db.ref("temporaryRange").withSchema(TableName.Role).as("userProjectMembershipRoleTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.ProjectUserMembershipRole)
.withSchema(TableName.Role)
.as("userProjectMembershipRoleTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.ProjectUserMembershipRole)
.withSchema(TableName.Role)
.as("userProjectMembershipRoleTemporaryAccessEndTime"),
db.ref("id").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userAdditionalPrivilegesId"),
db
.ref("permissions")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("userAdditionalPrivilegesPermissions"),
db
.ref("temporaryMode")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("userAdditionalPrivilegesTemporaryMode"),
db
.ref("isTemporary")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.as("userAdditionalPrivilegesIsTemporary"),
db.ref("id").withSchema(TableName.AdditionalPrivilege).as("userAdditionalPrivilegesId"),
db.ref("permissions").withSchema(TableName.AdditionalPrivilege).as("userAdditionalPrivilegesPermissions"),
db.ref("temporaryMode").withSchema(TableName.AdditionalPrivilege).as("userAdditionalPrivilegesTemporaryMode"),
db.ref("isTemporary").withSchema(TableName.AdditionalPrivilege).as("userAdditionalPrivilegesIsTemporary"),
db
.ref("temporaryRange")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.withSchema(TableName.AdditionalPrivilege)
.as("userAdditionalPrivilegesTemporaryRange"),
db.ref("userId").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userAdditionalPrivilegesUserId"),
db.ref("userId").withSchema(TableName.AdditionalPrivilege).as("userAdditionalPrivilegesUserId"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.withSchema(TableName.AdditionalPrivilege)
.as("userAdditionalPrivilegesTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.ProjectUserAdditionalPrivilege)
.withSchema(TableName.AdditionalPrivilege)
.as("userAdditionalPrivilegesTemporaryAccessEndTime"),
// general
db.ref("id").withSchema(TableName.IdentityMetadata).as("metadataId"),
db.ref("key").withSchema(TableName.IdentityMetadata).as("metadataKey"),
db.ref("value").withSchema(TableName.IdentityMetadata).as("metadataValue"),
db.ref("authEnforced").withSchema(TableName.Organization).as("orgAuthEnforced"),
db.ref("orgId").withSchema(TableName.Project),
db.ref("type").withSchema(TableName.Project).as("projectType"),
db.ref("id").withSchema(TableName.Project).as("projectId")
db.ref("value").withSchema(TableName.IdentityMetadata).as("metadataValue")
);
const userPermissions = sqlNestRelationships({
data: docs,
key: "userId",
parentMapper: ({
orgId,
username,
orgAuthEnforced,
membershipId,
groupMembershipId,
membershipCreatedAt,
groupMembershipCreatedAt,
groupMembershipUpdatedAt,
membershipUpdatedAt,
projectType,
userId
}) => ({
orgId,
orgAuthEnforced,
parentMapper: ({ username, membershipId, membershipCreatedAt, membershipUpdatedAt, userId }) => ({
userId,
projectId,
username,
projectType,
id: membershipId || groupMembershipId,
createdAt: membershipCreatedAt || groupMembershipCreatedAt,
updatedAt: membershipUpdatedAt || groupMembershipUpdatedAt
id: membershipId,
createdAt: membershipCreatedAt,
updatedAt: membershipUpdatedAt
}),
childrenMapper: [
{
@@ -767,68 +709,49 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
};
const getProjectIdentityPermissions: TPermissionDALFactory["getProjectIdentityPermissions"] = async (
projectId: string
projectId: string,
orgId: string
) => {
try {
const docs = await db
.replicaNode()(TableName.IdentityProjectMembership)
.join(
TableName.IdentityProjectMembershipRole,
`${TableName.IdentityProjectMembershipRole}.projectMembershipId`,
`${TableName.IdentityProjectMembership}.id`
)
.join(TableName.Identity, `${TableName.Identity}.id`, `${TableName.IdentityProjectMembership}.identityId`)
.leftJoin(
TableName.ProjectRoles,
`${TableName.IdentityProjectMembershipRole}.customRoleId`,
`${TableName.ProjectRoles}.id`
)
.leftJoin(
TableName.IdentityProjectAdditionalPrivilege,
`${TableName.IdentityProjectAdditionalPrivilege}.projectMembershipId`,
`${TableName.IdentityProjectMembership}.id`
)
.join(
// Join the Project table to later select orgId
TableName.Project,
`${TableName.IdentityProjectMembership}.projectId`,
`${TableName.Project}.id`
)
.replicaNode()(TableName.Membership)
.join(TableName.MembershipRole, `${TableName.Membership}.id`, `${TableName.MembershipRole}.membershipId`)
.leftJoin(TableName.Role, `${TableName.MembershipRole}.customRoleId`, `${TableName.Role}.id`)
.leftJoin(TableName.AdditionalPrivilege, (qb) => {
qb.on(`${TableName.Membership}.actorIdentityId`, `${TableName.AdditionalPrivilege}.actorIdentityId`).andOn(
`${TableName.Membership}.scopeOrgId`,
`${TableName.AdditionalPrivilege}.orgId`
);
})
.leftJoin(TableName.IdentityMetadata, (queryBuilder) => {
void queryBuilder
.on(`${TableName.Identity}.id`, `${TableName.IdentityMetadata}.identityId`)
.andOn(`${TableName.Project}.orgId`, `${TableName.IdentityMetadata}.orgId`);
.on(`${TableName.Membership}.actorIdentityId`, `${TableName.IdentityMetadata}.identityId`)
.andOn(`${TableName.Membership}.scopeOrgId`, `${TableName.IdentityMetadata}.orgId`);
})
.where(`${TableName.IdentityProjectMembership}.projectId`, projectId)
.select(selectAllTableCols(TableName.IdentityProjectMembershipRole))
.where(`${TableName.Membership}.scopeOrgId`, orgId)
.where(`${TableName.Membership}.scope`, AccessScope.Project)
.where(`${TableName.Membership}.scopeProjectId`, projectId)
.select(selectAllTableCols(TableName.MembershipRole))
.select(
db.ref("id").withSchema(TableName.IdentityProjectMembership).as("membershipId"),
db.ref("id").withSchema(TableName.Membership).as("membershipId"),
db.ref("id").withSchema(TableName.Identity).as("identityId"),
db.ref("name").withSchema(TableName.Identity).as("identityName"),
db.ref("orgId").withSchema(TableName.Project).as("orgId"), // Now you can select orgId from Project
db.ref("type").withSchema(TableName.Project).as("projectType"),
db.ref("createdAt").withSchema(TableName.IdentityProjectMembership).as("membershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.IdentityProjectMembership).as("membershipUpdatedAt"),
db.ref("slug").withSchema(TableName.ProjectRoles).as("customRoleSlug"),
db.ref("permissions").withSchema(TableName.ProjectRoles),
db.ref("id").withSchema(TableName.IdentityProjectAdditionalPrivilege).as("identityApId"),
db.ref("permissions").withSchema(TableName.IdentityProjectAdditionalPrivilege).as("identityApPermissions"),
db
.ref("temporaryMode")
.withSchema(TableName.IdentityProjectAdditionalPrivilege)
.as("identityApTemporaryMode"),
db.ref("isTemporary").withSchema(TableName.IdentityProjectAdditionalPrivilege).as("identityApIsTemporary"),
db
.ref("temporaryRange")
.withSchema(TableName.IdentityProjectAdditionalPrivilege)
.as("identityApTemporaryRange"),
db.ref("createdAt").withSchema(TableName.Membership).as("membershipCreatedAt"),
db.ref("updatedAt").withSchema(TableName.Membership).as("membershipUpdatedAt"),
db.ref("slug").withSchema(TableName.Role).as("customRoleSlug"),
db.ref("permissions").withSchema(TableName.Role),
db.ref("id").withSchema(TableName.AdditionalPrivilege).as("identityApId"),
db.ref("permissions").withSchema(TableName.AdditionalPrivilege).as("identityApPermissions"),
db.ref("temporaryMode").withSchema(TableName.AdditionalPrivilege).as("identityApTemporaryMode"),
db.ref("isTemporary").withSchema(TableName.AdditionalPrivilege).as("identityApIsTemporary"),
db.ref("temporaryRange").withSchema(TableName.AdditionalPrivilege).as("identityApTemporaryRange"),
db
.ref("temporaryAccessStartTime")
.withSchema(TableName.IdentityProjectAdditionalPrivilege)
.withSchema(TableName.AdditionalPrivilege)
.as("identityApTemporaryAccessStartTime"),
db
.ref("temporaryAccessEndTime")
.withSchema(TableName.IdentityProjectAdditionalPrivilege)
.withSchema(TableName.AdditionalPrivilege)
.as("identityApTemporaryAccessEndTime"),
db.ref("id").withSchema(TableName.IdentityMetadata).as("metadataId"),
db.ref("key").withSchema(TableName.IdentityMetadata).as("metadataKey"),
@@ -838,15 +761,7 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
const permissions = sqlNestRelationships({
data: docs,
key: "identityId",
parentMapper: ({
membershipId,
membershipCreatedAt,
membershipUpdatedAt,
orgId,
identityName,
projectType,
identityId
}) => ({
parentMapper: ({ membershipId, membershipCreatedAt, membershipUpdatedAt, identityName, identityId }) => ({
id: membershipId,
identityId,
username: identityName,
@@ -854,7 +769,6 @@ export const permissionDALFactory = (db: TDbClient): TPermissionDALFactory => {
createdAt: membershipCreatedAt,
updatedAt: membershipUpdatedAt,
orgId,
projectType,
// just a prefilled value
orgAuthEnforced: false
}),