refactor: remove loco-rs
This commit is contained in:
@@ -1,15 +1,17 @@
|
||||
use async_trait::async_trait;
|
||||
use axum::http::{HeaderValue, request::Parts};
|
||||
use base64::{self, Engine};
|
||||
use loco_rs::app::AppContext;
|
||||
use reqwest::header::AUTHORIZATION;
|
||||
|
||||
use super::{
|
||||
config::BasicAuthConfig,
|
||||
errors::AuthError,
|
||||
service::{AuthService, AuthUserInfo},
|
||||
service::{AuthServiceTrait, AuthUserInfo},
|
||||
};
|
||||
use crate::{
|
||||
app::AppContext,
|
||||
models::{auth::AuthType, subscribers::SEED_SUBSCRIBER},
|
||||
};
|
||||
use crate::models::{auth::AuthType, subscribers::SEED_SUBSCRIBER};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct AuthBasic {
|
||||
@@ -59,7 +61,7 @@ pub struct BasicAuthService {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AuthService for BasicAuthService {
|
||||
impl AuthServiceTrait for BasicAuthService {
|
||||
async fn extract_user_info(
|
||||
&self,
|
||||
ctx: &AppContext,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use jwt_authorizer::OneOrArray;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_with::{serde_as, NoneAsEmptyString};
|
||||
use serde_with::{NoneAsEmptyString, serde_as};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct BasicAuthConfig {
|
||||
@@ -33,7 +33,7 @@ pub struct OidcAuthConfig {
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "auth_type", rename_all = "snake_case")]
|
||||
pub enum AppAuthConfig {
|
||||
pub enum AuthConfig {
|
||||
Basic(BasicAuthConfig),
|
||||
Oidc(OidcAuthConfig),
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import { InjectionToken } from '@outposts/injection-js';
|
||||
import {
|
||||
type EventTypes,
|
||||
LogLevel,
|
||||
type OpenIdConfiguration,
|
||||
} from 'oidc-client-rx';
|
||||
import { LogLevel, type OpenIdConfiguration } from 'oidc-client-rx';
|
||||
|
||||
export const isBasicAuth = process.env.AUTH_TYPE === 'basic';
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use loco_rs::model::ModelError;
|
||||
use openidconnect::{
|
||||
ConfigurationError, RequestTokenError, SignatureVerificationError, SigningError,
|
||||
StandardErrorResponse, core::CoreErrorResponseType,
|
||||
@@ -14,7 +13,7 @@ use openidconnect::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{fetch::HttpClientError, models::auth::AuthType};
|
||||
use crate::{errors::RError, fetch::HttpClientError, models::auth::AuthType};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AuthError {
|
||||
@@ -24,7 +23,7 @@ pub enum AuthError {
|
||||
current: AuthType,
|
||||
},
|
||||
#[error("Failed to find auth record")]
|
||||
FindAuthRecordError(ModelError),
|
||||
FindAuthRecordError(RError),
|
||||
#[error("Invalid credentials")]
|
||||
BasicInvalidCredentials,
|
||||
#[error(transparent)]
|
||||
|
||||
@@ -6,16 +6,15 @@ use axum::{
|
||||
middleware::Next,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use loco_rs::prelude::AppContext;
|
||||
|
||||
use crate::{app::AppContextExt, auth::AuthService};
|
||||
use crate::{app::AppContext, auth::AuthServiceTrait};
|
||||
|
||||
pub async fn api_auth_middleware(
|
||||
pub async fn header_www_authenticate_middleware(
|
||||
State(ctx): State<Arc<AppContext>>,
|
||||
request: Request,
|
||||
next: Next,
|
||||
) -> Response {
|
||||
let auth_service = ctx.get_auth_service();
|
||||
let auth_service = &ctx.auth;
|
||||
|
||||
let (mut parts, body) = request.into_parts();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ pub mod middleware;
|
||||
pub mod oidc;
|
||||
pub mod service;
|
||||
|
||||
pub use config::{AppAuthConfig, BasicAuthConfig, OidcAuthConfig};
|
||||
pub use config::{AuthConfig, BasicAuthConfig, OidcAuthConfig};
|
||||
pub use errors::AuthError;
|
||||
pub use middleware::api_auth_middleware;
|
||||
pub use service::{AppAuthService, AuthService, AuthUserInfo};
|
||||
pub use middleware::header_www_authenticate_middleware;
|
||||
pub use service::{AuthService, AuthServiceTrait, AuthUserInfo};
|
||||
|
||||
@@ -7,13 +7,13 @@ use async_trait::async_trait;
|
||||
use axum::http::{HeaderValue, request::Parts};
|
||||
use itertools::Itertools;
|
||||
use jwt_authorizer::{NumericDate, OneOrArray, authorizer::Authorizer};
|
||||
use loco_rs::{app::AppContext, model::ModelError};
|
||||
use moka::future::Cache;
|
||||
use openidconnect::{
|
||||
AccessTokenHash, AuthorizationCode, ClientId, ClientSecret, CsrfToken, IssuerUrl, Nonce,
|
||||
OAuth2TokenResponse, PkceCodeChallenge, PkceCodeVerifier, RedirectUrl, TokenResponse,
|
||||
core::{CoreAuthenticationFlow, CoreClient, CoreProviderMetadata},
|
||||
};
|
||||
use sea_orm::DbErr;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use url::Url;
|
||||
@@ -21,9 +21,9 @@ use url::Url;
|
||||
use super::{
|
||||
config::OidcAuthConfig,
|
||||
errors::AuthError,
|
||||
service::{AuthService, AuthUserInfo},
|
||||
service::{AuthServiceTrait, AuthUserInfo},
|
||||
};
|
||||
use crate::{fetch::HttpClient, models::auth::AuthType};
|
||||
use crate::{app::AppContext, errors::RError, fetch::HttpClient, models::auth::AuthType};
|
||||
|
||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||
pub struct OidcAuthClaims {
|
||||
@@ -258,7 +258,7 @@ impl OidcAuthService {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AuthService for OidcAuthService {
|
||||
impl AuthServiceTrait for OidcAuthService {
|
||||
async fn extract_user_info(
|
||||
&self,
|
||||
ctx: &AppContext,
|
||||
@@ -306,7 +306,7 @@ impl AuthService for OidcAuthService {
|
||||
}
|
||||
}
|
||||
let subscriber_auth = match crate::models::auth::Model::find_by_pid(ctx, sub).await {
|
||||
Err(ModelError::EntityNotFound) => {
|
||||
Err(RError::DbError(DbErr::RecordNotFound(..))) => {
|
||||
crate::models::auth::Model::create_from_oidc(ctx, sub.to_string()).await
|
||||
}
|
||||
r => r,
|
||||
|
||||
@@ -7,20 +7,17 @@ use axum::{
|
||||
response::{IntoResponse as _, Response},
|
||||
};
|
||||
use jwt_authorizer::{JwtAuthorizer, Validation};
|
||||
use loco_rs::app::{AppContext, Initializer};
|
||||
use moka::future::Cache;
|
||||
use once_cell::sync::OnceCell;
|
||||
use reqwest::header::HeaderValue;
|
||||
|
||||
use super::{
|
||||
AppAuthConfig,
|
||||
AuthConfig,
|
||||
basic::BasicAuthService,
|
||||
errors::AuthError,
|
||||
oidc::{OidcAuthClaims, OidcAuthService},
|
||||
};
|
||||
use crate::{
|
||||
app::AppContextExt as _,
|
||||
config::AppConfigExt,
|
||||
app::AppContext,
|
||||
fetch::{
|
||||
HttpClient, HttpClientConfig,
|
||||
client::{HttpClientCacheBackendConfig, HttpClientCachePresetConfig},
|
||||
@@ -41,7 +38,7 @@ impl FromRequestParts<AppContext> for AuthUserInfo {
|
||||
parts: &mut Parts,
|
||||
state: &AppContext,
|
||||
) -> Result<Self, Self::Rejection> {
|
||||
let auth_service = state.get_auth_service();
|
||||
let auth_service = &state.auth;
|
||||
|
||||
auth_service
|
||||
.extract_user_info(state, parts)
|
||||
@@ -51,7 +48,7 @@ impl FromRequestParts<AppContext> for AuthUserInfo {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait AuthService {
|
||||
pub trait AuthServiceTrait {
|
||||
async fn extract_user_info(
|
||||
&self,
|
||||
ctx: &AppContext,
|
||||
@@ -61,24 +58,16 @@ pub trait AuthService {
|
||||
fn auth_type(&self) -> AuthType;
|
||||
}
|
||||
|
||||
pub enum AppAuthService {
|
||||
pub enum AuthService {
|
||||
Basic(BasicAuthService),
|
||||
Oidc(OidcAuthService),
|
||||
}
|
||||
|
||||
static APP_AUTH_SERVICE: OnceCell<AppAuthService> = OnceCell::new();
|
||||
|
||||
impl AppAuthService {
|
||||
pub fn app_instance() -> &'static Self {
|
||||
APP_AUTH_SERVICE
|
||||
.get()
|
||||
.expect("AppAuthService is not initialized")
|
||||
}
|
||||
|
||||
pub async fn from_conf(config: AppAuthConfig) -> Result<Self, AuthError> {
|
||||
impl AuthService {
|
||||
pub async fn from_conf(config: AuthConfig) -> Result<Self, AuthError> {
|
||||
let result = match config {
|
||||
AppAuthConfig::Basic(config) => AppAuthService::Basic(BasicAuthService { config }),
|
||||
AppAuthConfig::Oidc(config) => {
|
||||
AuthConfig::Basic(config) => AuthService::Basic(BasicAuthService { config }),
|
||||
AuthConfig::Oidc(config) => {
|
||||
let validation = Validation::new()
|
||||
.iss(&[&config.issuer])
|
||||
.aud(&[&config.audience]);
|
||||
@@ -96,7 +85,7 @@ impl AppAuthService {
|
||||
.build()
|
||||
.await?;
|
||||
|
||||
AppAuthService::Oidc(OidcAuthService {
|
||||
AuthService::Oidc(OidcAuthService {
|
||||
config,
|
||||
api_authorizer,
|
||||
oidc_provider_client,
|
||||
@@ -112,50 +101,29 @@ impl AppAuthService {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl AuthService for AppAuthService {
|
||||
impl AuthServiceTrait for AuthService {
|
||||
async fn extract_user_info(
|
||||
&self,
|
||||
ctx: &AppContext,
|
||||
request: &mut Parts,
|
||||
) -> Result<AuthUserInfo, AuthError> {
|
||||
match self {
|
||||
AppAuthService::Basic(service) => service.extract_user_info(ctx, request).await,
|
||||
AppAuthService::Oidc(service) => service.extract_user_info(ctx, request).await,
|
||||
AuthService::Basic(service) => service.extract_user_info(ctx, request).await,
|
||||
AuthService::Oidc(service) => service.extract_user_info(ctx, request).await,
|
||||
}
|
||||
}
|
||||
|
||||
fn www_authenticate_header_value(&self) -> Option<HeaderValue> {
|
||||
match self {
|
||||
AppAuthService::Basic(service) => service.www_authenticate_header_value(),
|
||||
AppAuthService::Oidc(service) => service.www_authenticate_header_value(),
|
||||
AuthService::Basic(service) => service.www_authenticate_header_value(),
|
||||
AuthService::Oidc(service) => service.www_authenticate_header_value(),
|
||||
}
|
||||
}
|
||||
|
||||
fn auth_type(&self) -> AuthType {
|
||||
match self {
|
||||
AppAuthService::Basic(service) => service.auth_type(),
|
||||
AppAuthService::Oidc(service) => service.auth_type(),
|
||||
AuthService::Basic(service) => service.auth_type(),
|
||||
AuthService::Oidc(service) => service.auth_type(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppAuthServiceInitializer;
|
||||
|
||||
#[async_trait]
|
||||
impl Initializer for AppAuthServiceInitializer {
|
||||
fn name(&self) -> String {
|
||||
String::from("AppAuthServiceInitializer")
|
||||
}
|
||||
|
||||
async fn before_run(&self, ctx: &AppContext) -> Result<(), loco_rs::Error> {
|
||||
let auth_conf = ctx.config.get_app_conf()?.auth;
|
||||
|
||||
let service = AppAuthService::from_conf(auth_conf)
|
||||
.await
|
||||
.map_err(loco_rs::Error::wrap)?;
|
||||
|
||||
APP_AUTH_SERVICE.get_or_init(|| service);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user