agent-exec transport 143b750c2cb52ec907a1a45df1416122/1ca104a38359
This commit is contained in:
@@ -485,7 +485,7 @@ func (e *env) loginAlice(t *testing.T) *userClient {
|
||||
}, nil)
|
||||
|
||||
apiKey := e.cliOut(t, "apikey", "create", "--dsn", e.dbDSN, "--owner", aliceOwner, "--name", "mi-acceptance")
|
||||
// IAM U4 把建项目改为系统动作 project.create:由引导管理员经真实 API 授予 alice。
|
||||
// 建项目需角色上的 project.create:由引导管理员经真实 API 建角色并绑定 alice。
|
||||
e.grantAliceProjectCreate(t)
|
||||
uc := &userClient{
|
||||
api: &http.Client{Timeout: httpWait, Transport: bearerRT{key: apiKey}},
|
||||
@@ -498,44 +498,53 @@ func (e *env) loginAlice(t *testing.T) *userClient {
|
||||
return uc
|
||||
}
|
||||
|
||||
// grantAliceProjectCreate 以 mi-root 身份经 admin API 为 alice 追加系统授权
|
||||
// project.create(保留其已有授权;PUT 为整体替换,按 authorityEpoch 乐观并发)。
|
||||
// mi-root 由 serve 启动时的 SUPER_ADMIN_* 建立,可直接为其发 API key。
|
||||
// grantAliceProjectCreate 以 mi-root 身份经 admin API 为 alice 授予项目访问:
|
||||
// project.create 只由已启用账号所绑定的已启用角色上的单一布尔决定,管理员
|
||||
// 身份或系统授权都不再隐含它。故新建角色、写入 project.create
|
||||
// (allowed=capAllowed=true,按 roleVersion 乐观并发),再按 alice 的
|
||||
// stateVersion 绑定该角色。mi-root 由 serve 启动时的 SUPER_ADMIN_* 建立,
|
||||
// 可直接为其发 API key。
|
||||
func (e *env) grantAliceProjectCreate(t *testing.T) {
|
||||
t.Helper()
|
||||
rootKey := e.cliOut(t, "apikey", "create", "--dsn", e.dbDSN, "--owner", "mi-root", "--name", "mi-acceptance-root")
|
||||
root := &http.Client{Timeout: httpWait, Transport: bearerRT{key: rootKey}}
|
||||
var users []struct {
|
||||
UserID string `json:"userId"`
|
||||
Owner string `json:"owner"`
|
||||
UserID string `json:"userId"`
|
||||
Owner string `json:"owner"`
|
||||
StateVersion int64 `json:"stateVersion"`
|
||||
}
|
||||
e.do(t, root, "GET", "/api/admin/users", nil, &users)
|
||||
userID := ""
|
||||
userID, stateVersion := "", int64(0)
|
||||
for _, u := range users {
|
||||
if u.Owner == aliceOwner {
|
||||
userID = u.UserID
|
||||
userID, stateVersion = u.UserID, u.StateVersion
|
||||
}
|
||||
}
|
||||
if userID == "" {
|
||||
t.Fatalf("user %s not found in /api/admin/users", aliceOwner)
|
||||
}
|
||||
var grants struct {
|
||||
Actions []string `json:"actions"`
|
||||
AuthorityEpoch int64 `json:"authorityEpoch"`
|
||||
var role struct {
|
||||
RoleID string `json:"roleId"`
|
||||
RoleVersion int64 `json:"roleVersion"`
|
||||
}
|
||||
e.do(t, root, "GET", "/api/admin/users/"+userID+"/system-grants", nil, &grants)
|
||||
actions := grants.Actions
|
||||
has := false
|
||||
for _, a := range actions {
|
||||
has = has || a == "project.create"
|
||||
e.do(t, root, "POST", "/api/admin/roles", map[string]any{
|
||||
"name": "mi-project-access",
|
||||
"description": "multi-instance acceptance: project.create",
|
||||
}, &role)
|
||||
if role.RoleID == "" {
|
||||
t.Fatal("POST /api/admin/roles returned no roleId")
|
||||
}
|
||||
if !has {
|
||||
actions = append(actions, "project.create")
|
||||
}
|
||||
e.do(t, root, "PUT", "/api/admin/users/"+userID+"/system-grants", map[string]any{
|
||||
"expectedAuthorityEpoch": grants.AuthorityEpoch,
|
||||
"idempotencyKey": "mi-alice-project-create",
|
||||
"actions": actions,
|
||||
e.do(t, root, "PUT", "/api/admin/roles/"+role.RoleID+"/permissions", map[string]any{
|
||||
"expectedRoleVersion": role.RoleVersion,
|
||||
"idempotencyKey": "mi-role-project-create",
|
||||
"changes": []map[string]any{
|
||||
{"actionId": "project.create", "allowed": true, "capAllowed": true},
|
||||
},
|
||||
}, nil)
|
||||
e.do(t, root, "PUT", "/api/admin/users/"+userID+"/role", map[string]any{
|
||||
"roleId": role.RoleID,
|
||||
"expectedStateVersion": stateVersion,
|
||||
"idempotencyKey": "mi-alice-project-access-role",
|
||||
}, nil)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user