update policy access control

This commit is contained in:
Fred KISSIE
2026-03-03 01:33:37 +01:00
parent 033cc62ce7
commit 5c280b024e
6 changed files with 335 additions and 190 deletions

View File

@@ -6,6 +6,8 @@ import createHttpError from "http-errors";
import { fromError } from "zod-validation-error";
import {
db,
idp,
idpOrg,
orgs,
resourcePolicies,
rolePolicies,
@@ -107,15 +109,23 @@ export async function createResourcePolicy(
const { name, sso, userIds, roleIds, skipToIdpId } = parsedBody.data;
const isAuthEnabeld = sso; // other conditions will follow
// Check if Identity provider in `skipToIdpId` exists
if (skipToIdpId) {
const [provider] = await db
.select()
.from(idp)
.innerJoin(idpOrg, eq(idpOrg.idpId, idp.idpId))
.where(and(eq(idp.idpId, skipToIdpId), eq(idpOrg.orgId, orgId)))
.limit(1);
if (!isAuthEnabeld) {
return next(
createHttpError(
HttpCode.BAD_REQUEST,
"At least one authentication policy must be set: platform SSO, an authentication method, one-time password, or a rule."
)
);
if (!provider) {
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Identity provider not found in this organization"
)
);
}
}
const adminRole = await db
@@ -163,7 +173,8 @@ export async function createResourcePolicy(
niceId,
orgId,
name,
sso
sso,
idpId: skipToIdpId
})
.returning();

View File

@@ -1,9 +1,17 @@
import { db, resourcePolicies, rolePolicies, userPolicies } from "@server/db";
import {
db,
idp,
resourcePolicies,
rolePolicies,
roles,
userPolicies,
users
} from "@server/db";
import response from "@server/lib/response";
import logger from "@server/logger";
import { OpenAPITags, registry } from "@server/openApi";
import HttpCode from "@server/types/HttpCode";
import { and, eq, type SQL } from "drizzle-orm";
import { and, eq, isNull, not, or, type SQL } from "drizzle-orm";
import type { NextFunction, Request, Response } from "express";
import createHttpError from "http-errors";
import z from "zod";
@@ -34,26 +42,48 @@ async function query(params: z.infer<typeof getResourcePolicySchema>) {
}
const [res] = await db
.select({
policy: resourcePolicies,
userPolicies,
rolePolicies
})
.select()
.from(resourcePolicies)
.leftJoin(
userPolicies,
eq(userPolicies.resourcePolicyId, resourcePolicies.resourcePolicyId)
)
.leftJoin(
rolePolicies,
eq(rolePolicies.resourcePolicyId, resourcePolicies.resourcePolicyId)
)
.where(and(...conditions))
.limit(1);
return res;
if (!res) return null;
const policyUsers = await db
.select({
userId: userPolicies.userId,
email: users.email,
name: users.name,
username: users.username,
type: users.type,
idpName: idp.name
})
.from(userPolicies)
.innerJoin(users, eq(userPolicies.userId, users.userId))
.leftJoin(idp, eq(idp.idpId, users.idpId))
.where(eq(userPolicies.resourcePolicyId, res.resourcePolicyId));
const policyRoles = await db
.select({
roleId: rolePolicies.roleId,
name: roles.name
})
.from(rolePolicies)
.innerJoin(
roles,
and(
eq(rolePolicies.roleId, roles.roleId),
or(isNull(roles.isAdmin), not(roles.isAdmin))
)
)
.where(eq(rolePolicies.resourcePolicyId, res.resourcePolicyId));
return { ...res, roles: policyRoles, users: policyUsers };
}
export type GetResourcePolicyResponse = Awaited<ReturnType<typeof query>>;
export type GetResourcePolicyResponse = NonNullable<
Awaited<ReturnType<typeof query>>
>;
registry.registerPath({
method: "get",

View File

@@ -16,14 +16,14 @@ import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors";
import logger from "@server/logger";
import { fromError } from "zod-validation-error";
import { and, eq, inArray, ne, type InferInsertModel } from "drizzle-orm";
import { and, eq, inArray, ne } from "drizzle-orm";
import { OpenAPITags, registry } from "@server/openApi";
const setResourcePolicyAcccessControlBodySchema = z.strictObject({
sso: z.boolean(),
userIds: z.array(z.string()),
roleIds: z.array(z.int().positive()),
skipToIdpId: z.int().positive().optional()
skipToIdpId: z.int().positive().optional().nullish()
});
const setResourcePolicyAccessControlParamsSchema = z.strictObject({