mirror of
https://github.com/rustfs/console.git
synced 2026-08-28 19:47:21 +08:00
fix(access-keys): load object policy responses (#172)
Co-authored-by: 季宏伟 <jihongwei@jihongweis-MacBook-Pro.local>
This commit is contained in:
+3
-27
@@ -2,6 +2,7 @@
|
||||
|
||||
import { useCallback } from "react"
|
||||
import { useApi } from "@/contexts/api-context"
|
||||
import { normalizePolicyStatements } from "@/lib/user-policy"
|
||||
|
||||
export function usePolicies() {
|
||||
const api = useApi()
|
||||
@@ -81,33 +82,8 @@ export function usePolicies() {
|
||||
if (allPolicyNames.size > 0) {
|
||||
await Promise.all(
|
||||
Array.from(allPolicyNames).map(async (policyName) => {
|
||||
const policyInfo = (await getPolicy(policyName)) as { policy?: string }
|
||||
const policyDocument = JSON.parse(policyInfo.policy ?? "{}") as {
|
||||
Statement?: Record<string, unknown>[]
|
||||
}
|
||||
|
||||
if (!Array.isArray(policyDocument.Statement)) return
|
||||
|
||||
const groupOrigins = Object.entries(groupPoliciesMap)
|
||||
.filter(([, policies]) => policies.includes(policyName))
|
||||
.map(([groupName]) => groupName)
|
||||
|
||||
policyDocument.Statement.forEach((statement) => {
|
||||
policyStatement.push({
|
||||
...statement,
|
||||
Sid: statement.Sid ?? policyName,
|
||||
Origin: {
|
||||
type:
|
||||
directPolicyNames.includes(policyName) && groupOrigins.length > 0
|
||||
? "both"
|
||||
: directPolicyNames.includes(policyName)
|
||||
? "direct"
|
||||
: "group",
|
||||
groups: groupOrigins,
|
||||
policyName,
|
||||
},
|
||||
})
|
||||
})
|
||||
const policyInfo = (await getPolicy(policyName)) as { policy?: unknown }
|
||||
policyStatement.push(...normalizePolicyStatements(policyName, policyInfo.policy ?? {}))
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
type PolicyStatement = Record<string, unknown>
|
||||
|
||||
export function normalizePolicyStatements(policyName: string, rawPolicy: unknown): PolicyStatement[] {
|
||||
const policy = typeof rawPolicy === "string" ? (JSON.parse(rawPolicy) as unknown) : rawPolicy
|
||||
|
||||
if (typeof policy !== "object" || policy === null || Array.isArray(policy)) {
|
||||
throw new TypeError("Policy must be a valid JSON object")
|
||||
}
|
||||
|
||||
const statements = (policy as { Statement?: unknown }).Statement
|
||||
if (statements === undefined) return []
|
||||
if (!Array.isArray(statements)) {
|
||||
throw new TypeError("Policy Statement must be an array")
|
||||
}
|
||||
|
||||
return statements.map((statement) => {
|
||||
if (typeof statement !== "object" || statement === null || Array.isArray(statement)) {
|
||||
throw new TypeError("Policy Statement entries must be JSON objects")
|
||||
}
|
||||
|
||||
const normalized = statement as PolicyStatement
|
||||
return {
|
||||
...normalized,
|
||||
Sid: normalized.Sid ?? policyName,
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import test from "node:test"
|
||||
import assert from "node:assert/strict"
|
||||
import { normalizePolicyStatements } from "../../lib/user-policy"
|
||||
|
||||
const policyStatement = {
|
||||
Effect: "Allow",
|
||||
Action: ["s3:GetObject"],
|
||||
Resource: ["arn:aws:s3:::example/*"],
|
||||
}
|
||||
|
||||
test("normalizePolicyStatements accepts policy objects returned by the admin API", () => {
|
||||
assert.deepEqual(
|
||||
normalizePolicyStatements("readonly", {
|
||||
Version: "2012-10-17",
|
||||
Statement: [policyStatement],
|
||||
}),
|
||||
[{ ...policyStatement, Sid: "readonly" }],
|
||||
)
|
||||
})
|
||||
|
||||
test("normalizePolicyStatements supports legacy string policy responses", () => {
|
||||
assert.deepEqual(
|
||||
normalizePolicyStatements(
|
||||
"readonly",
|
||||
JSON.stringify({
|
||||
Version: "2012-10-17",
|
||||
Statement: [{ ...policyStatement, Sid: "existing" }],
|
||||
}),
|
||||
),
|
||||
[{ ...policyStatement, Sid: "existing" }],
|
||||
)
|
||||
})
|
||||
|
||||
test("normalizePolicyStatements rejects invalid policy response shapes", () => {
|
||||
assert.throws(() => normalizePolicyStatements("readonly", []), /valid JSON object/)
|
||||
assert.throws(() => normalizePolicyStatements("readonly", { Statement: {} }), /Statement must be an array/)
|
||||
})
|
||||
Reference in New Issue
Block a user