mirror of
https://github.com/lennart-k/rustical.git
synced 2025-12-13 22:52:22 +00:00
making auth sync since that suffices for now and makes the code simpler
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use actix_web::{http::StatusCode, HttpResponse};
|
||||
use derive_more::{Display, Error};
|
||||
|
||||
#[derive(Debug, Display, Error)]
|
||||
#[derive(Debug, Display, Error, Clone)]
|
||||
pub enum Error {
|
||||
#[display(fmt = "Internal server error")]
|
||||
InternalError,
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use actix_web::{dev::Payload, web::Data, FromRequest, HttpRequest};
|
||||
use futures_util::{Future, FutureExt};
|
||||
use std::marker::PhantomData;
|
||||
use std::pin::Pin;
|
||||
use futures_util::Future;
|
||||
use std::{marker::PhantomData, task::Poll};
|
||||
|
||||
use super::{CheckAuthentication, AuthInfo};
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{AuthInfo, CheckAuthentication};
|
||||
|
||||
pub struct AuthInfoExtractor<A: CheckAuthentication> {
|
||||
pub inner: AuthInfo,
|
||||
@@ -19,28 +20,21 @@ impl<T: CheckAuthentication> From<AuthInfo> for AuthInfoExtractor<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AuthInfoExtractorFuture<A>
|
||||
where
|
||||
A: CheckAuthentication,
|
||||
{
|
||||
future: Pin<Box<A::Future>>,
|
||||
}
|
||||
pub struct AuthInfoExtractorFuture<A: CheckAuthentication>(Result<AuthInfo, Error>, PhantomData<A>);
|
||||
|
||||
impl<A> Future for AuthInfoExtractorFuture<A>
|
||||
where
|
||||
A: CheckAuthentication,
|
||||
{
|
||||
type Output = Result<AuthInfoExtractor<A>, A::Error>;
|
||||
impl<A: CheckAuthentication> Future for AuthInfoExtractorFuture<A> {
|
||||
type Output = Result<AuthInfoExtractor<A>, Error>;
|
||||
|
||||
fn poll(
|
||||
self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
_cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Self::Output> {
|
||||
match self.get_mut().future.poll_unpin(cx) {
|
||||
std::task::Poll::Pending => std::task::Poll::Pending,
|
||||
std::task::Poll::Ready(result) => {
|
||||
std::task::Poll::Ready(result.map(|auth_info| auth_info.into()))
|
||||
}
|
||||
match &self.0 {
|
||||
Ok(auth_info) => Poll::Ready(Ok(AuthInfoExtractor {
|
||||
inner: auth_info.clone(),
|
||||
_provider_type: PhantomData,
|
||||
})),
|
||||
Err(err) => Poll::Ready(Err(err.clone())),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,14 +43,12 @@ impl<A> FromRequest for AuthInfoExtractor<A>
|
||||
where
|
||||
A: CheckAuthentication,
|
||||
{
|
||||
type Error = A::Error;
|
||||
type Error = Error;
|
||||
type Future = AuthInfoExtractorFuture<A>;
|
||||
|
||||
fn extract(req: &HttpRequest) -> Self::Future {
|
||||
let a = req.app_data::<Data<A>>().unwrap().validate(req);
|
||||
Self::Future {
|
||||
future: Box::pin(a),
|
||||
}
|
||||
let result = req.app_data::<Data<A>>().unwrap().validate(req);
|
||||
AuthInfoExtractorFuture(result, PhantomData)
|
||||
}
|
||||
fn from_request(req: &HttpRequest, _payload: &mut Payload) -> Self::Future {
|
||||
Self::extract(req)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::error::Error;
|
||||
use actix_web::{http::header::Header, HttpRequest};
|
||||
use actix_web_httpauth::headers::authorization::{Authorization, Basic};
|
||||
use futures_util::future::{err, ok, Ready};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
@@ -22,10 +22,7 @@ pub struct HtpasswdAuthConfig {
|
||||
}
|
||||
|
||||
impl CheckAuthentication for HtpasswdAuth {
|
||||
type Error = crate::error::Error;
|
||||
type Future = Ready<Result<AuthInfo, Self::Error>>;
|
||||
|
||||
fn validate(&self, req: &HttpRequest) -> Self::Future {
|
||||
fn validate(&self, req: &HttpRequest) -> Result<AuthInfo, Error> {
|
||||
if let Ok(auth) = Authorization::<Basic>::parse(req) {
|
||||
let user_id = auth.as_ref().user_id();
|
||||
// Map None to empty password
|
||||
@@ -34,19 +31,19 @@ impl CheckAuthentication for HtpasswdAuth {
|
||||
let user_config = if let Some(user_config) = self.config.users.get(user_id) {
|
||||
user_config
|
||||
} else {
|
||||
return err(crate::error::Error::Unauthorized);
|
||||
return Err(crate::error::Error::Unauthorized);
|
||||
};
|
||||
|
||||
if let Err(e) = password_auth::verify_password(password, &user_config.password) {
|
||||
dbg!(e);
|
||||
return err(crate::error::Error::Unauthorized);
|
||||
return Err(crate::error::Error::Unauthorized);
|
||||
}
|
||||
|
||||
ok(AuthInfo {
|
||||
Ok(AuthInfo {
|
||||
user_id: user_id.to_string(),
|
||||
})
|
||||
} else {
|
||||
err(crate::error::Error::Unauthorized)
|
||||
Err(crate::error::Error::Unauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use actix_web::{HttpRequest, ResponseError};
|
||||
use futures_util::{future::Ready, Future};
|
||||
use actix_web::HttpRequest;
|
||||
|
||||
use crate::error::Error;
|
||||
pub use extractor::AuthInfoExtractor;
|
||||
pub use htpasswd::{HtpasswdAuth, HtpasswdAuthConfig};
|
||||
pub use none::NoneAuth;
|
||||
@@ -9,17 +9,13 @@ pub mod extractor;
|
||||
pub mod htpasswd;
|
||||
pub mod none;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AuthInfo {
|
||||
pub user_id: String,
|
||||
}
|
||||
|
||||
pub trait CheckAuthentication: Send + Sync + 'static {
|
||||
type Error: ResponseError;
|
||||
type Future: Future<Output = Result<AuthInfo, Self::Error>>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
fn validate(&self, req: &HttpRequest) -> Self::Future
|
||||
fn validate(&self, req: &HttpRequest) -> Result<AuthInfo, Error>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
@@ -31,10 +27,7 @@ pub enum AuthProvider {
|
||||
}
|
||||
|
||||
impl CheckAuthentication for AuthProvider {
|
||||
type Error = crate::error::Error;
|
||||
type Future = Ready<Result<AuthInfo, Self::Error>>;
|
||||
|
||||
fn validate(&self, req: &HttpRequest) -> Self::Future
|
||||
fn validate(&self, req: &HttpRequest) -> Result<AuthInfo, Error>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use actix_web::{http::header::Header, HttpRequest};
|
||||
use actix_web_httpauth::headers::authorization::{Authorization, Basic};
|
||||
use futures_util::future::{err, ok, Ready};
|
||||
|
||||
use crate::error::Error;
|
||||
|
||||
use super::{AuthInfo, CheckAuthentication};
|
||||
|
||||
@@ -8,16 +9,13 @@ use super::{AuthInfo, CheckAuthentication};
|
||||
pub struct NoneAuth;
|
||||
|
||||
impl CheckAuthentication for NoneAuth {
|
||||
type Error = crate::error::Error;
|
||||
type Future = Ready<Result<AuthInfo, Self::Error>>;
|
||||
|
||||
fn validate(&self, req: &HttpRequest) -> Self::Future {
|
||||
fn validate(&self, req: &HttpRequest) -> Result<AuthInfo, Error> {
|
||||
if let Ok(auth) = Authorization::<Basic>::parse(req) {
|
||||
ok(AuthInfo {
|
||||
Ok(AuthInfo {
|
||||
user_id: auth.as_ref().user_id().to_string(),
|
||||
})
|
||||
} else {
|
||||
err(crate::error::Error::Unauthorized)
|
||||
Err(crate::error::Error::Unauthorized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user