use crate::rest::sites::theme::Theme;
use crate::rest::users::web_user::UserStatus::PendingApproval;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_variant::to_variant_name;
use std::fmt;
use std::str::FromStr;
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct WebUser {
pub user_authz: UserAuthorization,
pub preferences: Option<UserPrefs>,
pub last_seen_data: Vec<LastSeenData>,
pub last_login_data: Vec<LastLoginData>,
pub status: UserStatus,
pub created_at: DateTime<Utc>,
pub modified_at: DateTime<Utc>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct UserAuthorization {
pub acct: String,
pub system_permissions: Vec<SystemPermission>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct UserPrefs {
pub theme: Theme,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct LastSeenData {
pub from: String,
pub at: DateTime<Utc>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct LastLoginData {
pub from: String,
pub at: DateTime<Utc>,
pub success: bool,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum UserStatus {
Active,
Suspended,
#[serde(rename = "Pending Approval")]
PendingApproval,
}
impl Default for UserStatus {
fn default() -> Self {
PendingApproval
}
}
impl fmt::Display for UserStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", to_variant_name(&self).unwrap())
}
}
impl FromStr for UserStatus {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.to_lowercase();
match s {
a if a == UserStatus::Active.to_string().to_lowercase() => Ok(UserStatus::Active),
a if a == UserStatus::Suspended.to_string().to_lowercase() => Ok(UserStatus::Suspended),
a if a == UserStatus::PendingApproval.to_string().to_lowercase() => {
Ok(UserStatus::PendingApproval)
}
_ => Err("no matching users status"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum SystemRole {
#[serde(rename = "User Administrator")]
UserAdmin,
#[serde(rename = "Actor Administrator")]
ActorAdmin,
#[serde(rename = "Content Administrator")]
ContentAdmin,
}
impl fmt::Display for SystemRole {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
SystemRole::UserAdmin => write!(f, "User Administrator"),
SystemRole::ActorAdmin => write!(f, "Actor Administrator"),
SystemRole::ContentAdmin => write!(f, "Content Administrator"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct SystemPermission {
pub role: SystemRole,
pub host_name: String,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct UserSystemInfo {
pub system_data: Option<UserSystemData>,
pub created_at: DateTime<Utc>,
pub modified_at: DateTime<Utc>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub struct UserSystemData {}
#[cfg(test)]
mod web_user_tests {
use super::*;
#[test]
fn roundtrip_serde() {
let w = super::UserAuthorization {
acct: "bob@test.example".to_string(),
system_permissions: vec![SystemPermission {
role: SystemRole::ActorAdmin,
host_name: "example.com".to_string(),
}],
};
let j = serde_json::to_string(&w);
let w2 = serde_json::from_str(&j.unwrap()).unwrap();
assert_eq!(w, w2)
}
}