Our Personal Data Server from scratch!
0

Configure Feed

Select the types of activity you want to include in your feed.

1mod grants; 2mod helpers; 3mod introspect; 4mod types; 5 6use axum::body::Bytes; 7use axum::{Json, extract::State, http::HeaderMap}; 8use tranquil_pds::oauth::OAuthError; 9use tranquil_pds::rate_limit::{OAuthRateLimited, OAuthTokenLimit}; 10use tranquil_pds::state::AppState; 11 12pub use grants::{handle_authorization_code_grant, handle_refresh_token_grant}; 13pub use helpers::{TokenClaims, extract_token_claims, verify_pkce}; 14pub use introspect::{ 15 IntrospectRequest, IntrospectResponse, RevokeRequest, introspect_token, revoke_token, 16}; 17pub use types::{ 18 GrantType, RequestClientAuth, TokenGrant, TokenRequest, TokenResponse, ValidatedTokenRequest, 19}; 20 21pub async fn token_endpoint( 22 State(state): State<AppState>, 23 _rate_limit: OAuthRateLimited<OAuthTokenLimit>, 24 headers: HeaderMap, 25 body: Bytes, 26) -> Result<(HeaderMap, Json<TokenResponse>), OAuthError> { 27 let content_type = headers 28 .get("content-type") 29 .and_then(|v| v.to_str().ok()) 30 .unwrap_or(""); 31 let request: TokenRequest = if content_type.starts_with("application/json") { 32 serde_json::from_slice(&body) 33 .map_err(|e| OAuthError::InvalidRequest(format!("Invalid JSON: {}", e)))? 34 } else if content_type.starts_with("application/x-www-form-urlencoded") { 35 serde_urlencoded::from_bytes(&body) 36 .map_err(|e| OAuthError::InvalidRequest(format!("Invalid form data: {}", e)))? 37 } else { 38 return Err(OAuthError::InvalidRequest( 39 "Content-Type must be application/json or application/x-www-form-urlencoded" 40 .to_string(), 41 )); 42 }; 43 let dpop_proof = headers 44 .get(tranquil_pds::util::HEADER_DPOP) 45 .and_then(|v| v.to_str().ok()) 46 .map(|s| s.to_string()); 47 let validated = request.validate()?; 48 match validated.grant { 49 TokenGrant::AuthorizationCode { .. } => { 50 handle_authorization_code_grant(state, headers, validated, dpop_proof).await 51 } 52 TokenGrant::RefreshToken { .. } => { 53 handle_refresh_token_grant(state, headers, validated, dpop_proof).await 54 } 55 } 56}