mirror of
https://github.com/Jackzmc/storage.git
synced 2025-05-07 05:23:21 +00:00
Fix login loop and add documentation
This commit is contained in:
parent
6ffa89a936
commit
bf2a87d746
8 changed files with 112 additions and 10 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
**/.idea
|
**/.idea
|
||||||
target
|
target
|
||||||
config
|
config
|
||||||
|
.env
|
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -2356,7 +2356,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "storage-app"
|
name = "storage_app"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "storage-app"
|
name = "storage_app"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
repository = "https://github.com/jackzmc/storage"
|
repository = "https://github.com/jackzmc/storage"
|
||||||
|
|
59
README.md
Normal file
59
README.md
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# storage-app
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project takes heavily inspiration from [Seafile](https://www.seafile.com/) in its functionality and UI design. File hosting service with performance, ease of use, and being lightweight.
|
||||||
|
|
||||||
|
Key features include:
|
||||||
|
|
||||||
|
- Web UI for managing files, with minimal/no client-side javascript
|
||||||
|
- Multiple storage backends supported (local filesystem, S3, etc)
|
||||||
|
- Multiple libraries per user, each with configurable storage backends
|
||||||
|
- WebDAV (soon)
|
||||||
|
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Rust 1.86+ (stable) and Cargo
|
||||||
|
- PostgreSQL 13+ database
|
||||||
|
- 512MB RAM minimum
|
||||||
|
|
||||||
|
### Installing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone https://github.com/jackzmc/storage.git
|
||||||
|
cd storage
|
||||||
|
|
||||||
|
# Configure your database (create .env file with your PostgreSQL connection)
|
||||||
|
echo "DATABASE_URL=postgres://username:password@localhost" > .env
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
# Run database migrations
|
||||||
|
#cargo run --bin migrate --features migrations
|
||||||
|
|
||||||
|
# Run the server
|
||||||
|
cargo run --release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
* [ ] WebDAV Support
|
||||||
|
* [ ] S3 backend support
|
||||||
|
* [ ] Administration panel
|
||||||
|
* [ ] Add storage backends
|
||||||
|
* [ ] Manage users
|
||||||
|
* [ ] Change app settings
|
||||||
|
* [ ] Email support (for password resets, user invites)
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
Todo, will be available at https://git.jackz.me/jackz/storage/wiki
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
Available under the AGPL-3.0 license. [LICENSE](LICENSE)
|
36
migrations/default.sql
Normal file
36
migrations/default.sql
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
create table libraries
|
||||||
|
(
|
||||||
|
owner_id uuid not null
|
||||||
|
constraint libraries_owner_id
|
||||||
|
references users
|
||||||
|
on update cascade on delete cascade,
|
||||||
|
created_at timestamp default now() not null,
|
||||||
|
name varchar(255) not null,
|
||||||
|
repo_id varchar(64) not null
|
||||||
|
constraint libraries_repo_id
|
||||||
|
references repos
|
||||||
|
on update cascade on delete cascade,
|
||||||
|
id uuid not null
|
||||||
|
constraint libraries_pk
|
||||||
|
primary key
|
||||||
|
);
|
||||||
|
create table repos
|
||||||
|
(
|
||||||
|
id varchar(64) not null
|
||||||
|
primary key,
|
||||||
|
created_at timestamp default now() not null,
|
||||||
|
storage_type varchar(32) not null,
|
||||||
|
storage_settings json not null,
|
||||||
|
flags smallint default 0 not null
|
||||||
|
);
|
||||||
|
create table users
|
||||||
|
(
|
||||||
|
id uuid not null
|
||||||
|
primary key,
|
||||||
|
created_at timestamp default now() not null,
|
||||||
|
name varchar(255) not null,
|
||||||
|
password varchar(128),
|
||||||
|
email varchar(128) not null,
|
||||||
|
username varchar(64) not null
|
||||||
|
);
|
||||||
|
|
|
@ -142,8 +142,10 @@ async fn rocket() -> _ {
|
||||||
ui::auth::forgot_password::page, ui::auth::forgot_password::handler,
|
ui::auth::forgot_password::page, ui::auth::forgot_password::handler,
|
||||||
])
|
])
|
||||||
.mount("/", routes![
|
.mount("/", routes![
|
||||||
ui::help::about,
|
|
||||||
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,
|
||||||
|
])
|
||||||
|
.mount("/", routes![
|
||||||
|
ui::help::about,
|
||||||
ui::help::test_get
|
ui::help::test_get
|
||||||
])
|
])
|
||||||
.register("/api", catchers![
|
.register("/api", catchers![
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use log::debug;
|
use log::{debug, trace};
|
||||||
use rocket::{get, post, FromForm, Responder, Route, State};
|
use rocket::{get, post, FromForm, Responder, Route, State};
|
||||||
use rocket::form::{Context, Contextual, Form};
|
use rocket::form::{Context, Contextual, Form};
|
||||||
use rocket::http::{Header, Status};
|
use rocket::http::{Header, Status};
|
||||||
|
@ -59,8 +59,10 @@ pub async fn handler(
|
||||||
mut form: Form<Contextual<'_, LoginForm<'_>>>,
|
mut form: Form<Contextual<'_, LoginForm<'_>>>,
|
||||||
return_to: Option<String>,
|
return_to: Option<String>,
|
||||||
) -> Result<HackyRedirectBecauseRocketBug, Template> {
|
) -> Result<HackyRedirectBecauseRocketBug, Template> {
|
||||||
|
trace!("handler");
|
||||||
validate_csrf_form(&mut form.context, &session).await;
|
validate_csrf_form(&mut form.context, &session).await;
|
||||||
let user = validate_user_form(&mut form.context, &pool).await;
|
let user = validate_user_form(&mut form.context, &pool).await;
|
||||||
|
trace!("check form");
|
||||||
if form.context.status() == Status::Ok {
|
if form.context.status() == Status::Ok {
|
||||||
if let Some(submission) = &form.value {
|
if let Some(submission) = &form.value {
|
||||||
session.set(SessionData {
|
session.set(SessionData {
|
||||||
|
@ -70,17 +72,19 @@ pub async fn handler(
|
||||||
ip_address: ip_addr,
|
ip_address: ip_addr,
|
||||||
}),
|
}),
|
||||||
}).await.unwrap();
|
}).await.unwrap();
|
||||||
debug!("returning user to {:?}", return_to);
|
let mut return_to_path = return_to.unwrap_or("/".to_string());
|
||||||
let return_to_path = return_to.unwrap_or("/".to_string());
|
if return_to_path == "" { return_to_path.push_str("/"); }
|
||||||
|
debug!("returning user to {:?}", return_to_path);
|
||||||
|
|
||||||
// Rocket redirect fails when `Redirect::to("/path/ has spaces")` has spaces, so manually do location... works better
|
// Rocket redirect fails when `Redirect::to("/path/ has spaces")` has spaces, so manually do location... works better
|
||||||
return Ok(HackyRedirectBecauseRocketBug {
|
return Ok(HackyRedirectBecauseRocketBug {
|
||||||
inner: "Login successful, redirecting...".to_string(),
|
inner: "Login successful, redirecting...".to_string(),
|
||||||
location: Header::new("Location", return_to_path),
|
location: Header::new("Location", return_to_path),
|
||||||
})
|
})
|
||||||
// let return_to_uri = Uri::parse::<Origin>(&return_to_path).unwrap_or(Uri::parse::<Origin>("/").unwrap());
|
|
||||||
// return Ok(Redirect::found(return_to_uri))
|
|
||||||
}
|
}
|
||||||
|
trace!("submission failed");
|
||||||
}
|
}
|
||||||
|
trace!("form failed");
|
||||||
|
|
||||||
let csrf_token = set_csrf(&session).await;
|
let csrf_token = set_csrf(&session).await;
|
||||||
let ctx = context! {
|
let ctx = context! {
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub(crate) fn setup_logger() {
|
||||||
tracing_subscriber::registry()
|
tracing_subscriber::registry()
|
||||||
.with(
|
.with(
|
||||||
tracing_subscriber::filter::EnvFilter::try_from_default_env()
|
tracing_subscriber::filter::EnvFilter::try_from_default_env()
|
||||||
.unwrap_or_else(|_| format!("warn,rocket=warn,storage_server=trace").into()),
|
.unwrap_or_else(|_| format!("warn,rocket=warn,{}=trace", env!("CARGO_PKG_NAME")).into()),
|
||||||
)
|
)
|
||||||
.with(tracing_subscriber::fmt::layer())
|
.with(tracing_subscriber::fmt::layer())
|
||||||
.init();
|
.init();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue