mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 14:27:59 +00:00
grant endpoints
This commit is contained in:
@@ -19,7 +19,8 @@ export const registerApprovalPolicyEndpoints = <P extends TApprovalPolicy>({
|
|||||||
updatePolicySchema,
|
updatePolicySchema,
|
||||||
policyResponseSchema,
|
policyResponseSchema,
|
||||||
createRequestSchema,
|
createRequestSchema,
|
||||||
requestResponseSchema
|
requestResponseSchema,
|
||||||
|
grantResponseSchema
|
||||||
}: {
|
}: {
|
||||||
server: FastifyZodProvider;
|
server: FastifyZodProvider;
|
||||||
policyType: ApprovalPolicyType;
|
policyType: ApprovalPolicyType;
|
||||||
@@ -38,6 +39,7 @@ export const registerApprovalPolicyEndpoints = <P extends TApprovalPolicy>({
|
|||||||
policyResponseSchema: z.ZodTypeAny;
|
policyResponseSchema: z.ZodTypeAny;
|
||||||
createRequestSchema: z.ZodType<TCreateRequestDTO>;
|
createRequestSchema: z.ZodType<TCreateRequestDTO>;
|
||||||
requestResponseSchema: z.ZodTypeAny;
|
requestResponseSchema: z.ZodTypeAny;
|
||||||
|
grantResponseSchema: z.ZodTypeAny;
|
||||||
}) => {
|
}) => {
|
||||||
// Policies
|
// Policies
|
||||||
server.route({
|
server.route({
|
||||||
@@ -365,4 +367,93 @@ export const registerApprovalPolicyEndpoints = <P extends TApprovalPolicy>({
|
|||||||
return { request };
|
return { request };
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Grants
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/grants",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
description: "List approval grants",
|
||||||
|
querystring: z.object({
|
||||||
|
projectId: z.string().uuid()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
grants: z.array(grantResponseSchema)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { grants } = await server.services.approvalPolicy.listGrants(
|
||||||
|
policyType,
|
||||||
|
req.query.projectId,
|
||||||
|
req.permission
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO(andrey): Audit log
|
||||||
|
|
||||||
|
return { grants };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "GET",
|
||||||
|
url: "/grants/:grantId",
|
||||||
|
config: {
|
||||||
|
rateLimit: readLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
description: "Get approval grant",
|
||||||
|
params: z.object({
|
||||||
|
grantId: z.string().uuid()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
grant: grantResponseSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { grant } = await server.services.approvalPolicy.getGrantById(req.params.grantId, req.permission);
|
||||||
|
|
||||||
|
// TODO(andrey): Audit log
|
||||||
|
|
||||||
|
return { grant };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "POST",
|
||||||
|
url: "/grants/:grantId/revoke",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
description: "Revoke approval grant",
|
||||||
|
params: z.object({
|
||||||
|
grantId: z.string().uuid()
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
revocationReason: z.string().optional()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
grant: grantResponseSchema
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
|
handler: async (req) => {
|
||||||
|
const { grant } = await server.services.approvalPolicy.revokeGrant(req.params.grantId, req.body, req.permission);
|
||||||
|
|
||||||
|
// TODO(andrey): Audit log
|
||||||
|
|
||||||
|
return { grant };
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import {
|
|||||||
CreatePamAccessPolicySchema,
|
CreatePamAccessPolicySchema,
|
||||||
CreatePamAccessRequestSchema,
|
CreatePamAccessRequestSchema,
|
||||||
PamAccessPolicySchema,
|
PamAccessPolicySchema,
|
||||||
|
PamAccessRequestGrantSchema,
|
||||||
PamAccessRequestSchema,
|
PamAccessRequestSchema,
|
||||||
UpdatePamAccessPolicySchema
|
UpdatePamAccessPolicySchema
|
||||||
} from "@app/services/approval-policy/pam-access/pam-access-policy-schemas";
|
} from "@app/services/approval-policy/pam-access/pam-access-policy-schemas";
|
||||||
@@ -21,7 +22,8 @@ export const APPROVAL_POLICY_REGISTER_ROUTER_MAP: Record<
|
|||||||
updatePolicySchema: UpdatePamAccessPolicySchema,
|
updatePolicySchema: UpdatePamAccessPolicySchema,
|
||||||
policyResponseSchema: PamAccessPolicySchema,
|
policyResponseSchema: PamAccessPolicySchema,
|
||||||
createRequestSchema: CreatePamAccessRequestSchema,
|
createRequestSchema: CreatePamAccessRequestSchema,
|
||||||
requestResponseSchema: PamAccessRequestSchema
|
requestResponseSchema: PamAccessRequestSchema,
|
||||||
|
grantResponseSchema: PamAccessRequestGrantSchema
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|||||||
import {
|
import {
|
||||||
ApprovalPoliciesSchema,
|
ApprovalPoliciesSchema,
|
||||||
ApprovalRequestApprovalsSchema,
|
ApprovalRequestApprovalsSchema,
|
||||||
|
ApprovalRequestGrantsSchema,
|
||||||
ApprovalRequestsSchema,
|
ApprovalRequestsSchema,
|
||||||
ApprovalRequestStepsSchema
|
ApprovalRequestStepsSchema
|
||||||
} from "@app/db/schemas";
|
} from "@app/db/schemas";
|
||||||
@@ -89,3 +90,6 @@ export const BaseCreateApprovalRequestSchema = z.object({
|
|||||||
.nullable()
|
.nullable()
|
||||||
.optional()
|
.optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Grants
|
||||||
|
export const BaseApprovalRequestGrantSchema = ApprovalRequestGrantsSchema;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ActionProjectType, ProjectMembershipRole, TApprovalPolicies, TApprovalRequests } from "@app/db/schemas";
|
import { ActionProjectType, ProjectMembershipRole, TApprovalPolicies, TApprovalRequests } from "@app/db/schemas";
|
||||||
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
import { TUserGroupMembershipDALFactory } from "@app/ee/services/group/user-group-membership-dal";
|
||||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||||
import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
import { OrgServiceActor } from "@app/lib/types";
|
import { OrgServiceActor } from "@app/lib/types";
|
||||||
import { TNotificationServiceFactory } from "@app/services/notification/notification-service";
|
import { TNotificationServiceFactory } from "@app/services/notification/notification-service";
|
||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
ApprovalPolicyType,
|
ApprovalPolicyType,
|
||||||
ApprovalRequestApprovalDecision,
|
ApprovalRequestApprovalDecision,
|
||||||
|
ApprovalRequestGrantStatus,
|
||||||
ApprovalRequestStatus,
|
ApprovalRequestStatus,
|
||||||
ApprovalRequestStepStatus,
|
ApprovalRequestStepStatus,
|
||||||
ApproverType
|
ApproverType
|
||||||
@@ -699,6 +700,50 @@ export const approvalPolicyServiceFactory = ({
|
|||||||
return { request: { ...updatedRequest, steps } };
|
return { request: { ...updatedRequest, steps } };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const listGrants = async (policyType: ApprovalPolicyType, projectId: string, actor: OrgServiceActor) => {
|
||||||
|
// TODO(andrey): Perm check
|
||||||
|
|
||||||
|
const grants = await approvalRequestGrantsDAL.find({ projectId, type: policyType });
|
||||||
|
return { grants };
|
||||||
|
};
|
||||||
|
|
||||||
|
const getGrantById = async (grantId: string, actor: OrgServiceActor) => {
|
||||||
|
// TODO(andrey): Perm check
|
||||||
|
|
||||||
|
const grant = await approvalRequestGrantsDAL.findById(grantId);
|
||||||
|
if (!grant) {
|
||||||
|
throw new NotFoundError({ message: "Grant not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { grant };
|
||||||
|
};
|
||||||
|
|
||||||
|
const revokeGrant = async (
|
||||||
|
grantId: string,
|
||||||
|
{ revocationReason }: { revocationReason?: string },
|
||||||
|
actor: OrgServiceActor
|
||||||
|
) => {
|
||||||
|
// TODO(andrey): Perm check
|
||||||
|
|
||||||
|
const grant = await approvalRequestGrantsDAL.findById(grantId);
|
||||||
|
if (!grant) {
|
||||||
|
throw new NotFoundError({ message: "Grant not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grant.status !== ApprovalRequestGrantStatus.Active) {
|
||||||
|
throw new BadRequestError({ message: "Grant is not active" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedGrant = await approvalRequestGrantsDAL.updateById(grantId, {
|
||||||
|
status: ApprovalRequestGrantStatus.Revoked,
|
||||||
|
revokedAt: new Date(),
|
||||||
|
revokedByUserId: actor.id,
|
||||||
|
revocationReason
|
||||||
|
});
|
||||||
|
|
||||||
|
return { grant: updatedGrant };
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
create,
|
create,
|
||||||
list,
|
list,
|
||||||
@@ -710,6 +755,9 @@ export const approvalPolicyServiceFactory = ({
|
|||||||
getRequestById,
|
getRequestById,
|
||||||
approveRequest,
|
approveRequest,
|
||||||
rejectRequest,
|
rejectRequest,
|
||||||
cancelRequest
|
cancelRequest,
|
||||||
|
listGrants,
|
||||||
|
getGrantById,
|
||||||
|
revokeGrant
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export interface TCreateRequestDTO {
|
|||||||
projectId: TApprovalRequest["projectId"];
|
projectId: TApprovalRequest["projectId"];
|
||||||
requestData: TApprovalRequest["requestData"]["requestData"];
|
requestData: TApprovalRequest["requestData"]["requestData"];
|
||||||
justification?: TApprovalRequest["justification"];
|
justification?: TApprovalRequest["justification"];
|
||||||
requestDuration?: string;
|
requestDuration?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Factory
|
// Factory
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { ms } from "@app/lib/ms";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
BaseApprovalPolicySchema,
|
BaseApprovalPolicySchema,
|
||||||
|
BaseApprovalRequestGrantSchema,
|
||||||
BaseApprovalRequestSchema,
|
BaseApprovalRequestSchema,
|
||||||
BaseCreateApprovalPolicySchema,
|
BaseCreateApprovalPolicySchema,
|
||||||
BaseCreateApprovalRequestSchema,
|
BaseCreateApprovalRequestSchema,
|
||||||
@@ -79,3 +80,8 @@ export const PamAccessRequestSchema = BaseApprovalRequestSchema.extend({
|
|||||||
export const CreatePamAccessRequestSchema = BaseCreateApprovalRequestSchema.extend({
|
export const CreatePamAccessRequestSchema = BaseCreateApprovalRequestSchema.extend({
|
||||||
requestData: PamAccessPolicyRequestDataSchema
|
requestData: PamAccessPolicyRequestDataSchema
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Grants
|
||||||
|
export const PamAccessRequestGrantSchema = BaseApprovalRequestGrantSchema.extend({
|
||||||
|
attributes: PamAccessPolicyRequestDataSchema
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user