fix: org admin/owner can access routng form (#25412)
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
import { enrichFormWithMigrationData } from "@calcom/app-store/routing-forms/enrichFormWithMigrationData";
|
||||
import { getSerializableForm } from "@calcom/app-store/routing-forms/lib/getSerializableForm";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
import { Resource } from "@calcom/features/pbac/domain/types/permission-registry";
|
||||
import { getResourcePermissions } from "@calcom/features/pbac/lib/resource-permissions";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { getRoutingFormPermissions } from "@calcom/features/pbac/lib/resource-permissions";
|
||||
import type { AppGetServerSidePropsContext, AppPrisma, AppUser } from "@calcom/types/AppGetServerSideProps";
|
||||
|
||||
export const getServerSidePropsForSingleFormView = async function getServerSidePropsForSingleFormView(
|
||||
@@ -78,7 +75,7 @@ export const getServerSidePropsForSingleFormView = async function getServerSideP
|
||||
};
|
||||
}
|
||||
|
||||
const { user: u, ...formWithoutUser } = form;
|
||||
const { user: _u, ...formWithoutUser } = form;
|
||||
|
||||
const formWithoutProfileInfo = {
|
||||
...formWithoutUser,
|
||||
@@ -98,55 +95,17 @@ export const getServerSidePropsForSingleFormView = async function getServerSideP
|
||||
user: await userRepo.enrichUserWithItsProfile({ user: form.user }),
|
||||
};
|
||||
|
||||
// Get PBAC permissions for team-scoped routing forms
|
||||
let permissions = {
|
||||
canCreate: false,
|
||||
canRead: false,
|
||||
canEdit: false,
|
||||
canDelete: false,
|
||||
};
|
||||
const permissions = await getRoutingFormPermissions({
|
||||
userId: user.id,
|
||||
formUserId: form.userId,
|
||||
formTeamId: form.teamId,
|
||||
formTeamParentId: form.team?.parentId ?? null,
|
||||
});
|
||||
|
||||
if (!form.teamId) {
|
||||
// For personal forms (teamId = null),
|
||||
// check if the form belongs to the current user
|
||||
if (form.userId !== user.id) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
permissions = {
|
||||
canCreate: true,
|
||||
canRead: true,
|
||||
canEdit: true,
|
||||
canDelete: true,
|
||||
if (!permissions) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
} else {
|
||||
// team-scoped routing form
|
||||
// Get user's role in the team
|
||||
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
|
||||
userId: user.id,
|
||||
teamId: form.teamId,
|
||||
});
|
||||
|
||||
if (!membership) {
|
||||
return {
|
||||
notFound: true,
|
||||
};
|
||||
}
|
||||
|
||||
permissions = await getResourcePermissions({
|
||||
userId: user.id,
|
||||
teamId: form.teamId,
|
||||
resource: Resource.RoutingForm,
|
||||
userRole: membership.role,
|
||||
fallbackRoles: {
|
||||
read: { roles: [MembershipRole.MEMBER, MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
create: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
update: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
delete: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { FeaturesRepository } from "@calcom/features/flags/features.repository";
|
||||
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import type { MembershipRole } from "@calcom/prisma/enums";
|
||||
import { MembershipRole } from "@calcom/prisma/enums";
|
||||
|
||||
import { PermissionMapper } from "../domain/mappers/PermissionMapper";
|
||||
import type { Resource, CustomAction } from "../domain/types/permission-registry";
|
||||
import { CrudAction } from "../domain/types/permission-registry";
|
||||
import type { CustomAction } from "../domain/types/permission-registry";
|
||||
import { CrudAction, Resource } from "../domain/types/permission-registry";
|
||||
import { PermissionCheckService } from "../services/permission-check.service";
|
||||
|
||||
interface RoleMapping {
|
||||
@@ -140,3 +141,72 @@ export const getSpecificPermissions = async ({
|
||||
|
||||
return permissions;
|
||||
};
|
||||
|
||||
export async function getRoutingFormPermissions({
|
||||
userId,
|
||||
formUserId,
|
||||
formTeamId,
|
||||
formTeamParentId,
|
||||
}: {
|
||||
userId: number;
|
||||
formUserId: number;
|
||||
formTeamId: number | null;
|
||||
formTeamParentId: number | null;
|
||||
}): Promise<ResourcePermissions | null> {
|
||||
if (!formTeamId) {
|
||||
if (formUserId !== userId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
canCreate: true,
|
||||
canRead: true,
|
||||
canEdit: true,
|
||||
canDelete: true,
|
||||
};
|
||||
}
|
||||
|
||||
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
|
||||
userId,
|
||||
teamId: formTeamId,
|
||||
});
|
||||
|
||||
let isParentOrgAdmin = false;
|
||||
if (!membership && formTeamParentId) {
|
||||
const parentOrgMembership = await MembershipRepository.getAdminOrOwnerMembership(
|
||||
userId,
|
||||
formTeamParentId
|
||||
);
|
||||
isParentOrgAdmin = !!parentOrgMembership;
|
||||
}
|
||||
|
||||
if (!membership && !isParentOrgAdmin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!membership && isParentOrgAdmin) {
|
||||
return {
|
||||
canCreate: true,
|
||||
canRead: true,
|
||||
canEdit: true,
|
||||
canDelete: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (membership) {
|
||||
return await getResourcePermissions({
|
||||
userId,
|
||||
teamId: formTeamId,
|
||||
resource: Resource.RoutingForm,
|
||||
userRole: membership.role,
|
||||
fallbackRoles: {
|
||||
read: { roles: [MembershipRole.MEMBER, MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
create: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
update: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
delete: { roles: [MembershipRole.ADMIN, MembershipRole.OWNER] },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user