mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Replace most getUserOrgPermissions with more generic getAuthDataOrgPermissions for MIs in backend
This commit is contained in:
@@ -21,7 +21,7 @@ import { validateRequest } from "../../helpers/validation";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../ee/services/RoleService";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
@@ -44,11 +44,12 @@ export const deleteMembershipOrg = async (req: Request, _res: Response) => {
|
||||
if (!membershipOrgToDelete) {
|
||||
throw new Error("Failed to delete organization membership that doesn't exist");
|
||||
}
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: membershipOrgToDelete.organization
|
||||
});
|
||||
|
||||
const { permission, membership: membershipOrg } = await getUserOrgPermissions(
|
||||
req.user._id,
|
||||
membershipOrgToDelete.organization.toString()
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.Member
|
||||
@@ -60,7 +61,7 @@ export const deleteMembershipOrg = async (req: Request, _res: Response) => {
|
||||
});
|
||||
|
||||
await updateSubscriptionOrgQuantity({
|
||||
organizationId: membershipOrg.organization.toString()
|
||||
organizationId: membershipOrgToDelete.organization.toString()
|
||||
});
|
||||
|
||||
return membershipOrgToDelete;
|
||||
@@ -96,7 +97,11 @@ export const inviteUserToOrganization = async (req: Request, res: Response) => {
|
||||
body: { inviteeEmail, organizationId }
|
||||
} = await validateRequest(reqValidator.InviteUserToOrgv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Member
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Request, Response } from "express";
|
||||
import { Types } from "mongoose";
|
||||
import {
|
||||
IncidentContactOrg,
|
||||
Membership,
|
||||
@@ -14,7 +15,7 @@ import { ACCEPTED } from "../../variables";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../ee/services/RoleService";
|
||||
import { OrganizationNotFoundError } from "../../utils/errors";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
@@ -44,7 +45,10 @@ export const getOrganization = async (req: Request, res: Response) => {
|
||||
} = await validateRequest(reqValidator.GetOrgv1, req);
|
||||
|
||||
// ensure user has membership
|
||||
await getUserOrgPermissions(req.user._id, organizationId);
|
||||
await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
})
|
||||
|
||||
const organization = await Organization.findById(organizationId);
|
||||
if (!organization) {
|
||||
@@ -68,8 +72,12 @@ export const getOrganizationMembers = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgMembersv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Member
|
||||
@@ -95,7 +103,10 @@ export const getOrganizationWorkspaces = async (req: Request, res: Response) =>
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgWorkspacesv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
})
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Workspace
|
||||
@@ -137,7 +148,10 @@ export const changeOrganizationName = async (req: Request, res: Response) => {
|
||||
body: { name }
|
||||
} = await validateRequest(reqValidator.ChangeOrgNamev1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.Settings
|
||||
@@ -172,7 +186,10 @@ export const getOrganizationIncidentContacts = async (req: Request, res: Respons
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgIncidentContactv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.IncidentAccount
|
||||
@@ -199,7 +216,10 @@ export const addOrganizationIncidentContact = async (req: Request, res: Response
|
||||
body: { email }
|
||||
} = await validateRequest(reqValidator.CreateOrgIncideContact, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.IncidentAccount
|
||||
@@ -228,7 +248,10 @@ export const deleteOrganizationIncidentContact = async (req: Request, res: Respo
|
||||
body: { email }
|
||||
} = await validateRequest(reqValidator.DelOrgIncideContact, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.IncidentAccount
|
||||
@@ -257,7 +280,10 @@ export const createOrganizationPortalSession = async (req: Request, res: Respons
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPlanBillingInfov1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -321,7 +347,10 @@ export const getOrganizationMembersAndTheirWorkspaces = async (req: Request, res
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgMembersv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Member
|
||||
|
||||
@@ -21,7 +21,7 @@ import * as reqValidator from "../../validation/secretScanning";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../ee/services/RoleService";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
@@ -37,8 +37,11 @@ export const createInstallationSession = async (req: Request, res: Response) =>
|
||||
message: "Failed to find organization"
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.SecretScanning
|
||||
@@ -70,11 +73,12 @@ export const linkInstallationToOrganization = async (req: Request, res: Response
|
||||
if (!installationSession) {
|
||||
throw UnauthorizedRequestError();
|
||||
}
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: installationSession.organization
|
||||
});
|
||||
|
||||
const { permission } = await getUserOrgPermissions(
|
||||
req.user._id,
|
||||
installationSession.organization.toString()
|
||||
);
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.SecretScanning
|
||||
@@ -142,7 +146,10 @@ export const getRisksForOrganization = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgRisksv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.SecretScanning
|
||||
@@ -162,7 +169,10 @@ export const updateRisksStatus = async (req: Request, res: Response) => {
|
||||
body: { status }
|
||||
} = await validateRequest(reqValidator.UpdateRiskStatusv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.SecretScanning
|
||||
|
||||
@@ -17,7 +17,7 @@ import { OrganizationNotFoundError } from "../../utils/errors";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../ee/services/RoleService";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { validateRequest } from "../../helpers/validation";
|
||||
@@ -152,7 +152,10 @@ export const createWorkspace = async (req: Request, res: Response) => {
|
||||
});
|
||||
}
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Workspace
|
||||
|
||||
@@ -14,14 +14,14 @@ import {
|
||||
updateSubscriptionOrgQuantity
|
||||
} from "../../helpers/organization";
|
||||
import { addMembershipsOrg } from "../../helpers/membershipOrg";
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { BadRequestError, ResourceNotFoundError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { ACCEPTED, ADMIN, CUSTOM, MEMBER, NO_ACCESS } from "../../variables";
|
||||
import * as reqValidator from "../../validation/organization";
|
||||
import { validateRequest } from "../../helpers/validation";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../ee/services/RoleService";
|
||||
import { EELicenseService } from "../../ee/services";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
@@ -69,7 +69,10 @@ export const getOrganizationMemberships = async (req: Request, res: Response) =>
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgMembersv2, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Member
|
||||
@@ -147,7 +150,11 @@ export const updateOrganizationMembership = async (req: Request, res: Response)
|
||||
params: { organizationId, membershipId },
|
||||
body: { role }
|
||||
} = await validateRequest(reqValidator.UpdateOrgMemberv2, req);
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.Member
|
||||
@@ -245,7 +252,18 @@ export const deleteOrganizationMembership = async (req: Request, res: Response)
|
||||
const {
|
||||
params: { organizationId, membershipId }
|
||||
} = await validateRequest(reqValidator.DeleteOrgMemberv2, req);
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
_id: new Types.ObjectId(membershipId),
|
||||
organization: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
if (!membershipOrg) throw ResourceNotFoundError();
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: membershipOrg.organization
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.Member
|
||||
@@ -309,7 +327,11 @@ export const getOrganizationWorkspaces = async (req: Request, res: Response) =>
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgWorkspacesv2, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Workspace
|
||||
@@ -407,8 +429,10 @@ export const getOrganizationMachineMemberships = async (req: Request, res: Respo
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgServiceMembersV2, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.MachineIdentity
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as reqValidator from "../../../validation/organization";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions,
|
||||
} from "../../services/RoleService";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { Organization } from "../../../models";
|
||||
@@ -20,7 +20,10 @@ export const getOrganizationPlansTable = async (req: Request, res: Response) =>
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPlansTablev1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -42,7 +45,10 @@ export const getOrganizationPlan = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPlanv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -70,7 +76,10 @@ export const startOrganizationTrial = async (req: Request, res: Response) => {
|
||||
body: { success_url }
|
||||
} = await validateRequest(reqValidator.StartOrgTrailv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -116,7 +125,10 @@ export const getOrganizationPlanBillingInfo = async (req: Request, res: Response
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPlanBillingInfov1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -149,7 +161,10 @@ export const getOrganizationPlanTable = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPlanTablev1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -176,7 +191,10 @@ export const getOrganizationBillingDetails = async (req: Request, res: Response)
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgBillingDetailsv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -204,7 +222,10 @@ export const updateOrganizationBillingDetails = async (req: Request, res: Respon
|
||||
body: { name, email }
|
||||
} = await validateRequest(reqValidator.UpdateOrgBillingDetailsv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -238,7 +259,10 @@ export const getOrganizationPmtMethods = async (req: Request, res: Response) =>
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgPmtMethodsv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -271,7 +295,10 @@ export const addOrganizationPmtMethod = async (req: Request, res: Response) => {
|
||||
body: { success_url, cancel_url }
|
||||
} = await validateRequest(reqValidator.CreateOrgPmtMethodv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -312,7 +339,10 @@ export const deleteOrganizationPmtMethod = async (req: Request, res: Response) =
|
||||
params: { organizationId, pmtMethodId }
|
||||
} = await validateRequest(reqValidator.DelOrgPmtMethodv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -342,7 +372,10 @@ export const getOrganizationTaxIds = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgTaxIdsv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -375,7 +408,10 @@ export const addOrganizationTaxId = async (req: Request, res: Response) => {
|
||||
body: { type, value }
|
||||
} = await validateRequest(reqValidator.CreateOrgTaxId, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -412,7 +448,10 @@ export const deleteOrganizationTaxId = async (req: Request, res: Response) => {
|
||||
params: { organizationId, taxId }
|
||||
} = await validateRequest(reqValidator.DelOrgTaxIdv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -445,7 +484,10 @@ export const getOrganizationInvoices = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgInvoicesv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
@@ -480,7 +522,10 @@ export const getOrganizationLicenses = async (req: Request, res: Response) => {
|
||||
params: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetOrgLicencesv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Billing
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
adminPermissions,
|
||||
getAuthDataOrgPermissions,
|
||||
getUserOrgPermissions,
|
||||
memberPermissions,
|
||||
noAccessPermissions
|
||||
@@ -38,7 +39,11 @@ export const createRole = async (req: Request, res: Response) => {
|
||||
|
||||
const isOrgRole = !workspaceId; // if workspaceid is provided then its a workspace rule
|
||||
if (isOrgRole) {
|
||||
const { permission } = await getUserOrgPermissions(req.user.id, orgId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(orgId)
|
||||
});
|
||||
|
||||
if (permission.cannot(OrgPermissionActions.Create, OrgPermissionSubjects.Role)) {
|
||||
throw BadRequestError({ message: "user doesn't have the permission." });
|
||||
}
|
||||
@@ -84,7 +89,10 @@ export const updateRole = async (req: Request, res: Response) => {
|
||||
const isOrgRole = !workspaceId; // if workspaceid is provided then its a workspace rule
|
||||
|
||||
if (isOrgRole) {
|
||||
const { permission } = await getUserOrgPermissions(req.user.id, orgId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(orgId)
|
||||
});
|
||||
if (permission.cannot(OrgPermissionActions.Edit, OrgPermissionSubjects.Role)) {
|
||||
throw BadRequestError({ message: "User doesn't have the org permission." });
|
||||
}
|
||||
@@ -140,7 +148,10 @@ export const deleteRole = async (req: Request, res: Response) => {
|
||||
|
||||
const isOrgRole = !role.workspace;
|
||||
if (isOrgRole) {
|
||||
const { permission } = await getUserOrgPermissions(req.user.id, role.organization.toString());
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: role.organization
|
||||
});
|
||||
if (permission.cannot(OrgPermissionActions.Delete, OrgPermissionSubjects.Role)) {
|
||||
throw BadRequestError({ message: "User doesn't have the org permission." });
|
||||
}
|
||||
@@ -172,7 +183,10 @@ export const getRoles = async (req: Request, res: Response) => {
|
||||
|
||||
const isOrgRole = !workspaceId;
|
||||
if (isOrgRole) {
|
||||
const { permission } = await getUserOrgPermissions(req.user.id, orgId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(orgId)
|
||||
});
|
||||
if (permission.cannot(OrgPermissionActions.Read, OrgPermissionSubjects.Role)) {
|
||||
throw BadRequestError({ message: "User doesn't have the org permission." });
|
||||
}
|
||||
@@ -238,7 +252,7 @@ export const getUserPermissions = async (req: Request, res: Response) => {
|
||||
const {
|
||||
params: { orgId }
|
||||
} = await validateRequest(GetUserPermission, req);
|
||||
|
||||
|
||||
const { permission, membership } = await getUserOrgPermissions(req.user._id, orgId);
|
||||
|
||||
res.status(200).json({
|
||||
|
||||
@@ -13,7 +13,7 @@ import { validateRequest } from "../../../helpers/validation";
|
||||
import {
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects,
|
||||
getUserOrgPermissions
|
||||
getAuthDataOrgPermissions
|
||||
} from "../../services/RoleService";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
@@ -47,7 +47,10 @@ export const getSSOConfig = async (req: Request, res: Response) => {
|
||||
query: { organizationId }
|
||||
} = await validateRequest(reqValidator.GetSsoConfigv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.Sso
|
||||
@@ -71,7 +74,10 @@ export const updateSSOConfig = async (req: Request, res: Response) => {
|
||||
body: { organizationId, authProvider, isActive, entryPoint, issuer, cert }
|
||||
} = await validateRequest(reqValidator.UpdateSsoConfigv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.Sso
|
||||
@@ -206,7 +212,10 @@ export const createSSOConfig = async (req: Request, res: Response) => {
|
||||
body: { organizationId, authProvider, isActive, entryPoint, issuer, cert }
|
||||
} = await validateRequest(reqValidator.CreateSsoConfigv1, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
OrgPermissionSubjects.Sso
|
||||
|
||||
@@ -22,8 +22,8 @@ import { validateRequest } from "../../../helpers/validation";
|
||||
import * as reqValidator from "../../../validation/machineIdentity";
|
||||
import { createToken } from "../../../helpers/auth";
|
||||
import {
|
||||
getOrgRolePermissions,
|
||||
getUserOrgPermissions,
|
||||
getAuthDataOrgPermissions,
|
||||
getOrgRolePermissions,
|
||||
isAtLeastAsPrivilegedOrg
|
||||
} from "../../services/RoleService";
|
||||
import {
|
||||
@@ -76,8 +76,10 @@ export const getMIClientSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
if (!machineMembershipOrg) throw ResourceNotFoundError();
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, machineMembershipOrg.organization.toString());
|
||||
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: machineMembershipOrg.organization
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Read,
|
||||
OrgPermissionSubjects.MachineIdentity
|
||||
@@ -146,7 +148,10 @@ export const createMIClientSecret = async (req: Request, res: Response) => {
|
||||
|
||||
if (!machineMembershipOrg) throw ResourceNotFoundError();
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, machineMembershipOrg.organization.toString());
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: machineMembershipOrg.organization
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
@@ -225,7 +230,10 @@ export const deleteMIClientSecret = async (req: Request, res: Response) => {
|
||||
message: `Failed to find machine identity with id ${machineId}`
|
||||
});
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, machineMembershipOrg.organization.toString());
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: machineMembershipOrg.organization
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
@@ -434,7 +442,10 @@ export const createMachineIdentity = async (req: Request, res: Response) => {
|
||||
}
|
||||
} = await validateRequest(reqValidator.CreateMachineIdentityV3, req);
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, organizationId);
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: new Types.ObjectId(organizationId)
|
||||
});
|
||||
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Create,
|
||||
@@ -567,7 +578,10 @@ export const updateMachineIdentity = async (req: Request, res: Response) => {
|
||||
message: `Failed to find machine identity with id ${machineId}`
|
||||
});
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, machineMembershipOrg.organization.toString());
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: machineMembershipOrg.organization
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Edit,
|
||||
OrgPermissionSubjects.MachineIdentity
|
||||
@@ -725,7 +739,10 @@ export const deleteMachineIdentity = async (req: Request, res: Response) => {
|
||||
message: `Failed to find machine identity with id ${machineId}`
|
||||
});
|
||||
|
||||
const { permission } = await getUserOrgPermissions(req.user._id, machineMembershipOrg.organization.toString());
|
||||
const { permission } = await getAuthDataOrgPermissions({
|
||||
authData: req.authData,
|
||||
organizationId: machineMembershipOrg.organization
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
OrgPermissionActions.Delete,
|
||||
OrgPermissionSubjects.MachineIdentity
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export enum ActorType {
|
||||
export enum ActorType { // would extend to AWS, Azure, ...
|
||||
USER = "user",
|
||||
SERVICE = "service",
|
||||
MACHINE = "machine"
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { Types } from "mongoose";
|
||||
import { AbilityBuilder, MongoAbility, RawRuleOf, createMongoAbility } from "@casl/ability";
|
||||
import { MembershipOrg } from "../../models";
|
||||
import { IRole, Role } from "../models";
|
||||
import {
|
||||
IMachineIdentity,
|
||||
MachineMembershipOrg,
|
||||
MembershipOrg
|
||||
} from "../../models";
|
||||
import { ActorType, IRole, Role } from "../models";
|
||||
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
|
||||
import { checkIPAgainstBlocklist } from "../../utils/ip";
|
||||
import { ACCEPTED, ADMIN, CUSTOM, MEMBER, NO_ACCESS} from "../../variables";
|
||||
import { conditionsMatcher } from "./ProjectRoleService";
|
||||
import { AuthData } from "../../interfaces/middleware";
|
||||
|
||||
export enum OrgPermissionActions {
|
||||
Read = "read",
|
||||
@@ -156,6 +162,94 @@ export const getUserOrgPermissions = async (userId: string, orgId: string) => {
|
||||
throw BadRequestError({ message: "User role not found" });
|
||||
};
|
||||
|
||||
/**
|
||||
* Return permissions for user/service pertaining to organization with id [organizationId]
|
||||
*
|
||||
* Note: should not rely on this function for ST V2 authorization logic
|
||||
* b/c ST V2 does not support role-based access control but also not organization-level resources
|
||||
*/
|
||||
export const getAuthDataOrgPermissions = async ({
|
||||
authData,
|
||||
organizationId
|
||||
}: {
|
||||
authData: AuthData;
|
||||
organizationId: Types.ObjectId;
|
||||
}) => {
|
||||
let role: "admin" | "member" | "no-access" | "custom";
|
||||
let customRole;
|
||||
|
||||
switch (authData.actor.type) {
|
||||
case ActorType.USER: {
|
||||
const membershipOrg = await MembershipOrg.findOne({
|
||||
user: authData.authPayload._id,
|
||||
organization: organizationId,
|
||||
status: ACCEPTED
|
||||
})
|
||||
.populate<{ customRole: IRole & { permissions: RawRuleOf<MongoAbility<OrgPermissionSet>>[] } }>(
|
||||
"customRole"
|
||||
)
|
||||
.exec();
|
||||
|
||||
if (!membershipOrg || (membershipOrg.role === "custom" && !membershipOrg.customRole)) {
|
||||
throw UnauthorizedRequestError({ message: "User doesn't belong to organization" });
|
||||
}
|
||||
|
||||
role = membershipOrg.role;
|
||||
customRole = membershipOrg.customRole;
|
||||
break;
|
||||
}
|
||||
case ActorType.SERVICE: {
|
||||
throw UnauthorizedRequestError({
|
||||
message: "Failed to access organization-level resources with service token"
|
||||
});
|
||||
}
|
||||
case ActorType.MACHINE: {
|
||||
const machineMembershipOrg = await MachineMembershipOrg.findOne({
|
||||
machineIdentity: authData.authPayload._id,
|
||||
organization: organizationId
|
||||
})
|
||||
.populate<{
|
||||
customRole: IRole & { permissions: RawRuleOf<MongoAbility<OrgPermissionSet>>[] };
|
||||
machineIdentity: IMachineIdentity
|
||||
}>("customRole machineIdentity")
|
||||
.exec();
|
||||
|
||||
if (!machineMembershipOrg || (machineMembershipOrg.role === "custom" && !machineMembershipOrg.customRole)) {
|
||||
throw UnauthorizedRequestError();
|
||||
}
|
||||
|
||||
checkIPAgainstBlocklist({
|
||||
ipAddress: authData.ipAddress,
|
||||
trustedIps: machineMembershipOrg.machineIdentity.accessTokenTrustedIps
|
||||
});
|
||||
|
||||
role = machineMembershipOrg.role;
|
||||
customRole = machineMembershipOrg.customRole;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw UnauthorizedRequestError();
|
||||
}
|
||||
|
||||
switch (role) {
|
||||
case ADMIN:
|
||||
return { permission: adminPermissions };
|
||||
case MEMBER:
|
||||
return { permission: memberPermissions };
|
||||
case NO_ACCESS:
|
||||
return { permission: noAccessPermissions };
|
||||
case CUSTOM: {
|
||||
if (!customRole) throw UnauthorizedRequestError();
|
||||
return {
|
||||
permission: createMongoAbility<OrgPermissionSet>(
|
||||
customRole.permissions,
|
||||
{ conditionsMatcher }
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getOrgRolePermissions = async (role: string, orgId: string) => {
|
||||
const isCustomRole = ![ADMIN, MEMBER, NO_ACCESS].includes(role);
|
||||
if (isCustomRole) {
|
||||
|
||||
@@ -5,7 +5,7 @@ export interface IMachineMembershipOrg {
|
||||
_id: Types.ObjectId;
|
||||
machineIdentity: Types.ObjectId;
|
||||
organization: Types.ObjectId;
|
||||
role: "admin" | "member" | "viewer" | "no-access" | "custom";
|
||||
role: "admin" | "member" | "no-access" | "custom";
|
||||
customRole: Types.ObjectId;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ export interface IMembershipOrg extends Document {
|
||||
user: Types.ObjectId;
|
||||
inviteEmail: string;
|
||||
organization: Types.ObjectId;
|
||||
role: "owner" | "admin" | "member" | "no-access" | "custom";
|
||||
role: "admin" | "member" | "no-access" | "custom";
|
||||
customRole: Types.ObjectId;
|
||||
status: "invited" | "accepted";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user