Feat: Scoped JWT to organization, add actorAuthMethod to services

This commit is contained in:
Daniel Hougaard
2024-03-12 14:25:14 +01:00
parent 750a43c978
commit fe638ce2c1
8 changed files with 366 additions and 68 deletions

View File

@@ -49,10 +49,17 @@ export const identityProjectServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
role role
}: TCreateProjectIdentityDTO) => { }: TCreateProjectIdentityDTO) => {
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.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Identity);
const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId }); const existingIdentity = await identityProjectDAL.findOne({ identityId, projectId });
@@ -112,9 +119,16 @@ export const identityProjectServiceFactory = ({
roles, roles,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TUpdateProjectIdentityDTO) => { }: TUpdateProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId }); const projectIdentity = await identityProjectDAL.findOne({ identityId, projectId });
@@ -127,6 +141,7 @@ export const identityProjectServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
projectIdentity.identityId, projectIdentity.identityId,
projectIdentity.projectId, projectIdentity.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@@ -185,6 +200,7 @@ export const identityProjectServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId projectId
}: TDeleteProjectIdentityDTO) => { }: TDeleteProjectIdentityDTO) => {
const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId }); const identityProjectMembership = await identityProjectDAL.findOne({ identityId, projectId });
@@ -195,6 +211,7 @@ export const identityProjectServiceFactory = ({
actor, actor,
actorId, actorId,
identityProjectMembership.projectId, identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Identity);
@@ -202,6 +219,7 @@ export const identityProjectServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityId, identityId,
identityProjectMembership.projectId, identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@@ -212,8 +230,20 @@ export const identityProjectServiceFactory = ({
return deletedIdentity; return deletedIdentity;
}; };
const listProjectIdentities = async ({ projectId, actor, actorId, actorOrgId }: TListProjectIdentityDTO) => { const listProjectIdentities = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TListProjectIdentityDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Identity);
const identityMemberhips = await identityProjectDAL.findByProjectId(projectId); const identityMemberhips = await identityProjectDAL.findByProjectId(projectId);

View File

@@ -144,6 +144,7 @@ export const identityUaServiceFactory = ({
accessTokenTrustedIps, accessTokenTrustedIps,
clientSecretTrustedIps, clientSecretTrustedIps,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId actorOrgId
}: TAttachUaDTO) => { }: TAttachUaDTO) => {
@@ -162,6 +163,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
@@ -233,6 +235,7 @@ export const identityUaServiceFactory = ({
accessTokenTrustedIps, accessTokenTrustedIps,
clientSecretTrustedIps, clientSecretTrustedIps,
actorId, actorId,
actorAuthMethod,
actor, actor,
actorOrgId actorOrgId
}: TUpdateUaDTO) => { }: TUpdateUaDTO) => {
@@ -256,6 +259,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
@@ -308,7 +312,7 @@ export const identityUaServiceFactory = ({
return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId }; return { ...updatedUaAuth, orgId: identityMembershipOrg.orgId };
}; };
const getIdentityUa = async ({ identityId, actorId, actor, actorOrgId }: TGetUaDTO) => { const getIdentityUa = async ({ identityId, actorId, actor, actorAuthMethod, actorOrgId }: TGetUaDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral) if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
@@ -322,6 +326,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
@@ -334,6 +339,7 @@ export const identityUaServiceFactory = ({
actorOrgId, actorOrgId,
identityId, identityId,
ttl, ttl,
actorAuthMethod,
description, description,
numUsesLimit numUsesLimit
}: TCreateUaClientSecretDTO) => { }: TCreateUaClientSecretDTO) => {
@@ -347,6 +353,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
@@ -355,6 +362,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
@@ -388,7 +396,13 @@ export const identityUaServiceFactory = ({
}; };
}; };
const getUaClientSecrets = async ({ actor, actorId, actorOrgId, identityId }: TGetUaClientSecretsDTO) => { const getUaClientSecrets = async ({
actor,
actorId,
actorOrgId,
actorAuthMethod,
identityId
}: TGetUaClientSecretsDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" }); if (!identityMembershipOrg) throw new BadRequestError({ message: "Failed to find identity" });
if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral) if (identityMembershipOrg.identity?.authMethod !== IdentityAuthMethod.Univeral)
@@ -399,6 +413,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
@@ -407,6 +422,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);
@@ -431,6 +447,7 @@ export const identityUaServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
clientSecretId clientSecretId
}: TRevokeUaClientSecretDTO) => { }: TRevokeUaClientSecretDTO) => {
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId });
@@ -443,6 +460,7 @@ export const identityUaServiceFactory = ({
actor, actor,
actorId, actorId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity);
@@ -451,6 +469,7 @@ export const identityUaServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
identityMembershipOrg.identityId, identityMembershipOrg.identityId,
identityMembershipOrg.orgId, identityMembershipOrg.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission); const hasPriviledge = isAtLeastAsPrivileged(permission, rolePermission);

View File

@@ -25,8 +25,16 @@ export const identityServiceFactory = ({
identityOrgMembershipDAL, identityOrgMembershipDAL,
permissionService permissionService
}: TIdentityServiceFactoryDep) => { }: TIdentityServiceFactoryDep) => {
const createIdentity = async ({ name, role, actor, orgId, actorId, actorOrgId }: TCreateIdentityDTO) => { const createIdentity = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorOrgId); name,
role,
actor,
orgId,
actorId,
actorAuthMethod,
actorOrgId
}: TCreateIdentityDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Identity);
const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole( const { permission: rolePermission, role: customRole } = await permissionService.getOrgPermissionByRole(
@@ -54,7 +62,15 @@ export const identityServiceFactory = ({
return identity; return identity;
}; };
const updateIdentity = async ({ id, role, name, actor, actorId, actorOrgId }: TUpdateIdentityDTO) => { const updateIdentity = async ({
id,
role,
name,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TUpdateIdentityDTO) => {
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id });
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
@@ -62,6 +78,7 @@ export const identityServiceFactory = ({
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Identity);
@@ -70,6 +87,7 @@ export const identityServiceFactory = ({
ActorType.IDENTITY, ActorType.IDENTITY,
id, id,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
@@ -108,7 +126,7 @@ export const identityServiceFactory = ({
return { ...identity, orgId: identityOrgMembership.orgId }; return { ...identity, orgId: identityOrgMembership.orgId };
}; };
const deleteIdentity = async ({ actorId, actor, actorOrgId, id }: TDeleteIdentityDTO) => { const deleteIdentity = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteIdentityDTO) => {
const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id }); const identityOrgMembership = await identityOrgMembershipDAL.findOne({ identityId: id });
if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` }); if (!identityOrgMembership) throw new BadRequestError({ message: `Failed to find identity with id ${id}` });
@@ -116,13 +134,15 @@ export const identityServiceFactory = ({
actor, actor,
actorId, actorId,
identityOrgMembership.orgId, identityOrgMembership.orgId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Identity);
const { permission: identityRolePermission } = await permissionService.getOrgPermission( const { permission: identityRolePermission } = await permissionService.getOrgPermission(
ActorType.IDENTITY, ActorType.IDENTITY,
id, id,
identityOrgMembership.orgId identityOrgMembership.orgId,
actorAuthMethod
); );
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission); const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
if (!hasRequiredPriviledges) if (!hasRequiredPriviledges)
@@ -132,8 +152,8 @@ export const identityServiceFactory = ({
return { ...deletedIdentity, orgId: identityOrgMembership.orgId }; return { ...deletedIdentity, orgId: identityOrgMembership.orgId };
}; };
const listOrgIdentities = async ({ orgId, actor, actorId, actorOrgId }: TOrgPermission) => { const listOrgIdentities = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPermission) => {
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.Identity); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Identity);
const identityMemberhips = await identityOrgMembershipDAL.findByOrgId(orgId); const identityMemberhips = await identityOrgMembershipDAL.findByOrgId(orgId);

View File

@@ -64,14 +64,26 @@ export const integrationAuthServiceFactory = ({
projectBotDAL, projectBotDAL,
projectBotService projectBotService
}: TIntegrationAuthServiceFactoryDep) => { }: TIntegrationAuthServiceFactoryDep) => {
const listIntegrationAuthByProjectId = async ({ actorId, actor, actorOrgId, projectId }: TProjectPermission) => { const listIntegrationAuthByProjectId = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const authorizations = await integrationAuthDAL.find({ projectId }); const authorizations = await integrationAuthDAL.find({ projectId });
return authorizations; return authorizations;
}; };
const getIntegrationAuth = async ({ actor, id, actorId, actorOrgId }: TGetIntegrationAuthDTO) => { const getIntegrationAuth = async ({ actor, id, actorId, actorAuthMethod, actorOrgId }: TGetIntegrationAuthDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -79,6 +91,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -90,6 +103,7 @@ export const integrationAuthServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
integration, integration,
url, url,
code code
@@ -97,7 +111,13 @@ export const integrationAuthServiceFactory = ({
if (!Object.values(Integrations).includes(integration as Integrations)) if (!Object.values(Integrations).includes(integration as Integrations))
throw new BadRequestError({ message: "Invalid integration" }); throw new BadRequestError({ message: "Invalid integration" });
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.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId }); const bot = await projectBotDAL.findOne({ isActive: true, projectId });
@@ -153,6 +173,7 @@ export const integrationAuthServiceFactory = ({
url, url,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
accessId, accessId,
namespace, namespace,
accessToken accessToken
@@ -160,7 +181,13 @@ export const integrationAuthServiceFactory = ({
if (!Object.values(Integrations).includes(integration as Integrations)) if (!Object.values(Integrations).includes(integration as Integrations))
throw new BadRequestError({ message: "Invalid integration" }); throw new BadRequestError({ message: "Invalid integration" });
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.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.findOne({ isActive: true, projectId }); const bot = await projectBotDAL.findOne({ isActive: true, projectId });
@@ -277,6 +304,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
teamId, teamId,
id, id,
workspaceSlug workspaceSlug
@@ -288,6 +316,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -305,7 +334,13 @@ export const integrationAuthServiceFactory = ({
return apps; return apps;
}; };
const getIntegrationAuthTeams = async ({ actor, actorId, actorOrgId, id }: TIntegrationAuthTeamsDTO) => { const getIntegrationAuthTeams = async ({
actor,
actorId,
actorAuthMethod,
actorOrgId,
id
}: TIntegrationAuthTeamsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -313,6 +348,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -327,7 +363,14 @@ export const integrationAuthServiceFactory = ({
return teams; return teams;
}; };
const getVercelBranches = async ({ appId, id, actor, actorId, actorOrgId }: TIntegrationAuthVercelBranchesDTO) => { const getVercelBranches = async ({
appId,
id,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TIntegrationAuthVercelBranchesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -335,6 +378,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -360,7 +404,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getChecklyGroups = async ({ actorId, actor, actorOrgId, id, accountId }: TIntegrationAuthChecklyGroupsDTO) => { const getChecklyGroups = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id,
accountId
}: TIntegrationAuthChecklyGroupsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -368,6 +419,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -386,7 +438,7 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getGithubOrgs = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthGithubOrgsDTO) => { const getGithubOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthGithubOrgsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -394,6 +446,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -418,6 +471,7 @@ export const integrationAuthServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
id, id,
repoOwner, repoOwner,
repoName repoName
@@ -429,6 +483,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -452,7 +507,7 @@ export const integrationAuthServiceFactory = ({
return environments.map(({ id: envId, name }) => ({ name, envId: String(envId) })); return environments.map(({ id: envId, name }) => ({ name, envId: String(envId) }));
}; };
const getQoveryOrgs = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthQoveryOrgsDTO) => { const getQoveryOrgs = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TIntegrationAuthQoveryOrgsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -460,6 +515,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -478,7 +534,14 @@ export const integrationAuthServiceFactory = ({
return data.results.map(({ name, id: orgId }) => ({ name, orgId })); return data.results.map(({ name, id: orgId }) => ({ name, orgId }));
}; };
const getQoveryProjects = async ({ actorId, actor, actorOrgId, id, orgId }: TIntegrationAuthQoveryProjectDTO) => { const getQoveryProjects = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id,
orgId
}: TIntegrationAuthQoveryProjectDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -486,6 +549,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -511,6 +575,7 @@ export const integrationAuthServiceFactory = ({
id, id,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TIntegrationAuthQoveryEnvironmentsDTO) => { }: TIntegrationAuthQoveryEnvironmentsDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@@ -520,6 +585,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -545,7 +611,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getQoveryApps = async ({ id, actor, actorId, actorOrgId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const getQoveryApps = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -553,6 +626,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -582,6 +656,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environmentId environmentId
}: TIntegrationAuthQoveryScopesDTO) => { }: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@@ -591,6 +666,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -615,7 +691,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getQoveryJobs = async ({ id, actor, actorId, actorOrgId, environmentId }: TIntegrationAuthQoveryScopesDTO) => { const getQoveryJobs = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
environmentId
}: TIntegrationAuthQoveryScopesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -623,6 +706,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -647,7 +731,13 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getHerokuPipelines = async ({ id, actor, actorId, actorOrgId }: TIntegrationAuthHerokuPipelinesDTO) => { const getHerokuPipelines = async ({
id,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TIntegrationAuthHerokuPipelinesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -655,6 +745,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -679,7 +770,14 @@ export const integrationAuthServiceFactory = ({
})); }));
}; };
const getRailwayEnvironments = async ({ id, actor, actorId, actorOrgId, appId }: TIntegrationAuthRailwayEnvDTO) => { const getRailwayEnvironments = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
appId
}: TIntegrationAuthRailwayEnvDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -687,6 +785,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -739,7 +838,14 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getRailwayServices = async ({ id, actor, actorId, actorOrgId, appId }: TIntegrationAuthRailwayServicesDTO) => { const getRailwayServices = async ({
id,
actor,
actorId,
actorOrgId,
actorAuthMethod,
appId
}: TIntegrationAuthRailwayServicesDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -747,6 +853,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -806,7 +913,13 @@ export const integrationAuthServiceFactory = ({
return []; return [];
}; };
const getBitbucketWorkspaces = async ({ actorId, actor, actorOrgId, id }: TIntegrationAuthBitbucketWorkspaceDTO) => { const getBitbucketWorkspaces = async ({
actorId,
actor,
actorOrgId,
actorAuthMethod,
id
}: TIntegrationAuthBitbucketWorkspaceDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -814,6 +927,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -852,6 +966,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
appId appId
}: TIntegrationAuthNorthflankSecretGroupDTO) => { }: TIntegrationAuthNorthflankSecretGroupDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@@ -861,6 +976,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -918,6 +1034,7 @@ export const integrationAuthServiceFactory = ({
id, id,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
actor actor
}: TGetIntegrationAuthTeamCityBuildConfigDTO) => { }: TGetIntegrationAuthTeamCityBuildConfigDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
@@ -927,6 +1044,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
@@ -958,16 +1076,29 @@ export const integrationAuthServiceFactory = ({
integration, integration,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteIntegrationAuthsDTO) => { }: TDeleteIntegrationAuthsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
const integrations = await integrationAuthDAL.delete({ integration, projectId }); const integrations = await integrationAuthDAL.delete({ integration, projectId });
return integrations; return integrations;
}; };
const deleteIntegrationAuthById = async ({ id, actorId, actor, actorOrgId }: TDeleteIntegrationAuthByIdDTO) => { const deleteIntegrationAuthById = async ({
id,
actorId,
actor,
actorAuthMethod,
actorOrgId
}: TDeleteIntegrationAuthByIdDTO) => {
const integrationAuth = await integrationAuthDAL.findById(id); const integrationAuth = await integrationAuthDAL.findById(id);
if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" }); if (!integrationAuth) throw new BadRequestError({ message: "Failed to find integration" });
@@ -975,6 +1106,7 @@ export const integrationAuthServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);

View File

@@ -42,6 +42,7 @@ export const integrationServiceFactory = ({
metadata, metadata,
secretPath, secretPath,
targetService, targetService,
actorAuthMethod,
targetServiceId, targetServiceId,
integrationAuthId, integrationAuthId,
sourceEnvironment, sourceEnvironment,
@@ -55,6 +56,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integrationAuth.projectId, integrationAuth.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
@@ -93,6 +95,7 @@ export const integrationServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
targetEnvironment, targetEnvironment,
app, app,
id, id,
@@ -109,6 +112,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integration.projectId, integration.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
@@ -129,7 +133,7 @@ export const integrationServiceFactory = ({
return updatedIntegration; return updatedIntegration;
}; };
const deleteIntegration = async ({ actorId, id, actor, actorOrgId }: TDeleteIntegrationDTO) => { const deleteIntegration = async ({ actorId, id, actor, actorAuthMethod, actorOrgId }: TDeleteIntegrationDTO) => {
const integration = await integrationDAL.findById(id); const integration = await integrationDAL.findById(id);
if (!integration) throw new BadRequestError({ message: "Integration auth not found" }); if (!integration) throw new BadRequestError({ message: "Integration auth not found" });
@@ -137,6 +141,7 @@ export const integrationServiceFactory = ({
actor, actor,
actorId, actorId,
integration.projectId, integration.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Integrations);
@@ -145,8 +150,20 @@ export const integrationServiceFactory = ({
return { ...integration, ...deletedIntegration }; return { ...integration, ...deletedIntegration };
}; };
const listIntegrationByProject = async ({ actor, actorId, actorOrgId, projectId }: TProjectPermission) => { const listIntegrationByProject = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const integrations = await integrationDAL.findByProjectId(projectId); const integrations = await integrationDAL.findByProjectId(projectId);

View File

@@ -12,6 +12,7 @@ import {
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ActorAuthMethod } from "../auth/auth-type";
import { TOrgRoleDALFactory } from "./org-role-dal"; import { TOrgRoleDALFactory } from "./org-role-dal";
type TOrgRoleServiceFactoryDep = { type TOrgRoleServiceFactoryDep = {
@@ -26,9 +27,10 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
userId: string, userId: string,
orgId: string, orgId: string,
data: Omit<TOrgRolesInsert, "orgId">, data: Omit<TOrgRolesInsert, "orgId">,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string actorOrgId?: string
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Role);
const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId });
if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" });
@@ -45,9 +47,10 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
orgId: string, orgId: string,
roleId: string, roleId: string,
data: Omit<TOrgRolesUpdate, "orgId">, data: Omit<TOrgRolesUpdate, "orgId">,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string actorOrgId?: string
) => { ) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Role);
if (data?.slug) { if (data?.slug) {
const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId }); const existingRole = await orgRoleDAL.findOne({ slug: data.slug, orgId });
@@ -62,8 +65,14 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return updatedRole; return updatedRole;
}; };
const deleteRole = async (userId: string, orgId: string, roleId: string, actorOrgId?: string) => { const deleteRole = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
roleId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Role);
const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId }); const [deletedRole] = await orgRoleDAL.delete({ id: roleId, orgId });
if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" });
@@ -71,8 +80,8 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return deletedRole; return deletedRole;
}; };
const listRoles = async (userId: string, orgId: string, actorOrgId?: string) => { const listRoles = async (userId: string, orgId: string, actorAuthMethod: ActorAuthMethod, actorOrgId?: string) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
const customRoles = await orgRoleDAL.find({ orgId }); const customRoles = await orgRoleDAL.find({ orgId });
const roles = [ const roles = [
@@ -115,8 +124,18 @@ export const orgRoleServiceFactory = ({ orgRoleDAL, permissionService }: TOrgRol
return roles; return roles;
}; };
const getUserPermission = async (userId: string, orgId: string, actorOrgId?: string) => { const getUserPermission = async (
const { permission, membership } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission, membership } = await permissionService.getUserOrgPermission(
userId,
orgId,
actorAuthMethod,
actorOrgId
);
return { permissions: packRules(permission.rules), membership }; return { permissions: packRules(permission.rules), membership };
}; };

View File

@@ -18,7 +18,7 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
import { isDisposableEmail } from "@app/lib/validator"; import { isDisposableEmail } from "@app/lib/validator";
import { ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType, AuthMethod, AuthTokenType } from "../auth/auth-type";
import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service"; import { TAuthTokenServiceFactory } from "../auth-token/auth-token-service";
import { TokenType } from "../auth-token/auth-token-types"; import { TokenType } from "../auth-token/auth-token-types";
import { TProjectDALFactory } from "../project/project-dal"; import { TProjectDALFactory } from "../project/project-dal";
@@ -79,8 +79,13 @@ export const orgServiceFactory = ({
/* /*
* Get organization details by the organization id * Get organization details by the organization id
* */ * */
const findOrganizationById = async (userId: string, orgId: string, actorOrgId?: string) => { const findOrganizationById = async (
await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" }); if (!org) throw new BadRequestError({ name: "Org not found", message: "Organization not found" });
return org; return org;
@@ -95,16 +100,28 @@ export const orgServiceFactory = ({
/* /*
* Get all workspace members * Get all workspace members
* */ * */
const findAllOrgMembers = async (userId: string, orgId: string, actorOrgId?: string) => { const findAllOrgMembers = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member);
const members = await orgDAL.findAllOrgMembers(orgId); const members = await orgDAL.findAllOrgMembers(orgId);
return members; return members;
}; };
const findOrgMembersByUsername = async ({ actor, actorId, orgId, emails }: TFindOrgMembersByEmailDTO) => { const findOrgMembersByUsername = async ({
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
orgId,
emails
}: TFindOrgMembersByEmailDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Member);
const members = await orgDAL.findOrgMembersByUsername(orgId, emails); const members = await orgDAL.findOrgMembersByUsername(orgId, emails);
@@ -112,8 +129,8 @@ export const orgServiceFactory = ({
return members; return members;
}; };
const findAllWorkspaces = async ({ actor, actorId, actorOrgId, orgId }: TFindAllWorkspacesDTO) => { const findAllWorkspaces = async ({ actor, actorId, actorOrgId, actorAuthMethod, orgId }: TFindAllWorkspacesDTO) => {
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.Workspace); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Workspace);
const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id)); const organizationWorkspaceIds = new Set((await projectDAL.find({ orgId })).map((workspace) => workspace.id));
@@ -193,10 +210,11 @@ export const orgServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
orgId, orgId,
data: { name, slug, authEnforced, scimEnabled } data: { name, slug, authEnforced, scimEnabled }
}: TUpdateOrgDTO) => { }: TUpdateOrgDTO) => {
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.Settings); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Settings);
const plan = await licenseService.getPlan(orgId); const plan = await licenseService.getPlan(orgId);
@@ -309,8 +327,13 @@ export const orgServiceFactory = ({
/* /*
* Delete organization by id * Delete organization by id
* */ * */
const deleteOrganizationById = async (userId: string, orgId: string, actorOrgId?: string) => { const deleteOrganizationById = async (
const { membership } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { membership } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
if ((membership.role as OrgMembershipRole) !== OrgMembershipRole.Admin) if ((membership.role as OrgMembershipRole) !== OrgMembershipRole.Admin)
throw new UnauthorizedError({ name: "Delete org by id", message: "Not an admin" }); throw new UnauthorizedError({ name: "Delete org by id", message: "Not an admin" });
@@ -324,8 +347,15 @@ export const orgServiceFactory = ({
* Org membership management * Org membership management
* Not another service because it has close ties with how an org works doesn't make sense to seperate them * Not another service because it has close ties with how an org works doesn't make sense to seperate them
* */ * */
const updateOrgMembership = async ({ role, orgId, userId, membershipId, actorOrgId }: TUpdateOrgMembershipDTO) => { const updateOrgMembership = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); role,
orgId,
userId,
membershipId,
actorAuthMethod,
actorOrgId
}: TUpdateOrgMembershipDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Member);
const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole); const isCustomRole = !Object.values(OrgMembershipRole).includes(role as OrgMembershipRole);
@@ -355,8 +385,14 @@ export const orgServiceFactory = ({
/* /*
* Invite user to organization * Invite user to organization
*/ */
const inviteUserToOrganization = async ({ orgId, userId, inviteeEmail, actorOrgId }: TInviteUserToOrgDTO) => { const inviteUserToOrganization = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); orgId,
userId,
inviteeEmail,
actorAuthMethod,
actorOrgId
}: TInviteUserToOrgDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Member);
const org = await orgDAL.findOrgById(orgId); const org = await orgDAL.findOrgById(orgId);
@@ -515,8 +551,14 @@ export const orgServiceFactory = ({
return { token, user }; return { token, user };
}; };
const deleteOrgMembership = async ({ orgId, userId, membershipId, actorOrgId }: TDeleteOrgMembershipDTO) => { const deleteOrgMembership = async ({
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); orgId,
userId,
membershipId,
actorAuthMethod,
actorOrgId
}: TDeleteOrgMembershipDTO) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.Member);
const deletedMembership = await orgDAL.transaction(async (tx) => { const deletedMembership = await orgDAL.transaction(async (tx) => {
@@ -568,15 +610,26 @@ export const orgServiceFactory = ({
/* /*
* CRUD operations of incident contacts * CRUD operations of incident contacts
* */ * */
const findIncidentContacts = async (userId: string, orgId: string, actorOrgId?: string) => { const findIncidentContacts = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount);
const incidentContacts = await incidentContactDAL.findByOrgId(orgId); const incidentContacts = await incidentContactDAL.findByOrgId(orgId);
return incidentContacts; return incidentContacts;
}; };
const createIncidentContact = async (userId: string, orgId: string, email: string, actorOrgId?: string) => { const createIncidentContact = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
email: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.IncidentAccount);
const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email }); const doesIncidentContactExist = await incidentContactDAL.findOne(orgId, { email });
if (doesIncidentContactExist) { if (doesIncidentContactExist) {
@@ -590,8 +643,14 @@ export const orgServiceFactory = ({
return incidentContact; return incidentContact;
}; };
const deleteIncidentContact = async (userId: string, orgId: string, id: string, actorOrgId?: string) => { const deleteIncidentContact = async (
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorOrgId); userId: string,
orgId: string,
id: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getUserOrgPermission(userId, orgId, actorAuthMethod, actorOrgId);
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Delete, OrgPermissionSubjects.IncidentAccount);
const incidentContact = await incidentContactDAL.deleteById(id, orgId); const incidentContact = await incidentContactDAL.deleteById(id, orgId);

View File

@@ -1,6 +1,6 @@
import { TOrgPermission } from "@app/lib/types"; import { TOrgPermission } from "@app/lib/types";
import { ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
export type TUpdateOrgMembershipDTO = { export type TUpdateOrgMembershipDTO = {
userId: string; userId: string;
@@ -32,6 +32,8 @@ export type TVerifyUserToOrgDTO = {
export type TFindOrgMembersByEmailDTO = { export type TFindOrgMembersByEmailDTO = {
actor: ActorType; actor: ActorType;
actorAuthMethod: ActorAuthMethod;
actorOrgId: string | undefined;
actorId: string; actorId: string;
orgId: string; orgId: string;
emails: string[]; emails: string[];