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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Session 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::session::client::SessionClient;
use crate::session::models::SessionSite;
impl SessionClient {
/// 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<SessionSite>, Error> {
let url = self.api_url("self/sites");
debug!("listing sites");
self.get(url).await
}
/// Get all site settings.
///
/// `GET /api/s/{site}/rest/setting`
pub async fn get_site_settings(&self) -> Result<Vec<serde_json::Value>, Error> {
let url = self.site_url("rest/setting");
debug!("fetching site settings");
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 a site setting.
///
/// `PUT /api/s/{site}/set/setting/{key}` with an arbitrary JSON body.
pub async fn set_site_setting(&self, key: &str, body: &serde_json::Value) -> Result<(), Error> {
let url = self.site_url(&format!("set/setting/{key}"));
debug!(key, "updating site setting");
let _: Vec<serde_json::Value> = self.put(url, body).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(())
}
}