commit 0aa33a2cb48ee5dbf31a6f448effb41e7467e417
parent fa7dbedd5d878305adbae1c20cd46207f8d45261
Author: Stefan Melmuk <stefan.melmuk@gmail.com>
Date: Mon, 28 Nov 2022 17:35:36 +0100
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>
Diffstat:
2 files changed, 36 insertions(+), 32 deletions(-)
diff --git a/src/api/admin.rs b/src/api/admin.rs
@@ -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 {
diff --git a/src/static/templates/admin/login.hbs b/src/static/templates/admin/login.hbs
@@ -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>