mirror of
https://github.com/Jackzmc/storage.git
synced 2025-05-06 22:33:21 +00:00
Add 404 and 401 check
This commit is contained in:
parent
a60f80cdda
commit
1931b07b0d
5 changed files with 70 additions and 10 deletions
37
server/src/guards.rs
Normal file
37
server/src/guards.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
use rocket::http::Status;
|
||||||
|
use rocket::Request;
|
||||||
|
use rocket::request::{FromRequest, Outcome};
|
||||||
|
use rocket_session_store::{Session, SessionResult};
|
||||||
|
use crate::models::user::UserModel;
|
||||||
|
use crate::{LoginSessionData, SessionData};
|
||||||
|
|
||||||
|
pub struct AuthUser {
|
||||||
|
pub user: LoginSessionData
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UserError {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl<'r> FromRequest<'r> for AuthUser {
|
||||||
|
type Error = UserError;
|
||||||
|
|
||||||
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
|
let sess = match request.guard::<Session<SessionData>>().await {
|
||||||
|
Outcome::Success(sess ) => sess,
|
||||||
|
_ => return Outcome::Forward(Status::Unauthorized)
|
||||||
|
};
|
||||||
|
let sess = match sess.get().await {
|
||||||
|
Ok(Some(sess)) => {
|
||||||
|
sess
|
||||||
|
}
|
||||||
|
_ => return Outcome::Forward(Status::Unauthorized),
|
||||||
|
};
|
||||||
|
if let Some(login) = &sess.login {
|
||||||
|
Outcome::Success(Self { user: login.clone() })
|
||||||
|
} else {
|
||||||
|
Outcome::Forward(Status::Unauthorized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,14 +2,15 @@ use std::net::IpAddr;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
use rocket::{catch, launch, routes, Request, State};
|
use rocket::{catch, catchers, launch, routes, uri, Request, Route, State};
|
||||||
use rocket::data::ByteUnit;
|
use rocket::data::ByteUnit;
|
||||||
use rocket::fs::{relative, FileServer};
|
use rocket::fs::{relative, FileServer};
|
||||||
use rocket::futures::AsyncWriteExt;
|
use rocket::futures::AsyncWriteExt;
|
||||||
use rocket::http::private::cookie::CookieBuilder;
|
use rocket::http::private::cookie::CookieBuilder;
|
||||||
|
use rocket::response::Redirect;
|
||||||
use rocket::serde::Serialize;
|
use rocket::serde::Serialize;
|
||||||
use rocket_dyn_templates::handlebars::{handlebars_helper, Context, Handlebars, Helper, HelperResult, Output, RenderContext};
|
use rocket_dyn_templates::handlebars::{handlebars_helper, Context, Handlebars, Helper, HelperResult, Output, RenderContext};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::{context, Template};
|
||||||
use rocket_session_store::memory::MemoryStore;
|
use rocket_session_store::memory::MemoryStore;
|
||||||
use rocket_session_store::SessionStore;
|
use rocket_session_store::SessionStore;
|
||||||
use sqlx::{migrate, Pool, Postgres};
|
use sqlx::{migrate, Pool, Postgres};
|
||||||
|
@ -36,6 +37,7 @@ mod managers;
|
||||||
mod objs;
|
mod objs;
|
||||||
mod helpers;
|
mod helpers;
|
||||||
mod consts;
|
mod consts;
|
||||||
|
mod guards;
|
||||||
|
|
||||||
pub type DB = Pool<Postgres>;
|
pub type DB = Pool<Postgres>;
|
||||||
|
|
||||||
|
@ -128,10 +130,29 @@ async fn rocket() -> _ {
|
||||||
ui::user::index, ui::user::redirect_list_library_files, ui::user::list_library_files, ui::user::get_library_file,
|
ui::user::index, ui::user::redirect_list_library_files, ui::user::list_library_files, ui::user::get_library_file,
|
||||||
ui::help::test_get
|
ui::help::test_get
|
||||||
])
|
])
|
||||||
|
.register("/api", catchers![
|
||||||
|
not_found_api,
|
||||||
|
])
|
||||||
|
.register("/", catchers![
|
||||||
|
not_found, not_authorized
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[catch(401)]
|
||||||
|
pub fn not_authorized(req: &Request) -> Redirect {
|
||||||
|
// uri!(ui::auth::login) doesn't work, it redirects to /login instead
|
||||||
|
Redirect::to(format!("/auth/login?path={}", req.uri()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[catch(404)]
|
#[catch(404)]
|
||||||
fn not_found(req: &Request) -> ResponseError {
|
fn not_found(req: &Request) -> Template {
|
||||||
|
Template::render("errors/404", context! {
|
||||||
|
path: req.uri()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[catch(404)]
|
||||||
|
fn not_found_api(req: &Request) -> ResponseError {
|
||||||
ResponseError::NotFound(
|
ResponseError::NotFound(
|
||||||
JsonErrorResponse {
|
JsonErrorResponse {
|
||||||
code: "ROUTE_NOT_FOUND".to_string(),
|
code: "ROUTE_NOT_FOUND".to_string(),
|
||||||
|
|
|
@ -2,7 +2,7 @@ use std::io::Cursor;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use rocket::{get, uri, Response, Route, State};
|
use rocket::{catch, get, uri, Response, Route, State};
|
||||||
use rocket::fs::NamedFile;
|
use rocket::fs::NamedFile;
|
||||||
use rocket::http::{ContentType, Header};
|
use rocket::http::{ContentType, Header};
|
||||||
use rocket::http::hyper::body::Buf;
|
use rocket::http::hyper::body::Buf;
|
||||||
|
@ -13,9 +13,12 @@ use rocket_dyn_templates::{context, Template};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
use crate::guards::{AuthUser};
|
||||||
use crate::managers::libraries::LibraryManager;
|
use crate::managers::libraries::LibraryManager;
|
||||||
|
use crate::routes::ui::auth;
|
||||||
use crate::util::{JsonErrorResponse, ResponseError};
|
use crate::util::{JsonErrorResponse, ResponseError};
|
||||||
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
pub async fn index(route: &Route) -> Template {
|
pub async fn index(route: &Route) -> Template {
|
||||||
Template::render("index", context! { user: true, route: route.uri.path(), test: "value" })
|
Template::render("index", context! { user: true, route: route.uri.path(), test: "value" })
|
||||||
|
@ -32,7 +35,7 @@ pub async fn redirect_list_library_files(libraries: &State<Arc<Mutex<LibraryMana
|
||||||
|
|
||||||
|
|
||||||
#[get("/library/<library_id>/<_>/<path..>")]
|
#[get("/library/<library_id>/<_>/<path..>")]
|
||||||
pub async fn list_library_files(route: &Route, libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: PathBuf)
|
pub async fn list_library_files(user: AuthUser, route: &Route, libraries: &State<Arc<Mutex<LibraryManager>>>, library_id: &str, path: PathBuf)
|
||||||
-> Result<Template, ResponseError>
|
-> Result<Template, ResponseError>
|
||||||
{
|
{
|
||||||
let libs = libraries.lock().await;
|
let libs = libraries.lock().await;
|
||||||
|
@ -63,9 +66,8 @@ pub async fn list_library_files(route: &Route, libraries: &State<Arc<Mutex<Libra
|
||||||
.collect();
|
.collect();
|
||||||
debug!("parent={:?}", parent);
|
debug!("parent={:?}", parent);
|
||||||
debug!("segments={:?}", segments);
|
debug!("segments={:?}", segments);
|
||||||
|
|
||||||
Ok(Template::render("libraries", context! {
|
Ok(Template::render("libraries", context! {
|
||||||
user: true,
|
user: user.user,
|
||||||
route: route.uri.path(),
|
route: route.uri.path(),
|
||||||
library: library.model(),
|
library: library.model(),
|
||||||
files: files,
|
files: files,
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
<h1 class="title is-1 has-text-centered">storage-app</h1>
|
<h1 class="title is-1 has-text-centered">storage-app</h1>
|
||||||
<div class="box is-radiusless">
|
<div class="box is-radiusless">
|
||||||
<h4 class="title is-4 has-text-centered">Login</h4>
|
<h4 class="title is-4 has-text-centered">Login</h4>
|
||||||
{{debug this}}
|
{{#unless (eq (len form.form_errors) 0) }}
|
||||||
{{#if (len form.form_errors) includeZero=true }}
|
|
||||||
<div class="notification is-danger is-light">
|
<div class="notification is-danger is-light">
|
||||||
<b>Login failed with errors:</b>
|
<b>Login failed with errors:</b>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -14,7 +13,7 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/unless}}
|
||||||
<form method="post" action="/auth/login">
|
<form method="post" action="/auth/login">
|
||||||
<input type="hidden" name="_csrf" value="{{ csrf_token }}">
|
<input type="hidden" name="_csrf" value="{{ csrf_token }}">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
<div class="navbar-item has-dropdown is-hoverable">
|
<div class="navbar-item has-dropdown is-hoverable">
|
||||||
<a class="navbar-link">
|
<a class="navbar-link">
|
||||||
<img src="/static/img/default_user.png" alt="User Image" />
|
<img src="/static/img/default_user.png" alt="User Image" />
|
||||||
|
{{ debug user }}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="navbar-dropdown">
|
<div class="navbar-dropdown">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue