Pull the rules and the policy information

This commit is contained in:
Owen
2026-06-03 15:33:15 -07:00
parent 40125c717c
commit cc5bec1d83
3 changed files with 159 additions and 46 deletions

View File

@@ -36,7 +36,8 @@ import {
ResourcePolicyHeaderAuth
} from "@server/db";
import { alias } from "drizzle-orm/sqlite-core";
import { and, eq, inArray, or, sql } from "drizzle-orm";
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
import logger from "@server/logger";
export type ResourceWithAuth = {
resource: Resource | null;
@@ -44,6 +45,7 @@ export type ResourceWithAuth = {
password: ResourcePassword | ResourcePolicyPassword | null;
headerAuth: ResourceHeaderAuth | ResourcePolicyHeaderAuth | null;
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
applyRules: boolean;
org: Org;
};
@@ -213,9 +215,14 @@ export async function getResourceByDomain(
const effectivePolicyHeaderAuth = hasSharedPolicy
? result.sharedPolicyHeaderAuth
: (result.defaultPolicyHeaderAuth ?? null);
const effectiveApplyRules =
(hasSharedPolicy
? (result.sharedPolicy?.applyRules ?? false)
: (result.defaultPolicy?.applyRules ?? false)) ||
result.resources.applyRules;
return {
resource: result.resources,
resource: { ...result.resources, applyRules: effectiveApplyRules }, // doing this for backward compatability so the remote nodes get the value as part of the resource struct
pincode: effectivePolicyPincode ?? result.resourcePincode,
password: effectivePolicyPassword ?? result.resourcePassword,
headerAuth: effectivePolicyHeaderAuth ?? result.resourceHeaderAuth,
@@ -227,6 +234,7 @@ export async function getResourceByDomain(
effectivePolicyHeaderAuth.extendedCompatibility
} as ResourceHeaderAuthExtendedCompatibility)
: result.resourceHeaderAuthExtendedCompatibility,
applyRules: effectiveApplyRules,
org: result.orgs
};
}
@@ -290,7 +298,21 @@ export async function getRoleResourceAccess(
.from(rolePolicies)
.innerJoin(
resources,
eq(resources.resourcePolicyId, rolePolicies.resourcePolicyId)
// Shared policy wins; only use default policy when no shared
// policy is assigned to the resource.
or(
eq(
resources.resourcePolicyId,
rolePolicies.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
rolePolicies.resourcePolicyId
)
)
)
)
.where(
and(
@@ -330,7 +352,21 @@ export async function getUserResourceAccess(
.from(userPolicies)
.innerJoin(
resources,
eq(resources.resourcePolicyId, userPolicies.resourcePolicyId)
// Shared policy wins; only use default policy when no shared
// policy is assigned to the resource.
or(
eq(
resources.resourcePolicyId,
userPolicies.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
userPolicies.resourcePolicyId
)
)
)
)
.where(
and(
@@ -368,9 +404,20 @@ export async function getResourceRules(
.from(resourcePolicyRules)
.innerJoin(
resources,
eq(
resources.resourcePolicyId,
resourcePolicyRules.resourcePolicyId
// Shared policy wins; only use default policy when no shared
// policy is assigned to the resource.
or(
eq(
resources.resourcePolicyId,
resourcePolicyRules.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
resourcePolicyRules.resourcePolicyId
)
)
)
)
.where(eq(resources.resourceId, resourceId))

View File

@@ -60,7 +60,7 @@ import {
userOrgRoles,
roles
} from "@server/db";
import { eq, and, inArray, isNotNull, ne, or, sql } from "drizzle-orm";
import { eq, and, inArray, isNotNull, isNull, ne, or, sql } from "drizzle-orm";
import { alias } from "drizzle-orm/sqlite-core";
import { response } from "@server/lib/response";
import HttpCode from "@server/types/HttpCode";
@@ -670,21 +670,28 @@ hybridRouter.get(
});
}
const effectivePolicyPincode =
result.sharedPolicyPincode ??
result.defaultPolicyPincode ??
null;
const effectivePolicyPassword =
result.sharedPolicyPassword ??
result.defaultPolicyPassword ??
null;
const effectivePolicyHeaderAuth =
result.sharedPolicyHeaderAuth ??
result.defaultPolicyHeaderAuth ??
null;
const hasSharedPolicy = result.sharedPolicy !== null;
const effectivePolicyPincode = hasSharedPolicy
? result.sharedPolicyPincode
: (result.defaultPolicyPincode ?? null);
const effectivePolicyPassword = hasSharedPolicy
? result.sharedPolicyPassword
: (result.defaultPolicyPassword ?? null);
const effectivePolicyHeaderAuth = hasSharedPolicy
? result.sharedPolicyHeaderAuth
: (result.defaultPolicyHeaderAuth ?? null);
const effectiveApplyRules =
(hasSharedPolicy
? (result.sharedPolicy?.applyRules ?? false)
: (result.defaultPolicy?.applyRules ?? false)) ||
result.resources.applyRules;
const resourceWithAuth: ResourceWithAuth = {
resource: result.resources,
resource: {
...result.resources,
applyRules: effectiveApplyRules
},
pincode: effectivePolicyPincode ?? result.resourcePincode,
password: effectivePolicyPassword ?? result.resourcePassword,
headerAuth:
@@ -1272,9 +1279,18 @@ hybridRouter.get(
.from(rolePolicies)
.innerJoin(
resources,
eq(
resources.resourcePolicyId,
rolePolicies.resourcePolicyId
or(
eq(
resources.resourcePolicyId,
rolePolicies.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
rolePolicies.resourcePolicyId
)
)
)
)
.where(
@@ -1386,9 +1402,18 @@ hybridRouter.get(
.from(rolePolicies)
.innerJoin(
resources,
eq(
resources.resourcePolicyId,
rolePolicies.resourcePolicyId
or(
eq(
resources.resourcePolicyId,
rolePolicies.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
rolePolicies.resourcePolicyId
)
)
)
)
.where(
@@ -1477,19 +1502,52 @@ hybridRouter.get(
);
}
const userResourceAccess = await db
.select()
.from(userResources)
.where(
and(
eq(userResources.userId, userId),
eq(userResources.resourceId, resourceId)
)
)
.limit(1);
const [directUserAccess, viaPoliciesUserAccess] = await Promise.all(
[
db
.select()
.from(userResources)
.where(
and(
eq(userResources.userId, userId),
eq(userResources.resourceId, resourceId)
)
)
.limit(1),
db
.select({
userId: userPolicies.userId,
resourcePolicyId: userPolicies.resourcePolicyId
})
.from(userPolicies)
.innerJoin(
resources,
or(
eq(
resources.resourcePolicyId,
userPolicies.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
userPolicies.resourcePolicyId
)
)
)
)
.where(
and(
eq(resources.resourceId, resourceId),
eq(userPolicies.userId, userId)
)
)
.limit(1)
]
);
const result =
userResourceAccess.length > 0 ? userResourceAccess[0] : null;
directUserAccess[0] ?? viaPoliciesUserAccess[0] ?? null;
return response<typeof userResources.$inferSelect | null>(res, {
data: result,
@@ -1580,9 +1638,18 @@ hybridRouter.get(
.from(resourcePolicyRules)
.innerJoin(
resources,
eq(
resources.resourcePolicyId,
resourcePolicyRules.resourcePolicyId
or(
eq(
resources.resourcePolicyId,
resourcePolicyRules.resourcePolicyId
),
and(
isNull(resources.resourcePolicyId),
eq(
resources.defaultResourcePolicyId,
resourcePolicyRules.resourcePolicyId
)
)
)
)
.where(eq(resources.resourceId, resourceId))

View File

@@ -144,6 +144,7 @@ export async function verifyResourceSession(
| ResourcePolicyHeaderAuth
| null;
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
applyRules: boolean;
org: Org;
}
| undefined = localCache.get(resourceCacheKey);
@@ -175,6 +176,7 @@ export async function verifyResourceSession(
const {
resource,
applyRules,
pincode,
password,
headerAuth,
@@ -220,7 +222,7 @@ export async function verifyResourceSession(
}
// check the rules
if (resource.applyRules) {
if (applyRules) {
const action = await checkRules(
resource.resourceId,
clientIp,
@@ -876,10 +878,7 @@ function allowed(
message: "Access allowed",
status: HttpCode.OK
};
logger.debug(
"++++++++++++++++++++++++++++++++++Access allowed, response data:",
data
);
logger.debug("Access allowed, response data:", data);
return response<VerifyUserResponse>(res, data);
}