respect full rbac feature in auto provisioning

This commit is contained in:
miloschwartz
2026-03-28 18:09:36 -07:00
parent c6f269b3fa
commit 6ab0555148
6 changed files with 178 additions and 55 deletions

View File

@@ -15,7 +15,8 @@ export enum TierFeature {
SessionDurationPolicies = "sessionDurationPolicies", // handle downgrade by setting to default duration
PasswordExpirationPolicies = "passwordExpirationPolicies", // handle downgrade by setting to default duration
AutoProvisioning = "autoProvisioning", // handle downgrade by disabling auto provisioning
SshPam = "sshPam"
SshPam = "sshPam",
FullRbac = "fullRbac"
}
export const tierMatrix: Record<TierFeature, Tier[]> = {
@@ -48,5 +49,6 @@ export const tierMatrix: Record<TierFeature, Tier[]> = {
"enterprise"
],
[TierFeature.AutoProvisioning]: ["tier1", "tier3", "enterprise"],
[TierFeature.SshPam]: ["tier1", "tier3", "enterprise"]
[TierFeature.SshPam]: ["tier1", "tier3", "enterprise"],
[TierFeature.FullRbac]: ["tier1", "tier2", "tier3", "enterprise"]
};

View File

@@ -26,9 +26,10 @@ import {
orgs,
resources,
roles,
siteResources
siteResources,
userOrgRoles
} from "@server/db";
import { eq } from "drizzle-orm";
import { and, eq } from "drizzle-orm";
/**
* Get the maximum allowed retention days for a given tier
@@ -291,6 +292,10 @@ async function disableFeature(
await disableSshPam(orgId);
break;
case TierFeature.FullRbac:
await disableFullRbac(orgId);
break;
default:
logger.warn(
`Unknown feature ${feature} for org ${orgId}, skipping`
@@ -326,6 +331,10 @@ async function disableSshPam(orgId: string): Promise<void> {
);
}
async function disableFullRbac(orgId: string): Promise<void> {
logger.info(`Disabled full RBAC for org ${orgId}`);
}
async function disableLoginPageBranding(orgId: string): Promise<void> {
const [existingBranding] = await db
.select()

View File

@@ -36,6 +36,7 @@ import { usageService } from "@server/lib/billing/usageService";
import { build } from "@server/build";
import { calculateUserClientsForOrgs } from "@server/lib/calculateUserClientsForOrgs";
import { isSubscribed } from "#dynamic/lib/isSubscribed";
import { isLicensedOrSubscribed } from "#dynamic/lib/isLicencedOrSubscribed";
import { tierMatrix } from "@server/lib/billing/tierMatrix";
import {
assignUserToOrg,
@@ -415,7 +416,15 @@ export async function validateOidcCallback(
roleMappingResult
);
if (!roleNames.length) {
const supportsMultiRole = await isLicensedOrSubscribed(
org.orgId,
tierMatrix.fullRbac
);
const effectiveRoleNames = supportsMultiRole
? roleNames
: roleNames.slice(0, 1);
if (!effectiveRoleNames.length) {
logger.error("Role mapping returned no valid roles", {
roleMappingResult
});
@@ -428,14 +437,14 @@ export async function validateOidcCallback(
.where(
and(
eq(roles.orgId, org.orgId),
inArray(roles.name, roleNames)
inArray(roles.name, effectiveRoleNames)
)
);
if (!roleRes.length) {
logger.error("No mapped roles found in organization", {
orgId: org.orgId,
roleNames
roleNames: effectiveRoleNames
});
continue;
}