set_password: Properly parse the URL, support trailing slashes

Fixes #597
This commit is contained in:
Valentin Tolmer
2023-08-02 13:10:05 +02:00
committed by nitnelave
parent 08b7c6ce33
commit f0bbcfd2c8
+16 -9
View File
@@ -1,6 +1,7 @@
use anyhow::{bail, ensure, Context, Result}; use anyhow::{bail, ensure, Context, Result};
use clap::Parser; use clap::Parser;
use lldap_auth::{opaque, registration}; use lldap_auth::{opaque, registration};
use reqwest::Url;
use serde::Serialize; use serde::Serialize;
/// Set the password for a user in LLDAP. /// Set the password for a user in LLDAP.
@@ -8,7 +9,7 @@ use serde::Serialize;
pub struct CliOpts { pub struct CliOpts {
/// Base LLDAP url, e.g. "https://lldap/". /// Base LLDAP url, e.g. "https://lldap/".
#[clap(short, long)] #[clap(short, long)]
pub base_url: String, pub base_url: Url,
/// Admin username. /// Admin username.
#[clap(long, default_value = "admin")] #[clap(long, default_value = "admin")]
@@ -31,10 +32,16 @@ pub struct CliOpts {
pub password: String, pub password: String,
} }
fn get_token(base_url: &str, username: &str, password: &str) -> Result<String> { fn append_to_url(base_url: &Url, path: &str) -> Url {
let mut new_url = base_url.clone();
new_url.path_segments_mut().unwrap().extend(path.split('/'));
new_url
}
fn get_token(base_url: &Url, username: &str, password: &str) -> Result<String> {
let client = reqwest::blocking::Client::new(); let client = reqwest::blocking::Client::new();
let response = client let response = client
.post(format!("{base_url}/auth/simple/login")) .post(append_to_url(base_url, "auth/simple/login"))
.header(reqwest::header::CONTENT_TYPE, "application/json") .header(reqwest::header::CONTENT_TYPE, "application/json")
.body( .body(
serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest { serde_json::to_string(&lldap_auth::login::ClientSimpleLoginRequest {
@@ -48,7 +55,7 @@ fn get_token(base_url: &str, username: &str, password: &str) -> Result<String> {
Ok(serde_json::from_str::<lldap_auth::login::ServerLoginResponse>(&response.text()?)?.token) Ok(serde_json::from_str::<lldap_auth::login::ServerLoginResponse>(&response.text()?)?.token)
} }
fn call_server(url: &str, token: &str, body: impl Serialize) -> Result<String> { fn call_server(url: Url, token: &str, body: impl Serialize) -> Result<String> {
let client = reqwest::blocking::Client::new(); let client = reqwest::blocking::Client::new();
let request = client let request = client
.post(url) .post(url)
@@ -60,13 +67,13 @@ fn call_server(url: &str, token: &str, body: impl Serialize) -> Result<String> {
} }
pub fn register_start( pub fn register_start(
base_url: &str, base_url: &Url,
token: &str, token: &str,
request: registration::ClientRegistrationStartRequest, request: registration::ClientRegistrationStartRequest,
) -> Result<registration::ServerRegistrationStartResponse> { ) -> Result<registration::ServerRegistrationStartResponse> {
let request = Some(request); let request = Some(request);
let data = call_server( let data = call_server(
&format!("{base_url}/auth/opaque/register/start"), append_to_url(base_url, "auth/opaque/register/start"),
token, token,
request, request,
)?; )?;
@@ -74,13 +81,13 @@ pub fn register_start(
} }
pub fn register_finish( pub fn register_finish(
base_url: &str, base_url: &Url,
token: &str, token: &str,
request: registration::ClientRegistrationFinishRequest, request: registration::ClientRegistrationFinishRequest,
) -> Result<()> { ) -> Result<()> {
let request = Some(request); let request = Some(request);
call_server( call_server(
&format!("{base_url}/auth/opaque/register/finish"), append_to_url(base_url, "auth/opaque/register/finish"),
token, token,
request, request,
) )
@@ -94,7 +101,7 @@ fn main() -> Result<()> {
"New password is too short, expected at least 8 characters" "New password is too short, expected at least 8 characters"
); );
ensure!( ensure!(
opts.base_url.starts_with("http://") || opts.base_url.starts_with("https://"), opts.base_url.scheme() == "http" || opts.base_url.scheme() == "https",
"Base URL should start with `http://` or `https://`" "Base URL should start with `http://` or `https://`"
); );
let token = match (opts.token.as_ref(), opts.admin_password.as_ref()) { let token = match (opts.token.as_ref(), opts.admin_password.as_ref()) {