tenants
This commit is contained in:
@@ -12,7 +12,7 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
const OWNER_CAPABILITIES: [ApiCapability; 19] = [
|
||||
const OWNER_CAPABILITIES: [ApiCapability; 22] = [
|
||||
ApiCapability::CorrespondentsEdit,
|
||||
ApiCapability::CorrespondentsRead,
|
||||
ApiCapability::CorrespondentsWrite,
|
||||
@@ -32,6 +32,9 @@ const OWNER_CAPABILITIES: [ApiCapability; 19] = [
|
||||
ApiCapability::WebdavWrite,
|
||||
ApiCapability::CapabilitySetsRead,
|
||||
ApiCapability::CapabilitySetsWrite,
|
||||
ApiCapability::TenantsWrite,
|
||||
ApiCapability::TenantsReset,
|
||||
ApiCapability::TenantsDelete,
|
||||
];
|
||||
|
||||
const USER_CAPABILITIES: [ApiCapability; 16] = [
|
||||
|
||||
@@ -42,16 +42,18 @@ pub struct JwtService {
|
||||
|
||||
impl JwtService {
|
||||
pub fn from_config(config: &AppConfig) -> Result<Self> {
|
||||
let access_expiry = Duration::minutes(config.jwt_expiry_minutes);
|
||||
|
||||
Ok(Self {
|
||||
encoding: EncodingKey::from_secret(config.jwt_secret.as_bytes()),
|
||||
decoding: DecodingKey::from_secret(config.jwt_secret.as_bytes()),
|
||||
issuer: config.jwt_issuer.clone(),
|
||||
audience: config.jwt_audience.clone(),
|
||||
expiry: Duration::minutes(config.jwt_expiry_minutes),
|
||||
expiry: access_expiry,
|
||||
download_audience: config.download_token_audience.clone(),
|
||||
download_expiry: Duration::minutes(config.download_token_expiry_minutes),
|
||||
selector_audience: format!("{}:tenant-selector", config.jwt_audience),
|
||||
selector_expiry: Duration::minutes(15),
|
||||
selector_expiry: access_expiry,
|
||||
signup_audience: format!("{}:signup", config.jwt_audience),
|
||||
signup_expiry: Duration::minutes(15),
|
||||
})
|
||||
|
||||
@@ -28,6 +28,44 @@ use uuid::Uuid;
|
||||
|
||||
use crate::auth::jwt::PrincipalKind;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TenantMembershipUser {
|
||||
pub user_id: Uuid,
|
||||
}
|
||||
|
||||
impl FromRequestParts<AppState> for TenantMembershipUser {
|
||||
type Rejection = AppError;
|
||||
|
||||
#[allow(refining_impl_trait)]
|
||||
fn from_request_parts<'a>(
|
||||
parts: &'a mut Parts,
|
||||
state: &AppState,
|
||||
) -> impl std::future::Future<Output = Result<Self, Self::Rejection>> + Send + 'a {
|
||||
let state = state.clone();
|
||||
async move {
|
||||
let TypedHeader(Authorization(bearer)) =
|
||||
TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, &state)
|
||||
.await
|
||||
.map_err(|_| AppError::unauthorized())?;
|
||||
|
||||
if let Ok(claims) = state.jwt.verify_token(bearer.token()) {
|
||||
return Ok(Self {
|
||||
user_id: claims.sub,
|
||||
});
|
||||
}
|
||||
|
||||
let selector = state
|
||||
.jwt
|
||||
.verify_tenant_selector_token(bearer.token())
|
||||
.map_err(|_| AppError::unauthorized())?;
|
||||
|
||||
Ok(Self {
|
||||
user_id: selector.sub,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TenantConnectionHolder {
|
||||
inner: Arc<Mutex<Option<PgPooledConnection>>>,
|
||||
|
||||
Reference in New Issue
Block a user