Feat: Scoped JWT to organization, add actorAuthMethod to services

This commit is contained in:
Daniel Hougaard
2024-03-17 18:49:29 +01:00
parent fe638ce2c1
commit 900facdb36
14 changed files with 512 additions and 84 deletions
@@ -37,10 +37,17 @@ export const projectBotServiceFactory = ({
projectId, projectId,
actorOrgId, actorOrgId,
privateKey, privateKey,
actorAuthMethod,
botKey, botKey,
publicKey publicKey
}: TFindBotByProjectIdDTO) => { }: TFindBotByProjectIdDTO) => {
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.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Integrations);
const bot = await projectBotDAL.transaction(async (tx) => { const bot = await projectBotDAL.transaction(async (tx) => {
@@ -88,11 +95,25 @@ export const projectBotServiceFactory = ({
} }
}; };
const setBotActiveState = async ({ actor, botId, botKey, actorId, actorOrgId, isActive }: TSetActiveStateDTO) => { const setBotActiveState = async ({
actor,
botId,
botKey,
actorId,
actorOrgId,
actorAuthMethod,
isActive
}: TSetActiveStateDTO) => {
const bot = await projectBotDAL.findById(botId); const bot = await projectBotDAL.findById(botId);
if (!bot) throw new BadRequestError({ message: "Bot not found" }); if (!bot) throw new BadRequestError({ message: "Bot not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, bot.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
bot.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Integrations);
const project = await projectBotDAL.findProjectByBotId(botId); const project = await projectBotDAL.findProjectByBotId(botId);
@@ -27,8 +27,22 @@ export const projectEnvServiceFactory = ({
projectDAL, projectDAL,
folderDAL folderDAL
}: TProjectEnvServiceFactoryDep) => { }: TProjectEnvServiceFactoryDep) => {
const createEnvironment = async ({ projectId, actorId, actor, actorOrgId, name, slug }: TCreateEnvDTO) => { const createEnvironment = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actorId,
actor,
actorOrgId,
actorAuthMethod,
name,
slug
}: TCreateEnvDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Environments);
const envs = await projectEnvDAL.find({ projectId }); const envs = await projectEnvDAL.find({ projectId });
@@ -65,11 +79,18 @@ export const projectEnvServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
name, name,
id, id,
position position
}: TUpdateEnvDTO) => { }: TUpdateEnvDTO) => {
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.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Environments);
const oldEnv = await projectEnvDAL.findOne({ id, projectId }); const oldEnv = await projectEnvDAL.findOne({ id, projectId });
@@ -94,8 +115,14 @@ export const projectEnvServiceFactory = ({
return { environment: env, old: oldEnv }; return { environment: env, old: oldEnv };
}; };
const deleteEnvironment = async ({ projectId, actor, actorId, actorOrgId, id }: TDeleteEnvDTO) => { const deleteEnvironment = async ({ projectId, actor, actorId, actorOrgId, actorAuthMethod, id }: TDeleteEnvDTO) => {
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.Environments); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Environments);
const env = await projectEnvDAL.transaction(async (tx) => { const env = await projectEnvDAL.transaction(async (tx) => {
@@ -26,11 +26,18 @@ export const projectKeyServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
nonce, nonce,
encryptedKey encryptedKey
}: TUploadProjectKeyDTO) => { }: TUploadProjectKeyDTO) => {
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.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const receiverMembership = await projectMembershipDAL.findOne({ const receiverMembership = await projectMembershipDAL.findOne({
@@ -46,14 +53,32 @@ export const projectKeyServiceFactory = ({
await projectKeyDAL.create({ projectId, receiverId, encryptedKey, nonce, senderId: actorId }); await projectKeyDAL.create({ projectId, receiverId, encryptedKey, nonce, senderId: actorId });
}; };
const getLatestProjectKey = async ({ actorId, projectId, actor, actorOrgId }: TGetLatestProjectKeyDTO) => { const getLatestProjectKey = async ({
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
projectId,
actor,
actorOrgId,
actorAuthMethod
}: TGetLatestProjectKeyDTO) => {
await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const latestKey = await projectKeyDAL.findLatestProjectKey(actorId, projectId); const latestKey = await projectKeyDAL.findLatestProjectKey(actorId, projectId);
return latestKey; return latestKey;
}; };
const getProjectPublicKeys = async ({ actor, actorId, actorOrgId, projectId }: TGetLatestProjectKeyDTO) => { const getProjectPublicKeys = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TGetLatestProjectKeyDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
return projectKeyDAL.findAllProjectUserPubKeys(projectId); return projectKeyDAL.findAllProjectUserPubKeys(projectId);
}; };
@@ -67,8 +67,20 @@ export const projectMembershipServiceFactory = ({
projectKeyDAL, projectKeyDAL,
licenseService licenseService
}: TProjectMembershipServiceFactoryDep) => { }: TProjectMembershipServiceFactoryDep) => {
const getProjectMemberships = async ({ actorId, actor, actorOrgId, projectId }: TGetProjectMembershipDTO) => { const getProjectMemberships = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TGetProjectMembershipDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
return projectMembershipDAL.findAllProjectMembers(projectId); return projectMembershipDAL.findAllProjectMembers(projectId);
@@ -79,13 +91,20 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
members, members,
sendEmails = true sendEmails = true
}: TAddUsersToWorkspaceDTO) => { }: TAddUsersToWorkspaceDTO) => {
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);
if (!project) throw new BadRequestError({ message: "Project not found" }); if (!project) throw new BadRequestError({ message: "Project not found" });
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.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member);
const orgMembers = await orgDAL.findMembership({ const orgMembers = await orgDAL.findMembership({
orgId: project.orgId, orgId: project.orgId,
@@ -145,6 +164,7 @@ export const projectMembershipServiceFactory = ({
const addUsersToProjectNonE2EE = async ({ const addUsersToProjectNonE2EE = async ({
projectId, projectId,
actorId, actorId,
actorAuthMethod,
actor, actor,
emails, emails,
usernames, usernames,
@@ -157,7 +177,7 @@ export const projectMembershipServiceFactory = ({
throw new BadRequestError({ message: "Please upgrade your project on your dashboard" }); throw new BadRequestError({ message: "Please upgrade your project on your dashboard" });
} }
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Member);
const usernamesAndEmails = [...emails, ...usernames]; const usernamesAndEmails = [...emails, ...usernames];
@@ -273,11 +293,18 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
membershipId, membershipId,
roles roles
}: TUpdateProjectMembershipDTO) => { }: TUpdateProjectMembershipDTO) => {
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.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const membershipUser = await userDAL.findUserByProjectMembershipId(membershipId); const membershipUser = await userDAL.findUserByProjectMembershipId(membershipId);
@@ -347,10 +374,17 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
membershipId membershipId
}: TDeleteProjectMembershipOldDTO) => { }: TDeleteProjectMembershipOldDTO) => {
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.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member);
const member = await userDAL.findUserByProjectMembershipId(membershipId); const member = await userDAL.findUserByProjectMembershipId(membershipId);
@@ -374,11 +408,18 @@ export const projectMembershipServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
emails, emails,
usernames usernames
}: TDeleteProjectMembershipsDTO) => { }: TDeleteProjectMembershipsDTO) => {
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.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Member);
const project = await projectDAL.findById(projectId); const project = await projectDAL.findById(projectId);
@@ -13,7 +13,7 @@ import {
} from "@app/ee/services/permission/project-permission"; } from "@app/ee/services/permission/project-permission";
import { BadRequestError } from "@app/lib/errors"; import { BadRequestError } from "@app/lib/errors";
import { ActorType } from "../auth/auth-type"; import { ActorAuthMethod, ActorType } from "../auth/auth-type";
import { TProjectRoleDALFactory } from "./project-role-dal"; import { TProjectRoleDALFactory } from "./project-role-dal";
type TProjectRoleServiceFactoryDep = { type TProjectRoleServiceFactoryDep = {
@@ -29,9 +29,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
actorId: string, actorId: string,
projectId: string, projectId: string,
data: Omit<TProjectRolesInsert, "projectId">, data: Omit<TProjectRolesInsert, "projectId">,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string actorOrgId?: string
) => { ) => {
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.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Role);
const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId });
if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" }); if (existingRole) throw new BadRequestError({ name: "Create Role", message: "Duplicate role" });
@@ -49,9 +56,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
projectId: string, projectId: string,
roleId: string, roleId: string,
data: Omit<TOrgRolesUpdate, "orgId">, data: Omit<TOrgRolesUpdate, "orgId">,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string actorOrgId?: string
) => { ) => {
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.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Role);
if (data?.slug) { if (data?.slug) {
const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId }); const existingRole = await projectRoleDAL.findOne({ slug: data.slug, projectId });
@@ -71,9 +85,16 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
actorId: string, actorId: string,
projectId: string, projectId: string,
roleId: string, roleId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string actorOrgId?: string
) => { ) => {
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.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Role);
const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId }); const [deletedRole] = await projectRoleDAL.delete({ id: roleId, projectId });
if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" }); if (!deletedRole) throw new BadRequestError({ message: "Role not found", name: "Update role" });
@@ -81,8 +102,20 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
return deletedRole; return deletedRole;
}; };
const listRoles = async (actor: ActorType, actorId: string, projectId: string, actorOrgId?: string) => { const listRoles = async (
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actor: ActorType,
actorId: string,
projectId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role);
const customRoles = await projectRoleDAL.find({ projectId }); const customRoles = await projectRoleDAL.find({ projectId });
const roles = [ const roles = [
@@ -135,8 +168,18 @@ export const projectRoleServiceFactory = ({ projectRoleDAL, permissionService }:
return roles; return roles;
}; };
const getUserPermission = async (userId: string, projectId: string, actorOrgId?: string) => { const getUserPermission = async (
const { permission, membership } = await permissionService.getUserProjectPermission(userId, projectId, actorOrgId); userId: string,
projectId: string,
actorAuthMethod: ActorAuthMethod,
actorOrgId?: string
) => {
const { permission, membership } = await permissionService.getUserProjectPermission(
userId,
projectId,
actorAuthMethod,
actorOrgId
);
return { permissions: packRules(permission.rules), membership }; return { permissions: packRules(permission.rules), membership };
}; };
+52 -13
View File
@@ -96,6 +96,7 @@ export const projectServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
workspaceName, workspaceName,
slug: projectSlug slug: projectSlug
}: TCreateProjectDTO) => { }: TCreateProjectDTO) => {
@@ -111,6 +112,7 @@ export const projectServiceFactory = ({
actor, actor,
actorId, actorId,
organization.id, organization.id,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace); ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Workspace);
@@ -330,10 +332,16 @@ export const projectServiceFactory = ({
return results; return results;
}; };
const deleteProject = async ({ actor, actorId, actorOrgId, filter }: TDeleteProjectDTO) => { const deleteProject = async ({ actor, actorId, actorOrgId, actorAuthMethod, filter }: TDeleteProjectDTO) => {
const project = await projectDAL.findProjectByFilter(filter); const project = await projectDAL.findProjectByFilter(filter);
const { permission } = await permissionService.getProjectPermission(actor, actorId, project.id, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
project.id,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project);
const deletedProject = await projectDAL.transaction(async (tx) => { const deletedProject = await projectDAL.transaction(async (tx) => {
@@ -356,17 +364,23 @@ export const projectServiceFactory = ({
return workspaces; return workspaces;
}; };
const getAProject = async ({ actorId, actorOrgId, filter, actor }: TGetProjectDTO) => { const getAProject = async ({ actorId, actorOrgId, actorAuthMethod, filter, actor }: TGetProjectDTO) => {
const project = await projectDAL.findProjectByFilter(filter); const project = await projectDAL.findProjectByFilter(filter);
await permissionService.getProjectPermission(actor, actorId, project.id, actorOrgId); await permissionService.getProjectPermission(actor, actorId, project.id, actorAuthMethod, actorOrgId);
return project; return project;
}; };
const updateProject = async ({ actor, actorId, actorOrgId, update, filter }: TUpdateProjectDTO) => { const updateProject = async ({ actor, actorId, actorOrgId, actorAuthMethod, update, filter }: TUpdateProjectDTO) => {
const project = await projectDAL.findProjectByFilter(filter); const project = await projectDAL.findProjectByFilter(filter);
const { permission } = await permissionService.getProjectPermission(actor, actorId, project.id, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
project.id,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(project.id, { const updatedProject = await projectDAL.updateById(project.id, {
@@ -381,25 +395,50 @@ export const projectServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
autoCapitalization autoCapitalization
}: TToggleProjectAutoCapitalizationDTO) => { }: TToggleProjectAutoCapitalizationDTO) => {
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.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(projectId, { autoCapitalization }); const updatedProject = await projectDAL.updateById(projectId, { autoCapitalization });
return updatedProject; return updatedProject;
}; };
const updateName = async ({ projectId, actor, actorId, actorOrgId, name }: TUpdateProjectNameDTO) => { const updateName = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); projectId,
actor,
actorId,
actorOrgId,
actorAuthMethod,
name
}: TUpdateProjectNameDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Settings);
const updatedProject = await projectDAL.updateById(projectId, { name }); const updatedProject = await projectDAL.updateById(projectId, { name });
return updatedProject; return updatedProject;
}; };
const upgradeProject = async ({ projectId, actor, actorId, userPrivateKey }: TUpgradeProjectDTO) => { const upgradeProject = async ({ projectId, actor, actorId, actorAuthMethod, userPrivateKey }: TUpgradeProjectDTO) => {
const { permission, hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId); const { permission, hasRole } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Project);
@@ -423,8 +462,8 @@ export const projectServiceFactory = ({
}); });
}; };
const getProjectUpgradeStatus = async ({ projectId, actor, actorId }: TProjectPermission) => { const getProjectUpgradeStatus = async ({ projectId, actor, actorAuthMethod, actorId }: TProjectPermission) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId); const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Secrets);
const project = await projectDAL.findProjectById(projectId); const project = await projectDAL.findProjectById(projectId);
@@ -28,16 +28,17 @@ export const secretBlindIndexServiceFactory = ({
actor, actor,
projectId, projectId,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TGetProjectBlindIndexStatusDTO) => { }: TGetProjectBlindIndexStatusDTO) => {
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId); const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId);
return Number(secretCount); return Number(secretCount);
}; };
const getProjectSecrets = async ({ projectId, actorId, actor }: TGetProjectSecretsDTO) => { const getProjectSecrets = async ({ projectId, actorId, actorAuthMethod, actor }: TGetProjectSecretsDTO) => {
const { hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId); const { hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod);
if (!hasRole(ProjectMembershipRole.Admin)) { if (!hasRole(ProjectMembershipRole.Admin)) {
throw new UnauthorizedError({ message: "User must be admin" }); throw new UnauthorizedError({ message: "User must be admin" });
} }
@@ -50,10 +51,17 @@ export const secretBlindIndexServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
secretsToUpdate secretsToUpdate
}: TUpdateProjectSecretNameDTO) => { }: TUpdateProjectSecretNameDTO) => {
const { hasRole } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { hasRole } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
if (!hasRole(ProjectMembershipRole.Admin)) { if (!hasRole(ProjectMembershipRole.Admin)) {
throw new UnauthorizedError({ message: "User must be admin" }); throw new UnauthorizedError({ message: "User must be admin" });
} }
@@ -34,12 +34,19 @@ export const secretFolderServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
name, name,
environment, environment,
path: secretPath path: secretPath
}: TCreateFolderDTO) => { }: TCreateFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@@ -114,12 +121,19 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
name, name,
environment, environment,
path: secretPath, path: secretPath,
id id
}: TUpdateFolderDTO) => { }: TUpdateFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@@ -162,11 +176,18 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
path: secretPath, path: secretPath,
idOrName idOrName
}: TDeleteFolderDTO) => { }: TDeleteFolderDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath }) subject(ProjectPermissionSub.Secrets, { environment, secretPath })
@@ -196,12 +217,13 @@ export const secretFolderServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
path: secretPath path: secretPath
}: TGetFolderDTO) => { }: TGetFolderDTO) => {
// folder list is allowed to be read by anyone // folder list is allowed to be read by anyone
// permission to check does user has access // permission to check does user has access
await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); await permissionService.getProjectPermission(actor, actorId, projectId, actorAuthMethod, actorOrgId);
const env = await projectEnvDAL.findOne({ projectId, slug: environment }); const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new BadRequestError({ message: "Environment not found", name: "get folders" }); if (!env) throw new BadRequestError({ message: "Environment not found", name: "get folders" });
@@ -45,10 +45,17 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
path path
}: TCreateSecretImportDTO) => { }: TCreateSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
// check if user has permission to import into destination path // check if user has permission to import into destination path
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
@@ -97,10 +104,17 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
data, data,
id id
}: TUpdateSecretImportDTO) => { }: TUpdateSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -144,9 +158,16 @@ export const secretImportServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
id id
}: TDeleteSecretImportDTO) => { }: TDeleteSecretImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -167,8 +188,22 @@ export const secretImportServiceFactory = ({
return secImport; return secImport;
}; };
const getImports = async ({ path, environment, projectId, actor, actorId, actorOrgId }: TGetSecretImportsDTO) => { const getImports = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); path,
environment,
projectId,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TGetSecretImportsDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -186,10 +221,17 @@ export const secretImportServiceFactory = ({
environment, environment,
projectId, projectId,
actor, actor,
actorAuthMethod,
actorId, actorId,
actorOrgId actorOrgId
}: TGetSecretsFromImportDTO) => { }: TGetSecretsFromImportDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -15,8 +15,23 @@ type TSecretTagServiceFactoryDep = {
export type TSecretTagServiceFactory = ReturnType<typeof secretTagServiceFactory>; export type TSecretTagServiceFactory = ReturnType<typeof secretTagServiceFactory>;
export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSecretTagServiceFactoryDep) => { export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSecretTagServiceFactoryDep) => {
const createTag = async ({ name, slug, actor, color, actorId, actorOrgId, projectId }: TCreateTagDTO) => { const createTag = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); name,
slug,
actor,
color,
actorId,
actorOrgId,
actorAuthMethod,
projectId
}: TCreateTagDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Tags);
const existingTag = await secretTagDAL.findOne({ slug, projectId }); const existingTag = await secretTagDAL.findOne({ slug, projectId });
@@ -32,19 +47,31 @@ export const secretTagServiceFactory = ({ secretTagDAL, permissionService }: TSe
return newTag; return newTag;
}; };
const deleteTag = async ({ actorId, actor, actorOrgId, id }: TDeleteTagDTO) => { const deleteTag = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteTagDTO) => {
const tag = await secretTagDAL.findById(id); const tag = await secretTagDAL.findById(id);
if (!tag) throw new BadRequestError({ message: "Tag doesn't exist" }); if (!tag) throw new BadRequestError({ message: "Tag doesn't exist" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, tag.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
tag.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Tags);
const deletedTag = await secretTagDAL.deleteById(tag.id); const deletedTag = await secretTagDAL.deleteById(tag.id);
return deletedTag; return deletedTag;
}; };
const getProjectTags = async ({ actor, actorId, actorOrgId, projectId }: TListProjectTagsDTO) => { const getProjectTags = async ({ actor, actorId, actorOrgId, actorAuthMethod, projectId }: TListProjectTagsDTO) => {
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.Tags); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Tags);
const tags = await secretTagDAL.find({ projectId }, { sort: [["createdAt", "asc"]] }); const tags = await secretTagDAL.find({ projectId }, { sort: [["createdAt", "asc"]] });
+83 -10
View File
@@ -145,10 +145,17 @@ export const secretServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
environment, environment,
actorAuthMethod,
projectId, projectId,
...inputSecret ...inputSecret
}: TCreateSecretDTO) => { }: TCreateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -230,10 +237,17 @@ export const secretServiceFactory = ({
actorId, actorId,
actorOrgId, actorOrgId,
environment, environment,
actorAuthMethod,
projectId, projectId,
...inputSecret ...inputSecret
}: TUpdateSecretDTO) => { }: TUpdateSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Edit, ProjectPermissionActions.Edit,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -341,11 +355,18 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
projectId, projectId,
...inputSecret ...inputSecret
}: TDeleteSecretDTO) => { }: TDeleteSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Delete, ProjectPermissionActions.Delete,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -401,9 +422,16 @@ export const secretServiceFactory = ({
projectId, projectId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
includeImports includeImports
}: TGetSecretsDTO) => { }: TGetSecretsDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -445,6 +473,7 @@ export const secretServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
environment, environment,
path, path,
@@ -453,7 +482,13 @@ export const secretServiceFactory = ({
version, version,
includeImports includeImports
}: TGetASecretDTO) => { }: TGetASecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Read, ProjectPermissionActions.Read,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -534,12 +569,19 @@ export const secretServiceFactory = ({
path, path,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
environment, environment,
projectId, projectId,
secrets: inputSecrets secrets: inputSecrets
}: TCreateBulkSecretDTO) => { }: TCreateBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -597,11 +639,18 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
projectId, projectId,
secrets: inputSecrets secrets: inputSecrets
}: TUpdateBulkSecretDTO) => { }: TUpdateBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -678,9 +727,16 @@ export const secretServiceFactory = ({
projectId, projectId,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteBulkSecretDTO) => { }: TDeleteBulkSecretDTO) => {
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionActions.Create, ProjectPermissionActions.Create,
subject(ProjectPermissionSub.Secrets, { environment, secretPath: path }) subject(ProjectPermissionSub.Secrets, { environment, secretPath: path })
@@ -728,6 +784,7 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
environment, environment,
includeImports includeImports
}: TGetSecretsRawDTO) => { }: TGetSecretsRawDTO) => {
@@ -740,6 +797,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
path, path,
includeImports includeImports
}); });
@@ -763,6 +821,7 @@ export const secretServiceFactory = ({
projectId, projectId,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
secretName, secretName,
includeImports, includeImports,
version version
@@ -773,6 +832,7 @@ export const secretServiceFactory = ({
const secret = await getSecretByName({ const secret = await getSecretByName({
actorId, actorId,
projectId, projectId,
actorAuthMethod,
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
@@ -792,6 +852,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath, secretPath,
secretValue, secretValue,
@@ -813,6 +874,7 @@ export const secretServiceFactory = ({
path: secretPath, path: secretPath,
actor, actor,
actorId, actorId,
actorAuthMethod,
actorOrgId, actorOrgId,
secretKeyCiphertext: secretKeyEncrypted.ciphertext, secretKeyCiphertext: secretKeyEncrypted.ciphertext,
secretKeyIV: secretKeyEncrypted.iv, secretKeyIV: secretKeyEncrypted.iv,
@@ -839,6 +901,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath, secretPath,
secretValue, secretValue,
@@ -858,6 +921,7 @@ export const secretServiceFactory = ({
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
secretValueCiphertext: secretValueEncrypted.ciphertext, secretValueCiphertext: secretValueEncrypted.ciphertext,
secretValueIV: secretValueEncrypted.iv, secretValueIV: secretValueEncrypted.iv,
secretValueTag: secretValueEncrypted.tag, secretValueTag: secretValueEncrypted.tag,
@@ -877,6 +941,7 @@ export const secretServiceFactory = ({
environment, environment,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
type, type,
secretPath secretPath
}: TDeleteSecretRawDTO) => { }: TDeleteSecretRawDTO) => {
@@ -891,7 +956,8 @@ export const secretServiceFactory = ({
path: secretPath, path: secretPath,
actor, actor,
actorId, actorId,
actorOrgId actorOrgId,
actorAuthMethod
}); });
await snapshotService.performSnapshot(secret.folderId); await snapshotService.performSnapshot(secret.folderId);
@@ -904,6 +970,7 @@ export const secretServiceFactory = ({
actorId, actorId,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
limit = 20, limit = 20,
offset = 0, offset = 0,
secretId secretId
@@ -914,7 +981,13 @@ export const secretServiceFactory = ({
const folder = await folderDAL.findById(secret.folderId); const folder = await folderDAL.findById(secret.folderId);
if (!folder) throw new BadRequestError({ message: "Failed to find secret" }); if (!folder) throw new BadRequestError({ message: "Failed to find secret" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, folder.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
folder.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] }); const secretVersions = await secretVersionDAL.find({ secretId }, { offset, limit, sort: [["createdAt", "desc"]] });
@@ -43,6 +43,7 @@ export const serviceTokenServiceFactory = ({
name, name,
actor, actor,
actorOrgId, actorOrgId,
actorAuthMethod,
scopes, scopes,
actorId, actorId,
projectId, projectId,
@@ -50,7 +51,13 @@ export const serviceTokenServiceFactory = ({
permissions, permissions,
encryptedKey encryptedKey
}: TCreateServiceTokenDTO) => { }: TCreateServiceTokenDTO) => {
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.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens);
scopes.forEach(({ environment, secretPath }) => { scopes.forEach(({ environment, secretPath }) => {
@@ -94,7 +101,7 @@ export const serviceTokenServiceFactory = ({
return { token, serviceToken }; return { token, serviceToken };
}; };
const deleteServiceToken = async ({ actorId, actor, actorOrgId, id }: TDeleteServiceTokenDTO) => { const deleteServiceToken = async ({ actorId, actor, actorOrgId, actorAuthMethod, id }: TDeleteServiceTokenDTO) => {
const serviceToken = await serviceTokenDAL.findById(id); const serviceToken = await serviceTokenDAL.findById(id);
if (!serviceToken) throw new BadRequestError({ message: "Token not found" }); if (!serviceToken) throw new BadRequestError({ message: "Token not found" });
@@ -102,6 +109,7 @@ export const serviceTokenServiceFactory = ({
actor, actor,
actorId, actorId,
serviceToken.projectId, serviceToken.projectId,
actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.ServiceTokens);
@@ -122,8 +130,20 @@ export const serviceTokenServiceFactory = ({
return { serviceToken, user: serviceTokenUser }; return { serviceToken, user: serviceTokenUser };
}; };
const getProjectServiceTokens = async ({ actorId, actor, actorOrgId, projectId }: TProjectServiceTokensDTO) => { const getProjectServiceTokens = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId
}: TProjectServiceTokensDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens);
const tokens = await serviceTokenDAL.find({ projectId }, { sort: [["createdAt", "desc"]] }); const tokens = await serviceTokenDAL.find({ projectId }, { sort: [["createdAt", "desc"]] });
@@ -136,6 +136,7 @@ export const superAdminServiceFactory = ({
await updateServerCfg({ initialized: true }); await updateServerCfg({ initialized: true });
const token = await authService.generateUserTokens({ const token = await authService.generateUserTokens({
user: userInfo.user, user: userInfo.user,
authMethod: AuthMethod.EMAIL,
ip, ip,
userAgent, userAgent,
organizationId: undefined organizationId: undefined
@@ -31,13 +31,20 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
actor, actor,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod,
projectId, projectId,
webhookUrl, webhookUrl,
environment, environment,
secretPath, secretPath,
webhookSecretKey webhookSecretKey
}: TCreateWebhookDTO) => { }: TCreateWebhookDTO) => {
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.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Webhooks);
const env = await projectEnvDAL.findOne({ projectId, slug: environment }); const env = await projectEnvDAL.findOne({ projectId, slug: environment });
if (!env) throw new BadRequestError({ message: "Env not found" }); if (!env) throw new BadRequestError({ message: "Env not found" });
@@ -73,33 +80,51 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
return { ...webhook, projectId, environment: env }; return { ...webhook, projectId, environment: env };
}; };
const updateWebhook = async ({ actorId, actor, actorOrgId, id, isDisabled }: TUpdateWebhookDTO) => { const updateWebhook = async ({ actorId, actor, actorOrgId, actorAuthMethod, id, isDisabled }: TUpdateWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Webhooks);
const updatedWebhook = await webhookDAL.updateById(id, { isDisabled }); const updatedWebhook = await webhookDAL.updateById(id, { isDisabled });
return { ...webhook, ...updatedWebhook }; return { ...webhook, ...updatedWebhook };
}; };
const deleteWebhook = async ({ id, actor, actorId, actorOrgId }: TDeleteWebhookDTO) => { const deleteWebhook = async ({ id, actor, actorId, actorAuthMethod, actorOrgId }: TDeleteWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Delete, ProjectPermissionSub.Webhooks);
const deletedWebhook = await webhookDAL.deleteById(id); const deletedWebhook = await webhookDAL.deleteById(id);
return { ...webhook, ...deletedWebhook }; return { ...webhook, ...deletedWebhook };
}; };
const testWebhook = async ({ id, actor, actorId, actorOrgId }: TTestWebhookDTO) => { const testWebhook = async ({ id, actor, actorId, actorAuthMethod, actorOrgId }: TTestWebhookDTO) => {
const webhook = await webhookDAL.findById(id); const webhook = await webhookDAL.findById(id);
if (!webhook) throw new BadRequestError({ message: "Webhook not found" }); if (!webhook) throw new BadRequestError({ message: "Webhook not found" });
const { permission } = await permissionService.getProjectPermission(actor, actorId, webhook.projectId, actorOrgId); const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
webhook.projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
let webhookError: string | undefined; let webhookError: string | undefined;
@@ -119,8 +144,22 @@ export const webhookServiceFactory = ({ webhookDAL, projectEnvDAL, permissionSer
return { ...webhook, ...updatedWebhook }; return { ...webhook, ...updatedWebhook };
}; };
const listWebhooks = async ({ actorId, actor, actorOrgId, projectId, secretPath, environment }: TListWebhookDTO) => { const listWebhooks = async ({
const { permission } = await permissionService.getProjectPermission(actor, actorId, projectId, actorOrgId); actorId,
actor,
actorOrgId,
actorAuthMethod,
projectId,
secretPath,
environment
}: TListWebhookDTO) => {
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
projectId,
actorAuthMethod,
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Webhooks);
return webhookDAL.findAllWebhooks(projectId, environment, secretPath); return webhookDAL.findAllWebhooks(projectId, environment, secretPath);