use std::net::IpAddr;
use chrono::{DateTime, Utc};
use schemars::JsonSchema;
use serde::Serialize;
use ulid::Ulid;
pub trait Resource {
const KIND: &'static str;
const PATH: &'static str;
fn id(&self) -> Ulid;
fn path(&self) -> String {
format!("{}/{}", Self::PATH, self.id())
}
}
#[derive(Serialize, JsonSchema)]
pub struct User {
#[serde(skip)]
id: Ulid,
username: String,
created_at: DateTime<Utc>,
locked_at: Option<DateTime<Utc>>,
admin: bool,
}
impl User {
pub fn samples() -> [Self; 3] {
[
Self {
id: Ulid::from_bytes([0x01; 16]),
username: "alice".to_owned(),
created_at: DateTime::default(),
locked_at: None,
admin: false,
},
Self {
id: Ulid::from_bytes([0x02; 16]),
username: "bob".to_owned(),
created_at: DateTime::default(),
locked_at: None,
admin: true,
},
Self {
id: Ulid::from_bytes([0x03; 16]),
username: "charlie".to_owned(),
created_at: DateTime::default(),
locked_at: Some(DateTime::default()),
admin: false,
},
]
}
}
impl From<mas_data_model::User> for User {
fn from(user: mas_data_model::User) -> Self {
Self {
id: user.id,
username: user.username,
created_at: user.created_at,
locked_at: user.locked_at,
admin: user.can_request_admin,
}
}
}
impl Resource for User {
const KIND: &'static str = "user";
const PATH: &'static str = "/api/admin/v1/users";
fn id(&self) -> Ulid {
self.id
}
}
#[derive(Serialize, JsonSchema)]
pub struct OAuth2Session {
#[serde(skip)]
id: Ulid,
created_at: DateTime<Utc>,
finished_at: Option<DateTime<Utc>>,
#[schemars(with = "Option<super::schema::Ulid>")]
user_id: Option<Ulid>,
#[schemars(with = "Option<super::schema::Ulid>")]
user_session_id: Option<Ulid>,
#[schemars(with = "super::schema::Ulid")]
client_id: Ulid,
scope: String,
user_agent: Option<String>,
last_active_at: Option<DateTime<Utc>>,
last_active_ip: Option<IpAddr>,
}
impl From<mas_data_model::Session> for OAuth2Session {
fn from(session: mas_data_model::Session) -> Self {
Self {
id: session.id,
created_at: session.created_at,
finished_at: session.finished_at(),
user_id: session.user_id,
user_session_id: session.user_session_id,
client_id: session.client_id,
scope: session.scope.to_string(),
user_agent: session.user_agent.map(|ua| ua.raw),
last_active_at: session.last_active_at,
last_active_ip: session.last_active_ip,
}
}
}
impl OAuth2Session {
pub fn samples() -> [Self; 3] {
[
Self {
id: Ulid::from_bytes([0x01; 16]),
created_at: DateTime::default(),
finished_at: None,
user_id: Some(Ulid::from_bytes([0x02; 16])),
user_session_id: Some(Ulid::from_bytes([0x03; 16])),
client_id: Ulid::from_bytes([0x04; 16]),
scope: "openid".to_owned(),
user_agent: Some("Mozilla/5.0".to_owned()),
last_active_at: Some(DateTime::default()),
last_active_ip: Some("127.0.0.1".parse().unwrap()),
},
Self {
id: Ulid::from_bytes([0x02; 16]),
created_at: DateTime::default(),
finished_at: None,
user_id: None,
user_session_id: None,
client_id: Ulid::from_bytes([0x05; 16]),
scope: "urn:mas:admin".to_owned(),
user_agent: None,
last_active_at: None,
last_active_ip: None,
},
Self {
id: Ulid::from_bytes([0x03; 16]),
created_at: DateTime::default(),
finished_at: Some(DateTime::default()),
user_id: Some(Ulid::from_bytes([0x04; 16])),
user_session_id: Some(Ulid::from_bytes([0x05; 16])),
client_id: Ulid::from_bytes([0x06; 16]),
scope: "urn:matrix:org.matrix.msc2967.client:api:*".to_owned(),
user_agent: Some("Mozilla/5.0".to_owned()),
last_active_at: Some(DateTime::default()),
last_active_ip: Some("127.0.0.1".parse().unwrap()),
},
]
}
}
impl Resource for OAuth2Session {
const KIND: &'static str = "oauth2-session";
const PATH: &'static str = "/api/admin/v1/oauth2-sessions";
fn id(&self) -> Ulid {
self.id
}
}