Move MI endpoints from v3 to v1

This commit is contained in:
Tuan Dang
2023-12-05 22:24:25 +07:00
parent 855158d0bb
commit 591f33ffbe
15 changed files with 34 additions and 33 deletions
@@ -26,7 +26,7 @@ import {
ProjectPermissionActions, ProjectPermissionActions,
ProjectPermissionSub, ProjectPermissionSub,
getAuthDataProjectPermissions, getAuthDataProjectPermissions,
getRolePermissions, getWorkspaceRolePermissions,
isAtLeastAsPrivilegedWorkspace isAtLeastAsPrivilegedWorkspace
} from "../../ee/services/ProjectRoleService"; } from "../../ee/services/ProjectRoleService";
import { ForbiddenError } from "@casl/ability"; import { ForbiddenError } from "@casl/ability";
@@ -550,7 +550,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
message: "Failed to add machine identity to project in another organization" message: "Failed to add machine identity to project in another organization"
}); });
const rolePermission = await getRolePermissions(role, workspaceId); const rolePermission = await getWorkspaceRolePermissions(role, workspaceId);
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission); const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({ if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
@@ -621,7 +621,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
message: `Machine identity with id ${machineId} does not exist in project with id ${workspaceId}` message: `Machine identity with id ${machineId} does not exist in project with id ${workspaceId}`
}); });
const machineIdentityRolePermission = await getRolePermissions( const machineIdentityRolePermission = await getWorkspaceRolePermissions(
machineMembership?.customRole?.slug ?? machineMembership.role, machineMembership?.customRole?.slug ?? machineMembership.role,
machineMembership.workspace.toString() machineMembership.workspace.toString()
); );
@@ -630,7 +630,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
message: "Failed to update role of more privileged MI" message: "Failed to update role of more privileged MI"
}); });
const rolePermission = await getRolePermissions(role, workspaceId); const rolePermission = await getWorkspaceRolePermissions(role, workspaceId);
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission); const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({ if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
@@ -705,7 +705,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
message: `Machine with id ${machineId} does not exist in project with id ${workspaceId}` message: `Machine with id ${machineId} does not exist in project with id ${workspaceId}`
}); });
const machineIdentityRolePermission = await getRolePermissions( const machineIdentityRolePermission = await getWorkspaceRolePermissions(
machineMembership?.customRole?.slug ?? machineMembership.role, machineMembership?.customRole?.slug ?? machineMembership.role,
machineMembership.workspace.toString() machineMembership.workspace.toString()
); );
+2
View File
@@ -1,3 +1,4 @@
import * as machineIdentitiesController from "./machineIdentitiesController";
import * as secretController from "./secretController"; import * as secretController from "./secretController";
import * as secretSnapshotController from "./secretSnapshotController"; import * as secretSnapshotController from "./secretSnapshotController";
import * as organizationsController from "./organizationsController"; import * as organizationsController from "./organizationsController";
@@ -13,6 +14,7 @@ import * as secretRotationProviderController from "./secretRotationProviderContr
import * as secretRotationController from "./secretRotationController"; import * as secretRotationController from "./secretRotationController";
export { export {
machineIdentitiesController,
secretController, secretController,
secretSnapshotController, secretSnapshotController,
organizationsController, organizationsController,
-2
View File
@@ -1,7 +1,5 @@
import * as machineIdentityController from "./machineIdentityController";
import * as apiKeyDataController from "./apiKeyDataController"; import * as apiKeyDataController from "./apiKeyDataController";
export { export {
machineIdentityController,
apiKeyDataController apiKeyDataController
} }
+2
View File
@@ -1,3 +1,4 @@
import machineIdentities from "./machineIdentities";
import secret from "./secret"; import secret from "./secret";
import secretSnapshot from "./secretSnapshot"; import secretSnapshot from "./secretSnapshot";
import organizations from "./organizations"; import organizations from "./organizations";
@@ -13,6 +14,7 @@ import secretRotationProvider from "./secretRotationProvider";
import secretRotation from "./secretRotation"; import secretRotation from "./secretRotation";
export { export {
machineIdentities,
secret, secret,
secretSnapshot, secretSnapshot,
organizations, organizations,
@@ -2,14 +2,14 @@ import express from "express";
const router = express.Router(); const router = express.Router();
import { requireAuth } from "../../../middleware"; import { requireAuth } from "../../../middleware";
import { AuthMode } from "../../../variables"; import { AuthMode } from "../../../variables";
import { machineIdentityController } from "../../controllers/v3"; import { machineIdentitiesController } from "../../controllers/v1";
router.get( router.get(
"/:machineId/client-secrets", "/:machineId/client-secrets",
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT] acceptedAuthModes: [AuthMode.JWT]
}), }),
machineIdentityController.getMIClientSecrets machineIdentitiesController.getMIClientSecrets
); );
router.post( router.post(
@@ -17,7 +17,7 @@ router.post(
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT] acceptedAuthModes: [AuthMode.JWT]
}), }),
machineIdentityController.createMIClientSecret machineIdentitiesController.createMIClientSecret
); );
router.delete( router.delete(
@@ -25,13 +25,12 @@ router.delete(
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT] acceptedAuthModes: [AuthMode.JWT]
}), }),
machineIdentityController.deleteMIClientSecret machineIdentitiesController.deleteMIClientSecret
); );
// consider moving to /auth/machine/login
router.post( router.post(
"/login", "/login",
machineIdentityController.loginMI machineIdentitiesController.loginMI
); );
router.post( router.post(
@@ -39,7 +38,7 @@ router.post(
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT, AuthMode.MACHINE_ACCESS_TOKEN] acceptedAuthModes: [AuthMode.JWT, AuthMode.MACHINE_ACCESS_TOKEN]
}), }),
machineIdentityController.createMachineIdentity machineIdentitiesController.createMachineIdentity
); );
router.patch( router.patch(
@@ -47,7 +46,7 @@ router.patch(
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT] acceptedAuthModes: [AuthMode.JWT]
}), }),
machineIdentityController.updateMachineIdentity machineIdentitiesController.updateMachineIdentity
); );
router.delete( router.delete(
@@ -55,7 +54,7 @@ router.delete(
requireAuth({ requireAuth({
acceptedAuthModes: [AuthMode.JWT] acceptedAuthModes: [AuthMode.JWT]
}), }),
machineIdentityController.deleteMachineIdentity machineIdentitiesController.deleteMachineIdentity
); );
export default router; export default router;
-2
View File
@@ -1,7 +1,5 @@
import machineIdentity from "./machineIdentity";
import apiKeyData from "./apiKeyData"; import apiKeyData from "./apiKeyData";
export { export {
machineIdentity,
apiKeyData apiKeyData
} }
@@ -362,7 +362,7 @@ export const getAuthDataProjectPermissions = async ({
} }
} }
export const getRolePermissions = async (role: string, workspaceId: string) => { export const getWorkspaceRolePermissions = async (role: string, workspaceId: string) => {
const isCustomRole = ![ADMIN, MEMBER, VIEWER, NO_ACCESS].includes(role); const isCustomRole = ![ADMIN, MEMBER, VIEWER, NO_ACCESS].includes(role);
if (isCustomRole) { if (isCustomRole) {
const workspaceRole = await Role.findOne({ const workspaceRole = await Role.findOne({
+3 -3
View File
@@ -25,6 +25,7 @@ import {
secretSnapshot as eeSecretSnapshotRouter, secretSnapshot as eeSecretSnapshotRouter,
users as eeUsersRouter, users as eeUsersRouter,
workspace as eeWorkspaceRouter, workspace as eeWorkspaceRouter,
machineIdentities as v1MachineIdentitiesRouter,
roles as v1RoleRouter, roles as v1RoleRouter,
secretApprovalPolicy as v1SecretApprovalPolicyRouter, secretApprovalPolicy as v1SecretApprovalPolicyRouter,
secretApprovalRequest as v1SecretApprovalRequestRouter, secretApprovalRequest as v1SecretApprovalRequestRouter,
@@ -33,7 +34,6 @@ import {
secretScanning as v1SecretScanningRouter secretScanning as v1SecretScanningRouter
} from "./ee/routes/v1"; } from "./ee/routes/v1";
import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3"; import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3";
import { machineIdentity as v3MachineIdentityRouter } from "./ee/routes/v3";
import { import {
admin as v1AdminRouter, admin as v1AdminRouter,
auth as v1AuthRouter, auth as v1AuthRouter,
@@ -198,6 +198,7 @@ const main = async () => {
} }
// (EE) routes // (EE) routes
app.use("/api/v1/machine-identities", v1MachineIdentitiesRouter);
app.use("/api/v1/secret", eeSecretRouter); app.use("/api/v1/secret", eeSecretRouter);
app.use("/api/v1/secret-snapshot", eeSecretSnapshotRouter); app.use("/api/v1/secret-snapshot", eeSecretSnapshotRouter);
app.use("/api/v1/users", eeUsersRouter); app.use("/api/v1/users", eeUsersRouter);
@@ -206,7 +207,6 @@ const main = async () => {
app.use("/api/v1/sso", eeSSORouter); app.use("/api/v1/sso", eeSSORouter);
app.use("/api/v1/cloud-products", eeCloudProductsRouter); app.use("/api/v1/cloud-products", eeCloudProductsRouter);
app.use("/api/v3/api-key", v3apiKeyDataRouter); app.use("/api/v3/api-key", v3apiKeyDataRouter);
app.use("/api/v3/machines", v3MachineIdentityRouter); // TODO: consider moving to v1
app.use("/api/v1/secret-rotation-providers", v1SecretRotationProviderRouter); app.use("/api/v1/secret-rotation-providers", v1SecretRotationProviderRouter);
app.use("/api/v1/secret-rotations", v1SecretRotation); app.use("/api/v1/secret-rotations", v1SecretRotation);
@@ -247,7 +247,7 @@ const main = async () => {
app.use("/api/v2/workspace", v2TagsRouter); app.use("/api/v2/workspace", v2TagsRouter);
app.use("/api/v2/workspace", v2WorkspaceRouter); app.use("/api/v2/workspace", v2WorkspaceRouter);
app.use("/api/v2/secret", v2SecretRouter); // deprecate app.use("/api/v2/secret", v2SecretRouter); // deprecate
app.use("/api/v2/secrets", v2SecretsRouter); // note: in the process of moving to v3/secrets app.use("/api/v2/secrets", v2SecretsRouter);
app.use("/api/v2/service-token", v2ServiceTokenDataRouter); app.use("/api/v2/service-token", v2ServiceTokenDataRouter);
// v3 routes (experimental) // v3 routes (experimental)
@@ -82,12 +82,12 @@ In the following steps, we explore how to create and use MIs for your applicatio
<Step title="Accessing the Infisical API with the MI"> <Step title="Accessing the Infisical API with the MI">
To access the Infisical API as the MI, you should first perform a login operation To access the Infisical API as the MI, you should first perform a login operation
that is to exchange the **Client ID** and **Client Secret** of the MI for an access token that is to exchange the **Client ID** and **Client Secret** of the MI for an access token
by making a request to the `/api/v3/machines/login` endpoint. by making a request to the `/api/v1/machine-identities/login` endpoint.
#### Sample request #### Sample request
``` ```
curl --location --request POST 'https://app.infisical.com/api/v3/machines/login' \ curl --location --request POST 'https://app.infisical.com/api/v1/machine-identities/login' \
--header 'Content-Type: application/x-www-form-urlencoded' \ --header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'clientSecret=...' \ --data-urlencode 'clientSecret=...' \
--data-urlencode 'clientId=...' --data-urlencode 'clientId=...'
@@ -18,7 +18,7 @@ export const useCreateMachineIdentity = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation<CreateMachineIdentityRes, {}, CreateMachineIdentityDTO>({ return useMutation<CreateMachineIdentityRes, {}, CreateMachineIdentityDTO>({
mutationFn: async (body) => { mutationFn: async (body) => {
const { data } = await apiRequest.post("/api/v3/machines/", body); const { data } = await apiRequest.post("/api/v1/machine-identities/", body);
return data; return data;
}, },
onSuccess: ({ machineIdentity }) => { onSuccess: ({ machineIdentity }) => {
@@ -37,7 +37,7 @@ export const useCreateMachineIdentityClientSecret = () => {
usageLimit usageLimit
}) => { }) => {
const { data } = await apiRequest.post(`/api/v3/machines/${machineId}/client-secrets`, { const { data } = await apiRequest.post(`/api/v1/machine-identities/${machineId}/client-secrets`, {
machineId, machineId,
description, description,
ttl, ttl,
@@ -62,7 +62,7 @@ export const useDeleteMachineIdentityClientSecret = () => {
machineId:string; machineId:string;
clientSecretId: string; clientSecretId: string;
}) => { }) => {
const { data } = await apiRequest.delete(`/api/v3/machines/${machineId}/client-secrets/${clientSecretId}`); const { data } = await apiRequest.delete(`/api/v1/machine-identities/${machineId}/client-secrets/${clientSecretId}`);
return data; return data;
}, },
onSuccess: (_, { machineId }) => { onSuccess: (_, { machineId }) => {
@@ -83,7 +83,7 @@ export const useUpdateMachineIdentity = () => {
accessTokenTTL accessTokenTTL
}) => { }) => {
const { data: { machineIdentity } } = await apiRequest.patch(`/api/v3/machines/${machineId}`, { const { data: { machineIdentity } } = await apiRequest.patch(`/api/v1/machine-identities/${machineId}`, {
name, name,
role, role,
clientSecretTrustedIps, clientSecretTrustedIps,
@@ -105,7 +105,7 @@ export const useDeleteMachineIdentity = () => {
mutationFn: async ({ mutationFn: async ({
machineId machineId
}) => { }) => {
const { data: { machineIdentity } } = await apiRequest.delete(`/api/v3/machines/${machineId}`); const { data: { machineIdentity } } = await apiRequest.delete(`/api/v1/machine-identities/${machineId}`);
return machineIdentity; return machineIdentity;
}, },
onSuccess: ({ organization }) => { onSuccess: ({ organization }) => {
@@ -14,8 +14,10 @@ export const useGetMachineIdentityClientSecrets = (machineId: string) => {
return useQuery({ return useQuery({
queryKey: machineIdentityKeys.getMachineIdentityClientSecrets(machineId), queryKey: machineIdentityKeys.getMachineIdentityClientSecrets(machineId),
queryFn: async () => { queryFn: async () => {
if (machineId === "") return [];
const { data: { clientSecretData } } = await apiRequest.get<{ clientSecretData: MachineIdentityClientSecret[] }>( const { data: { clientSecretData } } = await apiRequest.get<{ clientSecretData: MachineIdentityClientSecret[] }>(
`/api/v3/machines/${machineId}/client-secrets` `/api/v1/machine-identities/${machineId}/client-secrets`
); );
return clientSecretData; return clientSecretData;
@@ -20,7 +20,7 @@ export const MembersPage = withPermission(
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white"> <div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto"> <div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
<p className="mr-4 mb-4 text-3xl font-semibold text-white"> <p className="mr-4 mb-4 text-3xl font-semibold text-white">
Access Control Organization Access Control
</p> </p>
<Tabs defaultValue={TabSections.Member}> <Tabs defaultValue={TabSections.Member}>
<TabList> <TabList>
@@ -244,7 +244,7 @@ export const CreateClientSecretModal = ({
<div className="flex"> <div className="flex">
<Input <Input
{...field} {...field}
placeholder="7200" placeholder="0"
type="number" type="number"
min="0" min="0"
step="1" step="1"
@@ -25,7 +25,7 @@ export const MembersPage = withProjectPermission(
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white"> <div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto"> <div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
<p className="mr-4 mb-4 text-3xl font-semibold text-white"> <p className="mr-4 mb-4 text-3xl font-semibold text-white">
Access Control Project Access Control
</p> </p>
<Tabs defaultValue={TabSections.Member}> <Tabs defaultValue={TabSections.Member}>
<TabList> <TabList>