1use serde_json::json;
2
3use crate::client::AuthClient;
4use crate::error::AuthError;
5use crate::params::{
6 AdminCreateUserParams, AdminUpdateUserParams, CreateOAuthClientParams, GenerateLinkParams,
7 UpdateOAuthClientParams,
8};
9use crate::types::{AdminUserListResponse, Factor, OAuthClient, OAuthClientListResponse, User};
10
11#[derive(Debug)]
23pub struct AdminClient<'a> {
24 auth: &'a AuthClient,
25 service_role_key: Option<&'a str>,
26}
27
28impl<'a> AdminClient<'a> {
29 pub(crate) fn new(auth: &'a AuthClient) -> Self {
31 Self {
32 auth,
33 service_role_key: None,
34 }
35 }
36
37 pub(crate) fn with_key(auth: &'a AuthClient, key: &'a str) -> Self {
39 Self {
40 auth,
41 service_role_key: Some(key),
42 }
43 }
44
45 fn bearer_token(&self) -> &str {
46 self.service_role_key.unwrap_or(self.auth.api_key())
47 }
48
49 pub async fn list_users(
53 &self,
54 page: Option<u32>,
55 per_page: Option<u32>,
56 ) -> Result<AdminUserListResponse, AuthError> {
57 let mut url = self.auth.url("/admin/users");
58 {
59 let mut pairs = url.query_pairs_mut();
60 if let Some(page) = page {
61 pairs.append_pair("page", &page.to_string());
62 }
63 if let Some(per_page) = per_page {
64 pairs.append_pair("per_page", &per_page.to_string());
65 }
66 }
67
68 let resp = self
69 .auth
70 .http()
71 .get(url)
72 .bearer_auth(self.bearer_token())
73 .send()
74 .await?;
75
76 let status = resp.status().as_u16();
77 if status >= 400 {
78 return Err(parse_admin_error(status, resp).await);
79 }
80
81 let list: AdminUserListResponse = resp.json().await?;
82 Ok(list)
83 }
84
85 pub async fn get_user_by_id(&self, user_id: &str) -> Result<User, AuthError> {
89 let url = self.auth.url(&format!("/admin/users/{}", user_id));
90 let resp = self
91 .auth
92 .http()
93 .get(url)
94 .bearer_auth(self.bearer_token())
95 .send()
96 .await?;
97 self.auth.handle_user_response(resp).await
98 }
99
100 pub async fn create_user(
106 &self,
107 params: AdminCreateUserParams,
108 ) -> Result<User, AuthError> {
109 let url = self.auth.url("/admin/users");
110 let resp = self
111 .auth
112 .http()
113 .post(url)
114 .bearer_auth(self.bearer_token())
115 .json(¶ms)
116 .send()
117 .await?;
118 self.auth.handle_user_response(resp).await
119 }
120
121 pub async fn update_user_by_id(
127 &self,
128 user_id: &str,
129 params: AdminUpdateUserParams,
130 ) -> Result<User, AuthError> {
131 let url = self.auth.url(&format!("/admin/users/{}", user_id));
132 let resp = self
133 .auth
134 .http()
135 .put(url)
136 .bearer_auth(self.bearer_token())
137 .json(¶ms)
138 .send()
139 .await?;
140 self.auth.handle_user_response(resp).await
141 }
142
143 pub async fn delete_user(&self, user_id: &str) -> Result<(), AuthError> {
147 self.delete_user_with_options(user_id, false).await
148 }
149
150 pub async fn delete_user_with_options(
156 &self,
157 user_id: &str,
158 soft_delete: bool,
159 ) -> Result<(), AuthError> {
160 let url = self.auth.url(&format!("/admin/users/{}", user_id));
161
162 let body = if soft_delete {
163 json!({ "should_soft_delete": true })
164 } else {
165 json!({})
166 };
167
168 let resp = self
169 .auth
170 .http()
171 .delete(url)
172 .bearer_auth(self.bearer_token())
173 .json(&body)
174 .send()
175 .await?;
176 self.auth.handle_empty_response(resp).await
177 }
178
179 pub async fn invite_user_by_email(
183 &self,
184 email: &str,
185 redirect_to: Option<&str>,
186 ) -> Result<User, AuthError> {
187 let mut body = json!({ "email": email });
188 if let Some(redirect) = redirect_to {
189 body["redirect_to"] = json!(redirect);
190 }
191
192 let url = self.auth.url("/invite");
193 let resp = self
194 .auth
195 .http()
196 .post(url)
197 .bearer_auth(self.bearer_token())
198 .json(&body)
199 .send()
200 .await?;
201 self.auth.handle_user_response(resp).await
202 }
203
204 pub async fn generate_link(
206 &self,
207 params: GenerateLinkParams,
208 ) -> Result<serde_json::Value, AuthError> {
209 let url = self.auth.url("/admin/generate_link");
210 let resp = self
211 .auth
212 .http()
213 .post(url)
214 .bearer_auth(self.bearer_token())
215 .json(¶ms)
216 .send()
217 .await?;
218
219 let status = resp.status().as_u16();
220 if status >= 400 {
221 return Err(parse_admin_error(status, resp).await);
222 }
223
224 let value: serde_json::Value = resp.json().await?;
225 Ok(value)
226 }
227
228 pub async fn mfa_list_factors(&self, user_id: &str) -> Result<Vec<Factor>, AuthError> {
234 let url = self
235 .auth
236 .url(&format!("/admin/users/{}/factors", user_id));
237 let resp = self
238 .auth
239 .http()
240 .get(url)
241 .bearer_auth(self.bearer_token())
242 .send()
243 .await?;
244
245 let status = resp.status().as_u16();
246 if status >= 400 {
247 return Err(parse_admin_error(status, resp).await);
248 }
249
250 let factors: Vec<Factor> = resp.json().await?;
251 Ok(factors)
252 }
253
254 pub async fn oauth_list_clients(
260 &self,
261 page: Option<u32>,
262 per_page: Option<u32>,
263 ) -> Result<OAuthClientListResponse, AuthError> {
264 let mut url = self.auth.url("/admin/oauth/clients");
265 {
266 let mut pairs = url.query_pairs_mut();
267 if let Some(page) = page {
268 pairs.append_pair("page", &page.to_string());
269 }
270 if let Some(per_page) = per_page {
271 pairs.append_pair("per_page", &per_page.to_string());
272 }
273 }
274
275 let resp = self
276 .auth
277 .http()
278 .get(url)
279 .bearer_auth(self.bearer_token())
280 .send()
281 .await?;
282
283 let status = resp.status().as_u16();
284 if status >= 400 {
285 return Err(parse_admin_error(status, resp).await);
286 }
287
288 let list: OAuthClientListResponse = resp.json().await?;
289 Ok(list)
290 }
291
292 pub async fn oauth_create_client(
296 &self,
297 params: CreateOAuthClientParams,
298 ) -> Result<OAuthClient, AuthError> {
299 let url = self.auth.url("/admin/oauth/clients");
300 let resp = self
301 .auth
302 .http()
303 .post(url)
304 .bearer_auth(self.bearer_token())
305 .json(¶ms)
306 .send()
307 .await?;
308
309 let status = resp.status().as_u16();
310 if status >= 400 {
311 return Err(parse_admin_error(status, resp).await);
312 }
313
314 let client: OAuthClient = resp.json().await?;
315 Ok(client)
316 }
317
318 pub async fn oauth_get_client(
322 &self,
323 client_id: &str,
324 ) -> Result<OAuthClient, AuthError> {
325 let url = self.auth.url(&format!("/admin/oauth/clients/{}", client_id));
326 let resp = self
327 .auth
328 .http()
329 .get(url)
330 .bearer_auth(self.bearer_token())
331 .send()
332 .await?;
333
334 let status = resp.status().as_u16();
335 if status >= 400 {
336 return Err(parse_admin_error(status, resp).await);
337 }
338
339 let client: OAuthClient = resp.json().await?;
340 Ok(client)
341 }
342
343 pub async fn oauth_update_client(
347 &self,
348 client_id: &str,
349 params: UpdateOAuthClientParams,
350 ) -> Result<OAuthClient, AuthError> {
351 let url = self.auth.url(&format!("/admin/oauth/clients/{}", client_id));
352 let resp = self
353 .auth
354 .http()
355 .put(url)
356 .bearer_auth(self.bearer_token())
357 .json(¶ms)
358 .send()
359 .await?;
360
361 let status = resp.status().as_u16();
362 if status >= 400 {
363 return Err(parse_admin_error(status, resp).await);
364 }
365
366 let client: OAuthClient = resp.json().await?;
367 Ok(client)
368 }
369
370 pub async fn oauth_delete_client(
374 &self,
375 client_id: &str,
376 ) -> Result<(), AuthError> {
377 let url = self.auth.url(&format!("/admin/oauth/clients/{}", client_id));
378 let resp = self
379 .auth
380 .http()
381 .delete(url)
382 .bearer_auth(self.bearer_token())
383 .send()
384 .await?;
385 self.auth.handle_empty_response(resp).await
386 }
387
388 pub async fn oauth_regenerate_client_secret(
392 &self,
393 client_id: &str,
394 ) -> Result<OAuthClient, AuthError> {
395 let url = self.auth.url(&format!(
396 "/admin/oauth/clients/{}/regenerate_secret",
397 client_id
398 ));
399 let resp = self
400 .auth
401 .http()
402 .post(url)
403 .bearer_auth(self.bearer_token())
404 .send()
405 .await?;
406
407 let status = resp.status().as_u16();
408 if status >= 400 {
409 return Err(parse_admin_error(status, resp).await);
410 }
411
412 let client: OAuthClient = resp.json().await?;
413 Ok(client)
414 }
415
416 pub async fn mfa_delete_factor(
420 &self,
421 user_id: &str,
422 factor_id: &str,
423 ) -> Result<(), AuthError> {
424 let url = self
425 .auth
426 .url(&format!("/admin/users/{}/factors/{}", user_id, factor_id));
427 let resp = self
428 .auth
429 .http()
430 .delete(url)
431 .bearer_auth(self.bearer_token())
432 .send()
433 .await?;
434 self.auth.handle_empty_response(resp).await
435 }
436}
437
438async fn parse_admin_error(status: u16, resp: reqwest::Response) -> AuthError {
439 use crate::error::GoTrueErrorResponse;
440
441 match resp.json::<GoTrueErrorResponse>().await {
442 Ok(err_resp) => {
443 let error_code = err_resp.error_code.as_deref().map(|s| s.into());
444 AuthError::Api {
445 status,
446 message: err_resp.error_message(),
447 error_code,
448 }
449 }
450 Err(_) => AuthError::Api {
451 status,
452 message: format!("HTTP {}", status),
453 error_code: None,
454 },
455 }
456}