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