@@ -726,6 +726,136 @@ func TestDeleteClient(t *testing.T) {
726726 }
727727}
728728
729+ func TestGetClient (t * testing.T ) {
730+ readOnlyToken := jwt.Token {
731+ Claims : jwt.MapClaims {
732+ "exp" : time .Now ().Add (time .Hour ).Unix (),
733+ "iat" : time .Now ().Unix (),
734+ "client_id" : "client123" ,
735+ "scope" : "diode:read" ,
736+ },
737+ Valid : true ,
738+ }
739+ invalidToken := jwt.Token {
740+ Valid : false ,
741+ }
742+
743+ validAccessToken := "eyJhbGciOiJSUzI1NiIsImtpZCI6InRlc3Qta2V5IiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJzdWIiOiJ1c2VyMTIzIiwiYXVkIjoiYXBpIiwiZXhwIjoxNjUwMDAwMDAwLCJpYXQiOjE1MDAwMDAwMDAsImNsaWVudF9pZCI6ImNsaWVudDEyMyIsInNjb3BlIjoicmVhZCB3cml0ZSIsInVzZXJuYW1lIjoidGVzdHVzZXIifQ.WcPGXClpKD7Bc1C0CCDA1060E2GGlTfamrd8-W0ghBE"
744+ invalidAccessToken := "invalid.token.string"
745+
746+ tests := []struct {
747+ name string
748+ accessToken string
749+ clientID string
750+ parsedToken jwt.Token
751+ lookupResult auth.ClientInfo
752+ lookupErr error
753+ expectStatus int
754+ expect auth.ClientResponse
755+ }{
756+ {
757+ name : "can get client" ,
758+ accessToken : validAccessToken ,
759+ clientID : "test-client-1-abcdef0123567890" ,
760+ parsedToken : readOnlyToken ,
761+ lookupResult : auth.ClientInfo {
762+ ClientID : "test-client-1-abcdef0123567890" ,
763+ ClientName : "Test Client 1" ,
764+ Scope : "diode:ingest" ,
765+ Owner : "diode/user" ,
766+ CreatedAt : "2021-01-01T00:00:00Z" ,
767+ },
768+ expect : auth.ClientResponse {
769+ ClientID : "test-client-1-abcdef0123567890" ,
770+ ClientName : "Test Client 1" ,
771+ Scope : "diode:ingest" ,
772+ CreatedAt : "2021-01-01T00:00:00Z" ,
773+ },
774+ expectStatus : http .StatusOK ,
775+ },
776+ {
777+ name : "cannot get client with invalid access token" ,
778+ accessToken : invalidAccessToken ,
779+ clientID : "test-client-1-abcdef0123567890" ,
780+ parsedToken : invalidToken ,
781+ expectStatus : http .StatusUnauthorized ,
782+ },
783+ {
784+ name : "cannot get client that does not exist" ,
785+ accessToken : validAccessToken ,
786+ clientID : "test-client-1-abcdef0123567890" ,
787+ parsedToken : readOnlyToken ,
788+ lookupErr : auth .NewAuthError ("client not found" , http .StatusNotFound ),
789+ expectStatus : http .StatusNotFound ,
790+ },
791+ {
792+ name : "cannot get a client with the wrong owner" ,
793+ accessToken : validAccessToken ,
794+ clientID : "test-client-1-abcdef0123567890" ,
795+ parsedToken : readOnlyToken ,
796+ lookupResult : auth.ClientInfo {
797+ ClientID : "test-client-1-abcdef0123567890" ,
798+ ClientName : "Test Client 1" ,
799+ Owner : "diode/system" ,
800+ Scope : "diode:read diode:write" ,
801+ CreatedAt : "2021-01-01T00:00:00Z" ,
802+ },
803+ expectStatus : http .StatusNotFound ,
804+ },
805+ }
806+
807+ ctx := context .Background ()
808+ setupEnv ()
809+ defer teardownEnv ()
810+
811+ // Setup a test server to mock the OAuth2 server
812+ mockJWKSServer := mockJWKSServer ()
813+ defer mockJWKSServer .Close ()
814+
815+ _ = os .Setenv ("OAUTH2_PUBLIC_SERVER_URL" , mockJWKSServer .URL )
816+ defer func () {
817+ _ = os .Unsetenv ("OAUTH2_PUBLIC_SERVER_URL" )
818+ }()
819+
820+ for _ , test := range tests {
821+ t .Run (test .name , func (t * testing.T ) {
822+ defaultOwnership := & auth.DefaultTokenOwner {}
823+ accessToken := test .accessToken
824+ if accessToken == "" {
825+ accessToken = validAccessToken
826+ }
827+ mockTokenParser := & MockTokenParser {
828+ tokenMap : map [string ]jwt.Token {
829+ accessToken : test .parsedToken ,
830+ },
831+ }
832+ mockClientManager := & mocks.ClientManager {}
833+ logger := slog .New (slog .NewJSONHandler (os .Stdout , & slog.HandlerOptions {Level : slog .LevelDebug , AddSource : false }))
834+ server , err := auth .NewServer (ctx , logger , mockTokenParser , mockClientManager , defaultOwnership )
835+ require .NoError (t , err )
836+ require .NotNil (t , server )
837+
838+ testServer := httptest .NewServer (server .GetMux ())
839+ defer testServer .Close ()
840+
841+ if test .lookupResult != (auth.ClientInfo {}) || test .lookupErr != nil {
842+ mockClientManager .EXPECT ().RetrieveClientByID (mock .Anything , test .clientID ).Return (test .lookupResult , test .lookupErr )
843+ }
844+
845+ req , _ := http .NewRequest ("GET" , testServer .URL + "/clients/" + test .clientID , nil )
846+ req .Header .Set ("Authorization" , "Bearer " + accessToken )
847+ req .Header .Set ("Content-Type" , "application/json" )
848+ client := & http.Client {}
849+ resp , err := client .Do (req )
850+ require .NoError (t , err )
851+ defer func () {
852+ _ = resp .Body .Close ()
853+ }()
854+ require .Equal (t , test .expectStatus , resp .StatusCode )
855+ })
856+ }
857+ }
858+
729859func makeIntrospectRequest (serverURL , token string ) (* http.Response , error ) {
730860 req , _ := http .NewRequest (
731861 "POST" ,
0 commit comments