Skip to main content

unifly_api/legacy/
sites.rs

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