修复权限bug

This commit is contained in:
2026-07-04 14:40:58 +08:00
parent c3ea9f0eb1
commit fe66794168
2 changed files with 30 additions and 16 deletions

View File

@@ -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;
}

View File

@@ -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"]);