mz_frontegg_client/client/
app_password.rs

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.
9
10//! This module implements the client's functions for interacting with the Frontegg passwords API.
11
12use mz_frontegg_auth::AppPassword as AuthAppPassword;
13use reqwest::Method;
14use serde::{Deserialize, Serialize};
15use uuid::Uuid;
16
17use crate::client::Client;
18use crate::error::Error;
19
20const APP_PASSWORDS_PATH: [&str; 6] = [
21    "frontegg",
22    "identity",
23    "resources",
24    "users",
25    "api-tokens",
26    "v1",
27];
28const CREATE_APP_PASSWORDS_PATH: [&str; 6] = [
29    "frontegg",
30    "identity",
31    "resources",
32    "users",
33    "api-tokens",
34    "v1",
35];
36
37/// A structure that represents an app-password _metadata_.
38#[derive(Deserialize)]
39#[serde(rename_all = "camelCase")]
40pub struct AppPassword {
41    /// Description of the password.
42    ///
43    /// E.g.: "CI/CD Password", "Production password",
44    pub description: String,
45    /// Creation date in ISO 8601 of the password.
46    ///
47    /// E.g.: 2023-04-26T08:37:03.000Z
48    pub created_at: String,
49}
50
51/// Describes a request to create a new app password.
52#[derive(Serialize)]
53pub struct CreateAppPasswordRequest<'a> {
54    /// The description of the app password.
55    pub description: &'a str,
56}
57
58impl Client {
59    /// Lists all existing app passwords.
60    pub async fn list_app_passwords(&self) -> Result<Vec<AppPassword>, Error> {
61        let req = self.build_request(Method::GET, APP_PASSWORDS_PATH);
62        let passwords: Vec<AppPassword> = self.send_request(req).await?;
63        Ok(passwords)
64    }
65
66    /// Creates a new app password with the provided description.
67    pub async fn create_app_password(
68        &self,
69        app_password: CreateAppPasswordRequest<'_>,
70    ) -> Result<AuthAppPassword, Error> {
71        let req = self.build_request(Method::POST, CREATE_APP_PASSWORDS_PATH);
72        let req = req.json(&app_password);
73
74        // Temp AppPassword structure implementing Deserialization to avoid
75        // having any impact in `frontegg-auth`.
76        #[derive(Debug, Deserialize)]
77        struct AppPassword {
78            /// The client ID embedded in the app password.
79            #[serde(rename = "clientId")]
80            client_id: Uuid,
81            /// The secret key embedded in the app password.
82            #[serde(rename = "secret")]
83            secret_key: Uuid,
84        }
85
86        let password: AppPassword = self.send_request(req).await?;
87        Ok(AuthAppPassword {
88            client_id: password.client_id,
89            secret_key: password.secret_key,
90        })
91    }
92}