tenant gate active
This commit is contained in:
@@ -8,9 +8,19 @@ use papercrate::auth::passkeys::{
|
||||
PasskeyLoginFinishPayload, PasskeyLoginStartPayload, PasskeyRegistrationFinishPayload,
|
||||
RegistrationChallengeResponse,
|
||||
};
|
||||
use papercrate::models::{NewUserMembership, NewUserSession, TenantStatus, UserPasskey};
|
||||
use papercrate::models::{
|
||||
MagicToken, MagicTokenKind, NewUserMembership, NewUserSession, TenantStatus, UserPasskey,
|
||||
};
|
||||
use papercrate::openapi::schemas::PasskeySummary;
|
||||
use papercrate::schema::{capability_sets, tenants, user_memberships, user_sessions, users};
|
||||
use papercrate::schema::{
|
||||
capability_sets,
|
||||
magic_tokens::dsl as magic_dsl,
|
||||
tenants,
|
||||
tenants::dsl as tenant_dsl,
|
||||
user_memberships,
|
||||
user_sessions,
|
||||
users,
|
||||
};
|
||||
use papercrate::test_support::{acquire_db_lock, body_to_vec, TestApp, TestUserRole};
|
||||
use rand::{rngs::OsRng, TryRngCore};
|
||||
use serde::Deserialize;
|
||||
@@ -678,3 +688,71 @@ fn hash_session_token(value: &str) -> String {
|
||||
hasher.update(value.as_bytes());
|
||||
hex::encode(hasher.finalize())
|
||||
}
|
||||
#[tokio::test]
|
||||
async fn tenant_selection_excludes_inactive_tenants() -> Result<()> {
|
||||
let _lock = acquire_db_lock().await;
|
||||
let app = TestApp::new().await?;
|
||||
|
||||
let user_id = app.insert_user("tenant-user", TestUserRole::Owner).await?;
|
||||
|
||||
let tenant_id = app
|
||||
.with_conn(|conn| {
|
||||
let tenant: papercrate::models::Tenant = tenant_dsl::tenants
|
||||
.filter(tenant_dsl::name.eq("test_tenant"))
|
||||
.first(conn)?;
|
||||
Ok::<_, anyhow::Error>(tenant.id)
|
||||
})
|
||||
.await?;
|
||||
|
||||
app.with_conn(move |conn| {
|
||||
diesel::update(tenant_dsl::tenants.find(tenant_id))
|
||||
.set(tenant_dsl::status.eq(TenantStatus::Suspended))
|
||||
.execute(conn)?;
|
||||
Ok(())
|
||||
})
|
||||
.await?;
|
||||
|
||||
let magic_value = "tenant-status-token";
|
||||
let token_hash = {
|
||||
let mut hasher = Sha256::new();
|
||||
hasher.update(magic_value.as_bytes());
|
||||
hex::encode(hasher.finalize())
|
||||
};
|
||||
|
||||
let user_id_for_token = user_id;
|
||||
app.with_conn(move |conn| {
|
||||
let token = MagicToken {
|
||||
id: Uuid::new_v4(),
|
||||
user_id: user_id_for_token,
|
||||
kind: MagicTokenKind::EmailLogin,
|
||||
token_hash,
|
||||
metadata: json!({}),
|
||||
expires_at: (Utc::now() + ChronoDuration::hours(1)).naive_utc(),
|
||||
max_uses: None,
|
||||
used_count: 0,
|
||||
created_at: Utc::now().naive_utc(),
|
||||
created_by: None,
|
||||
last_used_at: None,
|
||||
};
|
||||
|
||||
diesel::insert_into(magic_dsl::magic_tokens)
|
||||
.values(&token)
|
||||
.execute(conn)?;
|
||||
Ok(())
|
||||
})
|
||||
.await?;
|
||||
|
||||
let payload = json!({
|
||||
"username": "tenant-user",
|
||||
"magic_token": magic_value,
|
||||
});
|
||||
|
||||
let response = app.post_json("/api/auth/login", &payload, None).await?;
|
||||
assert_eq!(response.status(), StatusCode::FORBIDDEN);
|
||||
let body = body_to_vec(response.into_body()).await?;
|
||||
let err: ApiErrorResponse = serde_json::from_slice(&body)?;
|
||||
assert_eq!(err.error, "no active tenants available");
|
||||
|
||||
app.cleanup().await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user