use actix_web::http::header;
use actix_web::{web, HttpRequest, HttpResponse};
use crate::pages::templates::MY;
use crate::pages::{insert_security_headers, naive_to_text, request_to_jar, CommonAuthInfo};
use crate::{DataBaseRo, WebData};
use uuid::Uuid;
#[derive(serde_derive::Serialize)]
struct PageData<'a> {
common_auth_info: CommonAuthInfo<'a>,
games: Vec<GameData>,
contacts: Vec<ContactData>,
csrf: Uuid,
}
#[derive(serde_derive::Serialize)]
struct GameData {
gameuid: String,
gameuidenc: String,
status: Option<String>,
}
#[derive(serde_derive::Serialize)]
struct ContactData {
protocol: String,
address: String,
is_active: bool,
create_ts: String,
delete_ts: Option<String>,
}
pub async fn my(
request: HttpRequest,
data: web::Data<WebData<'_>>,
data_ro: web::Data<DataBaseRo>,
) -> HttpResponse {
let jar = request_to_jar(request);
let u = jar
.private(&data.cookies_key)
.get("auth")
.map(|x| x.value().to_string());
if let Some(user) = u {
let dbclient = match data_ro.0.get().await {
Ok(client) => client,
Err(e) => {
log::error!("{}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
let stmt = match dbclient
.prepare("select g.game_uid, g.status::text from games.games g inner join games.players p on g.game_uid = p.game_uid where p.player_name = $1 order by g.game_uid;")
.await
{
Ok(stmt) => stmt,
Err(e) => {
log::error!("{}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
let rows = match dbclient.query(&stmt, &[&user]).await {
Ok(rows) => rows,
Err(e) => {
log::error!("{}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
let mut games = Vec::with_capacity(rows.len());
for row in rows {
let gameuid = row.get::<_, &str>(0);
let status = row.get::<_, Option<&str>>(1);
games.push(GameData {
gameuid: gameuid.to_string(),
gameuidenc: pct_str::PctString::encode(gameuid.chars(), pct_str::URIReserved)
.into_string(),
status: status.map(str::to_string),
});
}
let stmt = match dbclient
.prepare("select protocol::text, address, is_active, create_ts, delete_ts from auth.contacts where player_name = $1;")
.await
{
Ok(stmt) => stmt,
Err(e) => {
log::error!("{}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
let rows = match dbclient.query(&stmt, &[&user]).await {
Ok(rows) => rows,
Err(e) => {
log::error!("{}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
let mut contacts = Vec::with_capacity(rows.len());
for row in rows {
contacts.push(ContactData {
protocol: row.get::<_, String>(0),
address: row.get::<_, String>(1),
is_active: row.get::<_, bool>(2),
create_ts: naive_to_text(&row.get::<_, chrono::NaiveDateTime>(3)),
delete_ts: row
.get::<_, Option<chrono::NaiveDateTime>>(4)
.as_ref()
.map(naive_to_text),
});
}
let csrf = Uuid::new_v4();
{
let mut cache = data.cache_reset_game_pwd.lock().await;
cache.insert(
csrf,
(Uuid::nil(), user.to_string(), true),
std::time::Duration::from_secs(data.cache_duration_sec),
);
}
let body = match data.handlebars.render(
MY,
&PageData {
common_auth_info: CommonAuthInfo {
user: Some(user.into()),
},
games,
contacts,
csrf,
},
) {
Ok(b) => b,
Err(e) => {
log::error!("Render index error: {}", e);
return HttpResponse::ServiceUnavailable().body(actix_web::body::None::new());
}
};
insert_security_headers(HttpResponse::Ok()).body(body)
} else {
HttpResponse::Found()
.append_header((header::LOCATION, "login.html"))
.finish()
}
}