191 lines
7.1 KiB
Rust
191 lines
7.1 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use actix_web::{error, web, HttpRequest, Responder};
|
|
use actix_web_lab::respond::Html;
|
|
|
|
use log::info;
|
|
use minijinja::context;
|
|
use rusqlite::params;
|
|
use serde::Deserialize;
|
|
use uuid::Uuid;
|
|
use crate::db::external_id::{AccountId, Id, SecurityId};
|
|
|
|
use crate::events::Event;
|
|
|
|
use crate::webui::services::ServicesFactory;
|
|
use crate::webui::templates::MiniJinjaRenderer;
|
|
|
|
#[actix_web::get("/actions")]
|
|
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
|
tmpl_env.render("actions.html", ())
|
|
}
|
|
|
|
#[actix_web::get("/accounts")]
|
|
pub async fn get_accounts(tmpl_env: MiniJinjaRenderer,
|
|
req: HttpRequest,
|
|
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
|
let conn = service_factory.get_connection()?;
|
|
let auth_service = service_factory.get_authentication_service(&conn)?;
|
|
let user = auth_service.get_login(&req);
|
|
let account_service = service_factory.get_account_service(& conn)?;
|
|
let accounts = account_service.get_user_accounts(&user.unwrap())
|
|
.map_err(error::ErrorInternalServerError)?;
|
|
tmpl_env.render("accounts.html", context!{accounts => accounts})
|
|
}
|
|
|
|
#[actix_web::get("/accounts/{account_id}")]
|
|
pub async fn get_account(tmpl_env: MiniJinjaRenderer,
|
|
req: HttpRequest,
|
|
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
|
let path_event_type = req.match_info().get("account_id").unwrap();
|
|
let account_id = AccountId::from_string(&path_event_type.to_string()).unwrap();
|
|
let conn = service_factory.get_connection()?;
|
|
let auth_service = service_factory.get_authentication_service(&conn)?;
|
|
let account_service = service_factory.get_account_service(& conn)?;
|
|
let user_id = auth_service.get_login(&req).unwrap();
|
|
|
|
let ctx = context!{
|
|
account => account_service.get_account_by_id(&account_id, &user_id).map_err(error::ErrorInternalServerError)?
|
|
};
|
|
tmpl_env.render("account.html", ctx)
|
|
}
|
|
|
|
|
|
|
|
#[actix_web::get("/securities")]
|
|
pub async fn securities(tmpl_env: MiniJinjaRenderer,
|
|
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
|
let conn = service_factory.get_connection()?;
|
|
let account_service = service_factory.get_security_service(& conn)?;
|
|
let ctx = context!{
|
|
securities => account_service.list_securities()
|
|
};
|
|
tmpl_env.render("securities.html", ctx)
|
|
}
|
|
|
|
#[actix_web::get("/securities/{sec_id}")]
|
|
pub async fn security(tmpl_env: MiniJinjaRenderer,
|
|
service_factory: web::Data<ServicesFactory>) -> actix_web::Result<impl Responder> {
|
|
|
|
let ctx = context!{};
|
|
tmpl_env.render("security.html", ctx)
|
|
}
|
|
|
|
#[actix_web::get("/users")]
|
|
pub async fn users(
|
|
tmpl_env: MiniJinjaRenderer,
|
|
service_factory: web::Data<ServicesFactory>,
|
|
) -> actix_web::Result<impl Responder> {
|
|
let conn = service_factory.get_connection()?;
|
|
let user_service = service_factory.get_user_service(&conn)?;
|
|
|
|
let users = user_service.list_users().unwrap();
|
|
let ctx = context! {
|
|
users => users,
|
|
};
|
|
tmpl_env.render("users.html", ctx)
|
|
}
|
|
|
|
#[actix_web::get("/partials/overview/submit_button")]
|
|
pub async fn overview_submit_button(
|
|
tmpl_env: MiniJinjaRenderer,
|
|
query: web::Query<HashMap<String, String>>,
|
|
) -> actix_web::Result<Html> {
|
|
let ctx = context! {
|
|
event_type => query.get("event_type").unwrap_or(&"".to_string()),
|
|
};
|
|
tmpl_env.render("partials/overview/submit_button.html", ctx)
|
|
}
|
|
|
|
|
|
#[actix_web::get("/partials/actions/accounts-by-security-selectors")]
|
|
pub async fn get_accounts_by_security_selectors(
|
|
req: HttpRequest,
|
|
tmpl_env: MiniJinjaRenderer,
|
|
query: web::Query<HashMap<String, String>>,
|
|
service_factory: web::Data<ServicesFactory>,
|
|
) -> actix_web::Result<Html> {
|
|
let sec_id = query
|
|
.get("sec-id")
|
|
.and_then(SecurityId::from_string)
|
|
.ok_or(error::ErrorBadRequest("Invalid sec-id parameters"))?;
|
|
let conn = service_factory.get_connection()?;
|
|
let account_service = service_factory.get_account_service(&conn)?;
|
|
let authentication_service = service_factory.get_authentication_service(&conn)?;
|
|
|
|
let maybe_user = authentication_service.get_login(&req);
|
|
if maybe_user.is_none() {
|
|
return Err(error::ErrorForbidden(""))
|
|
}
|
|
let user_id = maybe_user.unwrap();
|
|
|
|
let ctx = context! {
|
|
sec_id => &sec_id,
|
|
user_id => &user_id,
|
|
accounts => account_service.get_checking_accounts_for_security(&sec_id).map_err(error::ErrorInternalServerError)?,
|
|
};
|
|
tmpl_env.render("partials/actions/accounts-by-security-selectors.html", ctx)
|
|
}
|
|
|
|
|
|
#[actix_web::get("/partials/actions/action-form")]
|
|
pub async fn actions_partials(
|
|
req: HttpRequest,
|
|
tmpl_env: MiniJinjaRenderer,
|
|
query: web::Query<HashMap<String, String>>,
|
|
service_factory: web::Data<ServicesFactory>,
|
|
) -> actix_web::Result<Html> {
|
|
let event_type = query
|
|
.get("event_type")
|
|
.unwrap_or(&"404".to_string())
|
|
.to_string();
|
|
let conn = service_factory.get_connection()?;
|
|
let security_service = service_factory.get_security_service(&conn)?;
|
|
let account_service = service_factory.get_account_service(&conn)?;
|
|
let authentication_service = service_factory.get_authentication_service(&conn)?;
|
|
let maybeUser = authentication_service.get_login(&req);
|
|
if maybeUser.is_none() {
|
|
return Err(actix_web::error::ErrorForbidden(""))
|
|
}
|
|
let user = maybeUser.unwrap();
|
|
let ctx = context! {
|
|
event_type => event_type,
|
|
securities => security_service.list_securities(),
|
|
emitter_accounts => account_service.get_user_emitter_accounts(&user).map_err(error::ErrorInternalServerError)?,
|
|
accounts => account_service.get_user_emitter_accounts(&user).map_err(error::ErrorInternalServerError)?,
|
|
user => authentication_service.get_logged_in_user(&req).map_err(error::ErrorInternalServerError)?,
|
|
};
|
|
let template_location = format!("partials/actions/{:}.html", event_type);
|
|
info!("Getting template at: {:?}", template_location);
|
|
tmpl_env.render(template_location.as_str(), ctx)
|
|
}
|
|
|
|
#[derive(Deserialize, Debug)]
|
|
pub struct CreateEventPayload {
|
|
event: Event,
|
|
event_type: String,
|
|
initiator: String,
|
|
}
|
|
|
|
#[actix_web::post("/events/{event_type}")]
|
|
pub async fn push_event(
|
|
req: HttpRequest,
|
|
tmpl_env: MiniJinjaRenderer,
|
|
event_channel: web::Data<async_channel::Sender<(Uuid, Event)>>,
|
|
web::Json(form): web::Json<CreateEventPayload>,
|
|
) -> actix_web::Result<Html> {
|
|
let path_event_type = req.match_info().get("event_type").unwrap();
|
|
if path_event_type.to_string() != form.event_type {
|
|
return Err(error::ErrorBadRequest("Inconsistent event type."));
|
|
}
|
|
let validation = form.event.validate_event();
|
|
if validation.is_err() {
|
|
return Err(error::ErrorBadRequest(validation.err().unwrap()));
|
|
}
|
|
let _ = event_channel.send((Uuid::new_v4(), form.event)).await;
|
|
let ctx = context! {
|
|
event_type => "event received.",
|
|
};
|
|
tmpl_env.render("partials/v1/event_processed.html", ctx)
|
|
}
|