Skip to main content

oauth2_passkey/userdb/
types.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use sqlx::FromRow;
4use std::fmt;
5
6/// Represents a core user identity in the system
7#[derive(Debug, Clone, Serialize, Deserialize, FromRow, PartialEq)]
8pub struct User {
9    /// Database-assigned sequence number (primary key, internal only)
10    #[serde(skip_serializing)]
11    pub sequence_number: Option<i64>,
12    /// Unique user identifier
13    pub id: String,
14    /// User account name or login identifier
15    pub account: String,
16    /// Display name or user-friendly label
17    pub label: String,
18    /// Whether the user has administrator privileges
19    pub is_admin: bool,
20    /// When the user account was created
21    pub created_at: DateTime<Utc>,
22    /// When the user account was last updated
23    pub updated_at: DateTime<Utc>,
24}
25
26#[allow(dead_code)]
27#[derive(Debug)]
28pub enum UserSearchField {
29    Id(String),
30    SequenceNumber(i64),
31}
32
33impl fmt::Display for UserSearchField {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        match self {
36            UserSearchField::Id(id) => write!(f, "Id({id})"),
37            UserSearchField::SequenceNumber(seq) => write!(f, "SequenceNumber({seq})"),
38        }
39    }
40}
41
42impl User {
43    /// Create a new user
44    pub fn new(id: String, account: String, label: String) -> Self {
45        let now = Utc::now();
46        Self {
47            sequence_number: None,
48            id,
49            account,
50            label,
51            is_admin: false,
52            created_at: now,
53            updated_at: now,
54        }
55    }
56
57    /// Check if the user has admin privileges
58    ///
59    /// This is determined by either:
60    /// 1. The user has is_admin flag set to true, or
61    /// 2. The user is the first user in the system (sequence_number = 1)
62    ///
63    /// IMPORTANT: This logic must stay in sync with SessionUser::has_admin_privileges()
64    /// and AuthUser::has_admin_privileges() implementations.
65    pub fn has_admin_privileges(&self) -> bool {
66        self.is_admin || self.sequence_number == Some(1)
67    }
68}
69
70#[cfg(test)]
71mod tests;