don't use param for passing the redirect info

revert some changes and also rename catcher to `admin_login` to make its
function clearer

Co-authored-by: BlackDex <black.dex@gmail.com>
This commit is contained in:
Stefan Melmuk 2022-11-28 17:35:36 +01:00
parent fa7dbedd5d
commit 0aa33a2cb4
No known key found for this signature in database
GPG key ID: 817020C608FE9C09
2 changed files with 36 additions and 32 deletions

View file

@ -31,7 +31,6 @@ pub fn routes() -> Vec<Route> {
}
routes![
admin_login,
get_users_json,
get_user_json,
post_admin_login,
@ -61,19 +60,10 @@ pub fn catchers() -> Vec<Catcher> {
if !CONFIG.disable_admin_token() && !CONFIG.is_admin_token_set() {
catchers![]
} else {
catchers![unauthorized]
catchers![admin_login]
}
}
#[catch(401)]
fn unauthorized(request: &Request<'_>) -> Result<Redirect, Error> {
if request.format() == Some(&MediaType::JSON) {
err_code!("Authorization failed.", Status::Unauthorized.code);
}
let redirect = request.segments::<std::path::PathBuf>(0..).unwrap_or_default().display().to_string();
Ok(Redirect::to(admin_redirect_url(&redirect)))
}
static DB_TYPE: Lazy<&str> = Lazy::new(|| {
DbConnType::from_url(&CONFIG.database_url())
.map(|t| match t {
@ -102,10 +92,6 @@ fn admin_path() -> String {
format!("{}{}", CONFIG.domain_path(), ADMIN_PATH)
}
fn admin_redirect_url(redirect: &str) -> String {
format!("{}/?redirect=/{}", admin_path(), redirect)
}
#[derive(Debug)]
struct IpHeader(Option<String>);
@ -134,24 +120,31 @@ fn admin_url() -> String {
#[derive(Responder)]
enum AdminResponse {
#[response(status = 200)]
Ok(ApiResult<Html<String>>),
#[response(status = 401)]
Unauthorized(ApiResult<Html<String>>),
#[response(status = 429)]
TooManyRequests(ApiResult<Html<String>>),
}
#[get("/?<_redirect..>")]
fn admin_login(_redirect: &str) -> ApiResult<Html<String>> {
render_admin_login(None)
#[catch(401)]
fn admin_login(request: &Request<'_>) -> ApiResult<Html<String>> {
if request.format() == Some(&MediaType::JSON) {
err_code!("Authorization failed.", Status::Unauthorized.code);
}
let redirect = request.segments::<std::path::PathBuf>(0..).unwrap_or_default().display().to_string();
render_admin_login(None, Some(redirect))
}
fn render_admin_login(msg: Option<&str>) -> ApiResult<Html<String>> {
fn render_admin_login(msg: Option<&str>, redirect: Option<String>) -> ApiResult<Html<String>> {
// If there is an error, show it
let msg = msg.map(|msg| format!("Error: {msg}"));
let json = json!({
"page_content": "admin/login",
"version": VERSION,
"error": msg,
"redirect": redirect,
"urlpath": CONFIG.domain_path()
});
@ -163,25 +156,25 @@ fn render_admin_login(msg: Option<&str>) -> ApiResult<Html<String>> {
#[derive(FromForm)]
struct LoginForm {
token: String,
redirect: Option<String>,
}
#[post("/?<redirect>", data = "<data>")]
fn post_admin_login(
data: Form<LoginForm>,
redirect: &str,
cookies: &CookieJar<'_>,
ip: ClientIp,
) -> Result<Redirect, AdminResponse> {
#[post("/", data = "<data>")]
fn post_admin_login(data: Form<LoginForm>, cookies: &CookieJar<'_>, ip: ClientIp) -> Result<Redirect, AdminResponse> {
let data = data.into_inner();
let redirect = data.redirect;
if crate::ratelimit::check_limit_admin(&ip.ip).is_err() {
return Err(AdminResponse::TooManyRequests(render_admin_login(Some("Too many requests, try again later."))));
return Err(AdminResponse::TooManyRequests(render_admin_login(
Some("Too many requests, try again later."),
redirect,
)));
}
// If the token is invalid, redirect to login page
if !_validate_token(&data.token) {
error!("Invalid admin token. IP: {}", ip.ip);
Err(AdminResponse::Unauthorized(render_admin_login(Some("Invalid admin token, please try again."))))
Err(AdminResponse::Unauthorized(render_admin_login(Some("Invalid admin token, please try again."), redirect)))
} else {
// If the token received is valid, generate JWT and save it as a cookie
let claims = generate_admin_claims();
@ -195,7 +188,11 @@ fn post_admin_login(
.finish();
cookies.add(cookie);
Ok(Redirect::to(format!("{}{}", admin_path(), redirect)))
if let Some(redirect) = redirect {
Ok(Redirect::to(format!("{}{}", admin_path(), redirect)))
} else {
Err(AdminResponse::Ok(render_admin_page()))
}
}
}
@ -247,12 +244,16 @@ impl AdminTemplateData {
}
}
#[get("/")]
fn admin_page(_token: AdminToken) -> ApiResult<Html<String>> {
fn render_admin_page() -> ApiResult<Html<String>> {
let text = AdminTemplateData::new().render()?;
Ok(Html(text))
}
#[get("/")]
fn admin_page(_token: AdminToken) -> ApiResult<Html<String>> {
render_admin_page()
}
#[derive(Deserialize, Debug)]
#[allow(non_snake_case)]
struct InviteData {

View file

@ -12,8 +12,11 @@
<h6 class="mb-0 text-white">Authentication key needed to continue</h6>
<small>Please provide it below:</small>
<form class="form-inline" method="post">
<form class="form-inline" method="post" action="{{urlpath}}/admin">
<input type="password" class="form-control w-50 mr-2" name="token" placeholder="Enter admin token" autofocus="autofocus">
{{#if redirect}}
<input type="hidden" id="redirect" name="redirect" value="/{{redirect}}">
{{/if}}
<button type="submit" class="btn btn-primary">Enter</button>
</form>
</div>