@@ -387,7 +387,7 @@ func TestOIDCController(t *testing.T) {
387387 err = json .Unmarshal (secondRecorder .Body .Bytes (), & secondRes )
388388 assert .NoError (t , err )
389389
390- assert .Equal (t , secondRes [ "error" ], "invalid_grant" )
390+ assert .Equal (t , "invalid_grant" , secondRes [ "error" ] )
391391 },
392392 },
393393 {
@@ -778,6 +778,74 @@ func TestOIDCController(t *testing.T) {
778778 assert .NotEmpty (t , error )
779779 },
780780 },
781+ {
782+ description : "Ensure access token gets invalidated on double code use" ,
783+ middlewares : []gin.HandlerFunc {
784+ simpleCtx ,
785+ },
786+ run : func (t * testing.T , router * gin.Engine , recorder * httptest.ResponseRecorder ) {
787+ authorizeCodeTest , found := getTestByDescription ("Ensure authorize succeeds with valid params" )
788+ assert .True (t , found , "Authorize test not found" )
789+ authorizeCodeTest (t , router , recorder )
790+
791+ var res map [string ]any
792+ err := json .Unmarshal (recorder .Body .Bytes (), & res )
793+ assert .NoError (t , err )
794+
795+ redirectURI := res ["redirect_uri" ].(string )
796+ url , err := url .Parse (redirectURI )
797+ assert .NoError (t , err )
798+
799+ queryParams := url .Query ()
800+ code := queryParams .Get ("code" )
801+ assert .NotEmpty (t , code )
802+
803+ reqBody := controller.TokenRequest {
804+ GrantType : "authorization_code" ,
805+ Code : code ,
806+ RedirectURI : "https://test.example.com/callback" ,
807+ }
808+ reqBodyEncoded , err := query .Values (reqBody )
809+ assert .NoError (t , err )
810+
811+ req := httptest .NewRequest ("POST" , "/api/oidc/token" , strings .NewReader (reqBodyEncoded .Encode ()))
812+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
813+ req .SetBasicAuth ("some-client-id" , "some-client-secret" )
814+ recorder = httptest .NewRecorder ()
815+ router .ServeHTTP (recorder , req )
816+
817+ assert .Equal (t , 200 , recorder .Code )
818+
819+ err = json .Unmarshal (recorder .Body .Bytes (), & res )
820+ assert .NoError (t , err )
821+
822+ accessToken := res ["access_token" ].(string )
823+ assert .NotEmpty (t , accessToken )
824+
825+ req = httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
826+ req .Header .Set ("Authorization" , "Bearer " + accessToken )
827+ recorder = httptest .NewRecorder ()
828+ router .ServeHTTP (recorder , req )
829+ assert .Equal (t , 200 , recorder .Code )
830+
831+ req = httptest .NewRequest ("POST" , "/api/oidc/token" , strings .NewReader (reqBodyEncoded .Encode ()))
832+ req .Header .Set ("Content-Type" , "application/x-www-form-urlencoded" )
833+ req .SetBasicAuth ("some-client-id" , "some-client-secret" )
834+ recorder = httptest .NewRecorder ()
835+ router .ServeHTTP (recorder , req )
836+ assert .Equal (t , 400 , recorder .Code )
837+
838+ req = httptest .NewRequest ("GET" , "/api/oidc/userinfo" , nil )
839+ req .Header .Set ("Authorization" , "Bearer " + accessToken )
840+ recorder = httptest .NewRecorder ()
841+ router .ServeHTTP (recorder , req )
842+ assert .Equal (t , 401 , recorder .Code )
843+
844+ err = json .Unmarshal (recorder .Body .Bytes (), & res )
845+ assert .NoError (t , err )
846+ assert .Equal (t , "invalid_grant" , res ["error" ])
847+ },
848+ },
781849 }
782850
783851 app := bootstrap .NewBootstrapApp (config.Config {})
0 commit comments