use std::collections::HashMap;
use std::sync::Arc;
use serde_json::Value;
use crate::error::Error;
use crate::transport::HttpTransport;
use crate::types::{AccessResponse, Collaborator};
pub struct AccessClient {
transport: Arc<HttpTransport>,
}
impl AccessClient {
pub fn new(transport: Arc<HttpTransport>) -> Self {
Self { transport }
}
pub async fn grant(
&self,
repo_id: &str,
agent_id: &str,
role: &str,
) -> Result<AccessResponse, Error> {
let mut body: HashMap<String, Value> = HashMap::new();
body.insert("repoId".to_string(), Value::String(repo_id.to_string()));
body.insert("agentId".to_string(), Value::String(agent_id.to_string()));
body.insert("role".to_string(), Value::String(role.to_string()));
let response: Value = self
.transport
.signed_request(
"POST",
&format!("/v1/repos/{repo_id}/collaborators"),
"access_grant",
body,
)
.await?;
let data = response
.get("data")
.ok_or_else(|| Error::Http("Missing data in response".to_string()))?;
serde_json::from_value(data.clone()).map_err(Error::from)
}
pub async fn revoke(&self, repo_id: &str, agent_id: &str) -> Result<AccessResponse, Error> {
let mut body: HashMap<String, Value> = HashMap::new();
body.insert("repoId".to_string(), Value::String(repo_id.to_string()));
body.insert("agentId".to_string(), Value::String(agent_id.to_string()));
let response: Value = self
.transport
.signed_request(
"DELETE",
&format!("/v1/repos/{repo_id}/collaborators/{agent_id}"),
"access_revoke",
body,
)
.await?;
let data = response
.get("data")
.ok_or_else(|| Error::Http("Missing data in response".to_string()))?;
serde_json::from_value(data.clone()).map_err(Error::from)
}
pub async fn list(&self, repo_id: &str) -> Result<Vec<Collaborator>, Error> {
let response: Value = self
.transport
.unsigned_request::<Value>(
"GET",
&format!("/v1/repos/{repo_id}/collaborators"),
None,
None::<&()>,
)
.await?;
let data = response
.get("data")
.ok_or_else(|| Error::Http("Missing data in response".to_string()))?;
let collaborators = data
.get("collaborators")
.ok_or_else(|| Error::Http("Missing collaborators in response".to_string()))?;
serde_json::from_value(collaborators.clone()).map_err(Error::from)
}
}