fix
This commit is contained in:
+22
-5
@@ -11,6 +11,7 @@ use axum::{
|
|||||||
extract::FromRequestParts,
|
extract::FromRequestParts,
|
||||||
http::{request::Parts, StatusCode},
|
http::{request::Parts, StatusCode},
|
||||||
};
|
};
|
||||||
|
use diesel::{pg::PgConnection, prelude::*};
|
||||||
use axum_extra::headers::{authorization::Bearer, Authorization};
|
use axum_extra::headers::{authorization::Bearer, Authorization};
|
||||||
use axum_extra::TypedHeader;
|
use axum_extra::TypedHeader;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -20,6 +21,7 @@ use crate::{
|
|||||||
auth::capability_sets::{load_capabilities_for_set, load_capability_set},
|
auth::capability_sets::{load_capabilities_for_set, load_capability_set},
|
||||||
error::{AppError, AppResult},
|
error::{AppError, AppResult},
|
||||||
models::{ApiCapability, TenantStatus},
|
models::{ApiCapability, TenantStatus},
|
||||||
|
schema::tenants::dsl as tenant_dsl,
|
||||||
state::{AppState, PgPooledConnection},
|
state::{AppState, PgPooledConnection},
|
||||||
};
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@@ -136,9 +138,7 @@ impl FromRequestParts<AppState> for TenantScopedConn {
|
|||||||
async move {
|
async move {
|
||||||
let user = AuthenticatedUser::from_request_parts(parts, &state).await?;
|
let user = AuthenticatedUser::from_request_parts(parts, &state).await?;
|
||||||
let tenant_id = user.tenant_id;
|
let tenant_id = user.tenant_id;
|
||||||
ensure_active_tenant(&state, tenant_id)?;
|
let mut conn = if let Some(holder) = parts.extensions.remove::<TenantConnectionHolder>() {
|
||||||
|
|
||||||
let conn = if let Some(holder) = parts.extensions.remove::<TenantConnectionHolder>() {
|
|
||||||
holder
|
holder
|
||||||
.into_conn()
|
.into_conn()
|
||||||
.ok_or_else(|| AppError::internal("tenant connection unavailable"))?
|
.ok_or_else(|| AppError::internal("tenant connection unavailable"))?
|
||||||
@@ -146,6 +146,8 @@ impl FromRequestParts<AppState> for TenantScopedConn {
|
|||||||
state.db_for_tenant(tenant_id)?
|
state.db_for_tenant(tenant_id)?
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ensure_active_tenant_with_conn(&mut conn, tenant_id)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
conn,
|
conn,
|
||||||
tenant_id,
|
tenant_id,
|
||||||
@@ -157,9 +159,24 @@ impl FromRequestParts<AppState> for TenantScopedConn {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ensure_active_tenant(state: &AppState, tenant_id: Uuid) -> AppResult<()> {
|
pub(crate) fn ensure_active_tenant(state: &AppState, tenant_id: Uuid) -> AppResult<()> {
|
||||||
let tenant = state.tenants.get_by_id(tenant_id)?;
|
let mut conn = state.db_unscoped()?;
|
||||||
if tenant.status != TenantStatus::Active {
|
ensure_active_tenant_with_conn(&mut conn, tenant_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ensure_active_tenant_with_conn(
|
||||||
|
conn: &mut PgConnection,
|
||||||
|
tenant_id: Uuid,
|
||||||
|
) -> AppResult<()> {
|
||||||
|
use tenant_dsl::tenants;
|
||||||
|
|
||||||
|
let status: TenantStatus = tenants
|
||||||
|
.find(tenant_id)
|
||||||
|
.select(tenant_dsl::status)
|
||||||
|
.first(conn)?;
|
||||||
|
|
||||||
|
if status != TenantStatus::Active {
|
||||||
return Err(AppError::new(StatusCode::FORBIDDEN, "tenant is not active"));
|
return Err(AppError::new(StatusCode::FORBIDDEN, "tenant is not active"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use tracing::{error, info};
|
|||||||
use utoipa::{IntoParams, ToSchema};
|
use utoipa::{IntoParams, ToSchema};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::auth::{ensure_active_tenant, jwt::DownloadSubject, TenantScopedConn};
|
use crate::auth::{ensure_active_tenant_with_conn, jwt::DownloadSubject, TenantScopedConn};
|
||||||
use crate::documents::asset::{
|
use crate::documents::asset::{
|
||||||
asset_object_disposition, DocumentAssetDetailResponse, DocumentAssetResponse,
|
asset_object_disposition, DocumentAssetDetailResponse, DocumentAssetResponse,
|
||||||
DocumentVersionDetailResponse, DocumentVersionResponse,
|
DocumentVersionDetailResponse, DocumentVersionResponse,
|
||||||
@@ -575,9 +575,8 @@ pub async fn download_with_token(
|
|||||||
.verify_download_token(&token)
|
.verify_download_token(&token)
|
||||||
.map_err(|_| AppError::unauthorized())?;
|
.map_err(|_| AppError::unauthorized())?;
|
||||||
|
|
||||||
ensure_active_tenant(&state, claims.tenant_id)?;
|
|
||||||
|
|
||||||
let mut conn = state.db_for_tenant(claims.tenant_id)?;
|
let mut conn = state.db_for_tenant(claims.tenant_id)?;
|
||||||
|
ensure_active_tenant_with_conn(&mut conn, claims.tenant_id)?;
|
||||||
|
|
||||||
let now = Utc::now().naive_utc();
|
let now = Utc::now().naive_utc();
|
||||||
let has_active_refresh: bool = select(exists(
|
let has_active_refresh: bool = select(exists(
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use uuid::Uuid;
|
|||||||
|
|
||||||
use crate::auth::{
|
use crate::auth::{
|
||||||
api_tokens::{find_active_token_by_secret, touch_api_token},
|
api_tokens::{find_active_token_by_secret, touch_api_token},
|
||||||
ensure_active_tenant,
|
ensure_active_tenant_with_conn,
|
||||||
};
|
};
|
||||||
use crate::error::{AppError, AppResult};
|
use crate::error::{AppError, AppResult};
|
||||||
use crate::models::{ApiCapability, Document, DocumentVersion, Folder, User};
|
use crate::models::{ApiCapability, Document, DocumentVersion, Folder, User};
|
||||||
@@ -486,7 +486,7 @@ fn authenticate(state: &AppState, headers: &HeaderMap) -> Result<Option<WebDavCo
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = ensure_active_tenant(state, tenant_id) {
|
if let Err(err) = ensure_active_tenant_with_conn(&mut conn, tenant_id) {
|
||||||
tracing::warn!(tenant_id = %tenant_id, error = ?err, "webdav tenant not active");
|
tracing::warn!(tenant_id = %tenant_id, error = ?err, "webdav tenant not active");
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -689,7 +689,7 @@ impl<'a> AuthService<'a> {
|
|||||||
user: &User,
|
user: &User,
|
||||||
tenant_id: Uuid,
|
tenant_id: Uuid,
|
||||||
) -> AppResult<Response> {
|
) -> AppResult<Response> {
|
||||||
crate::auth::ensure_active_tenant(&self.state, tenant_id)?;
|
crate::auth::ensure_active_tenant_with_conn(conn, tenant_id)?;
|
||||||
apply_tenant_guc(conn, tenant_id)?;
|
apply_tenant_guc(conn, tenant_id)?;
|
||||||
clear_user_guc(conn)?;
|
clear_user_guc(conn)?;
|
||||||
clear_user_session_hash(conn)?;
|
clear_user_session_hash(conn)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user