59 lines
1.9 KiB
Rust
59 lines
1.9 KiB
Rust
use tonic::{metadata::MetadataMap, Status};
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct TenantContext {
|
|
pub org_id: String,
|
|
pub project_id: String,
|
|
}
|
|
|
|
fn metadata_value(metadata: &MetadataMap, key: &str) -> Option<String> {
|
|
metadata
|
|
.get(key)
|
|
.and_then(|value| value.to_str().ok())
|
|
.map(|value| value.trim().to_string())
|
|
.filter(|value| !value.is_empty())
|
|
}
|
|
|
|
fn org_from_metadata(metadata: &MetadataMap) -> Option<String> {
|
|
metadata_value(metadata, "org-id")
|
|
.or_else(|| metadata_value(metadata, "x-org-id"))
|
|
.or_else(|| metadata_value(metadata, "org_id"))
|
|
}
|
|
|
|
fn project_from_metadata(metadata: &MetadataMap) -> Option<String> {
|
|
metadata_value(metadata, "project-id")
|
|
.or_else(|| metadata_value(metadata, "x-project-id"))
|
|
.or_else(|| metadata_value(metadata, "project_id"))
|
|
}
|
|
|
|
pub fn resolve_org(
|
|
metadata: &MetadataMap,
|
|
org_id: Option<String>,
|
|
) -> Result<String, Status> {
|
|
org_id
|
|
.filter(|value| !value.is_empty())
|
|
.or_else(|| org_from_metadata(metadata))
|
|
.ok_or_else(|| Status::invalid_argument("org_id is required"))
|
|
}
|
|
|
|
pub fn resolve_org_project_optional(
|
|
metadata: &MetadataMap,
|
|
org_id: Option<String>,
|
|
project_id: Option<String>,
|
|
) -> Result<(String, Option<String>), Status> {
|
|
let org_id = resolve_org(metadata, org_id)?;
|
|
let project_id = project_id
|
|
.filter(|value| !value.is_empty())
|
|
.or_else(|| project_from_metadata(metadata));
|
|
Ok((org_id, project_id))
|
|
}
|
|
|
|
pub fn resolve_tenant(
|
|
metadata: &MetadataMap,
|
|
org_id: Option<String>,
|
|
project_id: Option<String>,
|
|
) -> Result<TenantContext, Status> {
|
|
let (org_id, project_id) = resolve_org_project_optional(metadata, org_id, project_id)?;
|
|
let project_id = project_id.ok_or_else(|| Status::invalid_argument("project_id is required"))?;
|
|
Ok(TenantContext { org_id, project_id })
|
|
}
|