mirror of
https://github.com/hanzoai/mcp.git
synced 2026-10-15 12:30:12 +00:00
iam: pass the scope through, and let the server's refusal speak
Which list routes insist on an owner is the server's rule, and it moves. The deployed binary requires one on users, sessions and applications and not on roles, permissions, providers, invitations, tokens or audit-logs; the change that resolves a listing's tenant centrally is written and unreleased. So nothing here keeps a copy of that rule. `apps` no longer refuses a missing owner before asking, and no description promises that leaving it off makes the credential decide — today that answers 400, carrying the reason, which the transport already surfaces. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -365,8 +365,11 @@ impl HanzoTool {
|
||||
async fn iam(&self, action: &str, p: &Map<String, Value>) -> Result<Value> {
|
||||
let ok = |d| Ok(envelope_ok("hanzo", action, d));
|
||||
let id = pstr(p, "id");
|
||||
// Scope follows the caller: name an owner only when the caller names one,
|
||||
// and the server resolves the rest from the credential.
|
||||
// `owner` is passed through when the caller names one and left off when
|
||||
// they do not. Which routes insist on one is the server's to decide and
|
||||
// it varies by release, so nothing here keeps a copy of that rule — a
|
||||
// refusal arrives carrying its reason, and the reason is what the caller
|
||||
// sees.
|
||||
let owner = pstr(p, "owner");
|
||||
let scope: Vec<(String, String)> =
|
||||
owner.iter().map(|o| ("owner".to_string(), o.clone())).collect();
|
||||
@@ -445,12 +448,7 @@ impl HanzoTool {
|
||||
"permissions" => ok(self.call("iam", "GET", "/v1/iam/permissions", &scope, None).await?),
|
||||
"providers" => ok(self.call("iam", "GET", "/v1/iam/providers", &scope, None).await?),
|
||||
// Applications are listed one owner at a time; ask rather than guess.
|
||||
"apps" => {
|
||||
if owner.is_none() {
|
||||
return Ok(need(action, "owner"));
|
||||
}
|
||||
ok(self.call("iam", "GET", "/v1/iam/applications", &scope, None).await?)
|
||||
}
|
||||
"apps" => ok(self.call("iam", "GET", "/v1/iam/applications", &scope, None).await?),
|
||||
"tokens" => ok(self
|
||||
.call("iam", "GET", "/v1/iam/tokens", &with(&["organization"]), None)
|
||||
.await?),
|
||||
|
||||
@@ -77,7 +77,7 @@ export const iamTool: Tool = {
|
||||
'list_permissions', 'assign_role', 'remove_role',
|
||||
'list_sessions', 'delete_session'
|
||||
] },
|
||||
owner: { type: 'string', description: 'Organization owning the row; omit to let the credential decide' },
|
||||
owner: { type: 'string', description: 'Organization to scope the call to; the server decides which routes require it' },
|
||||
id: { type: 'string', description: 'owner/name — owner/name/application for delete_session' },
|
||||
name: { type: 'string' }, email: { type: 'string' }, password: { type: 'string' },
|
||||
displayName: { type: 'string' }, phone: { type: 'string' },
|
||||
|
||||
Reference in New Issue
Block a user