Skip to main content

comindly_api/
server.rs

1use serde::{Deserialize, Serialize};
2
3/// A way to sign in: an emailed link, a code, or an OpenID Connect provider; a server offers one or
4/// more, each for invited people only.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "lowercase")]
7pub enum SignIn {
8    Email,
9    Code,
10    Oidc,
11}
12
13/// What someone may do, each role including the ones below it.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
15#[serde(rename_all = "lowercase")]
16pub enum Role {
17    /// Members, repositories, settings, secrets and indexing.
18    Admin,
19    /// Writes to the ledger and conventions.
20    Member,
21    /// Reads.
22    Viewer,
23}
24
25impl Role {
26    pub fn as_str(self) -> &'static str {
27        match self {
28            Role::Admin => "admin",
29            Role::Member => "member",
30            Role::Viewer => "viewer",
31        }
32    }
33
34    fn rank(self) -> u8 {
35        match self {
36            Role::Admin => 2,
37            Role::Member => 1,
38            Role::Viewer => 0,
39        }
40    }
41
42    /// This role may do what `other` may.
43    pub fn at_least(self, other: Role) -> bool {
44        self.rank() >= other.rank()
45    }
46}
47
48/// How a request proved who it is.
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
50pub enum Via {
51    Session,
52    AdminToken,
53    /// A personal access token: enough for agents, not for managing the account.
54    Token,
55}
56
57#[derive(Debug, Serialize, Deserialize)]
58pub struct Member {
59    pub email: String,
60    pub role: Role,
61    pub fixed: bool,
62    pub created: String,
63    pub last_seen: Option<String>,
64}
65
66#[derive(Debug, Serialize, Deserialize)]
67pub struct Invite {
68    pub email: String,
69    pub role: Role,
70    pub created_by: String,
71    pub expires: String,
72}
73
74#[derive(Debug, Serialize, Deserialize)]
75pub struct AccessToken {
76    pub id: String,
77    pub name: String,
78    pub created: String,
79    pub last_used: Option<String>,
80    /// `None` for a token that never expires.
81    pub expires: Option<String>,
82    pub expired: bool,
83}
84
85/// One row of the audit log; details never hold token values or codes.
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct AuditEntry {
88    pub at: String,
89    pub actor: String,
90    pub action: String,
91    pub detail: String,
92}
93
94/// Which audit entries to list: `before` is the `next` cursor of the previous page.
95#[derive(Debug, Default, Serialize, Deserialize)]
96pub struct AuditQuery {
97    pub limit: Option<usize>,
98    pub before: Option<String>,
99    pub actor: Option<String>,
100    pub action: Option<String>,
101}
102
103#[derive(Debug, Serialize, Deserialize)]
104pub struct AuditPage {
105    pub entries: Vec<AuditEntry>,
106    /// The cursor for the next (older) page, when there is one.
107    pub next: Option<String>,
108}
109
110/// A secret's state for the UI; its value never leaves the server.
111#[derive(Debug, Serialize, Deserialize)]
112pub struct SecretInfo {
113    pub name: String,
114    pub source: String,
115    pub hint: Option<String>,
116    pub updated: Option<String>,
117    pub updated_by: Option<String>,
118}
119
120/// What a member sees before approving a command-line sign-in.
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct DeviceRequest {
123    pub client: String,
124    pub expires: String,
125}
126
127/// Where a command-line sign-in stands.
128#[derive(Debug, Clone, PartialEq, Eq)]
129pub enum DevicePoll {
130    Pending,
131    Approved {
132        token: String,
133        email: String,
134        expires: Option<String>,
135    },
136    Denied,
137    Expired,
138}
139
140/// How long a token lasts unless chosen otherwise, and a command-line sign-in's always.
141pub const TOKEN_DAYS: u32 = 90;