1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Legacy API site endpoints
//
// Site listing is controller-scoped (not site-scoped), using
// `/api/self/sites` rather than the usual `/api/s/{site}/...` pattern.
use serde_json::json;
use tracing::debug;
use crate::error::Error;
use crate::legacy::client::LegacyClient;
use crate::legacy::models::LegacySite;
impl LegacyClient {
/// List all sites visible to the authenticated user.
///
/// `GET /api/self/sites` (controller-level, not site-scoped)
pub async fn list_sites(&self) -> Result<Vec<LegacySite>, Error> {
let url = self.api_url("self/sites");
debug!("listing sites");
self.get(url).await
}
/// Create a new site.
///
/// `POST /api/s/{site}/cmd/sitemgr` with `{"cmd": "add-site", "name": "...", "desc": "..."}`
pub async fn create_site(&self, name: &str, description: &str) -> Result<(), Error> {
let url = self.site_url("cmd/sitemgr");
debug!(name, "creating site");
let _: Vec<serde_json::Value> = self
.post(
url,
&json!({
"cmd": "add-site",
"name": name,
"desc": description,
}),
)
.await?;
Ok(())
}
/// Delete a site.
///
/// `POST /api/s/{site}/cmd/sitemgr` with `{"cmd": "delete-site", "name": "..."}`
pub async fn delete_site(&self, name: &str) -> Result<(), Error> {
let url = self.site_url("cmd/sitemgr");
debug!(name, "deleting site");
let _: Vec<serde_json::Value> = self
.post(
url,
&json!({
"cmd": "delete-site",
"name": name,
}),
)
.await?;
Ok(())
}
/// Invite a site administrator.
///
/// `POST /api/s/{site}/cmd/sitemgr` with `{"cmd": "invite-admin", ...}`
pub async fn invite_admin(&self, name: &str, email: &str, role: &str) -> Result<(), Error> {
let url = self.site_url("cmd/sitemgr");
debug!(name, email, role, "inviting admin");
let _: Vec<serde_json::Value> = self
.post(
url,
&json!({
"cmd": "invite-admin",
"name": name,
"email": email,
"role": role,
}),
)
.await?;
Ok(())
}
/// Revoke a site administrator.
///
/// `POST /api/s/{site}/cmd/sitemgr` with `{"cmd": "revoke-admin", "admin": "..."}`
pub async fn revoke_admin(&self, admin_id: &str) -> Result<(), Error> {
let url = self.site_url("cmd/sitemgr");
debug!(admin_id, "revoking admin");
let _: Vec<serde_json::Value> = self
.post(
url,
&json!({
"cmd": "revoke-admin",
"admin": admin_id,
}),
)
.await?;
Ok(())
}
/// Update site administrator role.
///
/// `POST /api/s/{site}/cmd/sitemgr` with `{"cmd": "update-admin", ...}`
pub async fn update_admin(&self, admin_id: &str, role: Option<&str>) -> Result<(), Error> {
let url = self.site_url("cmd/sitemgr");
debug!(admin_id, ?role, "updating admin");
let mut body = serde_json::Map::new();
body.insert(
"cmd".into(),
serde_json::Value::String("update-admin".into()),
);
body.insert(
"admin".into(),
serde_json::Value::String(admin_id.to_owned()),
);
if let Some(role) = role {
body.insert("role".into(), serde_json::Value::String(role.to_owned()));
}
let _: Vec<serde_json::Value> = self.post(url, &serde_json::Value::Object(body)).await?;
Ok(())
}
}