fix expired client secret logic

This commit is contained in:
Maidul Islam
2023-12-05 16:38:43 -05:00
parent ea1f144b54
commit 9d9b83f909

View File

@@ -21,16 +21,16 @@ import {
import { validateRequest } from "../../../helpers/validation"; import { validateRequest } from "../../../helpers/validation";
import * as reqValidator from "../../../validation/machineIdentity"; import * as reqValidator from "../../../validation/machineIdentity";
import { createToken } from "../../../helpers/auth"; import { createToken } from "../../../helpers/auth";
import { import {
getAuthDataOrgPermissions, getAuthDataOrgPermissions,
getOrgRolePermissions, getOrgRolePermissions,
isAtLeastAsPrivilegedOrg isAtLeastAsPrivilegedOrg
} from "../../services/RoleService"; } from "../../services/RoleService";
import { import {
BadRequestError, BadRequestError,
ForbiddenRequestError, ForbiddenRequestError,
ResourceNotFoundError, ResourceNotFoundError,
UnauthorizedRequestError UnauthorizedRequestError
} from "../../../utils/errors"; } from "../../../utils/errors";
import { extractIPDetails, isValidIpOrCidr } from "../../../utils/ip"; import { extractIPDetails, isValidIpOrCidr } from "../../../utils/ip";
import { EEAuditLogService, EELicenseService } from "../../services"; import { EEAuditLogService, EELicenseService } from "../../services";
@@ -69,11 +69,11 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
const machineMembershipOrg = await MachineMembershipOrg.findOne({ const machineMembershipOrg = await MachineMembershipOrg.findOne({
machineIdentity: new Types.ObjectId(machineId) machineIdentity: new Types.ObjectId(machineId)
}).populate<{ }).populate<{
machineIdentity: IMachineIdentity, machineIdentity: IMachineIdentity,
customRole: IRole customRole: IRole
}>("machineIdentity customRole"); }>("machineIdentity customRole");
if (!machineMembershipOrg) throw ResourceNotFoundError(); if (!machineMembershipOrg) throw ResourceNotFoundError();
const { permission } = await getAuthDataOrgPermissions({ const { permission } = await getAuthDataOrgPermissions({
@@ -86,11 +86,11 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
); );
const rolePermission = await getOrgRolePermissions( const rolePermission = await getOrgRolePermissions(
machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role, machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role,
machineMembershipOrg.organization.toString() machineMembershipOrg.organization.toString()
); );
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to get client secrets for more privileged MI" message: "Failed to get client secrets for more privileged MI"
}); });
@@ -102,7 +102,7 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
}) })
.sort({ createdAt: -1 }) .sort({ createdAt: -1 })
.limit(5); .limit(5);
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
{ {
@@ -138,39 +138,39 @@ export const createMIClientSecret = async (req: Request, res: Response) => {
numUsesLimit numUsesLimit
} }
} = await validateRequest(reqValidator.CreateClientSecretV3, req); } = await validateRequest(reqValidator.CreateClientSecretV3, req);
const machineMembershipOrg = await MachineMembershipOrg.findOne({ const machineMembershipOrg = await MachineMembershipOrg.findOne({
machineIdentity: new Types.ObjectId(machineId) machineIdentity: new Types.ObjectId(machineId)
}).populate<{ }).populate<{
machineIdentity: IMachineIdentity, machineIdentity: IMachineIdentity,
customRole: IRole customRole: IRole
}>("machineIdentity customRole"); }>("machineIdentity customRole");
if (!machineMembershipOrg) throw ResourceNotFoundError(); if (!machineMembershipOrg) throw ResourceNotFoundError();
const { permission } = await getAuthDataOrgPermissions({ const { permission } = await getAuthDataOrgPermissions({
authData: req.authData, authData: req.authData,
organizationId: machineMembershipOrg.organization organizationId: machineMembershipOrg.organization
}); });
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
OrgPermissionActions.Create, OrgPermissionActions.Create,
OrgPermissionSubjects.MachineIdentity OrgPermissionSubjects.MachineIdentity
); );
const rolePermission = await getOrgRolePermissions( const rolePermission = await getOrgRolePermissions(
machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role, machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role,
machineMembershipOrg.organization.toString() machineMembershipOrg.organization.toString()
); );
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to create client secret for more privileged MI" message: "Failed to create client secret for more privileged MI"
}); });
const clientSecret = crypto.randomBytes(32).toString("hex"); const clientSecret = crypto.randomBytes(32).toString("hex");
const clientSecretHash = await bcrypt.hash(clientSecret, await getSaltRounds()); const clientSecretHash = await bcrypt.hash(clientSecret, await getSaltRounds());
const machineIdentityClientSecret = await new MachineIdentityClientSecret({ const machineIdentityClientSecret = await new MachineIdentityClientSecret({
machineIdentity: machineMembershipOrg.machineIdentity, machineIdentity: machineMembershipOrg.machineIdentity,
isActive: true, isActive: true,
@@ -197,7 +197,7 @@ export const createMIClientSecret = async (req: Request, res: Response) => {
organizationId: machineMembershipOrg.organization organizationId: machineMembershipOrg.organization
} }
); );
return res.status(200).send({ return res.status(200).send({
clientSecret, clientSecret,
clientSecretData: packageClientSecretData(machineIdentityClientSecret) clientSecretData: packageClientSecretData(machineIdentityClientSecret)
@@ -221,11 +221,11 @@ export const deleteMIClientSecret = async (req: Request, res: Response) => {
.findOne({ .findOne({
machineIdentity: new Types.ObjectId(machineId) machineIdentity: new Types.ObjectId(machineId)
}) })
.populate<{ .populate<{
machineIdentity: IMachineIdentity, machineIdentity: IMachineIdentity,
customRole: IRole customRole: IRole
}>("machineIdentity customRole"); }>("machineIdentity customRole");
if (!machineMembershipOrg) throw ResourceNotFoundError({ if (!machineMembershipOrg) throw ResourceNotFoundError({
message: `Failed to find machine identity with id ${machineId}` message: `Failed to find machine identity with id ${machineId}`
}); });
@@ -234,27 +234,27 @@ export const deleteMIClientSecret = async (req: Request, res: Response) => {
authData: req.authData, authData: req.authData,
organizationId: machineMembershipOrg.organization organizationId: machineMembershipOrg.organization
}); });
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
OrgPermissionActions.Delete, OrgPermissionActions.Delete,
OrgPermissionSubjects.MachineIdentity OrgPermissionSubjects.MachineIdentity
); );
const rolePermission = await getOrgRolePermissions( const rolePermission = await getOrgRolePermissions(
machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role, machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role,
machineMembershipOrg.organization.toString() machineMembershipOrg.organization.toString()
); );
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to delete client secrets for more privileged MI" message: "Failed to delete client secrets for more privileged MI"
}); });
const machineIdentityClientSecret = await MachineIdentityClientSecret.findOneAndDelete({ const machineIdentityClientSecret = await MachineIdentityClientSecret.findOneAndDelete({
_id: clientSecretId, _id: clientSecretId,
machineIdentity: machineId machineIdentity: machineId
}); });
if (!machineIdentityClientSecret) throw ResourceNotFoundError(); if (!machineIdentityClientSecret) throw ResourceNotFoundError();
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
@@ -290,14 +290,14 @@ export const loginMI = async (req: Request, res: Response) => {
clientSecret clientSecret
} }
} = await validateRequest(reqValidator.LoginMachineIdentityV3, req); } = await validateRequest(reqValidator.LoginMachineIdentityV3, req);
const machineIdentity = await MachineIdentity.findOne({ const machineIdentity = await MachineIdentity.findOne({
clientId, clientId,
isActive: true isActive: true
}); });
if (!machineIdentity) throw UnauthorizedRequestError(); if (!machineIdentity) throw UnauthorizedRequestError();
checkIPAgainstBlocklist({ checkIPAgainstBlocklist({
ipAddress: req.realIP, ipAddress: req.realIP,
trustedIps: machineIdentity.clientSecretTrustedIps trustedIps: machineIdentity.clientSecretTrustedIps
@@ -307,12 +307,12 @@ export const loginMI = async (req: Request, res: Response) => {
machineIdentity: machineIdentity._id, machineIdentity: machineIdentity._id,
isActive: true isActive: true
}); });
let validatedClientSecretDatum: IMachineIdentityClientSecret | undefined; let validatedClientSecretDatum: IMachineIdentityClientSecret | undefined;
for (const clientSecretDatum of clientSecretData) { for (const clientSecretDatum of clientSecretData) {
const isSecretValid = await bcrypt.compare( const isSecretValid = await bcrypt.compare(
clientSecret, clientSecret,
clientSecretDatum.clientSecretHash clientSecretDatum.clientSecretHash
); );
@@ -321,9 +321,9 @@ export const loginMI = async (req: Request, res: Response) => {
break; break;
} }
} }
if (!validatedClientSecretDatum) throw UnauthorizedRequestError(); if (!validatedClientSecretDatum) throw UnauthorizedRequestError();
const { const {
clientSecretTTL, clientSecretTTL,
clientSecretNumUses, clientSecretNumUses,
@@ -331,22 +331,25 @@ export const loginMI = async (req: Request, res: Response) => {
} = validatedClientSecretDatum; } = validatedClientSecretDatum;
if (clientSecretTTL > 0) { if (clientSecretTTL > 0) {
const expiresAt = new Date(new Date().getTime() + clientSecretTTL * 1000); const clientSecretCreated = new Date(validatedClientSecretDatum.createdAt)
const ttlInMilliseconds = clientSecretTTL * 1000;
if (expiresAt < new Date()) { const currentDate = new Date();
const expirationTime = new Date(clientSecretCreated.getTime() + ttlInMilliseconds);
if (currentDate > expirationTime) {
await MachineIdentityClientSecret.findByIdAndUpdate( await MachineIdentityClientSecret.findByIdAndUpdate(
validatedClientSecretDatum._id, validatedClientSecretDatum._id,
{ {
isActive: false isActive: false
} }
); );
throw UnauthorizedRequestError({ throw UnauthorizedRequestError({
message: "Failed to authenticate MI credentials due to expired client secret" message: "Failed to authenticate MI credentials due to expired client secret"
}); });
} }
} }
if (clientSecretNumUses > 0 && clientSecretNumUses === clientSecretNumUsesLimit) { if (clientSecretNumUses > 0 && clientSecretNumUses === clientSecretNumUsesLimit) {
// number of times client secret can be used for // number of times client secret can be used for
// a login operation reached // a login operation reached
@@ -432,9 +435,9 @@ export const loginMI = async (req: Request, res: Response) => {
*/ */
export const createMachineIdentity = async (req: Request, res: Response) => { export const createMachineIdentity = async (req: Request, res: Response) => {
const { const {
body: { body: {
name, name,
organizationId, organizationId,
role, role,
clientSecretTrustedIps, clientSecretTrustedIps,
accessTokenTrustedIps, accessTokenTrustedIps,
@@ -446,7 +449,7 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
authData: req.authData, authData: req.authData,
organizationId: new Types.ObjectId(organizationId) organizationId: new Types.ObjectId(organizationId)
}); });
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
OrgPermissionActions.Create, OrgPermissionActions.Create,
OrgPermissionSubjects.MachineIdentity OrgPermissionSubjects.MachineIdentity
@@ -454,7 +457,7 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
const rolePermission = await getOrgRolePermissions(role, organizationId); const rolePermission = await getOrgRolePermissions(role, organizationId);
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to create a more privileged MI" message: "Failed to create a more privileged MI"
}); });
@@ -463,7 +466,7 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
if (!organization) throw BadRequestError({ message: `Organization with id ${organizationId} not found` }); if (!organization) throw BadRequestError({ message: `Organization with id ${organizationId} not found` });
const isCustomRole = ![ADMIN, MEMBER, NO_ACCESS].includes(role); const isCustomRole = ![ADMIN, MEMBER, NO_ACCESS].includes(role);
let customRole; let customRole;
if (isCustomRole) { if (isCustomRole) {
customRole = await Role.findOne({ customRole = await Role.findOne({
@@ -471,12 +474,12 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
isOrgRole: true, isOrgRole: true,
organization: new Types.ObjectId(organizationId) organization: new Types.ObjectId(organizationId)
}); });
if (!customRole) throw BadRequestError({ message: "Role not found" }); if (!customRole) throw BadRequestError({ message: "Role not found" });
} }
const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId)); const plan = await EELicenseService.getPlan(new Types.ObjectId(organizationId));
// validate trusted ips // validate trusted ips
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => { const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map((clientSecretTrustedIp) => {
if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({ if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0") return res.status(400).send({
@@ -484,11 +487,11 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
}); });
const isValidIPOrCidr = isValidIpOrCidr(clientSecretTrustedIp.ipAddress); const isValidIPOrCidr = isValidIpOrCidr(clientSecretTrustedIp.ipAddress);
if (!isValidIPOrCidr) return res.status(400).send({ if (!isValidIPOrCidr) return res.status(400).send({
message: "The IP is not a valid IPv4, IPv6, or CIDR block" message: "The IP is not a valid IPv4, IPv6, or CIDR block"
}); });
return extractIPDetails(clientSecretTrustedIp.ipAddress); return extractIPDetails(clientSecretTrustedIp.ipAddress);
}); });
@@ -498,14 +501,14 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
}); });
const isValidIPOrCidr = isValidIpOrCidr(accessTokenTrustedIp.ipAddress); const isValidIPOrCidr = isValidIpOrCidr(accessTokenTrustedIp.ipAddress);
if (!isValidIPOrCidr) return res.status(400).send({ if (!isValidIPOrCidr) return res.status(400).send({
message: "The IP is not a valid IPv4, IPv6, or CIDR block" message: "The IP is not a valid IPv4, IPv6, or CIDR block"
}); });
return extractIPDetails(accessTokenTrustedIp.ipAddress); return extractIPDetails(accessTokenTrustedIp.ipAddress);
}); });
const isActive = true; const isActive = true;
const machineIdentity = await new MachineIdentity({ const machineIdentity = await new MachineIdentity({
clientId: crypto.randomUUID(), clientId: crypto.randomUUID(),
@@ -517,14 +520,14 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
clientSecretTrustedIps: reformattedClientSecretTrustedIps, clientSecretTrustedIps: reformattedClientSecretTrustedIps,
accessTokenTrustedIps: reformattedAccessTokenTrustedIps, accessTokenTrustedIps: reformattedAccessTokenTrustedIps,
}).save(); }).save();
await new MachineMembershipOrg({ await new MachineMembershipOrg({
machineIdentity: machineIdentity._id, machineIdentity: machineIdentity._id,
organization: machineIdentity.organization, organization: machineIdentity.organization,
role: isCustomRole ? CUSTOM : role, role: isCustomRole ? CUSTOM : role,
customRole customRole
}).save(); }).save();
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
{ {
@@ -541,7 +544,7 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
organizationId: new Types.ObjectId(organizationId) organizationId: new Types.ObjectId(organizationId)
} }
); );
return res.status(200).send({ return res.status(200).send({
machineIdentity machineIdentity
}); });
@@ -556,8 +559,8 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
export const updateMachineIdentity = async (req: Request, res: Response) => { export const updateMachineIdentity = async (req: Request, res: Response) => {
const { const {
params: { machineId }, params: { machineId },
body: { body: {
name, name,
role, role,
clientSecretTrustedIps, clientSecretTrustedIps,
accessTokenTrustedIps, accessTokenTrustedIps,
@@ -569,11 +572,11 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
.findOne({ .findOne({
machineIdentity: new Types.ObjectId(machineId) machineIdentity: new Types.ObjectId(machineId)
}) })
.populate<{ .populate<{
machineIdentity: IMachineIdentity, machineIdentity: IMachineIdentity,
customRole: IRole customRole: IRole
}>("machineIdentity customRole"); }>("machineIdentity customRole");
if (!machineMembershipOrg) throw ResourceNotFoundError({ if (!machineMembershipOrg) throw ResourceNotFoundError({
message: `Failed to find machine identity with id ${machineId}` message: `Failed to find machine identity with id ${machineId}`
}); });
@@ -588,18 +591,18 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
); );
const machineIdentityRolePermission = await getOrgRolePermissions( const machineIdentityRolePermission = await getOrgRolePermissions(
machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role, machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role,
machineMembershipOrg.organization.toString() machineMembershipOrg.organization.toString()
); );
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, machineIdentityRolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, machineIdentityRolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to update more privileged MI" message: "Failed to update more privileged MI"
}); });
if (role) { if (role) {
const rolePermission = await getOrgRolePermissions(role, machineMembershipOrg.organization.toString()); const rolePermission = await getOrgRolePermissions(role, machineMembershipOrg.organization.toString());
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, rolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to update MI to a more privileged role" message: "Failed to update MI to a more privileged role"
}); });
@@ -614,7 +617,7 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
isOrgRole: true, isOrgRole: true,
organization: machineMembershipOrg.organization organization: machineMembershipOrg.organization
}); });
if (!customRole) throw BadRequestError({ message: "Role not found" }); if (!customRole) throw BadRequestError({ message: "Role not found" });
} }
} }
@@ -630,11 +633,11 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
}); });
const isValidIPOrCidr = isValidIpOrCidr(clientSecretTrustedIp.ipAddress); const isValidIPOrCidr = isValidIpOrCidr(clientSecretTrustedIp.ipAddress);
if (!isValidIPOrCidr) return res.status(400).send({ if (!isValidIPOrCidr) return res.status(400).send({
message: "The IP is not a valid IPv4, IPv6, or CIDR block" message: "The IP is not a valid IPv4, IPv6, or CIDR block"
}); });
return extractIPDetails(clientSecretTrustedIp.ipAddress); return extractIPDetails(clientSecretTrustedIp.ipAddress);
}); });
} }
@@ -648,15 +651,15 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
}); });
const isValidIPOrCidr = isValidIpOrCidr(accessTokenTrustedIp.ipAddress); const isValidIPOrCidr = isValidIpOrCidr(accessTokenTrustedIp.ipAddress);
if (!isValidIPOrCidr) return res.status(400).send({ if (!isValidIPOrCidr) return res.status(400).send({
message: "The IP is not a valid IPv4, IPv6, or CIDR block" message: "The IP is not a valid IPv4, IPv6, or CIDR block"
}); });
return extractIPDetails(accessTokenTrustedIp.ipAddress); return extractIPDetails(accessTokenTrustedIp.ipAddress);
}); });
} }
const machineIdentity = await MachineIdentity.findByIdAndUpdate( const machineIdentity = await MachineIdentity.findByIdAndUpdate(
machineId, machineId,
{ {
@@ -673,7 +676,7 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
if (!machineIdentity) throw BadRequestError({ if (!machineIdentity) throw BadRequestError({
message: `Failed to update machine identity with id ${machineId}` message: `Failed to update machine identity with id ${machineId}`
}); });
await MachineMembershipOrg.findOneAndUpdate( await MachineMembershipOrg.findOneAndUpdate(
{ {
machineIdentity: machineIdentity._id machineIdentity: machineIdentity._id
@@ -681,7 +684,7 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
{ {
role: customRole ? CUSTOM : role, role: customRole ? CUSTOM : role,
...(customRole ? { ...(customRole ? {
customRole customRole
} : {}), } : {}),
...(role && !customRole ? { // non-custom role ...(role && !customRole ? { // non-custom role
$unset: { $unset: {
@@ -712,7 +715,7 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
return res.status(200).send({ return res.status(200).send({
machineIdentity machineIdentity
}); });
} }
/** /**
@@ -725,20 +728,20 @@ export const deleteMachineIdentity = async (req: Request, res: Response) => {
const { const {
params: { machineId } params: { machineId }
} = await validateRequest(reqValidator.DeleteMachineIdentityV3, req); } = await validateRequest(reqValidator.DeleteMachineIdentityV3, req);
const machineMembershipOrg = await MachineMembershipOrg const machineMembershipOrg = await MachineMembershipOrg
.findOne({ .findOne({
machineIdentity: new Types.ObjectId(machineId) machineIdentity: new Types.ObjectId(machineId)
}) })
.populate<{ .populate<{
machineIdentity: IMachineIdentity, machineIdentity: IMachineIdentity,
customRole: IRole customRole: IRole
}>("machineIdentity customRole"); }>("machineIdentity customRole");
if (!machineMembershipOrg) throw ResourceNotFoundError({ if (!machineMembershipOrg) throw ResourceNotFoundError({
message: `Failed to find machine identity with id ${machineId}` message: `Failed to find machine identity with id ${machineId}`
}); });
const { permission } = await getAuthDataOrgPermissions({ const { permission } = await getAuthDataOrgPermissions({
authData: req.authData, authData: req.authData,
organizationId: machineMembershipOrg.organization organizationId: machineMembershipOrg.organization
@@ -749,33 +752,33 @@ export const deleteMachineIdentity = async (req: Request, res: Response) => {
); );
const machineIdentityRolePermission = await getOrgRolePermissions( const machineIdentityRolePermission = await getOrgRolePermissions(
machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role, machineMembershipOrg?.customRole?.slug ?? machineMembershipOrg.role,
machineMembershipOrg.organization.toString() machineMembershipOrg.organization.toString()
); );
const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, machineIdentityRolePermission); const hasRequiredPrivileges = isAtLeastAsPrivilegedOrg(permission, machineIdentityRolePermission);
if (!hasRequiredPrivileges) throw ForbiddenRequestError({ if (!hasRequiredPrivileges) throw ForbiddenRequestError({
message: "Failed to delete more privileged MI" message: "Failed to delete more privileged MI"
}); });
const machineIdentity = await MachineIdentity.findByIdAndDelete(machineMembershipOrg.machineIdentity); const machineIdentity = await MachineIdentity.findByIdAndDelete(machineMembershipOrg.machineIdentity);
if (!machineIdentity) throw ResourceNotFoundError({ if (!machineIdentity) throw ResourceNotFoundError({
message: `Machine identity with id ${machineId} not found` message: `Machine identity with id ${machineId} not found`
}); });
await MachineMembershipOrg.findByIdAndDelete(machineMembershipOrg._id); await MachineMembershipOrg.findByIdAndDelete(machineMembershipOrg._id);
if (!machineMembershipOrg) throw BadRequestError({ if (!machineMembershipOrg) throw BadRequestError({
message: `Failed to delete machine identity with id ${machineId}` message: `Failed to delete machine identity with id ${machineId}`
}); });
await MachineMembership.deleteMany({ await MachineMembership.deleteMany({
machineIdentity: machineMembershipOrg.machineIdentity machineIdentity: machineMembershipOrg.machineIdentity
}); });
await MachineIdentityClientSecret.deleteMany({ await MachineIdentityClientSecret.deleteMany({
machineIdentity: machineMembershipOrg.machineIdentity machineIdentity: machineMembershipOrg.machineIdentity
}); });
await EEAuditLogService.createAuditLog( await EEAuditLogService.createAuditLog(
req.authData, req.authData,
{ {
@@ -795,5 +798,5 @@ export const deleteMachineIdentity = async (req: Request, res: Response) => {
return res.status(200).send({ return res.status(200).send({
machineIdentity machineIdentity
}); });
} }