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