修复权限bug
This commit is contained in:
@@ -32,36 +32,31 @@ const ADMIN_PREFIXES = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export function configuredAdminAuthorities(): string[] {
|
export function configuredAdminAuthorities(): string[] {
|
||||||
const configured = process.env.ZHINIAN_ADMIN_AUTHORITIES?.trim();
|
const configured = process.env.ZHINIAN_ADMIN_AUTHORITIES;
|
||||||
if (!configured) return DEFAULT_ADMIN_AUTHORITIES;
|
if (configured === undefined) return DEFAULT_ADMIN_AUTHORITIES;
|
||||||
return configured
|
return splitConfiguredList(configured);
|
||||||
.split(/[\n,]+/)
|
|
||||||
.map((item) => item.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function configuredAdminUsers(): string[] {
|
export function configuredAdminUsers(): string[] {
|
||||||
const configured = process.env.ZHINIAN_ADMIN_USERS?.trim();
|
const configured = process.env.ZHINIAN_ADMIN_USERS;
|
||||||
if (!configured) return DEFAULT_ADMIN_USERS;
|
if (configured === undefined) return DEFAULT_ADMIN_USERS;
|
||||||
return configured
|
return splitConfiguredList(configured);
|
||||||
.split(/[\n,]+/)
|
|
||||||
.map((item) => item.trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasAdminAccess(
|
export function hasAdminAccess(
|
||||||
user: AuthUser | null | undefined,
|
user: AuthUser | null | undefined,
|
||||||
adminAuthorities = configuredAdminAuthorities(),
|
adminAuthorities?: string[],
|
||||||
adminUsers = configuredAdminUsers()
|
adminUsers?: string[]
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
const allowedUsers = new Set(adminUsers.map(normalizeAccountName));
|
const allowedUsers = new Set((adminUsers ?? configuredAdminUsers()).map(normalizeAccountName));
|
||||||
const identities = [user.username, user.subject, user.displayName, user.id]
|
const identities = [user.username, user.subject, user.displayName, user.id]
|
||||||
.map((item) => item ? normalizeAccountName(item) : "")
|
.map((item) => item ? normalizeAccountName(item) : "")
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
if (identities.some((identity) => allowedUsers.has(identity))) return true;
|
if (identities.some((identity) => allowedUsers.has(identity))) return true;
|
||||||
|
|
||||||
const allowed = new Set(adminAuthorities.map(normalizeAuthority));
|
if (!shouldUseAuthorityGrants(adminAuthorities)) return false;
|
||||||
|
const allowed = new Set((adminAuthorities ?? configuredAdminAuthorities()).map(normalizeAuthority));
|
||||||
return user.authorities.some((authority) => {
|
return user.authorities.some((authority) => {
|
||||||
const normalized = normalizeAuthority(authority);
|
const normalized = normalizeAuthority(authority);
|
||||||
return allowed.has(normalized) || ADMIN_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
return allowed.has(normalized) || ADMIN_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
||||||
@@ -75,3 +70,16 @@ export function normalizeAuthority(value: string): string {
|
|||||||
function normalizeAccountName(value: string): string {
|
function normalizeAccountName(value: string): string {
|
||||||
return value.trim().toLowerCase();
|
return value.trim().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function splitConfiguredList(value: string): string[] {
|
||||||
|
return value
|
||||||
|
.split(/[\n,]+/)
|
||||||
|
.map((item) => item.trim())
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldUseAuthorityGrants(explicitAuthorities?: string[]): boolean {
|
||||||
|
if (explicitAuthorities !== undefined) return true;
|
||||||
|
if (process.env.ZHINIAN_ADMIN_AUTHORITIES !== undefined) return true;
|
||||||
|
return process.env.ZHINIAN_ADMIN_USERS === undefined;
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,12 @@ describe("auth permission helpers", () => {
|
|||||||
expect(hasAdminAccess({ ...baseUser, username: "ops-admin", subject: "ops-admin", authorities: [] })).toBe(true);
|
expect(hasAdminAccess({ ...baseUser, username: "ops-admin", subject: "ops-admin", authorities: [] })).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("uses configured admin usernames without falling back to default authority grants", () => {
|
||||||
|
vi.stubEnv("ZHINIAN_ADMIN_USERS", "admin");
|
||||||
|
expect(hasAdminAccess({ ...baseUser, username: "staff", subject: "staff", authorities: ["sys_user_view"] })).toBe(false);
|
||||||
|
expect(hasAdminAccess({ ...baseUser, username: "admin", subject: "admin", authorities: [] })).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it("accepts configured admin authorities and normalizes case", () => {
|
it("accepts configured admin authorities and normalizes case", () => {
|
||||||
vi.stubEnv("ZHINIAN_ADMIN_AUTHORITIES", "custom-admin, sys_config_view");
|
vi.stubEnv("ZHINIAN_ADMIN_AUTHORITIES", "custom-admin, sys_config_view");
|
||||||
expect(configuredAdminAuthorities()).toEqual(["custom-admin", "sys_config_view"]);
|
expect(configuredAdminAuthorities()).toEqual(["custom-admin", "sys_config_view"]);
|
||||||
|
|||||||
Reference in New Issue
Block a user