Public dry run dryrun-6341cce4cf9f
Source commit: 6341cce4cf9f801a3bfe2248d6e7e6a119cea715 Public tree identity: sha256:d909cba912925e66131fc55fe33774a2b26b1ff2c12b53ec4ef217c9788d8b7a
This commit is contained in:
parent
84ef57d84b
commit
9f2d6ec010
7 changed files with 654 additions and 27 deletions
|
|
@ -771,18 +771,64 @@ fn auth_logout_report(args: AuthLogoutArgs, cwd: PathBuf) -> Result<Value> {
|
|||
|
||||
fn key_add_report(args: KeyAddArgs) -> Result<Value> {
|
||||
if let Some(coordinator) = &args.scope.coordinator {
|
||||
let tenant = args.scope.tenant.clone();
|
||||
let project = args.scope.project.clone();
|
||||
let user = args.scope.user.clone();
|
||||
let agent = args.agent.clone();
|
||||
let public_key_fingerprint = Digest::sha256(&args.public_key);
|
||||
let mut session = JsonLineSession::connect(coordinator)?;
|
||||
let response = session.request(json!({
|
||||
"type": "register_agent_public_key",
|
||||
"tenant": args.scope.tenant,
|
||||
"project": args.scope.project,
|
||||
"user": args.scope.user,
|
||||
"agent": args.agent,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"agent": agent,
|
||||
"public_key": args.public_key,
|
||||
}))?;
|
||||
let record = response.get("record").cloned().unwrap_or_else(|| {
|
||||
json!({
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"agent": agent,
|
||||
"public_key_fingerprint": public_key_fingerprint,
|
||||
"scopes": ["project:read", "project:run"],
|
||||
"human_account_creation_privilege": false,
|
||||
"browser_interaction_required_each_run": false,
|
||||
})
|
||||
});
|
||||
return Ok(json!({
|
||||
"command": "key add",
|
||||
"coordinator": coordinator,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"agent": agent,
|
||||
"public_key_fingerprint": record
|
||||
.get("public_key_fingerprint")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(public_key_fingerprint)),
|
||||
"credential_scope": {
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"actions": record
|
||||
.get("scopes")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(["project:read", "project:run"])),
|
||||
"human_account_creation_privilege": record
|
||||
.get("human_account_creation_privilege")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(false)),
|
||||
},
|
||||
"browser_interaction_required_each_run": record
|
||||
.get("browser_interaction_required_each_run")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(false)),
|
||||
"attribution": {
|
||||
"registered_by_user": user,
|
||||
"agent": agent,
|
||||
"credential_kind": "public_key",
|
||||
},
|
||||
"response": response,
|
||||
"coordinator_session_requests": session.requests(),
|
||||
}));
|
||||
|
|
@ -798,16 +844,32 @@ fn key_add_report(args: KeyAddArgs) -> Result<Value> {
|
|||
|
||||
fn key_list_report(args: KeyListArgs) -> Result<Value> {
|
||||
if let Some(coordinator) = &args.scope.coordinator {
|
||||
let tenant = args.scope.tenant.clone();
|
||||
let project = args.scope.project.clone();
|
||||
let user = args.scope.user.clone();
|
||||
let mut session = JsonLineSession::connect(coordinator)?;
|
||||
let response = session.request(json!({
|
||||
"type": "list_agent_public_keys",
|
||||
"tenant": args.scope.tenant,
|
||||
"project": args.scope.project,
|
||||
"user": args.scope.user,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
}))?;
|
||||
return Ok(json!({
|
||||
"command": "key list",
|
||||
"coordinator": coordinator,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"records": response
|
||||
.get("records")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!([])),
|
||||
"credential_scope": {
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"listed_for_user": user,
|
||||
"human_account_creation_privilege": false,
|
||||
},
|
||||
"response": response,
|
||||
"coordinator_session_requests": session.requests(),
|
||||
}));
|
||||
|
|
@ -821,18 +883,41 @@ fn key_list_report(args: KeyListArgs) -> Result<Value> {
|
|||
|
||||
fn key_revoke_report(args: KeyRevokeArgs) -> Result<Value> {
|
||||
if let Some(coordinator) = &args.scope.coordinator {
|
||||
let tenant = args.scope.tenant.clone();
|
||||
let project = args.scope.project.clone();
|
||||
let user = args.scope.user.clone();
|
||||
let agent = args.agent.clone();
|
||||
let mut session = JsonLineSession::connect(coordinator)?;
|
||||
let response = session.request(json!({
|
||||
"type": "revoke_agent_public_key",
|
||||
"tenant": args.scope.tenant,
|
||||
"project": args.scope.project,
|
||||
"user": args.scope.user,
|
||||
"agent": args.agent,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"agent": agent,
|
||||
}))?;
|
||||
return Ok(json!({
|
||||
"command": "key revoke",
|
||||
"coordinator": coordinator,
|
||||
"requires_confirmation": !args.yes,
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"user": user,
|
||||
"agent": agent,
|
||||
"revoked": response
|
||||
.pointer("/record/revoked")
|
||||
.cloned()
|
||||
.unwrap_or_else(|| json!(true)),
|
||||
"credential_scope": {
|
||||
"tenant": tenant,
|
||||
"project": project,
|
||||
"revoked_for_user": user,
|
||||
"human_account_creation_privilege": false,
|
||||
},
|
||||
"attribution": {
|
||||
"revoked_by_user": user,
|
||||
"agent": agent,
|
||||
"credential_kind": "public_key",
|
||||
},
|
||||
"response": response,
|
||||
"coordinator_session_requests": session.requests(),
|
||||
}));
|
||||
|
|
@ -4273,6 +4358,84 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_lifecycle_reports_project_scoped_agent_credentials() {
|
||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||
let addr = listener.local_addr().unwrap().to_string();
|
||||
let server = std::thread::spawn(move || {
|
||||
let add_response = concat!(
|
||||
r#"{"type":"agent_public_key","actor":"user","record":{"tenant":"tenant","project":"project","user":"user","agent":"agent-ci","public_key":"agent-key-v1","public_key_fingerprint":"sha256:agent-v1","version":1,"revoked":false,"scopes":["project:read","project:run"],"human_account_creation_privilege":false,"browser_interaction_required_each_run":false}}"#
|
||||
);
|
||||
let list_response = concat!(
|
||||
r#"{"type":"agent_public_keys","actor":"user","records":[{"tenant":"tenant","project":"project","user":"user","agent":"agent-ci","public_key":"agent-key-v1","public_key_fingerprint":"sha256:agent-v1","version":1,"revoked":false,"scopes":["project:read","project:run"],"human_account_creation_privilege":false,"browser_interaction_required_each_run":false}]}"#
|
||||
);
|
||||
let revoke_response = concat!(
|
||||
r#"{"type":"agent_public_key","actor":"user","record":{"tenant":"tenant","project":"project","user":"user","agent":"agent-ci","public_key":"agent-key-v1","public_key_fingerprint":"sha256:agent-v1","version":1,"revoked":true,"scopes":["project:read","project:run"],"human_account_creation_privilege":false,"browser_interaction_required_each_run":false}}"#
|
||||
);
|
||||
for (expected, response) in [
|
||||
("register_agent_public_key", add_response),
|
||||
("list_agent_public_keys", list_response),
|
||||
("revoke_agent_public_key", revoke_response),
|
||||
] {
|
||||
let (mut stream, _) = listener.accept().unwrap();
|
||||
let mut reader = BufReader::new(stream.try_clone().unwrap());
|
||||
let mut line = String::new();
|
||||
reader.read_line(&mut line).unwrap();
|
||||
assert!(line.contains(&format!(r#""type":"{expected}""#)));
|
||||
assert!(line.contains(r#""tenant":"tenant""#));
|
||||
assert!(line.contains(r#""project":"project""#));
|
||||
assert!(line.contains(r#""user":"user""#));
|
||||
if expected != "list_agent_public_keys" {
|
||||
assert!(line.contains(r#""agent":"agent-ci""#));
|
||||
}
|
||||
if expected == "register_agent_public_key" {
|
||||
assert!(line.contains(r#""public_key":"agent-key-v1""#));
|
||||
}
|
||||
stream.write_all(response.as_bytes()).unwrap();
|
||||
stream.write_all(b"\n").unwrap();
|
||||
}
|
||||
});
|
||||
let scope = CliScopeArgs {
|
||||
coordinator: Some(addr),
|
||||
tenant: "tenant".to_owned(),
|
||||
project: "project".to_owned(),
|
||||
user: "user".to_owned(),
|
||||
json: false,
|
||||
};
|
||||
|
||||
let added = key_add_report(KeyAddArgs {
|
||||
scope: scope.clone(),
|
||||
agent: "agent-ci".to_owned(),
|
||||
public_key: "agent-key-v1".to_owned(),
|
||||
})
|
||||
.unwrap();
|
||||
let listed = key_list_report(KeyListArgs {
|
||||
scope: scope.clone(),
|
||||
})
|
||||
.unwrap();
|
||||
let revoked = key_revoke_report(KeyRevokeArgs {
|
||||
scope,
|
||||
agent: "agent-ci".to_owned(),
|
||||
yes: true,
|
||||
})
|
||||
.unwrap();
|
||||
server.join().unwrap();
|
||||
|
||||
assert_eq!(added["command"], "key add");
|
||||
assert_eq!(added["agent"], "agent-ci");
|
||||
assert_eq!(added["credential_scope"]["actions"][0], "project:read");
|
||||
assert_eq!(
|
||||
added["credential_scope"]["human_account_creation_privilege"],
|
||||
false
|
||||
);
|
||||
assert_eq!(added["browser_interaction_required_each_run"], false);
|
||||
assert_eq!(added["attribution"]["registered_by_user"], "user");
|
||||
assert_eq!(listed["records"].as_array().unwrap().len(), 1);
|
||||
assert_eq!(listed["credential_scope"]["listed_for_user"], "user");
|
||||
assert_eq!(revoked["revoked"], true);
|
||||
assert_eq!(revoked["attribution"]["revoked_by_user"], "user");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn human_report_is_text_not_json() {
|
||||
let report = json!({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue