1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
910//! This module implements the client's functions for interacting with the
11//! Frontegg users API.
1213use reqwest::Method;
14use serde::{Deserialize, Serialize};
1516use crate::client::Client;
17use crate::client::role::Role;
18use crate::error::Error;
19use crate::parse::{Empty, Paginated};
2021const USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v3"];
22const CREATE_USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v2"];
23const REMOVE_USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v1"];
2425/// Representation of all the mandatory fields for a user creation request.
26#[derive(Serialize)]
27#[serde(rename_all = "camelCase")]
28pub struct CreateUserRequest {
29/// Email for the user
30pub email: String,
31/// Name for the user
32pub name: String,
33/// Provider for the user.
34 /// E.g.: `local`
35pub provider: String,
36/// Roles the user will have in the organization.
37pub role_ids: Vec<uuid::Uuid>,
38}
3940/// Representation of the only required field to request a user removal.
41#[derive(Serialize)]
42#[serde(rename_all = "camelCase")]
43pub struct RemoveUserRequest {
44/// The identifier of the user to remove. Equals to the `id` inside the [User] struct.
45pub user_id: String,
46}
4748/// A structure that represents a user in Frontegg.
49#[derive(Debug, Deserialize)]
50#[serde(rename_all = "camelCase")]
51pub struct User {
52/// The ID of the user.
53pub id: String,
54/// The name of the user.
55pub name: String,
56/// The email for the user.
57pub email: String,
58/// Unique identifier for the subject; Currently it is the user ID
59pub sub: String,
60}
6162/// Representation of a succesfully response from a user creation.
63#[derive(Debug, Serialize, Deserialize)]
64#[serde(rename_all = "camelCase")]
65pub struct CreatedUser {
66/// The ID of the user.
67pub id: String,
68/// The email for the user.
69pub email: String,
70/// The name of the user.
71pub name: String,
72/// The profile picture URL of the user.
73pub profile_picture_url: String,
74/// Indicates if the user verified their email.
75pub verified: Option<bool>,
76/// Metadata about the user; it is usually empty.
77pub metadata: Option<String>,
78/// The roles to which this user belongs.
79pub roles: Vec<Role>,
80}
8182impl Client {
83/// Lists all existing users.
84pub async fn list_users(&self) -> Result<Vec<User>, Error> {
85let mut users = vec![];
86let mut page = 0;
8788loop {
89let req = self.build_request(Method::GET, USERS_PATH);
90let req = req.query(&[("_limit", "50"), ("_offset", &*page.to_string())]);
91let res: Paginated<User> = self.send_request(req).await?;
92for user in res.items {
93 users.push(user);
94 }
95 page += 1;
96if page >= res.metadata.total_pages {
97break;
98 }
99 }
100Ok(users)
101 }
102103/// Creates a new user in the authenticated organization.
104pub async fn create_user(&self, new_user: CreateUserRequest) -> Result<CreatedUser, Error> {
105let req = self.build_request(Method::POST, CREATE_USERS_PATH);
106let req = req.json(&new_user);
107let created_user = self.send_request(req).await?;
108Ok(created_user)
109 }
110111/// Removes a user from the authenticated organization.
112pub async fn remove_user(&self, remove_user: RemoveUserRequest) -> Result<(), Error> {
113let mut user_path = REMOVE_USERS_PATH.to_vec();
114 user_path.push(remove_user.user_id.as_str());
115116let req = self.build_request(Method::DELETE, user_path);
117118let req = req.json(&remove_user);
119self.send_request::<Empty>(req).await?;
120121Ok(())
122 }
123}