44// SPDX-License-Identifier: AGPL-3.0-only
55// Please see LICENSE in the repository root for full details.
66
7+ use std:: sync:: LazyLock ;
8+
79use axum:: { Json , extract:: State , http:: HeaderValue , response:: IntoResponse } ;
810use hyper:: { HeaderMap , StatusCode } ;
911use mas_axum_utils:: {
@@ -24,9 +26,21 @@ use oauth2_types::{
2426 requests:: { IntrospectionRequest , IntrospectionResponse } ,
2527 scope:: ScopeToken ,
2628} ;
29+ use opentelemetry:: { Key , KeyValue , metrics:: Counter } ;
2730use thiserror:: Error ;
2831
29- use crate :: { ActivityTracker , impl_from_error_for_route} ;
32+ use crate :: { ActivityTracker , METER , impl_from_error_for_route} ;
33+
34+ static INTROSPECTION_COUNTER : LazyLock < Counter < u64 > > = LazyLock :: new ( || {
35+ METER
36+ . u64_counter ( "mas.oauth2.introspection_request" )
37+ . with_description ( "Number of OAuth 2.0 introspection requests" )
38+ . with_unit ( "{request}" )
39+ . build ( )
40+ } ) ;
41+
42+ const KIND : Key = Key :: from_static_str ( "kind" ) ;
43+ const ACTIVE : Key = Key :: from_static_str ( "active" ) ;
3044
3145#[ derive( Debug , Error ) ]
3246pub enum RouteError {
@@ -118,14 +132,20 @@ impl IntoResponse for RouteError {
118132 ) ,
119133 )
120134 . into_response ( ) ,
135+
121136 Self :: UnknownToken ( _)
122137 | Self :: UnexpectedTokenType
123138 | Self :: InvalidToken ( _)
124139 | Self :: InvalidUser
125140 | Self :: InvalidCompatSession
126141 | Self :: InvalidOAuthSession
127142 | Self :: InvalidTokenFormat ( _)
128- | Self :: CantEncodeDeviceID ( _) => Json ( INACTIVE ) . into_response ( ) ,
143+ | Self :: CantEncodeDeviceID ( _) => {
144+ INTROSPECTION_COUNTER . add ( 1 , & [ KeyValue :: new ( ACTIVE . clone ( ) , false ) ] ) ;
145+
146+ Json ( INACTIVE ) . into_response ( )
147+ }
148+
129149 Self :: NotAllowed => (
130150 StatusCode :: UNAUTHORIZED ,
131151 Json ( ClientError :: from ( ClientErrorCode :: AccessDenied ) ) ,
@@ -275,6 +295,14 @@ pub(crate) async fn post(
275295 . record_oauth2_session ( & clock, & session, ip)
276296 . await ;
277297
298+ INTROSPECTION_COUNTER . add (
299+ 1 ,
300+ & [
301+ KeyValue :: new ( KIND , "oauth2_access_token" ) ,
302+ KeyValue :: new ( ACTIVE , true ) ,
303+ ] ,
304+ ) ;
305+
278306 IntrospectionResponse {
279307 active : true ,
280308 scope : Some ( session. scope ) ,
@@ -338,6 +366,14 @@ pub(crate) async fn post(
338366 . record_oauth2_session ( & clock, & session, ip)
339367 . await ;
340368
369+ INTROSPECTION_COUNTER . add (
370+ 1 ,
371+ & [
372+ KeyValue :: new ( KIND , "oauth2_refresh_token" ) ,
373+ KeyValue :: new ( ACTIVE , true ) ,
374+ ] ,
375+ ) ;
376+
341377 IntrospectionResponse {
342378 active : true ,
343379 scope : Some ( session. scope ) ,
@@ -412,6 +448,14 @@ pub(crate) async fn post(
412448 . record_compat_session ( & clock, & session, ip)
413449 . await ;
414450
451+ INTROSPECTION_COUNTER . add (
452+ 1 ,
453+ & [
454+ KeyValue :: new ( KIND , "compat_access_token" ) ,
455+ KeyValue :: new ( ACTIVE , true ) ,
456+ ] ,
457+ ) ;
458+
415459 IntrospectionResponse {
416460 active : true ,
417461 scope : Some ( scope) ,
@@ -488,6 +532,14 @@ pub(crate) async fn post(
488532 . record_compat_session ( & clock, & session, ip)
489533 . await ;
490534
535+ INTROSPECTION_COUNTER . add (
536+ 1 ,
537+ & [
538+ KeyValue :: new ( KIND , "compat_refresh_token" ) ,
539+ KeyValue :: new ( ACTIVE , true ) ,
540+ ] ,
541+ ) ;
542+
491543 IntrospectionResponse {
492544 active : true ,
493545 scope : Some ( scope) ,
0 commit comments