mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 20:25:43 +00:00
feat: completed membership identity
This commit is contained in:
@@ -2,7 +2,7 @@ import { MongoAbility } from "@casl/ability";
|
||||
import { MongoQuery } from "@ucast/mongo2js";
|
||||
import { Knex } from "knex";
|
||||
|
||||
import { AccessScope, AccessScopeData, ActionProjectType, TMemberships } from "@app/db/schemas";
|
||||
import { ActionProjectType, TMemberships } from "@app/db/schemas";
|
||||
import { ActorAuthMethod, ActorType } from "@app/services/auth/auth-type";
|
||||
|
||||
import { OrgPermissionSet } from "./org-permission";
|
||||
@@ -95,39 +95,40 @@ export type TPermissionServiceFactory = {
|
||||
}[];
|
||||
}>;
|
||||
// TODO(simp): switch to role dal later
|
||||
getOrgPermissionByRole: (
|
||||
role: string,
|
||||
getOrgPermissionByRoles: (
|
||||
roles: string[],
|
||||
orgId: string
|
||||
) => Promise<{
|
||||
permission: MongoAbility<OrgPermissionSet, MongoQuery>;
|
||||
role?: {
|
||||
name: string;
|
||||
orgId: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
slug: string;
|
||||
permissions?: unknown;
|
||||
description?: string | null | undefined;
|
||||
};
|
||||
}>;
|
||||
getProjectPermissionByRole: (
|
||||
role: string,
|
||||
) => Promise<
|
||||
{
|
||||
permission: MongoAbility<OrgPermissionSet, MongoQuery>;
|
||||
role?: {
|
||||
name: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
slug: string;
|
||||
permissions?: unknown;
|
||||
description?: string | null | undefined;
|
||||
};
|
||||
}[]
|
||||
>;
|
||||
getProjectPermissionByRoles: (
|
||||
roles: string[],
|
||||
projectId: string
|
||||
) => Promise<{
|
||||
permission: MongoAbility<ProjectPermissionSet, MongoQuery>;
|
||||
role?: {
|
||||
name: string;
|
||||
version: number;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
projectId: string;
|
||||
slug: string;
|
||||
permissions?: unknown;
|
||||
description?: string | null | undefined;
|
||||
};
|
||||
}>;
|
||||
) => Promise<
|
||||
{
|
||||
permission: MongoAbility<ProjectPermissionSet, MongoQuery>;
|
||||
role?: {
|
||||
name: string;
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
slug: string;
|
||||
permissions?: unknown;
|
||||
description?: string | null | undefined;
|
||||
};
|
||||
}[]
|
||||
>;
|
||||
checkGroupProjectPermission: ({
|
||||
groupId,
|
||||
projectId,
|
||||
|
||||
@@ -25,9 +25,8 @@ import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/
|
||||
import { objectify } from "@app/lib/fn";
|
||||
import { ActorType } from "@app/services/auth/auth-type";
|
||||
import { TIdentityDALFactory } from "@app/services/identity/identity-dal";
|
||||
import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
import { TProjectRoleDALFactory } from "@app/services/project-role/project-role-dal";
|
||||
import { TRoleDALFactory } from "@app/services/role/role-dal";
|
||||
import { TServiceTokenDALFactory } from "@app/services/service-token/service-token-dal";
|
||||
import { TUserDALFactory } from "@app/services/user/user-dal";
|
||||
|
||||
@@ -99,25 +98,23 @@ const buildProjectPermissionRules = (projectUserRoles: TBuildProjectPermissionDT
|
||||
};
|
||||
|
||||
type TPermissionServiceFactoryDep = {
|
||||
orgRoleDAL: Pick<TOrgRoleDALFactory, "findOne">;
|
||||
projectRoleDAL: Pick<TProjectRoleDALFactory, "findOne">;
|
||||
serviceTokenDAL: Pick<TServiceTokenDALFactory, "findById">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
permissionDAL: TPermissionDALFactory;
|
||||
keyStore: TKeyStoreFactory;
|
||||
userDAL: Pick<TUserDALFactory, "findById">;
|
||||
identityDAL: Pick<TIdentityDALFactory, "findById">;
|
||||
roleDAL: Pick<TRoleDALFactory, "find">;
|
||||
};
|
||||
|
||||
export const permissionServiceFactory = ({
|
||||
permissionDAL,
|
||||
orgRoleDAL,
|
||||
projectRoleDAL,
|
||||
serviceTokenDAL,
|
||||
projectDAL,
|
||||
userDAL,
|
||||
identityDAL,
|
||||
keyStore
|
||||
keyStore,
|
||||
roleDAL
|
||||
}: TPermissionServiceFactoryDep): TPermissionServiceFactory => {
|
||||
const invalidateProjectPermissionCache = async (projectId: string, tx?: Knex) => {
|
||||
const projectPermissionDalVersionKey = KeyStorePrefixes.ProjectPermissionDalVersion(projectId);
|
||||
@@ -245,33 +242,6 @@ export const permissionServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
// instead of actor type this will fetch by role slug. meaning it can be the pre defined slugs like
|
||||
// admin member or user defined ones like biller etc
|
||||
const getOrgPermissionByRole: TPermissionServiceFactory["getOrgPermissionByRole"] = async (role, orgId) => {
|
||||
const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole);
|
||||
if (isCustomRole) {
|
||||
const orgRole = await orgRoleDAL.findOne({ slug: role, orgId });
|
||||
if (!orgRole)
|
||||
throw new NotFoundError({
|
||||
message: `Specified role '${role}' was not found in the organization with ID '${orgId}'`
|
||||
});
|
||||
return {
|
||||
permission: createMongoAbility<OrgPermissionSet>(
|
||||
buildOrgPermissionRules([{ role: OrgMembershipRole.Custom, permissions: orgRole.permissions }]),
|
||||
{
|
||||
conditionsMatcher
|
||||
}
|
||||
),
|
||||
role: orgRole
|
||||
};
|
||||
}
|
||||
return {
|
||||
permission: createMongoAbility<OrgPermissionSet>(buildOrgPermissionRules([{ role, permissions: [] }]), {
|
||||
conditionsMatcher
|
||||
})
|
||||
};
|
||||
};
|
||||
|
||||
const getServiceTokenProjectPermission = async ({
|
||||
serviceTokenId,
|
||||
projectId,
|
||||
@@ -572,30 +542,105 @@ export const permissionServiceFactory = ({
|
||||
};
|
||||
};
|
||||
|
||||
const getProjectPermissionByRole: TPermissionServiceFactory["getProjectPermissionByRole"] = async (
|
||||
role,
|
||||
projectId
|
||||
) => {
|
||||
const isCustomRole = !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole);
|
||||
if (isCustomRole) {
|
||||
const projectRole = await projectRoleDAL.findOne({ slug: role, projectId });
|
||||
if (!projectRole) throw new NotFoundError({ message: `Specified role was not found: ${role}` });
|
||||
const rules = buildProjectPermissionRules([
|
||||
{ role: ProjectMembershipRole.Custom, permissions: projectRole.permissions }
|
||||
]);
|
||||
return {
|
||||
permission: createMongoAbility<ProjectPermissionSet>(rules, {
|
||||
conditionsMatcher
|
||||
}),
|
||||
role: projectRole
|
||||
};
|
||||
// instead of actor type this will fetch by role slug. meaning it can be the pre defined slugs like
|
||||
// admin member or user defined ones like biller etc
|
||||
const getOrgPermissionByRoles: TPermissionServiceFactory["getOrgPermissionByRoles"] = async (roles, orgId) => {
|
||||
const formattedRoles = roles.map((role) => ({
|
||||
name: role,
|
||||
isCustom: !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole)
|
||||
}));
|
||||
|
||||
const customRoles = formattedRoles.filter((el) => el.isCustom).map((el) => el.name);
|
||||
const customRoleDetails = customRoles.length
|
||||
? await roleDAL.find({
|
||||
orgId,
|
||||
$in: {
|
||||
slug: customRoles
|
||||
}
|
||||
})
|
||||
: [];
|
||||
if (customRoles.length !== customRoleDetails.length) {
|
||||
const missingRoles = customRoles.filter((role) => !customRoleDetails.find((el) => el.slug === role));
|
||||
throw new NotFoundError({
|
||||
message: `Specified roles '${missingRoles.join(",")}' was not found in the organization with ID '${orgId}'`
|
||||
});
|
||||
}
|
||||
|
||||
const rules = buildProjectPermissionRules([{ role, permissions: [] }]);
|
||||
const permission = createMongoAbility<ProjectPermissionSet>(rules, {
|
||||
conditionsMatcher
|
||||
return formattedRoles.map((el) => {
|
||||
if (el.isCustom) {
|
||||
const roleDetails = customRoleDetails.find((role) => role.slug === el.name);
|
||||
return {
|
||||
permission: createMongoAbility<OrgPermissionSet>(
|
||||
buildOrgPermissionRules([{ role: OrgMembershipRole.Custom, permissions: roleDetails?.permissions || [] }]),
|
||||
{
|
||||
conditionsMatcher
|
||||
}
|
||||
),
|
||||
role: roleDetails!
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
permission: createMongoAbility<OrgPermissionSet>(
|
||||
buildOrgPermissionRules([{ role: el.name, permissions: [] }]),
|
||||
{
|
||||
conditionsMatcher
|
||||
}
|
||||
)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const getProjectPermissionByRoles: TPermissionServiceFactory["getProjectPermissionByRoles"] = async (
|
||||
roles,
|
||||
projectId
|
||||
) => {
|
||||
const formattedRoles = roles.map((role) => ({
|
||||
name: role,
|
||||
isCustom: !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole)
|
||||
}));
|
||||
|
||||
const customRoles = formattedRoles.filter((el) => el.isCustom).map((el) => el.name);
|
||||
const customRoleDetails = customRoles.length
|
||||
? await roleDAL.find({
|
||||
projectId,
|
||||
$in: {
|
||||
slug: customRoles
|
||||
}
|
||||
})
|
||||
: [];
|
||||
if (customRoles.length !== customRoleDetails.length) {
|
||||
const missingRoles = customRoles.filter((role) => !customRoleDetails.find((el) => el.slug === role));
|
||||
throw new NotFoundError({
|
||||
message: `Specified roles '${missingRoles.join(",")}' was not found in the project with ID '${projectId}'`
|
||||
});
|
||||
}
|
||||
|
||||
return formattedRoles.map((el) => {
|
||||
if (el.isCustom) {
|
||||
const roleDetails = customRoleDetails.find((role) => role.slug === el.name);
|
||||
return {
|
||||
permission: createMongoAbility<ProjectPermissionSet>(
|
||||
buildProjectPermissionRules([
|
||||
{ role: ProjectMembershipRole.Custom, permissions: roleDetails?.permissions || [] }
|
||||
]),
|
||||
{
|
||||
conditionsMatcher
|
||||
}
|
||||
),
|
||||
role: roleDetails!
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
permission: createMongoAbility<ProjectPermissionSet>(
|
||||
buildProjectPermissionRules([{ role: el.name, permissions: [] }]),
|
||||
{
|
||||
conditionsMatcher
|
||||
}
|
||||
)
|
||||
};
|
||||
});
|
||||
return { permission };
|
||||
};
|
||||
|
||||
const checkGroupProjectPermission: TPermissionServiceFactory["checkGroupProjectPermission"] = async ({
|
||||
@@ -626,8 +671,8 @@ export const permissionServiceFactory = ({
|
||||
getOrgPermission,
|
||||
getProjectPermission,
|
||||
getProjectPermissions,
|
||||
getOrgPermissionByRole,
|
||||
getProjectPermissionByRole,
|
||||
getOrgPermissionByRoles,
|
||||
getProjectPermissionByRoles,
|
||||
checkGroupProjectPermission,
|
||||
invalidateProjectPermissionCache
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user