mirror of https://github.com/buster-so/buster.git
402 error
This commit is contained in:
parent
7e866c54b1
commit
69c12b2144
|
@ -338,6 +338,7 @@ pub struct Organization {
|
|||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub deleted_at: Option<DateTime<Utc>>,
|
||||
pub payment_required: bool,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
|
|
|
@ -433,6 +433,7 @@ diesel::table! {
|
|||
created_at -> Timestamptz,
|
||||
updated_at -> Timestamptz,
|
||||
deleted_at -> Nullable<Timestamptz>,
|
||||
payment_required -> Bool,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ pub async fn post_organization_handler(
|
|||
created_at: now,
|
||||
updated_at: now,
|
||||
deleted_at: None,
|
||||
payment_required: true,
|
||||
};
|
||||
|
||||
insert_into(organizations::table)
|
||||
|
|
|
@ -85,16 +85,62 @@ pub async fn auth(mut req: Request, next: Next) -> Result<Response, StatusCode>
|
|||
};
|
||||
|
||||
let user = match authorize_current_user(&token).await {
|
||||
Ok(user) => match user {
|
||||
Some(user) => user,
|
||||
None => return Err(StatusCode::UNAUTHORIZED),
|
||||
},
|
||||
Ok(Some(user)) => user,
|
||||
Ok(None) => return Err(StatusCode::UNAUTHORIZED),
|
||||
Err(e) => {
|
||||
tracing::error!("Authorization error: {}", e);
|
||||
return handle_auth_error("invalid jwt");
|
||||
}
|
||||
};
|
||||
|
||||
// --- Payment Required Check START ---
|
||||
if let Some(org_membership) = user.organizations.get(0) {
|
||||
let org_id = org_membership.id;
|
||||
let pg_pool = get_pg_pool();
|
||||
let mut conn = match pg_pool.get().await {
|
||||
Ok(conn) => conn,
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to get DB connection for payment check: {}", e);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
};
|
||||
|
||||
match database::schema::organizations::table
|
||||
.filter(database::schema::organizations::id.eq(org_id))
|
||||
.select(database::schema::organizations::payment_required)
|
||||
.first::<bool>(&mut conn)
|
||||
.await
|
||||
{
|
||||
Ok(payment_required) => {
|
||||
if payment_required {
|
||||
tracing::warn!(
|
||||
user_id = %user.id,
|
||||
org_id = %org_id,
|
||||
"Access denied due to payment requirement for organization."
|
||||
);
|
||||
return Err(StatusCode::PAYMENT_REQUIRED);
|
||||
}
|
||||
}
|
||||
Err(diesel::NotFound) => {
|
||||
tracing::error!(
|
||||
user_id = %user.id,
|
||||
org_id = %org_id,
|
||||
"Organization not found during payment check."
|
||||
);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
user_id = %user.id,
|
||||
org_id = %org_id,
|
||||
"Database error during payment check: {}", e
|
||||
);
|
||||
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
// --- Payment Required Check END ---
|
||||
|
||||
req.extensions_mut().insert(user);
|
||||
Ok(next.run(req).await)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ use sentry::protocol::{Event, Level};
|
|||
use tower::ServiceBuilder;
|
||||
use tracing::{error, warn};
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
|
||||
use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
Json,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
/// Creates a Sentry layer for the Axum application
|
||||
///
|
||||
|
@ -189,4 +195,29 @@ pub fn capture_anyhow(err: &Error, msg: Option<&str>) {
|
|||
level: Level::Error,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Define a custom error type for authentication/authorization issues
|
||||
// #[derive(Debug)]
|
||||
// pub enum AuthError {
|
||||
// Unauthorized,
|
||||
// PaymentRequired,
|
||||
// InternalError(String),
|
||||
// }
|
||||
|
||||
// Implement IntoResponse for AuthError to convert it into an HTTP response
|
||||
// impl IntoResponse for AuthError {
|
||||
// fn into_response(self) -> Response {
|
||||
// let (status, error_message) = match self {
|
||||
// AuthError::Unauthorized => (StatusCode::UNAUTHORIZED, "Unauthorized".to_string()),
|
||||
// AuthError::PaymentRequired => {
|
||||
// (StatusCode::PAYMENT_REQUIRED, "Payment Required".to_string())
|
||||
// }
|
||||
// AuthError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
|
||||
// };
|
||||
//
|
||||
// let body = Json(json!({ "error": error_message }));
|
||||
//
|
||||
// (status, body).into_response()
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,4 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
|
||||
ALTER TABLE organizations
|
||||
DROP COLUMN payment_required;
|
|
@ -0,0 +1,3 @@
|
|||
-- Your SQL goes here
|
||||
ALTER TABLE organizations
|
||||
ADD COLUMN payment_required BOOLEAN NOT NULL DEFAULT false;
|
|
@ -119,6 +119,7 @@ pub async fn get_user_information(user_id: &Uuid) -> Result<UserInfoObject> {
|
|||
organizations::created_at,
|
||||
organizations::updated_at,
|
||||
organizations::deleted_at,
|
||||
organizations::payment_required,
|
||||
)
|
||||
.nullable(),
|
||||
users_to_organizations::role.nullable(),
|
||||
|
|
|
@ -409,6 +409,7 @@ pub async fn get_user_information(user_id: &Uuid) -> Result<UserInfoObject> {
|
|||
organizations::created_at,
|
||||
organizations::updated_at,
|
||||
organizations::deleted_at,
|
||||
organizations::payment_required,
|
||||
)
|
||||
.nullable(),
|
||||
users_to_organizations::role.nullable(),
|
||||
|
|
Loading…
Reference in New Issue