mirror of
https://github.com/Dokploy/dokploy
synced 2025-06-26 18:27:59 +00:00
refactor: update permission checks to use organization context
This commit is contained in:
@@ -155,7 +155,7 @@ const MENU: Menu = {
|
|||||||
// Only enabled for admins and users with access to Traefik files in non-cloud environments
|
// Only enabled for admins and users with access to Traefik files in non-cloud environments
|
||||||
isEnabled: ({ auth, isCloud }) =>
|
isEnabled: ({ auth, isCloud }) =>
|
||||||
!!(
|
!!(
|
||||||
(auth?.role === "owner" || auth?.user?.canAccessToTraefikFiles) &&
|
(auth?.role === "owner" || auth?.canAccessToTraefikFiles) &&
|
||||||
!isCloud
|
!isCloud
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -166,10 +166,7 @@ const MENU: Menu = {
|
|||||||
icon: BlocksIcon,
|
icon: BlocksIcon,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, isCloud }) =>
|
isEnabled: ({ auth, isCloud }) =>
|
||||||
!!(
|
!!((auth?.role === "owner" || auth?.canAccessToDocker) && !isCloud),
|
||||||
(auth?.role === "owner" || auth?.user?.canAccessToDocker) &&
|
|
||||||
!isCloud
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -178,10 +175,7 @@ const MENU: Menu = {
|
|||||||
icon: PieChart,
|
icon: PieChart,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, isCloud }) =>
|
isEnabled: ({ auth, isCloud }) =>
|
||||||
!!(
|
!!((auth?.role === "owner" || auth?.canAccessToDocker) && !isCloud),
|
||||||
(auth?.role === "owner" || auth?.user?.canAccessToDocker) &&
|
|
||||||
!isCloud
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -190,10 +184,7 @@ const MENU: Menu = {
|
|||||||
icon: Forward,
|
icon: Forward,
|
||||||
// Only enabled for admins and users with access to Docker in non-cloud environments
|
// Only enabled for admins and users with access to Docker in non-cloud environments
|
||||||
isEnabled: ({ auth, isCloud }) =>
|
isEnabled: ({ auth, isCloud }) =>
|
||||||
!!(
|
!!((auth?.role === "owner" || auth?.canAccessToDocker) && !isCloud),
|
||||||
(auth?.role === "owner" || auth?.user?.canAccessToDocker) &&
|
|
||||||
!isCloud
|
|
||||||
),
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Legacy unused menu, adjusted to the new structure
|
// Legacy unused menu, adjusted to the new structure
|
||||||
@@ -291,7 +282,7 @@ const MENU: Menu = {
|
|||||||
url: "/dashboard/settings/ssh-keys",
|
url: "/dashboard/settings/ssh-keys",
|
||||||
// Only enabled for admins and users with access to SSH keys
|
// Only enabled for admins and users with access to SSH keys
|
||||||
isEnabled: ({ auth }) =>
|
isEnabled: ({ auth }) =>
|
||||||
!!(auth?.role === "owner" || auth?.user?.canAccessToSSHKeys),
|
!!(auth?.role === "owner" || auth?.canAccessToSSHKeys),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
@@ -300,7 +291,7 @@ const MENU: Menu = {
|
|||||||
icon: GitBranch,
|
icon: GitBranch,
|
||||||
// Only enabled for admins and users with access to Git providers
|
// Only enabled for admins and users with access to Git providers
|
||||||
isEnabled: ({ auth }) =>
|
isEnabled: ({ auth }) =>
|
||||||
!!(auth?.role === "owner" || auth?.user?.canAccessToGitProviders),
|
!!(auth?.role === "owner" || auth?.canAccessToGitProviders),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
isSingle: true,
|
isSingle: true,
|
||||||
|
|||||||
@@ -38,7 +38,11 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ ctx, input }) => {
|
.mutation(async ({ ctx, input }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "member") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkProjectAccess(ctx.user.id, "create");
|
await checkProjectAccess(
|
||||||
|
ctx.user.id,
|
||||||
|
"create",
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const admin = await findUserById(ctx.user.ownerId);
|
const admin = await findUserById(ctx.user.ownerId);
|
||||||
@@ -55,7 +59,11 @@ export const projectRouter = createTRPCRouter({
|
|||||||
ctx.session.activeOrganizationId,
|
ctx.session.activeOrganizationId,
|
||||||
);
|
);
|
||||||
if (ctx.user.rol === "member") {
|
if (ctx.user.rol === "member") {
|
||||||
await addNewProject(ctx.user.id, project.projectId);
|
await addNewProject(
|
||||||
|
ctx.user.id,
|
||||||
|
project.projectId,
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
@@ -77,7 +85,12 @@ export const projectRouter = createTRPCRouter({
|
|||||||
ctx.session.activeOrganizationId,
|
ctx.session.activeOrganizationId,
|
||||||
);
|
);
|
||||||
|
|
||||||
await checkProjectAccess(ctx.user.id, "access", input.projectId);
|
await checkProjectAccess(
|
||||||
|
ctx.user.id,
|
||||||
|
"access",
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
input.projectId,
|
||||||
|
);
|
||||||
|
|
||||||
const project = await db.query.projects.findFirst({
|
const project = await db.query.projects.findFirst({
|
||||||
where: and(
|
where: and(
|
||||||
@@ -212,7 +225,11 @@ export const projectRouter = createTRPCRouter({
|
|||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
try {
|
try {
|
||||||
if (ctx.user.rol === "member") {
|
if (ctx.user.rol === "member") {
|
||||||
await checkProjectAccess(ctx.user.id, "delete");
|
await checkProjectAccess(
|
||||||
|
ctx.user.id,
|
||||||
|
"delete",
|
||||||
|
ctx.session.activeOrganizationId,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const currentProject = await findProjectById(input.projectId);
|
const currentProject = await findProjectById(input.projectId);
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -33,32 +33,48 @@ export const findUserByAuthId = async (authId: string) => {
|
|||||||
// return userR;
|
// return userR;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addNewProject = async (userId: string, projectId: string) => {
|
export const addNewProject = async (
|
||||||
const userR = await findUserById(userId);
|
userId: string,
|
||||||
|
projectId: string,
|
||||||
|
organizationId: string,
|
||||||
|
) => {
|
||||||
|
const userR = await findMemberById(userId, organizationId);
|
||||||
|
|
||||||
// await db
|
await db
|
||||||
// .update(user)
|
.update(member)
|
||||||
// .set({
|
.set({
|
||||||
// accessedProjects: [...userR.accessedProjects, projectId],
|
accessedProjects: [...userR.accessedProjects, projectId],
|
||||||
// })
|
})
|
||||||
// .where(eq(user.authId, authId));
|
.where(
|
||||||
|
and(eq(member.id, userR.id), eq(member.organizationId, organizationId)),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const addNewService = async (userId: string, serviceId: string) => {
|
export const addNewService = async (
|
||||||
const userR = await findUserById(userId);
|
userId: string,
|
||||||
// await db
|
serviceId: string,
|
||||||
// .update(user)
|
organizationId: string,
|
||||||
// .set({
|
) => {
|
||||||
// accessedServices: [...userR.accessedServices, serviceId],
|
const userR = await findMemberById(userId, organizationId);
|
||||||
// })
|
await db
|
||||||
// .where(eq(user.userId, userId));
|
.update(member)
|
||||||
|
.set({
|
||||||
|
accessedServices: [...userR.accessedServices, serviceId],
|
||||||
|
})
|
||||||
|
.where(
|
||||||
|
and(eq(member.id, userR.id), eq(member.organizationId, organizationId)),
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const canPerformCreationService = async (
|
export const canPerformCreationService = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
|
organizationId: string,
|
||||||
) => {
|
) => {
|
||||||
const { accessedProjects, canCreateServices } = await findUserById(userId);
|
const { accessedProjects, canCreateServices } = await findMemberById(
|
||||||
|
userId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
const haveAccessToProject = accessedProjects.includes(projectId);
|
const haveAccessToProject = accessedProjects.includes(projectId);
|
||||||
|
|
||||||
if (canCreateServices && haveAccessToProject) {
|
if (canCreateServices && haveAccessToProject) {
|
||||||
@@ -71,8 +87,9 @@ export const canPerformCreationService = async (
|
|||||||
export const canPerformAccessService = async (
|
export const canPerformAccessService = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
serviceId: string,
|
serviceId: string,
|
||||||
|
organizationId: string,
|
||||||
) => {
|
) => {
|
||||||
const { accessedServices } = await findUserById(userId);
|
const { accessedServices } = await findMemberById(userId, organizationId);
|
||||||
const haveAccessToService = accessedServices.includes(serviceId);
|
const haveAccessToService = accessedServices.includes(serviceId);
|
||||||
|
|
||||||
if (haveAccessToService) {
|
if (haveAccessToService) {
|
||||||
@@ -85,8 +102,12 @@ export const canPerformAccessService = async (
|
|||||||
export const canPeformDeleteService = async (
|
export const canPeformDeleteService = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
serviceId: string,
|
serviceId: string,
|
||||||
|
organizationId: string,
|
||||||
) => {
|
) => {
|
||||||
const { accessedServices, canDeleteServices } = await findUserById(userId);
|
const { accessedServices, canDeleteServices } = await findMemberById(
|
||||||
|
userId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
const haveAccessToService = accessedServices.includes(serviceId);
|
const haveAccessToService = accessedServices.includes(serviceId);
|
||||||
|
|
||||||
if (canDeleteServices && haveAccessToService) {
|
if (canDeleteServices && haveAccessToService) {
|
||||||
@@ -96,8 +117,11 @@ export const canPeformDeleteService = async (
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const canPerformCreationProject = async (userId: string) => {
|
export const canPerformCreationProject = async (
|
||||||
const { canCreateProjects } = await findUserById(userId);
|
userId: string,
|
||||||
|
organizationId: string,
|
||||||
|
) => {
|
||||||
|
const { canCreateProjects } = await findMemberById(userId, organizationId);
|
||||||
|
|
||||||
if (canCreateProjects) {
|
if (canCreateProjects) {
|
||||||
return true;
|
return true;
|
||||||
@@ -106,8 +130,11 @@ export const canPerformCreationProject = async (userId: string) => {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const canPerformDeleteProject = async (userId: string) => {
|
export const canPerformDeleteProject = async (
|
||||||
const { canDeleteProjects } = await findUserById(userId);
|
userId: string,
|
||||||
|
organizationId: string,
|
||||||
|
) => {
|
||||||
|
const { canDeleteProjects } = await findMemberById(userId, organizationId);
|
||||||
|
|
||||||
if (canDeleteProjects) {
|
if (canDeleteProjects) {
|
||||||
return true;
|
return true;
|
||||||
@@ -119,8 +146,9 @@ export const canPerformDeleteProject = async (userId: string) => {
|
|||||||
export const canPerformAccessProject = async (
|
export const canPerformAccessProject = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
projectId: string,
|
projectId: string,
|
||||||
|
organizationId: string,
|
||||||
) => {
|
) => {
|
||||||
const { accessedProjects } = await findUserById(userId);
|
const { accessedProjects } = await findMemberById(userId, organizationId);
|
||||||
|
|
||||||
const haveAccessToProject = accessedProjects.includes(projectId);
|
const haveAccessToProject = accessedProjects.includes(projectId);
|
||||||
|
|
||||||
@@ -130,26 +158,45 @@ export const canPerformAccessProject = async (
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const canAccessToTraefikFiles = async (userId: string) => {
|
export const canAccessToTraefikFiles = async (
|
||||||
const { canAccessToTraefikFiles } = await findUserById(userId);
|
userId: string,
|
||||||
|
organizationId: string,
|
||||||
|
) => {
|
||||||
|
const { canAccessToTraefikFiles } = await findMemberById(
|
||||||
|
userId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
return canAccessToTraefikFiles;
|
return canAccessToTraefikFiles;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const checkServiceAccess = async (
|
export const checkServiceAccess = async (
|
||||||
userId: string,
|
userId: string,
|
||||||
serviceId: string,
|
serviceId: string,
|
||||||
|
organizationId: string,
|
||||||
action = "access" as "access" | "create" | "delete",
|
action = "access" as "access" | "create" | "delete",
|
||||||
) => {
|
) => {
|
||||||
let hasPermission = false;
|
let hasPermission = false;
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "create":
|
case "create":
|
||||||
hasPermission = await canPerformCreationService(userId, serviceId);
|
hasPermission = await canPerformCreationService(
|
||||||
|
userId,
|
||||||
|
serviceId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "access":
|
case "access":
|
||||||
hasPermission = await canPerformAccessService(userId, serviceId);
|
hasPermission = await canPerformAccessService(
|
||||||
|
userId,
|
||||||
|
serviceId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
hasPermission = await canPeformDeleteService(userId, serviceId);
|
hasPermission = await canPeformDeleteService(
|
||||||
|
userId,
|
||||||
|
serviceId,
|
||||||
|
organizationId,
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hasPermission = false;
|
hasPermission = false;
|
||||||
@@ -165,6 +212,7 @@ export const checkServiceAccess = async (
|
|||||||
export const checkProjectAccess = async (
|
export const checkProjectAccess = async (
|
||||||
authId: string,
|
authId: string,
|
||||||
action: "create" | "delete" | "access",
|
action: "create" | "delete" | "access",
|
||||||
|
organizationId: string,
|
||||||
projectId?: string,
|
projectId?: string,
|
||||||
) => {
|
) => {
|
||||||
let hasPermission = false;
|
let hasPermission = false;
|
||||||
@@ -173,13 +221,14 @@ export const checkProjectAccess = async (
|
|||||||
hasPermission = await canPerformAccessProject(
|
hasPermission = await canPerformAccessProject(
|
||||||
authId,
|
authId,
|
||||||
projectId as string,
|
projectId as string,
|
||||||
|
organizationId,
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "create":
|
case "create":
|
||||||
hasPermission = await canPerformCreationProject(authId);
|
hasPermission = await canPerformCreationProject(authId, organizationId);
|
||||||
break;
|
break;
|
||||||
case "delete":
|
case "delete":
|
||||||
hasPermission = await canPerformDeleteProject(authId);
|
hasPermission = await canPerformDeleteProject(authId, organizationId);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hasPermission = false;
|
hasPermission = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user