163952e
use crate::models::users::{user_sessions, user_ssh_keys};
use crate::protos::auth::common::v1::{SessionInfo, SshKeyInfo};
use chrono::{DateTime, NaiveDate, TimeZone, Utc};
use prost_types::Timestamp;
use crate::internal::store;
pub const DEFAULT_PAGE_SIZE: i32 = 20;
pub const MAX_PAGE_SIZE: i32 = 100;
pub fn timestamp(seconds: i64, nanos: i32) -> Timestamp {
Timestamp { seconds, nanos }
}
pub fn timestamp_from_datetime(value: DateTime<Utc>) -> Timestamp {
Timestamp {
seconds: value.timestamp(),
nanos: value.timestamp_subsec_nanos() as i32,
}
}
pub fn now_timestamp() -> Timestamp {
timestamp_from_datetime(Utc::now())
}
pub fn datetime(value: &Timestamp) -> Option<DateTime<Utc>> {
let nanos = value.nanos.clamp(0, 999_999_999) as u32;
Utc.timestamp_opt(value.seconds, nanos).single()
}
pub fn date_timestamp(value: NaiveDate) -> Option<Timestamp> {
value
.and_hms_opt(0, 0, 0)
.map(|naive| timestamp_from_datetime(Utc.from_utc_datetime(&naive)))
}
pub fn naive_date(value: &Timestamp) -> Option<NaiveDate> {
datetime(value).map(|value| value.date_naive())
}
pub fn datetime_opt(value: Option<DateTime<Utc>>) -> Option<Timestamp> {
value.map(timestamp_from_datetime)
}
pub fn session_info(row: &user_sessions::Model) -> SessionInfo {
SessionInfo {
session_id: row.id.to_string(),
user_id: row.user_id,
security_version: row.security_version,
client_ip: row.ip_address.clone().unwrap_or_default(),
user_agent: row.user_agent.clone().unwrap_or_default(),
created_at: datetime_opt(Some(row.created_at)),
last_seen_at: datetime_opt(Some(row.last_seen_at)),
expires_at: datetime_opt(Some(row.expires_at)),
refresh_expires_at: datetime_opt(row.refresh_expires_at),
mfa_verified_at: datetime_opt(row.mfa_verified_at),
revoked_at: datetime_opt(row.revoked_at),
revoke_reason: String::new(),
}
}
pub fn ssh_key_info(row: &user_ssh_keys::Model) -> SshKeyInfo {
SshKeyInfo {
key_id: row.id.to_string(),
user_id: row.user_id,
name: row.name.clone(),
description: row.description.clone().unwrap_or_default(),
algorithm: store::ssh_algorithm_code(row.algorithm.clone()),
public_key: row.public_key.clone(),
fingerprint: row.fingerprint.clone(),
created_at: datetime_opt(Some(row.created_at)),
expires_at: datetime_opt(row.expires_at),
last_used_at: datetime_opt(row.last_used_at),
revoked_at: datetime_opt(row.revoked_at),
}
}
pub fn page_size(requested: i32) -> i32 {
if requested <= 0 {
DEFAULT_PAGE_SIZE
} else {
requested.min(MAX_PAGE_SIZE)
}
}
pub fn offset(page: i32, page_size: i32) -> u64 {
let page = page.max(1) as u64;
let page_size = page_size.max(1) as u64;
page.saturating_sub(1).saturating_mul(page_size)
}
pub fn has_more(offset: u64, page_size: i32, row_count: usize) -> bool {
row_count as u64 == page_size.max(0) as u64 && offset + row_count as u64 > offset
}