docker
This commit is contained in:
parent
487d97cb01
commit
f3f5e03651
8 changed files with 103 additions and 17 deletions
5
.dockerignore
Normal file
5
.dockerignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
.git
|
||||
.gitignore
|
||||
deployments
|
||||
target
|
||||
xssbook.db
|
13
LICENSE
Normal file
13
LICENSE
Normal file
|
@ -0,0 +1,13 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
42
README.md
Normal file
42
README.md
Normal file
|
@ -0,0 +1,42 @@
|
|||
# xssbook
|
||||
|
||||
**description**
|
||||
|
||||
who doesn't want to run non free javascript
|
||||
|
||||
now with xssbook you can run as much stallman disapprovement as you want
|
||||
- all inputs on the site are unfiltered
|
||||
- api calls dont care what you send them as long as they are valid strings
|
||||
- /console page to see everyones amazing api calls
|
||||
|
||||
**installation**
|
||||
|
||||
The project is written in rust, so you can build it by running
|
||||
|
||||
`cargo build --release`
|
||||
|
||||
Make sure where you run the binary from, you also move the public folder to.
|
||||
|
||||
Finally, the site runs on port `8080`, so its recommended you put it begind a reverse proxy, or you could use a docker container and remap the outsite port (see below).
|
||||
|
||||
**docker**
|
||||
|
||||
If you want to run it in a docker container a premade dockerfile is here for you
|
||||
|
||||
`docker build -f deployments/docker/Dockerfile -t xssbook .`
|
||||
|
||||
There is also a docker-compose.yml file for your reference in the /deployments/docker folder.
|
||||
|
||||
The one thing about the docker container is you have to mount the volume
|
||||
|
||||
`-v [your directory]/xssbook.db:/data/xssbook.db`
|
||||
|
||||
to make the database persistant. Finally, before running the container run
|
||||
|
||||
`touch [your directory]/xssbook.db`
|
||||
|
||||
since docker will create a folder there otherwise and it won't work.
|
||||
|
||||
**license**
|
||||
|
||||
This amazing project is licensed under the WTFPL
|
18
deployments/docker/Dockerfile
Normal file
18
deployments/docker/Dockerfile
Normal file
|
@ -0,0 +1,18 @@
|
|||
FROM rust:1.67-buster as builder
|
||||
WORKDIR /usr/src/xssbook
|
||||
|
||||
COPY ./Cargo.toml ./Cargo.toml
|
||||
COPY ./Cargo.lock ./Cargo.lock
|
||||
COPY ./src ./src
|
||||
RUN cargo install --path .
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
COPY --from=builder /usr/local/cargo/bin/xssbook /usr/local/bin/xssbook
|
||||
|
||||
RUN mkdir /data
|
||||
WORKDIR /data
|
||||
COPY ./public ./public
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["/usr/local/bin/xssbook"]
|
10
deployments/docker/docker-compose.yml
Normal file
10
deployments/docker/docker-compose.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
version: "3.9"
|
||||
|
||||
services:
|
||||
ritlug-discord-bot:
|
||||
container_name: xssbook
|
||||
image: xssbook
|
||||
ports:
|
||||
- 8080:8080
|
||||
volumes:
|
||||
- ${PWD}/xssbook.db:/data/xssbook.db
|
|
@ -14,7 +14,7 @@ async fn login(user: Option<AuthorizedUser>) -> Response {
|
|||
if user.is_some() {
|
||||
return Redirect::to("/home").into_response()
|
||||
} else {
|
||||
return ResponseCode::Success.file("/login.html").await.unwrap()
|
||||
return ResponseCode::Success.file("/login.html").await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ async fn home(user: Option<AuthorizedUser>) -> Response {
|
|||
if user.is_none() {
|
||||
return Redirect::to("/login").into_response()
|
||||
} else {
|
||||
return ResponseCode::Success.file("/home.html").await.unwrap()
|
||||
return ResponseCode::Success.file("/home.html").await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ async fn people(user: Option<AuthorizedUser>) -> Response {
|
|||
if user.is_none() {
|
||||
return Redirect::to("/login").into_response()
|
||||
} else {
|
||||
return ResponseCode::Success.file("/people.html").await.unwrap()
|
||||
return ResponseCode::Success.file("/people.html").await
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ async fn profile(user: Option<AuthorizedUser>) -> Response {
|
|||
if user.is_none() {
|
||||
return Redirect::to("/login").into_response()
|
||||
} else {
|
||||
return ResponseCode::Success.file("/profile.html").await.unwrap()
|
||||
return ResponseCode::Success.file("/profile.html").await
|
||||
}
|
||||
}
|
||||
|
||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,5 +1,5 @@
|
|||
use std::net::SocketAddr;
|
||||
use axum::{Router, response::Response, http::Request, middleware::{Next, self}, extract::ConnectInfo, RequestExt, body::HttpBody, Extension};
|
||||
use axum::{Router, response::Response, http::{Request, StatusCode}, middleware::{Next, self}, extract::ConnectInfo, RequestExt, body::HttpBody, Extension};
|
||||
use tower_cookies::CookieManagerLayer;
|
||||
use tracing::metadata::LevelFilter;
|
||||
use tracing_subscriber::{prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, Layer, filter::filter_fn};
|
||||
|
@ -13,9 +13,10 @@ mod types;
|
|||
mod console;
|
||||
|
||||
async fn serve<B>(req: Request<B>, next: Next<B>) -> Response {
|
||||
let Ok(file) = ResponseCode::Success.file(&req.uri().to_string()).await else {
|
||||
return next.run(req).await
|
||||
};
|
||||
let file = ResponseCode::Success.file(&req.uri().to_string()).await;
|
||||
if file.status() != StatusCode::OK {
|
||||
return next.run(req).await;
|
||||
}
|
||||
file
|
||||
}
|
||||
|
||||
|
@ -33,10 +34,7 @@ async fn log<B>(mut req: Request<B>, next: Next<B>) -> Response where
|
|||
}
|
||||
|
||||
async fn not_found() -> Response {
|
||||
match ResponseCode::NotFound.file("/404.html").await {
|
||||
Ok(file) => file,
|
||||
Err(err) => err
|
||||
}
|
||||
ResponseCode::NotFound.file("/404.html").await
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
|
@ -54,21 +54,21 @@ impl ResponseCode {
|
|||
}
|
||||
|
||||
#[instrument()]
|
||||
pub async fn file(self, path: &str) -> Result<Response> {
|
||||
pub async fn file(self, path: &str) -> Response {
|
||||
if path.chars().position(|c| c == '.' ).is_none() {
|
||||
return Err(ResponseCode::BadRequest.text("Folders cannot be served"));
|
||||
return ResponseCode::BadRequest.text("Folders cannot be served");
|
||||
}
|
||||
let path = format!("public{}", path);
|
||||
let svc = ServeFile::new(path);
|
||||
let Ok(mut res) = svc.oneshot(Request::new(Body::empty())).await else {
|
||||
tracing::error!("Error while fetching file");
|
||||
return Err(ResponseCode::InternalServerError.text("Error while fetching file"));
|
||||
return ResponseCode::InternalServerError.text("Error while fetching file");
|
||||
};
|
||||
if res.status() != StatusCode::OK {
|
||||
return Err(ResponseCode::NotFound.text("File not found"));
|
||||
return ResponseCode::NotFound.text("File not found");
|
||||
}
|
||||
*res.status_mut() = self.code();
|
||||
Ok(res.into_response())
|
||||
res.into_response()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue