mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 17:27:40 +00:00
feat(server): completed routes for user additional privilege
This commit is contained in:
Vendored
+2
@@ -8,6 +8,7 @@ import { TDynamicSecretLeaseServiceFactory } from "@app/ee/services/dynamic-secr
|
|||||||
import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service";
|
import { TLdapConfigServiceFactory } from "@app/ee/services/ldap-config/ldap-config-service";
|
||||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
|
import { TProjectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
|
||||||
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
|
import { TSamlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
|
||||||
import { TScimServiceFactory } from "@app/ee/services/scim/scim-service";
|
import { TScimServiceFactory } from "@app/ee/services/scim/scim-service";
|
||||||
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
import { TSecretApprovalPolicyServiceFactory } from "@app/ee/services/secret-approval-policy/secret-approval-policy-service";
|
||||||
@@ -121,6 +122,7 @@ declare module "fastify" {
|
|||||||
telemetry: TTelemetryServiceFactory;
|
telemetry: TTelemetryServiceFactory;
|
||||||
dynamicSecret: TDynamicSecretServiceFactory;
|
dynamicSecret: TDynamicSecretServiceFactory;
|
||||||
dynamicSecretLease: TDynamicSecretLeaseServiceFactory;
|
dynamicSecretLease: TDynamicSecretLeaseServiceFactory;
|
||||||
|
projectUserAdditionalPrivilege: TProjectUserAdditionalPrivilegeServiceFactory;
|
||||||
};
|
};
|
||||||
// this is exclusive use for middlewares in which we need to inject data
|
// this is exclusive use for middlewares in which we need to inject data
|
||||||
// everywhere else access using service layer
|
// everywhere else access using service layer
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { registerSecretScanningRouter } from "./secret-scanning-router";
|
|||||||
import { registerSecretVersionRouter } from "./secret-version-router";
|
import { registerSecretVersionRouter } from "./secret-version-router";
|
||||||
import { registerSnapshotRouter } from "./snapshot-router";
|
import { registerSnapshotRouter } from "./snapshot-router";
|
||||||
import { registerTrustedIpRouter } from "./trusted-ip-router";
|
import { registerTrustedIpRouter } from "./trusted-ip-router";
|
||||||
|
import { registerUserAdditionalPrivilegeRouter } from "./user-additional-privilege-router";
|
||||||
|
|
||||||
export const registerV1EERoutes = async (server: FastifyZodProvider) => {
|
export const registerV1EERoutes = async (server: FastifyZodProvider) => {
|
||||||
// org role starts with organization
|
// org role starts with organization
|
||||||
@@ -51,4 +52,10 @@ export const registerV1EERoutes = async (server: FastifyZodProvider) => {
|
|||||||
await server.register(registerSecretScanningRouter, { prefix: "/secret-scanning" });
|
await server.register(registerSecretScanningRouter, { prefix: "/secret-scanning" });
|
||||||
await server.register(registerSecretRotationRouter, { prefix: "/secret-rotations" });
|
await server.register(registerSecretRotationRouter, { prefix: "/secret-rotations" });
|
||||||
await server.register(registerSecretVersionRouter, { prefix: "/secret" });
|
await server.register(registerSecretVersionRouter, { prefix: "/secret" });
|
||||||
|
await server.register(
|
||||||
|
async (privilegeRouter) => {
|
||||||
|
await privilegeRouter.register(registerUserAdditionalPrivilegeRouter, { prefix: "/users" });
|
||||||
|
},
|
||||||
|
{ prefix: "/additional-privilege" }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
import ms from "ms";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import { ProjectUserAdditionalPrivilegeSchema } from "@app/db/schemas";
|
||||||
|
import { ProjectUserAdditionalPrivilegeTemporaryMode } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-types";
|
||||||
|
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||||
|
import { AuthMode } from "@app/services/auth/auth-type";
|
||||||
|
|
||||||
|
export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.route({
|
||||||
|
url: "/",
|
||||||
|
method: "POST",
|
||||||
|
schema: {
|
||||||
|
body: z.union([
|
||||||
|
z.object({
|
||||||
|
projectMembershipId: z.string(),
|
||||||
|
slug: z.string().max(60).trim(),
|
||||||
|
name: z.string().trim(),
|
||||||
|
description: z.string().trim().optional(),
|
||||||
|
permissions: z.any().array(),
|
||||||
|
isTemporary: z.literal(false).default(false)
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
projectMembershipId: z.string(),
|
||||||
|
slug: z.string().max(60).trim(),
|
||||||
|
name: z.string().trim(),
|
||||||
|
description: z.string().trim().optional(),
|
||||||
|
permissions: z.any().array(),
|
||||||
|
isTemporary: z.literal(true),
|
||||||
|
temporaryMode: z.nativeEnum(ProjectUserAdditionalPrivilegeTemporaryMode),
|
||||||
|
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
|
||||||
|
temporaryAccessStartTime: z.string().datetime()
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
privilege: ProjectUserAdditionalPrivilegeSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const privilege = await server.services.projectUserAdditionalPrivilege.create({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
permissions: JSON.stringify(req.body.permissions)
|
||||||
|
});
|
||||||
|
return { privilege };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:privilegeId",
|
||||||
|
method: "PATCH",
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
privilegeId: z.string()
|
||||||
|
}),
|
||||||
|
body: z
|
||||||
|
.object({
|
||||||
|
slug: z.string().max(60).trim(),
|
||||||
|
name: z.string().trim(),
|
||||||
|
description: z.string().trim().optional(),
|
||||||
|
permissions: z.any().array(),
|
||||||
|
isTemporary: z.boolean(),
|
||||||
|
temporaryMode: z.nativeEnum(ProjectUserAdditionalPrivilegeTemporaryMode),
|
||||||
|
temporaryRange: z.string().refine((val) => ms(val) > 0, "Temporary range must be a positive number"),
|
||||||
|
temporaryAccessStartTime: z.string().datetime()
|
||||||
|
})
|
||||||
|
.partial(),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
privilege: ProjectUserAdditionalPrivilegeSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const privilege = await server.services.projectUserAdditionalPrivilege.updateById({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
...req.body,
|
||||||
|
permissions: req.body.permissions ? JSON.stringify(req.body.permissions) : undefined,
|
||||||
|
privilegeId: req.params.privilegeId
|
||||||
|
});
|
||||||
|
return { privilege };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:privilegeId",
|
||||||
|
method: "DELETE",
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
privilegeId: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
privilege: ProjectUserAdditionalPrivilegeSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const privilege = await server.services.projectUserAdditionalPrivilege.deleteById({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
privilegeId: req.params.privilegeId
|
||||||
|
});
|
||||||
|
return { privilege };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
url: "/:privilegeId",
|
||||||
|
method: "GET",
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
privilegeId: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
privilege: ProjectUserAdditionalPrivilegeSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const privilege = await server.services.projectUserAdditionalPrivilege.getPrivilegeDetailsById({
|
||||||
|
actorId: req.permission.id,
|
||||||
|
actor: req.permission.type,
|
||||||
|
actorOrgId: req.permission.orgId,
|
||||||
|
privilegeId: req.params.privilegeId
|
||||||
|
});
|
||||||
|
return { privilege };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -17,6 +17,8 @@ import { licenseDALFactory } from "@app/ee/services/license/license-dal";
|
|||||||
import { licenseServiceFactory } from "@app/ee/services/license/license-service";
|
import { licenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||||
import { permissionDALFactory } from "@app/ee/services/permission/permission-dal";
|
import { permissionDALFactory } from "@app/ee/services/permission/permission-dal";
|
||||||
import { permissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
import { permissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||||
|
import { projectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal";
|
||||||
|
import { projectUserAdditionalPrivilegeServiceFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-service";
|
||||||
import { samlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal";
|
import { samlConfigDALFactory } from "@app/ee/services/saml-config/saml-config-dal";
|
||||||
import { samlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
|
import { samlConfigServiceFactory } from "@app/ee/services/saml-config/saml-config-service";
|
||||||
import { scimDALFactory } from "@app/ee/services/scim/scim-dal";
|
import { scimDALFactory } from "@app/ee/services/scim/scim-dal";
|
||||||
@@ -149,6 +151,7 @@ export const registerRoutes = async (
|
|||||||
|
|
||||||
const projectDAL = projectDALFactory(db);
|
const projectDAL = projectDALFactory(db);
|
||||||
const projectMembershipDAL = projectMembershipDALFactory(db);
|
const projectMembershipDAL = projectMembershipDALFactory(db);
|
||||||
|
const projectUserAdditionalPrivilegeDAL = projectUserAdditionalPrivilegeDALFactory(db);
|
||||||
const projectUserMembershipRoleDAL = projectUserMembershipRoleDALFactory(db);
|
const projectUserMembershipRoleDAL = projectUserMembershipRoleDALFactory(db);
|
||||||
const projectRoleDAL = projectRoleDALFactory(db);
|
const projectRoleDAL = projectRoleDALFactory(db);
|
||||||
const projectEnvDAL = projectEnvDALFactory(db);
|
const projectEnvDAL = projectEnvDALFactory(db);
|
||||||
@@ -345,6 +348,11 @@ export const registerRoutes = async (
|
|||||||
projectRoleDAL,
|
projectRoleDAL,
|
||||||
licenseService
|
licenseService
|
||||||
});
|
});
|
||||||
|
const projectUserAdditionalPrivilegeService = projectUserAdditionalPrivilegeServiceFactory({
|
||||||
|
permissionService,
|
||||||
|
projectMembershipDAL,
|
||||||
|
projectUserAdditionalPrivilegeDAL
|
||||||
|
});
|
||||||
const projectKeyService = projectKeyServiceFactory({
|
const projectKeyService = projectKeyServiceFactory({
|
||||||
permissionService,
|
permissionService,
|
||||||
projectKeyDAL,
|
projectKeyDAL,
|
||||||
@@ -638,7 +646,8 @@ export const registerRoutes = async (
|
|||||||
trustedIp: trustedIpService,
|
trustedIp: trustedIpService,
|
||||||
scim: scimService,
|
scim: scimService,
|
||||||
secretBlindIndex: secretBlindIndexService,
|
secretBlindIndex: secretBlindIndexService,
|
||||||
telemetry: telemetryService
|
telemetry: telemetryService,
|
||||||
|
projectUserAdditionalPrivilege: projectUserAdditionalPrivilegeService
|
||||||
});
|
});
|
||||||
|
|
||||||
server.decorate<FastifyZodProvider["store"]>("store", {
|
server.decorate<FastifyZodProvider["store"]>("store", {
|
||||||
|
|||||||
@@ -40,6 +40,20 @@ export const registerProjectMembershipRouter = async (server: FastifyZodProvider
|
|||||||
lastName: true,
|
lastName: true,
|
||||||
id: true
|
id: true
|
||||||
}).merge(UserEncryptionKeysSchema.pick({ publicKey: true })),
|
}).merge(UserEncryptionKeysSchema.pick({ publicKey: true })),
|
||||||
|
additionalPrivileges: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
slug: z.string(),
|
||||||
|
description: z.string().optional().nullable(),
|
||||||
|
isTemporary: z.boolean(),
|
||||||
|
temporaryMode: z.string().optional().nullable(),
|
||||||
|
temporaryRange: z.string().nullable().optional(),
|
||||||
|
temporaryAccessStartTime: z.date().nullable().optional(),
|
||||||
|
temporaryAccessEndTime: z.date().nullable().optional(),
|
||||||
|
createdAt: z.date()
|
||||||
|
})
|
||||||
|
),
|
||||||
roles: z.array(
|
roles: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
|||||||
@@ -73,6 +73,20 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
lastName: true,
|
lastName: true,
|
||||||
id: true
|
id: true
|
||||||
}).merge(UserEncryptionKeysSchema.pick({ publicKey: true })),
|
}).merge(UserEncryptionKeysSchema.pick({ publicKey: true })),
|
||||||
|
additionalPrivileges: z.array(
|
||||||
|
z.object({
|
||||||
|
id: z.string(),
|
||||||
|
name: z.string(),
|
||||||
|
slug: z.string(),
|
||||||
|
description: z.string().optional().nullable(),
|
||||||
|
isTemporary: z.boolean(),
|
||||||
|
temporaryMode: z.string().optional().nullable(),
|
||||||
|
temporaryRange: z.string().nullable().optional(),
|
||||||
|
temporaryAccessStartTime: z.date().nullable().optional(),
|
||||||
|
temporaryAccessEndTime: z.date().nullable().optional(),
|
||||||
|
createdAt: z.date()
|
||||||
|
})
|
||||||
|
),
|
||||||
roles: z.array(
|
roles: z.array(
|
||||||
z.object({
|
z.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
|||||||
@@ -29,6 +29,11 @@ export const projectMembershipDALFactory = (db: TDbClient) => {
|
|||||||
`${TableName.ProjectUserMembershipRole}.customRoleId`,
|
`${TableName.ProjectUserMembershipRole}.customRoleId`,
|
||||||
`${TableName.ProjectRoles}.id`
|
`${TableName.ProjectRoles}.id`
|
||||||
)
|
)
|
||||||
|
.leftJoin(
|
||||||
|
TableName.ProjectUserAdditionalPrivilege,
|
||||||
|
`${TableName.ProjectMembership}.id`,
|
||||||
|
`${TableName.ProjectUserAdditionalPrivilege}.projectMembershipId`
|
||||||
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.ProjectMembership),
|
db.ref("id").withSchema(TableName.ProjectMembership),
|
||||||
db.ref("isGhost").withSchema(TableName.Users),
|
db.ref("isGhost").withSchema(TableName.Users),
|
||||||
@@ -47,7 +52,23 @@ export const projectMembershipDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("isTemporary").withSchema(TableName.ProjectUserMembershipRole),
|
db.ref("isTemporary").withSchema(TableName.ProjectUserMembershipRole),
|
||||||
db.ref("temporaryRange").withSchema(TableName.ProjectUserMembershipRole),
|
db.ref("temporaryRange").withSchema(TableName.ProjectUserMembershipRole),
|
||||||
db.ref("temporaryAccessStartTime").withSchema(TableName.ProjectUserMembershipRole),
|
db.ref("temporaryAccessStartTime").withSchema(TableName.ProjectUserMembershipRole),
|
||||||
db.ref("temporaryAccessEndTime").withSchema(TableName.ProjectUserMembershipRole)
|
db.ref("temporaryAccessEndTime").withSchema(TableName.ProjectUserMembershipRole),
|
||||||
|
db.ref("id").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApId"),
|
||||||
|
db.ref("name").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApName"),
|
||||||
|
db.ref("description").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApDescription"),
|
||||||
|
db.ref("slug").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApSlug"),
|
||||||
|
db.ref("temporaryMode").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApTemporaryMode"),
|
||||||
|
db.ref("isTemporary").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApIsTemporary"),
|
||||||
|
db.ref("createdAt").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApCreatedAt"),
|
||||||
|
db.ref("temporaryRange").withSchema(TableName.ProjectUserAdditionalPrivilege).as("userApTemporaryRange"),
|
||||||
|
db
|
||||||
|
.ref("temporaryAccessStartTime")
|
||||||
|
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||||
|
.as("userApTemporaryAccessStartTime"),
|
||||||
|
db
|
||||||
|
.ref("temporaryAccessEndTime")
|
||||||
|
.withSchema(TableName.ProjectUserAdditionalPrivilege)
|
||||||
|
.as("userApTemporaryAccessEndTime")
|
||||||
)
|
)
|
||||||
.where({ isGhost: false });
|
.where({ isGhost: false });
|
||||||
|
|
||||||
@@ -87,6 +108,33 @@ export const projectMembershipDALFactory = (db: TDbClient) => {
|
|||||||
temporaryAccessStartTime,
|
temporaryAccessStartTime,
|
||||||
isTemporary
|
isTemporary
|
||||||
})
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "additionalPrivileges" as const,
|
||||||
|
key: "userApId",
|
||||||
|
mapper: ({
|
||||||
|
userApId,
|
||||||
|
userApDescription,
|
||||||
|
userApName,
|
||||||
|
userApSlug,
|
||||||
|
userApIsTemporary,
|
||||||
|
userApTemporaryMode,
|
||||||
|
userApTemporaryRange,
|
||||||
|
userApTemporaryAccessEndTime,
|
||||||
|
userApTemporaryAccessStartTime,
|
||||||
|
userApCreatedAt
|
||||||
|
}) => ({
|
||||||
|
id: userApId,
|
||||||
|
name: userApName,
|
||||||
|
description: userApDescription,
|
||||||
|
slug: userApSlug,
|
||||||
|
temporaryRange: userApTemporaryRange,
|
||||||
|
temporaryMode: userApTemporaryMode,
|
||||||
|
temporaryAccessEndTime: userApTemporaryAccessEndTime,
|
||||||
|
temporaryAccessStartTime: userApTemporaryAccessStartTime,
|
||||||
|
isTemporary: userApIsTemporary,
|
||||||
|
createdAt: userApCreatedAt
|
||||||
|
})
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user