mirror of https://github.com/raftario/filite.git
Use headers crate for basic auth
This commit is contained in:
parent
6da60a96b6
commit
daef6e9b94
|
@ -55,7 +55,7 @@ jobs:
|
|||
cache-to: type=local,dest=/tmp/.buildx-cache
|
||||
labels: |
|
||||
org.opencontainers.image.title=${{ github.event.repository.name }}
|
||||
org.opencontainers.image.description='${{ github.event.repository.description }}'
|
||||
org.opencontainers.image.description=${{ github.event.repository.description }}
|
||||
org.opencontainers.image.url=${{ github.event.repository.html_url }}
|
||||
org.opencontainers.image.source=${{ github.event.repository.clone_url }}
|
||||
org.opencontainers.image.version=${{ steps.prep.outputs.version }}
|
||||
|
|
|
@ -276,11 +276,10 @@ version = "0.3.0"
|
|||
dependencies = [
|
||||
"anyhow 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"askama 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"base64 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bincode 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bytes 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"headers 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rust-argon2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.116 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -329,7 +328,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
dependencies = [
|
||||
"futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -350,32 +348,11 @@ name = "futures-core"
|
|||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.5"
|
||||
|
@ -385,27 +362,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "futures-task"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-project 0.4.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pin-utils 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proc-macro-nested 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -744,11 +711,6 @@ dependencies = [
|
|||
"libc 0.2.77 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
|
@ -840,16 +802,6 @@ dependencies = [
|
|||
"version_check 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-nested"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.18"
|
||||
|
@ -1581,9 +1533,7 @@ dependencies = [
|
|||
"checksum futures 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
|
||||
"checksum futures-channel 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
||||
"checksum futures-core 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
|
||||
"checksum futures-executor 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
|
||||
"checksum futures-io 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||
"checksum futures-macro 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
|
||||
"checksum futures-sink 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
|
||||
"checksum futures-task 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
|
||||
"checksum futures-util 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
||||
|
@ -1625,7 +1575,6 @@ dependencies = [
|
|||
"checksum num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
|
||||
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
"checksum once_cell 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
|
||||
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
"checksum parking_lot 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
|
||||
"checksum parking_lot_core 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
|
||||
|
@ -1637,8 +1586,6 @@ dependencies = [
|
|||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
"checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678"
|
||||
"checksum proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53"
|
||||
"checksum proc-macro-hack 0.5.16 (registry+https://github.com/rust-lang/crates.io-index)" = "7e0456befd48169b9f13ef0f0ad46d492cf9d2dbb918bcf38e01eed4ce3ec5e4"
|
||||
"checksum proc-macro-nested 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
|
||||
"checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
|
||||
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
"checksum rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
|
|
|
@ -17,11 +17,10 @@ license = "MIT"
|
|||
[dependencies]
|
||||
anyhow = "1.0.32"
|
||||
askama = "0.10.3"
|
||||
base64 = "0.12.3"
|
||||
bincode = "1.3.1"
|
||||
bytes = "0.5.6"
|
||||
chrono = { version = "0.4.18", features = ["serde"] }
|
||||
futures = "0.3.5"
|
||||
headers = "0.3.2"
|
||||
rand = "0.7.3"
|
||||
rust-argon2 = "0.8.2"
|
||||
serde = { version = "1.0.116", features = ["derive"] }
|
||||
|
|
53
src/auth.rs
53
src/auth.rs
|
@ -4,56 +4,49 @@ use crate::{
|
|||
reject::TryExt,
|
||||
};
|
||||
use anyhow::Result;
|
||||
use headers::authorization::{Basic, Credentials};
|
||||
use rand::Rng;
|
||||
use sled::Db;
|
||||
use tokio::task;
|
||||
use warp::{Filter, Rejection};
|
||||
use warp::{http::HeaderValue, Filter, Rejection};
|
||||
|
||||
pub fn optional(
|
||||
db: &'static Db,
|
||||
config: &'static Config,
|
||||
) -> impl Filter<Extract = (Option<User>,), Error = Rejection> + Copy + Send + Sync + 'static {
|
||||
warp::header::optional("Authorization").and_then(move |header| async move {
|
||||
match header {
|
||||
Some(h) => match user(h, db, config).await {
|
||||
warp::header::value("Authorization")
|
||||
.and_then(move |header| async move {
|
||||
match user(header, db, config) {
|
||||
Ok(u) => Ok(Some(u)),
|
||||
Err(e) => Err(e),
|
||||
},
|
||||
None => Ok(None),
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
.or(warp::any().and_then(|| async move { Result::<_, Rejection>::Ok(None) }))
|
||||
.unify()
|
||||
}
|
||||
|
||||
pub fn required(
|
||||
db: &'static Db,
|
||||
config: &'static Config,
|
||||
) -> impl Filter<Extract = (User,), Error = Rejection> + Copy + Send + Sync + 'static {
|
||||
warp::header::header("Authorization").and_then(move |header| user(header, db, config))
|
||||
warp::header::value("Authorization")
|
||||
.and_then(move |header| async move { user(header, db, config) })
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug", skip(db))]
|
||||
async fn user(header: String, db: &Db, config: &Config) -> Result<User, Rejection> {
|
||||
if &header[..5] != "Basic" {
|
||||
return Err(crate::reject::unauthorized());
|
||||
}
|
||||
fn user(header: HeaderValue, db: &Db, config: &Config) -> Result<User, Rejection> {
|
||||
let credentials = Basic::decode(&header).or_400()?;
|
||||
|
||||
let decoded = base64::decode(&header[6..]).or_401()?;
|
||||
|
||||
let (user, password) = {
|
||||
let mut split = None;
|
||||
for (i, b) in decoded.iter().copied().enumerate() {
|
||||
if b == b':' {
|
||||
split = Some(i);
|
||||
}
|
||||
}
|
||||
let split = split.or_401()?;
|
||||
|
||||
let (u, p) = (&decoded[..split], &decoded[(split + 1)..]);
|
||||
(std::str::from_utf8(u).or_401()?, p)
|
||||
};
|
||||
|
||||
let user = crate::db::user(user, db).or_500()?.or_401()?;
|
||||
if !verify(&user.password_hash, password, &config.password).or_500()? {
|
||||
let user = crate::db::user(credentials.username(), db)
|
||||
.or_500()?
|
||||
.or_401()?;
|
||||
if !verify(
|
||||
&user.password_hash,
|
||||
credentials.password().as_bytes(),
|
||||
&config.password,
|
||||
)
|
||||
.or_500()?
|
||||
{
|
||||
return Err(crate::reject::unauthorized());
|
||||
}
|
||||
|
||||
|
|
|
@ -7,10 +7,11 @@ use warp::{
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
enum FiliteRejection {
|
||||
NotFound,
|
||||
BadRequest,
|
||||
Unauthorized,
|
||||
InternalServerError,
|
||||
NotFound,
|
||||
Conflict,
|
||||
InternalServerError,
|
||||
|
||||
Custom(String, StatusCode),
|
||||
}
|
||||
|
@ -18,8 +19,8 @@ impl Reject for FiliteRejection {}
|
|||
impl Reply for FiliteRejection {
|
||||
fn into_response(self) -> Response {
|
||||
match self {
|
||||
Self::NotFound => {
|
||||
warp::reply::with_status("Not Found", StatusCode::NOT_FOUND).into_response()
|
||||
Self::BadRequest => {
|
||||
warp::reply::with_status("Bad Request", StatusCode::BAD_REQUEST).into_response()
|
||||
}
|
||||
Self::Unauthorized => warp::reply::with_status(
|
||||
warp::reply::with_header(
|
||||
|
@ -30,13 +31,17 @@ impl Reply for FiliteRejection {
|
|||
StatusCode::UNAUTHORIZED,
|
||||
)
|
||||
.into_response(),
|
||||
Self::InternalServerError => {
|
||||
warp::reply::with_status("Internal Server Error", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.into_response()
|
||||
Self::NotFound => {
|
||||
warp::reply::with_status("Not Found", StatusCode::NOT_FOUND).into_response()
|
||||
}
|
||||
Self::Conflict => {
|
||||
warp::reply::with_status("Conflict", StatusCode::CONFLICT).into_response()
|
||||
}
|
||||
Self::InternalServerError => {
|
||||
warp::reply::with_status("Internal Server Error", StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
Self::Custom(reply, status) => warp::reply::with_status(reply, status).into_response(),
|
||||
}
|
||||
}
|
||||
|
@ -53,24 +58,37 @@ pub fn custom<T: ToString>(reply: T, status: StatusCode) -> Rejection {
|
|||
}
|
||||
|
||||
pub trait TryExt<T> {
|
||||
fn or_404(self) -> Result<T, Rejection>;
|
||||
fn or_400(self) -> Result<T, Rejection>;
|
||||
fn or_401(self) -> Result<T, Rejection>;
|
||||
fn or_500(self) -> Result<T, Rejection>;
|
||||
fn or_404(self) -> Result<T, Rejection>;
|
||||
fn or_409(self) -> Result<T, Rejection>;
|
||||
|
||||
fn or_500(self) -> Result<T, Rejection>;
|
||||
}
|
||||
|
||||
impl<T, E: Display> TryExt<T> for Result<T, E> {
|
||||
fn or_400(self) -> Result<T, Rejection> {
|
||||
self.map_err(|e| {
|
||||
tracing::info!("{}", e);
|
||||
warp::reject::custom(FiliteRejection::BadRequest)
|
||||
})
|
||||
}
|
||||
fn or_401(self) -> Result<T, Rejection> {
|
||||
self.map_err(|e| {
|
||||
tracing::info!("{}", e);
|
||||
warp::reject::custom(FiliteRejection::Unauthorized)
|
||||
})
|
||||
}
|
||||
fn or_404(self) -> Result<T, Rejection> {
|
||||
self.map_err(|e| {
|
||||
tracing::info!("{}", e);
|
||||
warp::reject::custom(FiliteRejection::NotFound)
|
||||
})
|
||||
}
|
||||
|
||||
fn or_401(self) -> Result<T, Rejection> {
|
||||
fn or_409(self) -> Result<T, Rejection> {
|
||||
self.map_err(|e| {
|
||||
tracing::info!("{}", e);
|
||||
warp::reject::custom(FiliteRejection::Unauthorized)
|
||||
warp::reject::custom(FiliteRejection::Conflict)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -80,31 +98,25 @@ impl<T, E: Display> TryExt<T> for Result<T, E> {
|
|||
warp::reject::custom(FiliteRejection::InternalServerError)
|
||||
})
|
||||
}
|
||||
|
||||
fn or_409(self) -> Result<T, Rejection> {
|
||||
self.map_err(|e| {
|
||||
tracing::info!("{}", e);
|
||||
warp::reject::custom(FiliteRejection::Conflict)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> TryExt<T> for Option<T> {
|
||||
fn or_400(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::BadRequest))
|
||||
}
|
||||
fn or_401(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::Unauthorized))
|
||||
}
|
||||
fn or_404(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::NotFound))
|
||||
}
|
||||
|
||||
fn or_401(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::Unauthorized))
|
||||
fn or_409(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::Conflict))
|
||||
}
|
||||
|
||||
fn or_500(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::InternalServerError))
|
||||
}
|
||||
|
||||
fn or_409(self) -> Result<T, Rejection> {
|
||||
self.ok_or_else(|| warp::reject::custom(FiliteRejection::Conflict))
|
||||
}
|
||||
}
|
||||
|
||||
#[tracing::instrument(level = "debug")]
|
||||
|
|
|
@ -5,10 +5,10 @@ use crate::{
|
|||
};
|
||||
use bytes::Bytes;
|
||||
use sled::Db;
|
||||
use warp::reply::Response;
|
||||
use warp::{
|
||||
http::{StatusCode, Uri},
|
||||
Filter, Rejection, Reply,
|
||||
reply::{Reply, Response},
|
||||
Filter, Rejection,
|
||||
};
|
||||
|
||||
pub fn handler(
|
||||
|
|
Loading…
Reference in New Issue