refactor: use permission check service in /organizations endpoints (#24099)
* getUserConnectedApps * create teams * use permission check in team deletion * team read * revert * publish handler * wip
This commit is contained in:
+17
-4
@@ -1,6 +1,7 @@
|
||||
import { isOrganisationAdmin } from "@calcom/lib/server/queries/organisations";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import prisma from "@calcom/prisma";
|
||||
import type { Prisma } from "@calcom/prisma/client";
|
||||
import { MembershipRole } from "@calcom/prisma/client";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
@@ -18,9 +19,21 @@ type AddBulkToEventTypeHandler = {
|
||||
export async function addMembersToEventTypesHandler({ ctx, input }: AddBulkToEventTypeHandler) {
|
||||
if (!ctx.user.organizationId) throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
|
||||
// check if user is admin of organization
|
||||
if (!(await isOrganisationAdmin(ctx.user?.id, ctx.user.organizationId)))
|
||||
throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
// Check if user has permission to manage event types in the organization
|
||||
const permissionCheckService = new PermissionCheckService();
|
||||
const hasPermission = await permissionCheckService.checkPermission({
|
||||
userId: ctx.user.id,
|
||||
teamId: ctx.user.organizationId,
|
||||
permission: "eventType.update",
|
||||
fallbackRoles: [MembershipRole.OWNER, MembershipRole.ADMIN],
|
||||
});
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to manage event types in this organization",
|
||||
});
|
||||
}
|
||||
|
||||
const { eventTypeIds, teamIds, userIds } = input;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains";
|
||||
import stripe from "@calcom/features/ee/payments/server/stripe";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import logger from "@calcom/lib/logger";
|
||||
import { safeStringify } from "@calcom/lib/safeStringify";
|
||||
import { UserRepository } from "@calcom/lib/server/repository/user";
|
||||
@@ -41,24 +42,20 @@ export const createTeamsHandler = async ({ ctx, input }: CreateTeamsOptions) =>
|
||||
throw new NotAuthorizedError();
|
||||
}
|
||||
|
||||
// Validate user membership role
|
||||
const userMembershipRole = await prisma.membership.findFirst({
|
||||
where: {
|
||||
userId: organizationOwner.id,
|
||||
teamId: orgId,
|
||||
role: {
|
||||
in: ["OWNER", "ADMIN"],
|
||||
},
|
||||
// @TODO: not sure if this already setup earlier
|
||||
// accepted: true,
|
||||
},
|
||||
select: {
|
||||
role: true,
|
||||
},
|
||||
// Validate user has permission to create teams in the organization
|
||||
const permissionCheckService = new PermissionCheckService();
|
||||
const hasPermission = await permissionCheckService.checkPermission({
|
||||
userId: organizationOwner.id,
|
||||
teamId: orgId,
|
||||
permission: "team.create",
|
||||
fallbackRoles: [MembershipRole.OWNER, MembershipRole.ADMIN],
|
||||
});
|
||||
|
||||
if (!userMembershipRole) {
|
||||
log.error("User is not a member of the organization", safeStringify({ orgId, organizationOwner }));
|
||||
if (!hasPermission) {
|
||||
log.error(
|
||||
"User is not authorized to create teams in the organization",
|
||||
safeStringify({ orgId, organizationOwner })
|
||||
);
|
||||
throw new NotAuthorizedError();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,52 @@
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { MembershipRole } from "@calcom/prisma/client";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
|
||||
import type { TrpcSessionUser } from "../../../types";
|
||||
import type { TDeleteTeamInputSchema } from "./deleteTeam.schema";
|
||||
|
||||
type DeleteOptions = {
|
||||
ctx: {
|
||||
user: NonNullable<TrpcSessionUser>;
|
||||
};
|
||||
input: TDeleteTeamInputSchema;
|
||||
};
|
||||
|
||||
export const deleteTeamHandler = async ({ input }: DeleteOptions) => {
|
||||
export const deleteTeamHandler = async ({ ctx, input }: DeleteOptions) => {
|
||||
const team = await prisma.team.findUnique({
|
||||
where: { id: input.teamId },
|
||||
select: {
|
||||
id: true,
|
||||
parentId: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!team) {
|
||||
throw new TRPCError({ code: "NOT_FOUND", message: "Team not found" });
|
||||
}
|
||||
|
||||
if (!team.parentId) {
|
||||
throw new TRPCError({ code: "BAD_REQUEST", message: "Can only delete teams within organizations" });
|
||||
}
|
||||
|
||||
// Check if user has permission to delete teams in this organization
|
||||
const permissionCheckService = new PermissionCheckService();
|
||||
const hasPermission = await permissionCheckService.checkPermission({
|
||||
userId: ctx.user.id,
|
||||
teamId: team.parentId,
|
||||
permission: "team.delete",
|
||||
fallbackRoles: [MembershipRole.OWNER, MembershipRole.ADMIN],
|
||||
});
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to delete teams in this organization",
|
||||
});
|
||||
}
|
||||
|
||||
// delete all memberships
|
||||
await prisma.membership.deleteMany({
|
||||
where: {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getRequestedSlugError } from "@calcom/app-store/stripepayment/lib/team-billing";
|
||||
import { purchaseTeamOrOrgSubscription } from "@calcom/features/ee/teams/lib/payments";
|
||||
import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service";
|
||||
import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { isOrganisationAdmin } from "@calcom/lib/server/queries/organisations";
|
||||
import { prisma } from "@calcom/prisma";
|
||||
import { MembershipRole } from "@calcom/prisma/client";
|
||||
import { teamMetadataStrictSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { TRPCError } from "@trpc/server";
|
||||
@@ -20,7 +21,21 @@ export const publishHandler = async ({ ctx }: PublishOptions) => {
|
||||
if (!orgId)
|
||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "You do not have an organization to upgrade" });
|
||||
|
||||
if (!(await isOrganisationAdmin(ctx.user.id, orgId))) throw new TRPCError({ code: "UNAUTHORIZED" });
|
||||
// Check if user has permission to publish the organization
|
||||
const permissionCheckService = new PermissionCheckService();
|
||||
const hasPermission = await permissionCheckService.checkPermission({
|
||||
userId: ctx.user.id,
|
||||
teamId: orgId,
|
||||
permission: "organization.update",
|
||||
fallbackRoles: [MembershipRole.OWNER, MembershipRole.ADMIN],
|
||||
});
|
||||
|
||||
if (!hasPermission) {
|
||||
throw new TRPCError({
|
||||
code: "UNAUTHORIZED",
|
||||
message: "You are not authorized to publish this organization",
|
||||
});
|
||||
}
|
||||
|
||||
const prevTeam = await prisma.team.findUnique({
|
||||
where: {
|
||||
@@ -66,7 +81,6 @@ export const publishHandler = async ({ ctx }: PublishOptions) => {
|
||||
const { requestedSlug, ...newMetadata } = metadata.data;
|
||||
let updatedTeam: Awaited<ReturnType<typeof prisma.team.update>>;
|
||||
|
||||
|
||||
try {
|
||||
updatedTeam = await prisma.team.update({
|
||||
where: { id: orgId },
|
||||
|
||||
Reference in New Issue
Block a user