Skip to content

Commit

Permalink
feat: add more examples to introspect
Browse files Browse the repository at this point in the history
Co-authored-by: Kim Tore Jensen <[email protected]>
  • Loading branch information
tronghn and kimtore committed Nov 7, 2024
1 parent c89feba commit 2ede3c8
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 12 deletions.
19 changes: 7 additions & 12 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use jsonwebtoken as jwt;
use jsonwebtoken::Algorithm::RS512;
use jsonwebtoken::DecodingKey;
use log::{error, info};
use serde_json::Value;
use serde_json::{Value};
use std::sync::Arc;
use thiserror::Error;
use tokio::sync::RwLock;
Expand Down Expand Up @@ -88,41 +88,36 @@ pub async fn token_exchange(
responses(
(status = OK, description = "Success", body = IntrospectResponse, content_type = "application/json",
examples(
("Demo" = (summary = "Example response", value = json!(IntrospectResponse::new(HashMap::from(
("Valid token" = (value = json!(IntrospectResponse::new(HashMap::from(
[("aud".to_string(), Value::String("dev-gcp:mynamespace:myapplication".to_string())),
("iat".to_string(), Value::Number(1730969701.into())),
("nbf".to_string(), Value::Number(1730969701.into())),
("exp".to_string(), Value::Number(1730969731.into())),
],
))))),
("Invalid token" = (value = json!(IntrospectResponse::new_invalid("token is expired".to_string())))),
)
),
(status = BAD_REQUEST, description = "Bad request", body = IntrospectResponse, content_type = "application/json"),
(status = INTERNAL_SERVER_ERROR, description = "Server error", body = IntrospectResponse, content_type = "application/json"),
)
)]
pub async fn introspect(
State(state): State<HandlerState>,
JsonOrForm(request): JsonOrForm<IntrospectRequest>,
) -> Result<impl IntoResponse, Json<HashMap<String, Value>>> {
) -> Result<impl IntoResponse, Json<IntrospectResponse>> {
// Need to decode the token to get the issuer before we actually validate it.
let mut validation = jwt::Validation::new(RS512);
validation.validate_exp = false;
validation.insecure_disable_signature_validation();
let key = DecodingKey::from_secret(&[]);
let token_data = jwt::decode::<Claims>(&request.token, &key, &validation).map_err(|err| {
Json(HashMap::from([
("active".to_string(), Value::Bool(false)),
("error".to_string(), Value::String(format!("{:?}", err))),
]))
})?;
let token_data = jwt::decode::<Claims>(&request.token, &key, &validation).
map_err(IntrospectResponse::new_invalid)?;

let identity_provider = token_data.claims.identity_provider(state.cfg);
let claims = match identity_provider {
Some(IdentityProvider::Maskinporten) => state.maskinporten.write().await.introspect(request.token).await,
Some(IdentityProvider::AzureAD) => state.azure_ad_obo.write().await.introspect(request.token).await,
Some(IdentityProvider::TokenX) => state.token_x.write().await.introspect(request.token).await,
None => panic!("Unknown issuer: {}", token_data.claims.iss), // FIXME: no panics pls
None => IntrospectResponse::new_invalid("token has unknown issuer".to_string()),
};

Ok((StatusCode::OK, Json(claims)))
Expand Down
6 changes: 6 additions & 0 deletions src/identity_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ pub enum TokenType {
}

/// RFC 7662 introspection response from section 2.2.
///
/// For provider specific claims, see the respective reference pages:
///
/// - Azure AD: <https://doc.nais.io/auth/entra-id/reference/#claims>
/// - TokenX: <https://doc.nais.io/auth/tokenx/reference/#claims>
/// - Maskinporten: <https://doc.nais.io/auth/maskinporten/reference/#claims>
#[derive(Serialize, Deserialize, ToSchema, Debug)]
pub struct IntrospectResponse {
/// Indicates whether the token is valid. If this field is `false`,
Expand Down

0 comments on commit 2ede3c8

Please sign in to comment.