mirror of
https://github.com/fosrl/pangolin.git
synced 2026-06-08 00:24:00 +00:00
Pull the rules and the policy information
This commit is contained in:
@@ -36,7 +36,8 @@ import {
|
|||||||
ResourcePolicyHeaderAuth
|
ResourcePolicyHeaderAuth
|
||||||
} from "@server/db";
|
} from "@server/db";
|
||||||
import { alias } from "drizzle-orm/sqlite-core";
|
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 = {
|
export type ResourceWithAuth = {
|
||||||
resource: Resource | null;
|
resource: Resource | null;
|
||||||
@@ -44,6 +45,7 @@ export type ResourceWithAuth = {
|
|||||||
password: ResourcePassword | ResourcePolicyPassword | null;
|
password: ResourcePassword | ResourcePolicyPassword | null;
|
||||||
headerAuth: ResourceHeaderAuth | ResourcePolicyHeaderAuth | null;
|
headerAuth: ResourceHeaderAuth | ResourcePolicyHeaderAuth | null;
|
||||||
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
|
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
|
||||||
|
applyRules: boolean;
|
||||||
org: Org;
|
org: Org;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -213,9 +215,14 @@ export async function getResourceByDomain(
|
|||||||
const effectivePolicyHeaderAuth = hasSharedPolicy
|
const effectivePolicyHeaderAuth = hasSharedPolicy
|
||||||
? result.sharedPolicyHeaderAuth
|
? result.sharedPolicyHeaderAuth
|
||||||
: (result.defaultPolicyHeaderAuth ?? null);
|
: (result.defaultPolicyHeaderAuth ?? null);
|
||||||
|
const effectiveApplyRules =
|
||||||
|
(hasSharedPolicy
|
||||||
|
? (result.sharedPolicy?.applyRules ?? false)
|
||||||
|
: (result.defaultPolicy?.applyRules ?? false)) ||
|
||||||
|
result.resources.applyRules;
|
||||||
|
|
||||||
return {
|
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,
|
pincode: effectivePolicyPincode ?? result.resourcePincode,
|
||||||
password: effectivePolicyPassword ?? result.resourcePassword,
|
password: effectivePolicyPassword ?? result.resourcePassword,
|
||||||
headerAuth: effectivePolicyHeaderAuth ?? result.resourceHeaderAuth,
|
headerAuth: effectivePolicyHeaderAuth ?? result.resourceHeaderAuth,
|
||||||
@@ -227,6 +234,7 @@ export async function getResourceByDomain(
|
|||||||
effectivePolicyHeaderAuth.extendedCompatibility
|
effectivePolicyHeaderAuth.extendedCompatibility
|
||||||
} as ResourceHeaderAuthExtendedCompatibility)
|
} as ResourceHeaderAuthExtendedCompatibility)
|
||||||
: result.resourceHeaderAuthExtendedCompatibility,
|
: result.resourceHeaderAuthExtendedCompatibility,
|
||||||
|
applyRules: effectiveApplyRules,
|
||||||
org: result.orgs
|
org: result.orgs
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -290,7 +298,21 @@ export async function getRoleResourceAccess(
|
|||||||
.from(rolePolicies)
|
.from(rolePolicies)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
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(
|
.where(
|
||||||
and(
|
and(
|
||||||
@@ -330,7 +352,21 @@ export async function getUserResourceAccess(
|
|||||||
.from(userPolicies)
|
.from(userPolicies)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
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(
|
.where(
|
||||||
and(
|
and(
|
||||||
@@ -368,9 +404,20 @@ export async function getResourceRules(
|
|||||||
.from(resourcePolicyRules)
|
.from(resourcePolicyRules)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
resources,
|
||||||
|
// Shared policy wins; only use default policy when no shared
|
||||||
|
// policy is assigned to the resource.
|
||||||
|
or(
|
||||||
eq(
|
eq(
|
||||||
resources.resourcePolicyId,
|
resources.resourcePolicyId,
|
||||||
resourcePolicyRules.resourcePolicyId
|
resourcePolicyRules.resourcePolicyId
|
||||||
|
),
|
||||||
|
and(
|
||||||
|
isNull(resources.resourcePolicyId),
|
||||||
|
eq(
|
||||||
|
resources.defaultResourcePolicyId,
|
||||||
|
resourcePolicyRules.resourcePolicyId
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.where(eq(resources.resourceId, resourceId))
|
.where(eq(resources.resourceId, resourceId))
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import {
|
|||||||
userOrgRoles,
|
userOrgRoles,
|
||||||
roles
|
roles
|
||||||
} from "@server/db";
|
} 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 { alias } from "drizzle-orm/sqlite-core";
|
||||||
import { response } from "@server/lib/response";
|
import { response } from "@server/lib/response";
|
||||||
import HttpCode from "@server/types/HttpCode";
|
import HttpCode from "@server/types/HttpCode";
|
||||||
@@ -670,21 +670,28 @@ hybridRouter.get(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const effectivePolicyPincode =
|
const hasSharedPolicy = result.sharedPolicy !== null;
|
||||||
result.sharedPolicyPincode ??
|
|
||||||
result.defaultPolicyPincode ??
|
const effectivePolicyPincode = hasSharedPolicy
|
||||||
null;
|
? result.sharedPolicyPincode
|
||||||
const effectivePolicyPassword =
|
: (result.defaultPolicyPincode ?? null);
|
||||||
result.sharedPolicyPassword ??
|
const effectivePolicyPassword = hasSharedPolicy
|
||||||
result.defaultPolicyPassword ??
|
? result.sharedPolicyPassword
|
||||||
null;
|
: (result.defaultPolicyPassword ?? null);
|
||||||
const effectivePolicyHeaderAuth =
|
const effectivePolicyHeaderAuth = hasSharedPolicy
|
||||||
result.sharedPolicyHeaderAuth ??
|
? result.sharedPolicyHeaderAuth
|
||||||
result.defaultPolicyHeaderAuth ??
|
: (result.defaultPolicyHeaderAuth ?? null);
|
||||||
null;
|
const effectiveApplyRules =
|
||||||
|
(hasSharedPolicy
|
||||||
|
? (result.sharedPolicy?.applyRules ?? false)
|
||||||
|
: (result.defaultPolicy?.applyRules ?? false)) ||
|
||||||
|
result.resources.applyRules;
|
||||||
|
|
||||||
const resourceWithAuth: ResourceWithAuth = {
|
const resourceWithAuth: ResourceWithAuth = {
|
||||||
resource: result.resources,
|
resource: {
|
||||||
|
...result.resources,
|
||||||
|
applyRules: effectiveApplyRules
|
||||||
|
},
|
||||||
pincode: effectivePolicyPincode ?? result.resourcePincode,
|
pincode: effectivePolicyPincode ?? result.resourcePincode,
|
||||||
password: effectivePolicyPassword ?? result.resourcePassword,
|
password: effectivePolicyPassword ?? result.resourcePassword,
|
||||||
headerAuth:
|
headerAuth:
|
||||||
@@ -1272,9 +1279,18 @@ hybridRouter.get(
|
|||||||
.from(rolePolicies)
|
.from(rolePolicies)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
resources,
|
||||||
|
or(
|
||||||
eq(
|
eq(
|
||||||
resources.resourcePolicyId,
|
resources.resourcePolicyId,
|
||||||
rolePolicies.resourcePolicyId
|
rolePolicies.resourcePolicyId
|
||||||
|
),
|
||||||
|
and(
|
||||||
|
isNull(resources.resourcePolicyId),
|
||||||
|
eq(
|
||||||
|
resources.defaultResourcePolicyId,
|
||||||
|
rolePolicies.resourcePolicyId
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
@@ -1386,9 +1402,18 @@ hybridRouter.get(
|
|||||||
.from(rolePolicies)
|
.from(rolePolicies)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
resources,
|
||||||
|
or(
|
||||||
eq(
|
eq(
|
||||||
resources.resourcePolicyId,
|
resources.resourcePolicyId,
|
||||||
rolePolicies.resourcePolicyId
|
rolePolicies.resourcePolicyId
|
||||||
|
),
|
||||||
|
and(
|
||||||
|
isNull(resources.resourcePolicyId),
|
||||||
|
eq(
|
||||||
|
resources.defaultResourcePolicyId,
|
||||||
|
rolePolicies.resourcePolicyId
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.where(
|
.where(
|
||||||
@@ -1477,7 +1502,9 @@ hybridRouter.get(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const userResourceAccess = await db
|
const [directUserAccess, viaPoliciesUserAccess] = await Promise.all(
|
||||||
|
[
|
||||||
|
db
|
||||||
.select()
|
.select()
|
||||||
.from(userResources)
|
.from(userResources)
|
||||||
.where(
|
.where(
|
||||||
@@ -1486,10 +1513,41 @@ hybridRouter.get(
|
|||||||
eq(userResources.resourceId, resourceId)
|
eq(userResources.resourceId, resourceId)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.limit(1);
|
.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 =
|
const result =
|
||||||
userResourceAccess.length > 0 ? userResourceAccess[0] : null;
|
directUserAccess[0] ?? viaPoliciesUserAccess[0] ?? null;
|
||||||
|
|
||||||
return response<typeof userResources.$inferSelect | null>(res, {
|
return response<typeof userResources.$inferSelect | null>(res, {
|
||||||
data: result,
|
data: result,
|
||||||
@@ -1580,9 +1638,18 @@ hybridRouter.get(
|
|||||||
.from(resourcePolicyRules)
|
.from(resourcePolicyRules)
|
||||||
.innerJoin(
|
.innerJoin(
|
||||||
resources,
|
resources,
|
||||||
|
or(
|
||||||
eq(
|
eq(
|
||||||
resources.resourcePolicyId,
|
resources.resourcePolicyId,
|
||||||
resourcePolicyRules.resourcePolicyId
|
resourcePolicyRules.resourcePolicyId
|
||||||
|
),
|
||||||
|
and(
|
||||||
|
isNull(resources.resourcePolicyId),
|
||||||
|
eq(
|
||||||
|
resources.defaultResourcePolicyId,
|
||||||
|
resourcePolicyRules.resourcePolicyId
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.where(eq(resources.resourceId, resourceId))
|
.where(eq(resources.resourceId, resourceId))
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export async function verifyResourceSession(
|
|||||||
| ResourcePolicyHeaderAuth
|
| ResourcePolicyHeaderAuth
|
||||||
| null;
|
| null;
|
||||||
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
|
headerAuthExtendedCompatibility: ResourceHeaderAuthExtendedCompatibility | null;
|
||||||
|
applyRules: boolean;
|
||||||
org: Org;
|
org: Org;
|
||||||
}
|
}
|
||||||
| undefined = localCache.get(resourceCacheKey);
|
| undefined = localCache.get(resourceCacheKey);
|
||||||
@@ -175,6 +176,7 @@ export async function verifyResourceSession(
|
|||||||
|
|
||||||
const {
|
const {
|
||||||
resource,
|
resource,
|
||||||
|
applyRules,
|
||||||
pincode,
|
pincode,
|
||||||
password,
|
password,
|
||||||
headerAuth,
|
headerAuth,
|
||||||
@@ -220,7 +222,7 @@ export async function verifyResourceSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check the rules
|
// check the rules
|
||||||
if (resource.applyRules) {
|
if (applyRules) {
|
||||||
const action = await checkRules(
|
const action = await checkRules(
|
||||||
resource.resourceId,
|
resource.resourceId,
|
||||||
clientIp,
|
clientIp,
|
||||||
@@ -876,10 +878,7 @@ function allowed(
|
|||||||
message: "Access allowed",
|
message: "Access allowed",
|
||||||
status: HttpCode.OK
|
status: HttpCode.OK
|
||||||
};
|
};
|
||||||
logger.debug(
|
logger.debug("Access allowed, response data:", data);
|
||||||
"++++++++++++++++++++++++++++++++++Access allowed, response data:",
|
|
||||||
data
|
|
||||||
);
|
|
||||||
return response<VerifyUserResponse>(res, data);
|
return response<VerifyUserResponse>(res, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user