kanidm_proto/v1/
mod.rs

1//! Kanidm Version 1
2//!
3//! Items defined in this module will remain stable, or change in ways that are forward
4//! compatible with newer releases.
5
6#![allow(non_upper_case_globals)]
7
8use serde::{Deserialize, Serialize};
9use std::collections::BTreeMap;
10use std::fmt;
11use std::fmt::Display;
12use utoipa::ToSchema;
13use uuid::Uuid;
14
15mod auth;
16mod unix;
17
18pub use self::auth::*;
19pub use self::unix::*;
20
21/// The type of Account in use.
22#[derive(Serialize, Deserialize, Clone, Copy, Debug, ToSchema)]
23pub enum AccountType {
24    Person,
25    ServiceAccount,
26}
27
28impl Display for AccountType {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        f.write_str(match self {
31            AccountType::Person => "person",
32            AccountType::ServiceAccount => "service_account",
33        })
34    }
35}
36
37/* ===== higher level types ===== */
38// These are all types that are conceptually layers on top of entry and
39// friends. They allow us to process more complex requests and provide
40// domain specific fields for the purposes of IDM, over the normal
41// entry/ava/filter types. These related deeply to schema.
42
43/// The current purpose of a User Auth Token. It may be read-only, read-write
44/// or privilege capable (able to step up to read-write after re-authentication).
45#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
46#[serde(rename_all = "lowercase")]
47pub enum UatPurposeStatus {
48    ReadOnly,
49    ReadWrite,
50    PrivilegeCapable,
51}
52
53/// The expiry of the User Auth Token.
54#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
55#[serde(rename_all = "lowercase")]
56pub enum UatStatusState {
57    #[serde(with = "time::serde::timestamp")]
58    ExpiresAt(time::OffsetDateTime),
59    NeverExpires,
60    Revoked,
61}
62
63impl fmt::Display for UatStatusState {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        match self {
66            UatStatusState::ExpiresAt(odt) => write!(f, "expires at {}", odt),
67            UatStatusState::NeverExpires => write!(f, "never expires"),
68            UatStatusState::Revoked => write!(f, "revoked"),
69        }
70    }
71}
72
73/// The status of a User Auth Token
74#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
75#[serde(rename_all = "lowercase")]
76pub struct UatStatus {
77    pub account_id: Uuid,
78    pub session_id: Uuid,
79    pub state: UatStatusState,
80    #[serde(with = "time::serde::timestamp")]
81    pub issued_at: time::OffsetDateTime,
82    pub purpose: UatPurposeStatus,
83}
84
85impl fmt::Display for UatStatus {
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        writeln!(f, "account_id: {}", self.account_id)?;
88        writeln!(f, "session_id: {}", self.session_id)?;
89        writeln!(f, "state: {}", self.state)?;
90        writeln!(f, "issued_at: {}", self.issued_at)?;
91        match &self.purpose {
92            UatPurposeStatus::ReadOnly => writeln!(f, "purpose: read only")?,
93            UatPurposeStatus::ReadWrite => writeln!(f, "purpose: read write")?,
94            UatPurposeStatus::PrivilegeCapable => writeln!(f, "purpose: privilege capable")?,
95        }
96        Ok(())
97    }
98}
99
100/// A request to generate a new API token for a service account
101#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
102#[serde(rename_all = "lowercase")]
103pub struct ApiTokenGenerate {
104    pub label: String,
105    #[serde(with = "time::serde::timestamp::option")]
106    pub expiry: Option<time::OffsetDateTime>,
107    pub read_write: bool,
108}
109
110/* ===== low level proto types ===== */
111
112/// A limited view of an entry in Kanidm.
113#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default, ToSchema)]
114pub struct Entry {
115    pub attrs: BTreeMap<String, Vec<String>>,
116}
117
118impl fmt::Display for Entry {
119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120        writeln!(f, "---")?;
121        self.attrs
122            .iter()
123            .try_for_each(|(k, vs)| vs.iter().try_for_each(|v| writeln!(f, "{}: {}", k, v)))
124    }
125}
126
127/// A response to a whoami request
128#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, ToSchema)]
129pub struct WhoamiResponse {
130    // Should we just embed the entry? Or destructure it?
131    pub youare: Entry,
132}
133
134impl WhoamiResponse {
135    pub fn new(youare: Entry) -> Self {
136        WhoamiResponse { youare }
137    }
138}
139
140// Simple string value provision.
141#[derive(Debug, Serialize, Deserialize, ToSchema)]
142pub struct SingleStringRequest {
143    pub value: String,
144}
145
146impl SingleStringRequest {
147    pub fn new(s: String) -> Self {
148        SingleStringRequest { value: s }
149    }
150}