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
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.
//! This module implements the client's functions for interacting with the
//! Frontegg users API.
use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::client::role::Role;
use crate::client::Client;
use crate::error::Error;
use crate::parse::{Empty, Paginated};
const USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v3"];
const CREATE_USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v2"];
const REMOVE_USERS_PATH: [&str; 5] = ["frontegg", "identity", "resources", "users", "v1"];
/// Representation of all the mandatory fields for a user creation request.
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateUserRequest {
/// Email for the user
pub email: String,
/// Name for the user
pub name: String,
/// Provider for the user.
/// E.g.: `local`
pub provider: String,
/// Roles the user will have in the organization.
pub role_ids: Vec<uuid::Uuid>,
}
/// Representation of the only required field to request a user removal.
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoveUserRequest {
/// The identifier of the user to remove. Equals to the `id` inside the [User] struct.
pub user_id: String,
}
/// A structure that represents a user in Frontegg.
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct User {
/// The ID of the user.
pub id: String,
/// The name of the user.
pub name: String,
/// The email for the user.
pub email: String,
/// Unique identifier for the subject; Currently it is the user ID
pub sub: String,
}
/// Representation of a succesfully response from a user creation.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreatedUser {
/// The ID of the user.
pub id: String,
/// The email for the user.
pub email: String,
/// The name of the user.
pub name: String,
/// The profile picture URL of the user.
pub profile_picture_url: String,
/// Indicates if the user verified their email.
pub verified: Option<bool>,
/// Metadata about the user; it is usually empty.
pub metadata: Option<String>,
/// The roles to which this user belongs.
pub roles: Vec<Role>,
}
impl Client {
/// Lists all existing users.
pub async fn list_users(&self) -> Result<Vec<User>, Error> {
let mut users = vec![];
let mut page = 0;
loop {
let req = self.build_request(Method::GET, USERS_PATH);
let req = req.query(&[("_limit", "50"), ("_offset", &*page.to_string())]);
let res: Paginated<User> = self.send_request(req).await?;
for user in res.items {
users.push(user);
}
page += 1;
if page >= res.metadata.total_pages {
break;
}
}
Ok(users)
}
/// Creates a new user in the authenticated organization.
pub async fn create_user(&self, new_user: CreateUserRequest) -> Result<CreatedUser, Error> {
let req = self.build_request(Method::POST, CREATE_USERS_PATH);
let req = req.json(&new_user);
let created_user = self.send_request(req).await?;
Ok(created_user)
}
/// Removes a user from the authenticated organization.
pub async fn remove_user(&self, remove_user: RemoveUserRequest) -> Result<(), Error> {
let mut user_path = REMOVE_USERS_PATH.to_vec();
user_path.push(remove_user.user_id.as_str());
let req = self.build_request(Method::DELETE, user_path);
let req = req.json(&remove_user);
self.send_request::<Empty>(req).await?;
Ok(())
}
}