use tonic::codegen::async_trait;
use crate::error::Result;
use crate::identity::{
AuthorizeRequest, AuthorizeResponse, GetGrantRequest, GetGrantResponse, IntrospectRequest,
IntrospectResponse, ListGrantsRequest, ListGrantsResponse, RevokeGrantRequest,
RevokeGrantResponse, TokenRequest, TokenResponse, UserInfoRequest, UserInfoResponse,
};
pub const CALLER_BEARER_TOKEN_METADATA_KEY: &str = "x-gestalt-caller-bearer-token";
pub const GRANT_TYPE_AUTHORIZATION_CODE: &str = "authorization_code";
pub const GRANT_TYPE_TOKEN_EXCHANGE: &str = "urn:ietf:params:oauth:grant-type:token-exchange";
pub const SUBJECT_TOKEN_TYPE_ACCESS_TOKEN: &str = "urn:ietf:params:oauth:token-type:access_token";
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct IdentityCallContext {
pub caller_bearer_token: String,
}
#[async_trait]
pub trait IdentityProvider: Send + Sync + 'static {
async fn configure(
&self,
_name: &str,
_config: serde_json::Map<String, serde_json::Value>,
) -> Result<()> {
Ok(())
}
fn metadata(&self) -> Option<crate::api::RuntimeMetadata> {
None
}
fn warnings(&self) -> Vec<String> {
Vec::new()
}
async fn health_check(&self) -> Result<()> {
Ok(())
}
async fn start(&self) -> Result<()> {
Ok(())
}
async fn close(&self) -> Result<()> {
Ok(())
}
async fn authorize(&self, req: AuthorizeRequest) -> Result<AuthorizeResponse>;
async fn token(&self, req: TokenRequest) -> Result<TokenResponse>;
async fn introspect(&self, req: IntrospectRequest) -> Result<IntrospectResponse>;
async fn user_info(
&self,
call: IdentityCallContext,
req: UserInfoRequest,
) -> Result<UserInfoResponse>;
async fn list_grants(
&self,
call: IdentityCallContext,
req: ListGrantsRequest,
) -> Result<ListGrantsResponse>;
async fn get_grant(
&self,
call: IdentityCallContext,
req: GetGrantRequest,
) -> Result<GetGrantResponse>;
async fn revoke_grant(
&self,
call: IdentityCallContext,
req: RevokeGrantRequest,
) -> Result<RevokeGrantResponse>;
}
pub(crate) fn caller_bearer_token_from_metadata(metadata: &tonic::metadata::MetadataMap) -> String {
metadata
.get(CALLER_BEARER_TOKEN_METADATA_KEY)
.and_then(|value| value.to_str().ok())
.map(str::trim)
.filter(|value| !value.is_empty())
.map(str::to_owned)
.unwrap_or_default()
}