this repo has no description
1mod grants; 2mod helpers; 3mod introspect; 4mod types; 5 6use axum::{ 7 Form, Json, 8 extract::State, 9 http::HeaderMap, 10}; 11use crate::state::{AppState, RateLimitKind}; 12use crate::oauth::OAuthError; 13 14pub use grants::{handle_authorization_code_grant, handle_refresh_token_grant}; 15pub use helpers::{create_access_token, extract_token_claims, verify_pkce, TokenClaims}; 16pub use introspect::{ 17 introspect_token, revoke_token, IntrospectRequest, IntrospectResponse, RevokeRequest, 18}; 19pub use types::{TokenRequest, TokenResponse}; 20 21fn extract_client_ip(headers: &HeaderMap) -> String { 22 if let Some(forwarded) = headers.get("x-forwarded-for") { 23 if let Ok(value) = forwarded.to_str() { 24 if let Some(first_ip) = value.split(',').next() { 25 return first_ip.trim().to_string(); 26 } 27 } 28 } 29 if let Some(real_ip) = headers.get("x-real-ip") { 30 if let Ok(value) = real_ip.to_str() { 31 return value.trim().to_string(); 32 } 33 } 34 "unknown".to_string() 35} 36 37pub async fn token_endpoint( 38 State(state): State<AppState>, 39 headers: HeaderMap, 40 Form(request): Form<TokenRequest>, 41) -> Result<(HeaderMap, Json<TokenResponse>), OAuthError> { 42 let client_ip = extract_client_ip(&headers); 43 if !state.check_rate_limit(RateLimitKind::OAuthToken, &client_ip).await { 44 tracing::warn!(ip = %client_ip, "OAuth token rate limit exceeded"); 45 return Err(OAuthError::InvalidRequest( 46 "Too many requests. Please try again later.".to_string(), 47 )); 48 } 49 let dpop_proof = headers 50 .get("DPoP") 51 .and_then(|v| v.to_str().ok()) 52 .map(|s| s.to_string()); 53 match request.grant_type.as_str() { 54 "authorization_code" => { 55 handle_authorization_code_grant(state, headers, request, dpop_proof).await 56 } 57 "refresh_token" => { 58 handle_refresh_token_grant(state, headers, request, dpop_proof).await 59 } 60 _ => Err(OAuthError::UnsupportedGrantType(format!( 61 "Unsupported grant_type: {}", 62 request.grant_type 63 ))), 64 } 65}