moved template logic into own module.
This commit is contained in:
1 parent
f8d676e5df
commit
eebe848e4b
11 files changed
+68
-76
No files matched your search
@@ -1,6 +1,6 @@
|
|||||||
use crate::util::{CustomResult, Error};
|
use crate::util::{CustomResult, Error};
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
use base64::{engine::general_purpose, Engine as _};
|
||||||
use rusqlite::{params, Connection, Result, Row, Transaction};
|
use rusqlite::{params, Result, Row, Transaction};
|
||||||
|
|
||||||
pub struct LedgerInternal {}
|
pub struct LedgerInternal {}
|
||||||
|
|
||||||
@@ -49,6 +49,7 @@ impl LedgerInternal {
|
|||||||
mod test_ledger_internal {
|
mod test_ledger_internal {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::migration;
|
use crate::migration;
|
||||||
|
use rusqlite::Connection;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_initial_cookie_secret() -> CustomResult<()> {
|
fn test_initial_cookie_secret() -> CustomResult<()> {
|
||||||
|
|||||||
+2
-7
@@ -436,7 +436,6 @@ mod cli_test {
|
|||||||
"123abc",
|
"123abc",
|
||||||
]);
|
]);
|
||||||
let mut logic = TestCommandLineLogic::new();
|
let mut logic = TestCommandLineLogic::new();
|
||||||
let mut conn = Connection::open_in_memory().unwrap();
|
|
||||||
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
||||||
assert_eq!(logic.create_user_count, 1);
|
assert_eq!(logic.create_user_count, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -447,7 +446,6 @@ mod cli_test {
|
|||||||
let cmd = command_line_parser();
|
let cmd = command_line_parser();
|
||||||
let m = cmd.get_matches_from(vec!["test", "users", "ls"]);
|
let m = cmd.get_matches_from(vec!["test", "users", "ls"]);
|
||||||
let mut logic = TestCommandLineLogic::new();
|
let mut logic = TestCommandLineLogic::new();
|
||||||
let mut conn = Connection::open_in_memory().unwrap();
|
|
||||||
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
||||||
assert_eq!(logic.list_user_count, 1);
|
assert_eq!(logic.list_user_count, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -458,7 +456,6 @@ mod cli_test {
|
|||||||
let cmd = command_line_parser();
|
let cmd = command_line_parser();
|
||||||
let m = cmd.get_matches_from(vec!["test", "securities", "ls"]);
|
let m = cmd.get_matches_from(vec!["test", "securities", "ls"]);
|
||||||
let mut logic = TestCommandLineLogic::new();
|
let mut logic = TestCommandLineLogic::new();
|
||||||
let mut conn = Connection::open_in_memory().unwrap();
|
|
||||||
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
||||||
assert_eq!(logic.list_securities_count, 1);
|
assert_eq!(logic.list_securities_count, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -469,7 +466,6 @@ mod cli_test {
|
|||||||
let cmd = command_line_parser();
|
let cmd = command_line_parser();
|
||||||
let m = cmd.get_matches_from(vec!["test", "events", "process", "/dev/null"]);
|
let m = cmd.get_matches_from(vec!["test", "events", "process", "/dev/null"]);
|
||||||
let mut logic = TestCommandLineLogic::new();
|
let mut logic = TestCommandLineLogic::new();
|
||||||
let mut conn = Connection::open_in_memory().unwrap();
|
|
||||||
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
||||||
assert_eq!(logic.process_events_count, 1);
|
assert_eq!(logic.process_events_count, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -480,7 +476,6 @@ mod cli_test {
|
|||||||
let cmd = command_line_parser();
|
let cmd = command_line_parser();
|
||||||
let m = cmd.get_matches_from(vec!["test", "wui", "run"]);
|
let m = cmd.get_matches_from(vec!["test", "wui", "run"]);
|
||||||
let mut logic = TestCommandLineLogic::new();
|
let mut logic = TestCommandLineLogic::new();
|
||||||
let mut conn = Connection::open_in_memory().unwrap();
|
|
||||||
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
|
||||||
assert_eq!(logic.run_webui_count, 1);
|
assert_eq!(logic.run_webui_count, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -523,8 +518,8 @@ impl CommandLineUserLogic for ProCommandLineLogic {
|
|||||||
|
|
||||||
fn process_events(
|
fn process_events(
|
||||||
&mut self,
|
&mut self,
|
||||||
conn: &mut Connection,
|
_conn: &mut Connection,
|
||||||
files: ValuesRef<PathBuf>,
|
_files: ValuesRef<PathBuf>,
|
||||||
) -> CustomResult<()> {
|
) -> CustomResult<()> {
|
||||||
// process_event_files(conn, files)
|
// process_event_files(conn, files)
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ impl SessionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn _decrypt_cookie(&self, cookie: Cookie<'static>) -> Option<Cookie> {
|
fn _decrypt_cookie(&self, cookie: Cookie<'static>) -> Option<Cookie> {
|
||||||
let mut jar = CookieJar::new();
|
let jar = CookieJar::new();
|
||||||
jar.private(&self.key).decrypt(cookie)
|
jar.private(&self.key).decrypt(cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use rusqlite::Connection;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::db::external_id::UserId;
|
|
||||||
use crate::db::users::{list_users, User};
|
use crate::db::users::{list_users, User};
|
||||||
use crate::util::CustomResult;
|
use crate::util::CustomResult;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use crate::{CustomResult, Error};
|
use crate::{CustomResult};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
pub use crate::services::_authentication::SessionService;
|
pub use crate::services::_authentication::SessionService;
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use actix_web::{web, HttpRequest, Responder};
|
use actix_web::{web, HttpRequest, Responder};
|
||||||
use cookie::time::macros::datetime;
|
|
||||||
use cookie::time::OffsetDateTime;
|
|
||||||
use cookie::{Cookie, CookieJar, Key};
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
use crate::db::external_id::UserId;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use crate::services::ReadOnlyServiceFactory;
|
use crate::services::ReadOnlyServiceFactory;
|
||||||
use crate::webui::MiniJinjaRenderer;
|
use crate::webui::templates::MiniJinjaRenderer;
|
||||||
use crate::SQLiteConnectionFactory;
|
use crate::SQLiteConnectionFactory;
|
||||||
use minijinja::context;
|
use minijinja::context;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct LoginPayload {
|
pub struct LoginPayload {
|
||||||
username: String,
|
username: String,
|
||||||
password: String,
|
password: String,
|
||||||
}
|
}
|
||||||
@@ -30,7 +30,7 @@ pub async fn login(
|
|||||||
let ctx = context! {
|
let ctx = context! {
|
||||||
name => form.username,
|
name => form.username,
|
||||||
};
|
};
|
||||||
let mut ret = tmpl_env
|
let ret = tmpl_env
|
||||||
.render("partials/index/success.html", ctx)?
|
.render("partials/index/success.html", ctx)?
|
||||||
.customize();
|
.customize();
|
||||||
Ok(ret.insert_header(("Set-Cookie", cookie.to_string())))
|
Ok(ret.insert_header(("Set-Cookie", cookie.to_string())))
|
||||||
|
|||||||
+7
-46
@@ -1,65 +1,30 @@
|
|||||||
#![feature(future_join)]
|
|
||||||
|
|
||||||
use std::{env, path::PathBuf};
|
use std::{env, path::PathBuf};
|
||||||
|
|
||||||
use actix_files;
|
use actix_files;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
dev::ServiceResponse,
|
dev::ServiceResponse,
|
||||||
error,
|
|
||||||
http::{header::ContentType, StatusCode},
|
http::{header::ContentType, StatusCode},
|
||||||
middleware::{ErrorHandlerResponse, ErrorHandlers, Logger},
|
middleware::{ErrorHandlerResponse, ErrorHandlers, Logger},
|
||||||
web, App, FromRequest, HttpRequest, HttpResponse, HttpServer, Responder, Result, Scope,
|
web, App, FromRequest, HttpResponse, HttpServer, Responder, Result, Scope,
|
||||||
};
|
};
|
||||||
use actix_web_lab::respond::Html;
|
|
||||||
use async_channel;
|
use async_channel;
|
||||||
use futures::{pin_mut, select, FutureExt};
|
use futures::{pin_mut, select, FutureExt};
|
||||||
use minijinja;
|
use minijinja;
|
||||||
use minijinja_autoreload::AutoReloader;
|
use minijinja_autoreload::AutoReloader;
|
||||||
use rusqlite::Connection;
|
|
||||||
|
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
use crate::util::{CustomResult, Error, SQLiteConnectionFactory};
|
use crate::util::{CustomResult, Error, SQLiteConnectionFactory};
|
||||||
|
use crate::webui::templates::MiniJinjaRenderer;
|
||||||
use crate::webui::worker::event_processor_loop;
|
use crate::webui::worker::event_processor_loop;
|
||||||
|
|
||||||
mod index_views;
|
mod index_views;
|
||||||
mod services;
|
mod services;
|
||||||
|
mod templates;
|
||||||
mod views;
|
mod views;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
|
||||||
struct MiniJinjaRenderer {
|
|
||||||
tmpl_env: web::Data<minijinja_autoreload::AutoReloader>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MiniJinjaRenderer {
|
|
||||||
fn render(&self, tmpl: &str, ctx: impl Into<minijinja::value::Value>) -> Result<Html> {
|
|
||||||
log::info!("Rendering template {:?}", tmpl);
|
|
||||||
self.tmpl_env
|
|
||||||
.acquire_env()
|
|
||||||
.map_err(|_| error::ErrorInternalServerError("could not acquire template env"))?
|
|
||||||
.get_template(tmpl)
|
|
||||||
.map_err(|e| error::ErrorInternalServerError(format!("{:?}", e)))?
|
|
||||||
.render(ctx.into())
|
|
||||||
.map(Html)
|
|
||||||
.map_err(|err| {
|
|
||||||
log::error!("{err}");
|
|
||||||
error::ErrorInternalServerError("template error")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromRequest for MiniJinjaRenderer {
|
|
||||||
type Error = actix_web::Error;
|
|
||||||
type Future = actix_utils::future::Ready<Result<Self, Self::Error>>;
|
|
||||||
|
|
||||||
fn from_request(req: &HttpRequest, _pl: &mut actix_web::dev::Payload) -> Self::Future {
|
|
||||||
let tmpl_env = <web::Data<minijinja_autoreload::AutoReloader>>::extract(req)
|
|
||||||
.into_inner()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
actix_utils::future::ready(Ok(Self { tmpl_env }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_auto_reloader(enable_template_autoreload: bool) -> AutoReloader {
|
fn create_auto_reloader(enable_template_autoreload: bool) -> AutoReloader {
|
||||||
AutoReloader::new(move |notifier| {
|
AutoReloader::new(move |notifier| {
|
||||||
let mut env: minijinja::Environment<'static> = minijinja::Environment::new();
|
let mut env: minijinja::Environment<'static> = minijinja::Environment::new();
|
||||||
@@ -102,21 +67,17 @@ pub async fn web_ui_main(
|
|||||||
port: u16,
|
port: u16,
|
||||||
enable_template_autoreload: bool,
|
enable_template_autoreload: bool,
|
||||||
) -> CustomResult<()> {
|
) -> CustomResult<()> {
|
||||||
// The closure is invoked every time the environment is outdated to recreate it.
|
|
||||||
let tmpl_reloader = create_auto_reloader(enable_template_autoreload);
|
|
||||||
|
|
||||||
let (event_sender, event_receiver) = async_channel::unbounded::<Event>();
|
let (event_sender, event_receiver) = async_channel::unbounded::<Event>();
|
||||||
|
|
||||||
let tmpl_reloader = web::Data::new(tmpl_reloader);
|
|
||||||
|
|
||||||
// use r2d2 for connection pools (https://github.com/sfackler/r2d2 &
|
// use r2d2 for connection pools (https://github.com/sfackler/r2d2 &
|
||||||
// https://github.com/ivanceras/r2d2-sqlite) use
|
// https://github.com/ivanceras/r2d2-sqlite) use
|
||||||
// https://docs.rs/actix-web/4.3.1/actix_web/web/fn.block.html
|
// https://docs.rs/actix-web/4.3.1/actix_web/web/fn.block.html
|
||||||
// in handlers.
|
// in handlers.
|
||||||
let cloned_conn_fact = conn_fact.clone();
|
let cloned_conn_fact = conn_fact.clone();
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
|
let template_reloader = create_auto_reloader(enable_template_autoreload);
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(tmpl_reloader.clone())
|
.app_data(web::Data::new(template_reloader))
|
||||||
.app_data(web::Data::new(event_sender.clone()))
|
.app_data(web::Data::new(event_sender.clone()))
|
||||||
.app_data(web::Data::new(cloned_conn_fact.clone()))
|
.app_data(web::Data::new(cloned_conn_fact.clone()))
|
||||||
.service(create_static_scope())
|
.service(create_static_scope())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::services::{ReadOnlyServiceFactory, SessionService, UserService};
|
use crate::services::{SessionService};
|
||||||
use crate::util::{CustomResult, Error, SQLiteConnectionFactory};
|
use crate::util::{SQLiteConnectionFactory};
|
||||||
|
|
||||||
struct ServicesCache {
|
struct ServicesCache {
|
||||||
session_service: SessionService,
|
session_service: SessionService,
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
use actix_web::{error, web, FromRequest, HttpRequest, Result};
|
||||||
|
use actix_web_lab::respond::Html;
|
||||||
|
|
||||||
|
pub struct MiniJinjaRenderer {
|
||||||
|
tmpl_env: web::Data<minijinja_autoreload::AutoReloader>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MiniJinjaRenderer {
|
||||||
|
pub fn render(&self, tmpl: &str, ctx: impl Into<minijinja::value::Value>) -> Result<Html> {
|
||||||
|
log::info!("Rendering template {:?}", tmpl);
|
||||||
|
self.tmpl_env
|
||||||
|
.acquire_env()
|
||||||
|
.map_err(|_| error::ErrorInternalServerError("could not acquire template env"))?
|
||||||
|
.get_template(tmpl)
|
||||||
|
.map_err(|e| error::ErrorInternalServerError(format!("{:?}", e)))?
|
||||||
|
.render(ctx.into())
|
||||||
|
.map(Html)
|
||||||
|
.map_err(|err| {
|
||||||
|
log::error!("{err}");
|
||||||
|
error::ErrorInternalServerError("template error")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromRequest for MiniJinjaRenderer {
|
||||||
|
type Error = actix_web::Error;
|
||||||
|
type Future = actix_utils::future::Ready<Result<Self, Self::Error>>;
|
||||||
|
|
||||||
|
fn from_request(req: &HttpRequest, _pl: &mut actix_web::dev::Payload) -> Self::Future {
|
||||||
|
let tmpl_env = <web::Data<minijinja_autoreload::AutoReloader>>::extract(req)
|
||||||
|
.into_inner()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
actix_utils::future::ready(Ok(Self { tmpl_env }))
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-5
@@ -1,17 +1,16 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use actix_web::{error, web, HttpRequest, Responder};
|
use actix_web::{error, web, HttpRequest, Responder};
|
||||||
use actix_web_lab::__reexports::futures_util::SinkExt;
|
|
||||||
use clap::builder::TypedValueParser;
|
|
||||||
use log::info;
|
use log::info;
|
||||||
use minijinja::context;
|
use minijinja::context;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::db::users::list_users;
|
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
use crate::services::ReadOnlyServiceFactory;
|
use crate::services::ReadOnlyServiceFactory;
|
||||||
use crate::util::SQLiteConnectionFactory;
|
use crate::util::SQLiteConnectionFactory;
|
||||||
use crate::webui::MiniJinjaRenderer;
|
use crate::webui::templates::MiniJinjaRenderer;
|
||||||
|
|
||||||
#[actix_web::get("/actions")]
|
#[actix_web::get("/actions")]
|
||||||
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
|
||||||
@@ -67,7 +66,7 @@ pub async fn actions_partials(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct CreateEventPayload {
|
pub struct CreateEventPayload {
|
||||||
event: Event,
|
event: Event,
|
||||||
event_type: String,
|
event_type: String,
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
use std::io;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use rusqlite::Connection;
|
|
||||||
use tokio::time::sleep;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
use crate::event_processor::process_event;
|
use crate::event_processor::process_event;
|
||||||
use crate::events::Event;
|
use crate::events::Event;
|
||||||
|
|||||||
Reference in new issue
Block a user