feat: Add a configurable headline to the form

This commit is contained in:
Philipp Matthias Schaefer 2021-02-27 20:11:47 +01:00
parent 0916b3fa7c
commit 10d5a1c515
6 changed files with 62 additions and 12 deletions

View File

@ -22,7 +22,7 @@ use rocket_contrib::json::Json;
use rocket::post;
use serde_derive::{Deserialize, Serialize};
use crate::config::Config;
use crate::context::Context;
#[derive(Deserialize)]
pub struct PasswordData {
@ -43,10 +43,11 @@ pub struct Response {
message: Option<Message>,
}
fn change_password(data: Json<PasswordData>, config: rocket::State<Config>) -> Result<()> {
fn change_password(data: Json<PasswordData>,
context: rocket::State<Context>) -> Result<()> {
let dn = format!("uid={},ou=People,dc=fiveop,dc=de", &data.username);
let mut ldap = LdapConn::new(&config.ldap_url)?;
let mut ldap = LdapConn::new(&context.ldap_url)?;
ldap
.simple_bind(&dn, &data.old_password)?
.success()?;
@ -63,9 +64,10 @@ fn change_password(data: Json<PasswordData>, config: rocket::State<Config>) -> R
}
#[post("/update", data = "<data>")]
pub fn update(data: Json<PasswordData>, config: rocket::State<Config>) -> Json<Response> {
pub fn update(data: Json<PasswordData>,
context: rocket::State<Context>) -> Json<Response> {
Json(
match change_password(data, config) {
match change_password(data, context) {
Ok(_) => Response{
success: true,
message: None,

View File

@ -22,6 +22,10 @@ use handlebars::Handlebars;
use serde_derive::Deserialize;
use serde_json::json;
fn default_headline() -> String {
"Change your password".to_string()
}
fn default_ldap_url() -> String {
"ldap://localhost".to_string()
}
@ -38,6 +42,9 @@ fn default_port() -> u16 {
pub struct Config {
pub dn: String,
#[serde(default = "default_headline")]
pub headline: String,
#[serde(default = "default_ldap_url")]
pub ldap_url: String,
@ -50,15 +57,21 @@ pub struct Config {
pub fn load_config(file_path: &str) -> Result<Config> {
let file = File::open(file_path).
with_context(|| format!("Failed to open configuration file '{}'", file_path))?;
with_context(|| format!("Failed to open configuration file '{}'",
file_path))?;
let config: Config = serde_json::from_reader(BufReader::new(file))
.with_context(|| format!("Failed to parse configuration file '{}'", file_path))?;
.with_context(|| format!("Failed to parse configuration file '{}'",
file_path))?;
Handlebars::new()
.render_template(&config.dn, &json!({"username" : "foo"}))
.map(|_| ())
.with_context(|| format!("Failed to parse DN ({}) in configuration file '{}'", config.dn, file_path))?;
.with_context(|| format!(
"Failed to render DN ({}) from configuration file '{}'",
config.dn,
file_path
))?;
Ok(config)
}

25
src/context.rs Normal file
View File

@ -0,0 +1,25 @@
use anyhow::{Context as AnyhowContext, Result};
use handlebars::Handlebars;
use serde_json::json;
use crate::config::Config;
pub struct Context {
pub ldap_url: String,
pub index_html: String,
}
impl Context {
pub fn new(config: &Config) -> Result<Context> {
let index_html = Handlebars::new()
.render_template(include_str!("static/index.html.hbs"),
&json!({"headline" : config.headline}))
.with_context(|| format!(
"Failed to render index.html from template and configured headline '{}'",
config.headline
))?;
Ok(Context{ldap_url: config.ldap_url.clone(),
index_html})
}
}

View File

@ -18,6 +18,7 @@
mod api;
mod config;
mod context;
mod r#static;
use anyhow::{Context, Result};
@ -46,11 +47,17 @@ fn main() -> Result<()> {
let config = load_config(config_file_path)?;
let context = context::Context::new(&config)?;
let rocket_config = Config::build(Environment::Production)
.address(&config.host)
.port(config.port)
.finalize()
.with_context(|| format!("Bad host address ({}) in configuration file '{}'", config.host, config_file_path))?;
.with_context(|| format!(
"Bad host address ({}) in configuration file '{}'",
config.host,
config_file_path
))?;
rocket::custom(rocket_config)
.mount("/", routes![r#static::index,
@ -62,7 +69,7 @@ fn main() -> Result<()> {
r#static::logo,
r#static::hourglass,
api::update])
.manage(config)
.manage(context)
.launch();
Ok(())

View File

@ -20,6 +20,8 @@ use rocket::response::{content, Responder, Response};
use rocket::get;
use crate::context::Context;
pub struct Svg<R>(pub R);
impl<'r, R: Responder<'r>> Responder<'r> for Svg<R> {
@ -29,8 +31,8 @@ impl<'r, R: Responder<'r>> Responder<'r> for Svg<R> {
}
#[get("/")]
pub fn index() -> content::Html<&'static str> {
content::Html(include_str!("static/index.html"))
pub fn index(context: rocket::State<Context>) -> content::Html<String> {
content::Html(context.index_html.clone())
}
#[get("/checkmark.svg")]

View File

@ -26,6 +26,7 @@ with the WebLDAPPasswd. If not, see <https://www.gnu.org/licenses/>.
<script src="webldappasswd.js"></script>
</head>
<body>
<h1>{{headline}}</h1>
<form>
<label>Username</label>
<input type="text" name="username" autocomplete="username">