From 560274bde80b16d6ffca1203c14bda20fc8b3c6d Mon Sep 17 00:00:00 2001 From: Daniel Hougaard <62331820+DanielHougaard@users.noreply.github.com> Date: Tue, 12 Mar 2024 14:20:04 +0100 Subject: [PATCH] Feat: Scoped JWT to organization, Add authMethod to services --- .../services/audit-log/audit-log-service.ts | 9 ++- .../ee/services/license/license-service.ts | 81 ++++++++++++------- .../saml-config/saml-config-service.ts | 7 +- backend/src/ee/services/scim/scim-service.ts | 26 ++++-- .../secret-approval-policy-service.ts | 45 +++++++++-- .../secret-approval-request-service.ts | 48 +++++++++-- .../secret-rotation-service.ts | 55 ++++++++++--- .../secret-scanning-service.ts | 45 ++++++++--- .../secret-snapshot-service.ts | 44 ++++++++-- .../services/trusted-ip/trusted-ip-service.ts | 45 +++++++++-- 10 files changed, 326 insertions(+), 79 deletions(-) diff --git a/backend/src/ee/services/audit-log/audit-log-service.ts b/backend/src/ee/services/audit-log/audit-log-service.ts index c4d4aabc0..1564c6dcb 100644 --- a/backend/src/ee/services/audit-log/audit-log-service.ts +++ b/backend/src/ee/services/audit-log/audit-log-service.ts @@ -31,10 +31,17 @@ export const auditLogServiceFactory = ({ actor, actorId, actorOrgId, + actorAuthMethod, projectId, auditLogActor }: TListProjectAuditLogDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.AuditLogs); const auditLogs = await auditLogDAL.find({ startDate, diff --git a/backend/src/ee/services/license/license-service.ts b/backend/src/ee/services/license/license-service.ts index a55f2edff..e81f6dc12 100644 --- a/backend/src/ee/services/license/license-service.ts +++ b/backend/src/ee/services/license/license-service.ts @@ -224,9 +224,10 @@ export const licenseServiceFactory = ({ actor, actorId, actorOrgId, + actorAuthMethod, billingCycle }: TOrgPlansTableDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const { data } = await licenseServerCloudApi.request.get( `/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}` @@ -234,15 +235,22 @@ export const licenseServiceFactory = ({ return data; }; - const getOrgPlan = async ({ orgId, actor, actorId, actorOrgId, projectId }: TOrgPlanDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgPlan = async ({ orgId, actor, actorId, actorOrgId, actorAuthMethod, projectId }: TOrgPlanDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const plan = await getPlan(orgId, projectId); return plan; }; - const startOrgTrial = async ({ orgId, actorId, actor, actorOrgId, success_url }: TStartOrgTrialDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const startOrgTrial = async ({ + orgId, + actorId, + actor, + actorOrgId, + actorAuthMethod, + success_url + }: TStartOrgTrialDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); @@ -263,8 +271,14 @@ export const licenseServiceFactory = ({ return { url }; }; - const createOrganizationPortalSession = async ({ orgId, actorId, actor, actorOrgId }: TCreateOrgPortalSession) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const createOrganizationPortalSession = async ({ + orgId, + actorId, + actor, + actorAuthMethod, + actorOrgId + }: TCreateOrgPortalSession) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing); @@ -310,8 +324,8 @@ export const licenseServiceFactory = ({ return { url }; }; - const getOrgBillingInfo = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgBillingInfo = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -327,8 +341,8 @@ export const licenseServiceFactory = ({ }; // returns org current plan feature table - const getOrgPlanTable = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgPlanTable = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -343,8 +357,8 @@ export const licenseServiceFactory = ({ return data; }; - const getOrgBillingDetails = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgBillInfoDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgBillingDetails = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -364,11 +378,12 @@ export const licenseServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, orgId, name, email }: TUpdateOrgBillingDetailsDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -387,8 +402,8 @@ export const licenseServiceFactory = ({ return data; }; - const getOrgPmtMethods = async ({ orgId, actor, actorId, actorOrgId }: TOrgPmtMethodsDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgPmtMethods = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPmtMethodsDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -410,11 +425,12 @@ export const licenseServiceFactory = ({ orgId, actor, actorId, + actorAuthMethod, actorOrgId, success_url, cancel_url }: TAddOrgPmtMethodDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -435,8 +451,15 @@ export const licenseServiceFactory = ({ return { url }; }; - const delOrgPmtMethods = async ({ actorId, actor, actorOrgId, orgId, pmtMethodId }: TDelOrgPmtMethodDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const delOrgPmtMethods = async ({ + actorId, + actor, + actorAuthMethod, + actorOrgId, + orgId, + pmtMethodId + }: TDelOrgPmtMethodDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -452,8 +475,8 @@ export const licenseServiceFactory = ({ return data; }; - const getOrgTaxIds = async ({ orgId, actor, actorId, actorOrgId }: TGetOrgTaxIdDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgTaxIds = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgTaxIdDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -470,8 +493,8 @@ export const licenseServiceFactory = ({ return taxIds; }; - const addOrgTaxId = async ({ actorId, actor, actorOrgId, orgId, type, value }: TAddOrgTaxIdDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const addOrgTaxId = async ({ actorId, actor, actorAuthMethod, actorOrgId, orgId, type, value }: TAddOrgTaxIdDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -491,8 +514,8 @@ export const licenseServiceFactory = ({ return data; }; - const delOrgTaxId = async ({ orgId, actor, actorId, actorOrgId, taxId }: TDelOrgTaxIdDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const delOrgTaxId = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId, taxId }: TDelOrgTaxIdDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -508,8 +531,8 @@ export const licenseServiceFactory = ({ return data; }; - const getOrgTaxInvoices = async ({ actorId, actor, actorOrgId, orgId }: TOrgInvoiceDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgTaxInvoices = async ({ actorId, actor, actorOrgId, actorAuthMethod, orgId }: TOrgInvoiceDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); @@ -525,8 +548,8 @@ export const licenseServiceFactory = ({ return invoices; }; - const getOrgLicenses = async ({ orgId, actor, actorId, actorOrgId }: TOrgLicensesDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgLicenses = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgLicensesDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing); const organization = await orgDAL.findOrgById(orgId); diff --git a/backend/src/ee/services/saml-config/saml-config-service.ts b/backend/src/ee/services/saml-config/saml-config-service.ts index e9249d4aa..dc9728957 100644 --- a/backend/src/ee/services/saml-config/saml-config-service.ts +++ b/backend/src/ee/services/saml-config/saml-config-service.ts @@ -55,6 +55,7 @@ export const samlConfigServiceFactory = ({ const createSamlCfg = async ({ cert, actor, + actorAuthMethod, actorOrgId, orgId, issuer, @@ -63,7 +64,7 @@ export const samlConfigServiceFactory = ({ entryPoint, authProvider }: TCreateSamlCfgDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Sso); const plan = await licenseService.getPlan(orgId); @@ -146,6 +147,7 @@ export const samlConfigServiceFactory = ({ orgId, actor, actorOrgId, + actorAuthMethod, cert, actorId, issuer, @@ -153,7 +155,7 @@ export const samlConfigServiceFactory = ({ entryPoint, authProvider }: TUpdateSamlCfgDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Sso); const plan = await licenseService.getPlan(orgId); if (!plan.samlSSO) @@ -238,6 +240,7 @@ export const samlConfigServiceFactory = ({ dto.actor, dto.actorId, ssoConfig.orgId, + dto.actorAuthMethod, dto.actorOrgId ); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Sso); diff --git a/backend/src/ee/services/scim/scim-service.ts b/backend/src/ee/services/scim/scim-service.ts index 1ca881ed0..0f3a44c12 100644 --- a/backend/src/ee/services/scim/scim-service.ts +++ b/backend/src/ee/services/scim/scim-service.ts @@ -56,8 +56,16 @@ export const scimServiceFactory = ({ permissionService, smtpService }: TScimServiceFactoryDep) => { - const createScimToken = async ({ actor, actorId, actorOrgId, orgId, description, ttlDays }: TCreateScimTokenDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const createScimToken = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + orgId, + description, + ttlDays + }: TCreateScimTokenDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Scim); const plan = await licenseService.getPlan(orgId); @@ -85,8 +93,8 @@ export const scimServiceFactory = ({ return { scimToken }; }; - const listScimTokens = async ({ actor, actorId, actorOrgId, orgId }: TOrgPermission) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const listScimTokens = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TOrgPermission) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Scim); const plan = await licenseService.getPlan(orgId); @@ -99,11 +107,17 @@ export const scimServiceFactory = ({ return scimTokens; }; - const deleteScimToken = async ({ scimTokenId, actor, actorId, actorOrgId }: TDeleteScimTokenDTO) => { + const deleteScimToken = async ({ scimTokenId, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteScimTokenDTO) => { let scimToken = await scimDAL.findById(scimTokenId); if (!scimToken) throw new BadRequestError({ message: "Failed to find SCIM token to delete" }); - const { permission } = await permissionService.getOrgPermission(actor, actorId, scimToken.orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission( + actor, + actorId, + scimToken.orgId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Scim); const plan = await licenseService.getPlan(scimToken.orgId); diff --git a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts index 9d65ec7cc..8ddadb9bf 100644 --- a/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts +++ b/backend/src/ee/services/secret-approval-policy/secret-approval-policy-service.ts @@ -45,6 +45,7 @@ export const secretApprovalPolicyServiceFactory = ({ actor, actorId, actorOrgId, + actorAuthMethod, approvals, approvers, projectId, @@ -54,7 +55,13 @@ export const secretApprovalPolicyServiceFactory = ({ if (approvals > approvers.length) throw new BadRequestError({ message: "Approvals cannot be greater than approvers" }); - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, ProjectPermissionSub.SecretApproval @@ -98,6 +105,7 @@ export const secretApprovalPolicyServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, approvals, secretPolicyId }: TUpdateSapDTO) => { @@ -108,6 +116,7 @@ export const secretApprovalPolicyServiceFactory = ({ actor, actorId, secretApprovalPolicy.projectId, + actorAuthMethod, actorOrgId ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretApproval); @@ -152,7 +161,13 @@ export const secretApprovalPolicyServiceFactory = ({ }; }; - const deleteSecretApprovalPolicy = async ({ secretPolicyId, actor, actorId, actorOrgId }: TDeleteSapDTO) => { + const deleteSecretApprovalPolicy = async ({ + secretPolicyId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TDeleteSapDTO) => { const sapPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId); if (!sapPolicy) throw new BadRequestError({ message: "Secret approval policy not found" }); @@ -160,6 +175,7 @@ export const secretApprovalPolicyServiceFactory = ({ actor, actorId, sapPolicy.projectId, + actorAuthMethod, actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( @@ -171,8 +187,20 @@ export const secretApprovalPolicyServiceFactory = ({ return sapPolicy; }; - const getSecretApprovalPolicyByProjectId = async ({ actorId, actor, actorOrgId, projectId }: TListSapDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const getSecretApprovalPolicyByProjectId = async ({ + actorId, + actor, + actorOrgId, + actorAuthMethod, + projectId + }: TListSapDTO) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretApproval); const sapPolicies = await secretApprovalPolicyDAL.find({ projectId }); @@ -201,10 +229,17 @@ export const secretApprovalPolicyServiceFactory = ({ actor, actorId, actorOrgId, + actorAuthMethod, environment, secretPath }: TGetBoardSapDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Read, subject(ProjectPermissionSub.Secrets, { secretPath, environment }) diff --git a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts index b48b6bf95..b8ad89e45 100644 --- a/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts +++ b/backend/src/ee/services/secret-approval-request/secret-approval-request-service.ts @@ -82,13 +82,14 @@ export const secretApprovalRequestServiceFactory = ({ secretVersionDAL, secretQueueService }: TSecretApprovalRequestServiceFactoryDep) => { - const requestCount = async ({ projectId, actor, actorId, actorOrgId }: TApprovalRequestCountDTO) => { + const requestCount = async ({ projectId, actor, actorId, actorOrgId, actorAuthMethod }: TApprovalRequestCountDTO) => { if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); const { membership } = await permissionService.getProjectPermission( actor as ActorType.USER, actorId, projectId, + actorAuthMethod, actorOrgId ); @@ -100,6 +101,7 @@ export const secretApprovalRequestServiceFactory = ({ projectId, actorId, actor, + actorAuthMethod, actorOrgId, status, environment, @@ -109,7 +111,13 @@ export const secretApprovalRequestServiceFactory = ({ }: TListApprovalsDTO) => { if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); - const { membership } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { membership } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); const approvals = await secretApprovalRequestDAL.findByProjectId({ projectId, committer, @@ -122,7 +130,13 @@ export const secretApprovalRequestServiceFactory = ({ return approvals; }; - const getSecretApprovalDetails = async ({ actor, actorId, actorOrgId, id }: TSecretApprovalDetailsDTO) => { + const getSecretApprovalDetails = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + id + }: TSecretApprovalDetailsDTO) => { if (actor === ActorType.SERVICE) throw new BadRequestError({ message: "Cannot use service token" }); const secretApprovalRequest = await secretApprovalRequestDAL.findById(id); @@ -133,6 +147,7 @@ export const secretApprovalRequestServiceFactory = ({ actor, actorId, secretApprovalRequest.projectId, + actorAuthMethod, actorOrgId ); if ( @@ -150,7 +165,14 @@ export const secretApprovalRequestServiceFactory = ({ return { ...secretApprovalRequest, secretPath: secretPath?.[0]?.path || "/", commits: secrets }; }; - const reviewApproval = async ({ approvalId, actor, status, actorId, actorOrgId }: TReviewRequestDTO) => { + const reviewApproval = async ({ + approvalId, + actor, + status, + actorId, + actorAuthMethod, + actorOrgId + }: TReviewRequestDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); @@ -160,6 +182,7 @@ export const secretApprovalRequestServiceFactory = ({ ActorType.USER, actorId, secretApprovalRequest.projectId, + actorAuthMethod, actorOrgId ); if ( @@ -192,7 +215,14 @@ export const secretApprovalRequestServiceFactory = ({ return reviewStatus; }; - const updateApprovalStatus = async ({ actorId, status, approvalId, actor, actorOrgId }: TStatusChangeDTO) => { + const updateApprovalStatus = async ({ + actorId, + status, + approvalId, + actor, + actorOrgId, + actorAuthMethod + }: TStatusChangeDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); if (actor !== ActorType.USER) throw new BadRequestError({ message: "Must be a user" }); @@ -202,6 +232,7 @@ export const secretApprovalRequestServiceFactory = ({ ActorType.USER, actorId, secretApprovalRequest.projectId, + actorAuthMethod, actorOrgId ); if ( @@ -229,7 +260,8 @@ export const secretApprovalRequestServiceFactory = ({ approvalId, actor, actorId, - actorOrgId + actorOrgId, + actorAuthMethod }: TMergeSecretApprovalRequestDTO) => { const secretApprovalRequest = await secretApprovalRequestDAL.findById(approvalId); if (!secretApprovalRequest) throw new BadRequestError({ message: "Secret approval request not found" }); @@ -240,8 +272,10 @@ export const secretApprovalRequestServiceFactory = ({ ActorType.USER, actorId, projectId, + actorAuthMethod, actorOrgId ); + if ( !hasRole(ProjectMembershipRole.Admin) && secretApprovalRequest.committerId !== membership.id && @@ -438,6 +472,7 @@ export const secretApprovalRequestServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, policy, projectId, secretPath, @@ -449,6 +484,7 @@ export const secretApprovalRequestServiceFactory = ({ actor, actorId, projectId, + actorAuthMethod, actorOrgId ); ForbiddenError.from(permission).throwUnlessCan( diff --git a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts index 75c19c6e9..1e1648a66 100644 --- a/backend/src/ee/services/secret-rotation/secret-rotation-service.ts +++ b/backend/src/ee/services/secret-rotation/secret-rotation-service.ts @@ -39,8 +39,20 @@ export const secretRotationServiceFactory = ({ folderDAL, secretDAL }: TSecretRotationServiceFactoryDep) => { - const getProviderTemplates = async ({ actor, actorId, actorOrgId, projectId }: TProjectPermission) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const getProviderTemplates = async ({ + actor, + actorId, + actorOrgId, + actorAuthMethod, + projectId + }: TProjectPermission) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); return { @@ -54,6 +66,7 @@ export const secretRotationServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, inputs, outputs, interval, @@ -61,7 +74,13 @@ export const secretRotationServiceFactory = ({ secretPath, environment }: TCreateSecretRotationDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, ProjectPermissionSub.SecretRotation @@ -139,14 +158,20 @@ export const secretRotationServiceFactory = ({ return secretRotation; }; - const getByProjectId = async ({ actorId, projectId, actor, actorOrgId }: TListByProjectIdDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const getByProjectId = async ({ actorId, projectId, actor, actorOrgId, actorAuthMethod }: TListByProjectIdDTO) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRotation); const doc = await secretRotationDAL.find({ projectId }); return doc; }; - const restartById = async ({ actor, actorId, actorOrgId, rotationId }: TRestartDTO) => { + const restartById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TRestartDTO) => { const doc = await secretRotationDAL.findById(rotationId); if (!doc) throw new BadRequestError({ message: "Rotation not found" }); @@ -157,18 +182,30 @@ export const secretRotationServiceFactory = ({ message: "Failed to add secret rotation due to plan restriction. Upgrade plan to add secret rotation." }); - const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + doc.projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.SecretRotation); await secretRotationQueue.removeFromQueue(doc.id, doc.interval); await secretRotationQueue.addToQueue(doc.id, doc.interval); return doc; }; - const deleteById = async ({ actor, actorId, actorOrgId, rotationId }: TDeleteDTO) => { + const deleteById = async ({ actor, actorId, actorOrgId, actorAuthMethod, rotationId }: TDeleteDTO) => { const doc = await secretRotationDAL.findById(rotationId); if (!doc) throw new BadRequestError({ message: "Rotation not found" }); - const { permission } = await permissionService.getProjectPermission(actor, actorId, doc.projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + doc.projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Delete, ProjectPermissionSub.SecretRotation diff --git a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts index 7066fd485..9b78da3af 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts @@ -39,8 +39,14 @@ export const secretScanningServiceFactory = ({ permissionService, secretScanningQueue }: TSecretScanningServiceFactoryDep) => { - const createInstallationSession = async ({ actor, orgId, actorId, actorOrgId }: TInstallAppSessionDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const createInstallationSession = async ({ + actor, + orgId, + actorId, + actorAuthMethod, + actorOrgId + }: TInstallAppSessionDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); const sessionId = crypto.randomBytes(16).toString("hex"); @@ -53,12 +59,19 @@ export const secretScanningServiceFactory = ({ actorId, installationId, actor, + actorAuthMethod, actorOrgId }: TLinkInstallSessionDTO) => { const session = await gitAppInstallSessionDAL.findOne({ sessionId }); if (!session) throw new UnauthorizedError({ message: "Session not found" }); - const { permission } = await permissionService.getOrgPermission(actor, actorId, session.orgId, actorOrgId); + const { permission } = await permissionService.getOrgPermission( + actor, + actorId, + session.orgId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.SecretScanning); const installatedApp = await gitAppOrgDAL.transaction(async (tx) => { await gitAppInstallSessionDAL.deleteById(session.id, tx); @@ -89,23 +102,37 @@ export const secretScanningServiceFactory = ({ return { installatedApp }; }; - const getOrgInstallationStatus = async ({ actorId, orgId, actor, actorOrgId }: TGetOrgInstallStatusDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getOrgInstallationStatus = async ({ + actorId, + orgId, + actor, + actorAuthMethod, + actorOrgId + }: TGetOrgInstallStatusDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); const appInstallation = await gitAppOrgDAL.findOne({ orgId }); return Boolean(appInstallation); }; - const getRisksByOrg = async ({ actor, orgId, actorId, actorOrgId }: TGetOrgRisksDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const getRisksByOrg = async ({ actor, orgId, actorId, actorAuthMethod, actorOrgId }: TGetOrgRisksDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning); const risks = await secretScanningDAL.find({ orgId }, { sort: [["createdAt", "desc"]] }); return { risks }; }; - const updateRiskStatus = async ({ actorId, orgId, actor, actorOrgId, riskId, status }: TUpdateRiskStatusDTO) => { - const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); + const updateRiskStatus = async ({ + actorId, + orgId, + actor, + actorOrgId, + actorAuthMethod, + riskId, + status + }: TUpdateRiskStatusDTO) => { + const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.SecretScanning); const isRiskResolved = Boolean( diff --git a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts index 6ec7a23d5..de2f6efcb 100644 --- a/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts +++ b/backend/src/ee/services/secret-snapshot/secret-snapshot-service.ts @@ -59,9 +59,16 @@ export const secretSnapshotServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, path }: TProjectSnapshotCountDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -77,11 +84,18 @@ export const secretSnapshotServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, path, limit = 20, offset = 0 }: TProjectSnapshotListDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); const folder = await folderDAL.findBySecretPath(projectId, environment, path); @@ -91,10 +105,16 @@ export const secretSnapshotServiceFactory = ({ return snapshots; }; - const getSnapshotData = async ({ actorId, actor, actorOrgId, id }: TGetSnapshotDataDTO) => { + const getSnapshotData = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TGetSnapshotDataDTO) => { const snapshot = await snapshotDAL.findSecretSnapshotDataById(id); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); - const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + snapshot.projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); return snapshot; }; @@ -145,11 +165,23 @@ export const secretSnapshotServiceFactory = ({ } }; - const rollbackSnapshot = async ({ id: snapshotId, actor, actorId, actorOrgId }: TRollbackSnapshotDTO) => { + const rollbackSnapshot = async ({ + id: snapshotId, + actor, + actorId, + actorAuthMethod, + actorOrgId + }: TRollbackSnapshotDTO) => { const snapshot = await snapshotDAL.findById(snapshotId); if (!snapshot) throw new BadRequestError({ message: "Snapshot not found" }); - const { permission } = await permissionService.getProjectPermission(actor, actorId, snapshot.projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + snapshot.projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan( ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback diff --git a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts index 14c73db1f..ecd2b3070 100644 --- a/backend/src/ee/services/trusted-ip/trusted-ip-service.ts +++ b/backend/src/ee/services/trusted-ip/trusted-ip-service.ts @@ -26,8 +26,14 @@ export const trustedIpServiceFactory = ({ licenseService, projectDAL }: TTrustedIpServiceFactoryDep) => { - const listIpsByProjectId = async ({ projectId, actor, actorId, actorOrgId }: TProjectPermission) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const listIpsByProjectId = async ({ projectId, actor, actorId, actorAuthMethod, actorOrgId }: TProjectPermission) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.IpAllowList); const trustedIps = await trustedIpDAL.find({ projectId @@ -38,13 +44,20 @@ export const trustedIpServiceFactory = ({ const addProjectIp = async ({ projectId, actorId, + actorAuthMethod, actor, actorOrgId, ipAddress: ip, comment, isActive }: TCreateIpDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId); @@ -78,11 +91,18 @@ export const trustedIpServiceFactory = ({ actorId, actor, actorOrgId, + actorAuthMethod, ipAddress: ip, comment, trustedIpId }: TUpdateIpDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId); @@ -113,8 +133,21 @@ export const trustedIpServiceFactory = ({ return { trustedIp, project }; // for audit log }; - const deleteProjectIp = async ({ projectId, actorId, actor, actorOrgId, trustedIpId }: TDeleteIpDTO) => { - const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); + const deleteProjectIp = async ({ + projectId, + actorId, + actor, + actorOrgId, + actorAuthMethod, + trustedIpId + }: TDeleteIpDTO) => { + const { permission } = await permissionService.getProjectPermission( + actor, + actorId, + projectId, + actorAuthMethod, + actorOrgId + ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.IpAllowList); const project = await projectDAL.findById(projectId);