moved template logic into own module.

This commit is contained in:
didier amyot committed 2023-03-09 10:09:12 -05:00
1 parent f8d676e5df
commit eebe848e4b
11 files changed
+68 -76

No files matched your search

+2 -1
View File
@@ -1,6 +1,6 @@
use crate::util::{CustomResult, Error};
use base64::{engine::general_purpose, Engine as _};
use rusqlite::{params, Connection, Result, Row, Transaction};
use rusqlite::{params, Result, Row, Transaction};
pub struct LedgerInternal {}
@@ -49,6 +49,7 @@ impl LedgerInternal {
mod test_ledger_internal {
use super::*;
use crate::migration;
use rusqlite::Connection;
#[test]
fn test_initial_cookie_secret() -> CustomResult<()> {
+2 -7
View File
@@ -436,7 +436,6 @@ mod cli_test {
"123abc",
]);
let mut logic = TestCommandLineLogic::new();
let mut conn = Connection::open_in_memory().unwrap();
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
assert_eq!(logic.create_user_count, 1);
Ok(())
@@ -447,7 +446,6 @@ mod cli_test {
let cmd = command_line_parser();
let m = cmd.get_matches_from(vec!["test", "users", "ls"]);
let mut logic = TestCommandLineLogic::new();
let mut conn = Connection::open_in_memory().unwrap();
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
assert_eq!(logic.list_user_count, 1);
Ok(())
@@ -458,7 +456,6 @@ mod cli_test {
let cmd = command_line_parser();
let m = cmd.get_matches_from(vec!["test", "securities", "ls"]);
let mut logic = TestCommandLineLogic::new();
let mut conn = Connection::open_in_memory().unwrap();
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
assert_eq!(logic.list_securities_count, 1);
Ok(())
@@ -469,7 +466,6 @@ mod cli_test {
let cmd = command_line_parser();
let m = cmd.get_matches_from(vec!["test", "events", "process", "/dev/null"]);
let mut logic = TestCommandLineLogic::new();
let mut conn = Connection::open_in_memory().unwrap();
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
assert_eq!(logic.process_events_count, 1);
Ok(())
@@ -480,7 +476,6 @@ mod cli_test {
let cmd = command_line_parser();
let m = cmd.get_matches_from(vec!["test", "wui", "run"]);
let mut logic = TestCommandLineLogic::new();
let mut conn = Connection::open_in_memory().unwrap();
process_command_line(SQLiteConnectionFactory::in_memory(), &m, &mut logic)?;
assert_eq!(logic.run_webui_count, 1);
Ok(())
@@ -523,8 +518,8 @@ impl CommandLineUserLogic for ProCommandLineLogic {
fn process_events(
&mut self,
conn: &mut Connection,
files: ValuesRef<PathBuf>,
_conn: &mut Connection,
_files: ValuesRef<PathBuf>,
) -> CustomResult<()> {
// process_event_files(conn, files)
Ok(())
+1 -1
View File
@@ -29,7 +29,7 @@ impl SessionService {
}
fn _decrypt_cookie(&self, cookie: Cookie<'static>) -> Option<Cookie> {
let mut jar = CookieJar::new();
let jar = CookieJar::new();
jar.private(&self.key).decrypt(cookie)
}
+1 -1
View File
@@ -2,7 +2,7 @@ use rusqlite::Connection;
use serde::Deserialize;
use serde::Serialize;
use crate::db::external_id::UserId;
use crate::db::users::{list_users, User};
use crate::util::CustomResult;
+1 -1
View File
@@ -1,4 +1,4 @@
use crate::{CustomResult, Error};
use crate::{CustomResult};
use rusqlite::Connection;
pub use crate::services::_authentication::SessionService;
+8 -8
View File
@@ -1,18 +1,18 @@
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::webui::MiniJinjaRenderer;
use crate::webui::templates::MiniJinjaRenderer;
use crate::SQLiteConnectionFactory;
use minijinja::context;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct LoginPayload {
pub struct LoginPayload {
username: String,
password: String,
}
@@ -30,7 +30,7 @@ pub async fn login(
let ctx = context! {
name => form.username,
};
let mut ret = tmpl_env
let ret = tmpl_env
.render("partials/index/success.html", ctx)?
.customize();
Ok(ret.insert_header(("Set-Cookie", cookie.to_string())))
+7 -46
View File
@@ -1,65 +1,30 @@
#![feature(future_join)]
use std::{env, path::PathBuf};
use actix_files;
use actix_web::{
dev::ServiceResponse,
error,
http::{header::ContentType, StatusCode},
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 futures::{pin_mut, select, FutureExt};
use minijinja;
use minijinja_autoreload::AutoReloader;
use rusqlite::Connection;
use crate::events::Event;
use crate::util::{CustomResult, Error, SQLiteConnectionFactory};
use crate::webui::templates::MiniJinjaRenderer;
use crate::webui::worker::event_processor_loop;
mod index_views;
mod services;
mod templates;
mod views;
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 {
AutoReloader::new(move |notifier| {
let mut env: minijinja::Environment<'static> = minijinja::Environment::new();
@@ -102,21 +67,17 @@ pub async fn web_ui_main(
port: u16,
enable_template_autoreload: bool,
) -> 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 tmpl_reloader = web::Data::new(tmpl_reloader);
// use r2d2 for connection pools (https://github.com/sfackler/r2d2 &
// https://github.com/ivanceras/r2d2-sqlite) use
// https://docs.rs/actix-web/4.3.1/actix_web/web/fn.block.html
// in handlers.
let cloned_conn_fact = conn_fact.clone();
let server = HttpServer::new(move || {
let template_reloader = create_auto_reloader(enable_template_autoreload);
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(cloned_conn_fact.clone()))
.service(create_static_scope())
+2 -2
View File
@@ -1,5 +1,5 @@
use crate::services::{ReadOnlyServiceFactory, SessionService, UserService};
use crate::util::{CustomResult, Error, SQLiteConnectionFactory};
use crate::services::{SessionService};
use crate::util::{SQLiteConnectionFactory};
struct ServicesCache {
session_service: SessionService,
+36
View File
@@ -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
View File
@@ -1,17 +1,16 @@
use std::collections::HashMap;
use actix_web::{error, web, HttpRequest, Responder};
use actix_web_lab::__reexports::futures_util::SinkExt;
use clap::builder::TypedValueParser;
use log::info;
use minijinja::context;
use serde::Deserialize;
use crate::db::users::list_users;
use crate::events::Event;
use crate::services::ReadOnlyServiceFactory;
use crate::util::SQLiteConnectionFactory;
use crate::webui::MiniJinjaRenderer;
use crate::webui::templates::MiniJinjaRenderer;
#[actix_web::get("/actions")]
pub async fn actions(tmpl_env: MiniJinjaRenderer) -> actix_web::Result<impl Responder> {
@@ -67,7 +66,7 @@ pub async fn actions_partials(
}
#[derive(Deserialize, Debug)]
struct CreateEventPayload {
pub struct CreateEventPayload {
event: Event,
event_type: String,
}
+4 -4
View File
@@ -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::events::Event;