github.com/Axway/agent-sdk@v1.1.101/pkg/authz/oauth/mockidpserver.go (about) 1 package oauth 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "net/url" 10 "strings" 11 "time" 12 13 "github.com/google/uuid" 14 ) 15 16 // MockIDPServer - interface for mock IDP server 17 type MockIDPServer interface { 18 GetMetadataURL() string 19 GetIssuer() string 20 GetTokenURL() string 21 GetAuthEndpoint() string 22 GetRegistrationEndpoint() string 23 SetMetadataResponseCode(statusCode int) 24 SetTokenResponse(accessToken string, expiry time.Duration, statusCode int) 25 SetRegistrationResponseCode(statusCode int) 26 SetUseRegistrationAccessToken(useRegistrationAccessToken bool) 27 GetTokenRequestHeaders() http.Header 28 GetTokenQueryParams() url.Values 29 GetTokenRequestValues() url.Values 30 GetRequestHeaders() http.Header 31 GetQueryParams() url.Values 32 Close() 33 } 34 35 type mockIDPServer struct { 36 metadataResponseCode int 37 tokenResponseCode int 38 registerResponseCode int 39 useRegistrationAccessToken bool 40 accessToken string 41 tokenExpiry time.Duration 42 serverMetadata *AuthorizationServerMetadata 43 server *httptest.Server 44 tokenReqHeaders http.Header 45 tokenQueryParams url.Values 46 tokenReqValues url.Values 47 reqHeaders http.Header 48 reqQueryParam url.Values 49 } 50 51 // NewMockIDPServer - creates a new mock IDP server for tests 52 func NewMockIDPServer() MockIDPServer { 53 m := &mockIDPServer{ 54 metadataResponseCode: http.StatusOK, 55 tokenResponseCode: http.StatusOK, 56 registerResponseCode: http.StatusCreated, 57 } 58 59 m.server = httptest.NewServer(http.HandlerFunc(m.handleRequest)) 60 m.serverMetadata = &AuthorizationServerMetadata{ 61 Issuer: m.GetIssuer(), 62 TokenEndpoint: m.GetTokenURL(), 63 AuthorizationEndpoint: m.GetAuthEndpoint(), 64 RegistrationEndpoint: m.GetRegistrationEndpoint(), 65 } 66 return m 67 } 68 69 func (m *mockIDPServer) handleRequest(resp http.ResponseWriter, req *http.Request) { 70 if strings.Contains(req.RequestURI, "/metadata") { 71 defer func() { 72 m.metadataResponseCode = http.StatusOK 73 }() 74 if m.metadataResponseCode != http.StatusOK { 75 resp.WriteHeader(m.metadataResponseCode) 76 77 return 78 } 79 buf, _ := json.Marshal(m.serverMetadata) 80 resp.Write(buf) 81 } 82 if strings.Contains(req.RequestURI, "/token") { 83 m.tokenReqHeaders = req.Header 84 m.tokenQueryParams = req.URL.Query() 85 m.tokenReqValues = nil 86 reqBuf, _ := io.ReadAll(req.Body) 87 if len(reqBuf) != 0 { 88 fmt.Printf("%s\n", string(reqBuf)) 89 val, err := url.ParseQuery(string(reqBuf)) 90 if err == nil { 91 m.tokenReqValues = val 92 } 93 } 94 defer func() { 95 m.tokenResponseCode = http.StatusOK 96 m.accessToken = "" 97 m.tokenExpiry = 0 98 }() 99 if m.tokenResponseCode != http.StatusOK { 100 resp.WriteHeader(m.tokenResponseCode) 101 return 102 } 103 104 now := time.Now() 105 t := tokenResponse{ 106 AccessToken: m.accessToken, 107 ExpiresIn: now.Add(m.tokenExpiry).UnixNano() / 1e9, 108 } 109 buf, _ := json.Marshal(t) 110 resp.Write(buf) 111 } 112 if strings.Contains(req.RequestURI, "/register") { 113 m.reqHeaders = req.Header 114 m.reqQueryParam = req.URL.Query() 115 defer func() { 116 m.registerResponseCode = http.StatusCreated 117 }() 118 if req.Method == http.MethodPost { 119 if m.registerResponseCode != http.StatusCreated { 120 resp.WriteHeader(m.registerResponseCode) 121 return 122 } 123 resp.WriteHeader(http.StatusCreated) 124 clientBuf, _ := io.ReadAll(req.Body) 125 cl := &clientMetadata{} 126 json.Unmarshal(clientBuf, cl) 127 cl.ClientID = uuid.New().String() 128 cl.ClientSecret = uuid.New().String() 129 if m.useRegistrationAccessToken { 130 cl.RegistrationAccessToken = uuid.New().String() 131 } 132 clientBuf, _ = json.Marshal(cl) 133 resp.Write(clientBuf) 134 } 135 if req.Method == http.MethodDelete { 136 if m.registerResponseCode != http.StatusNoContent { 137 resp.WriteHeader(m.registerResponseCode) 138 return 139 } 140 resp.WriteHeader(http.StatusNoContent) 141 } 142 } 143 } 144 145 func (m *mockIDPServer) GetMetadataURL() string { 146 return m.server.URL + "/metadata" 147 } 148 149 func (m *mockIDPServer) GetIssuer() string { 150 return m.server.URL 151 } 152 153 func (m *mockIDPServer) GetTokenURL() string { 154 return m.server.URL + "/token" 155 } 156 157 func (m *mockIDPServer) GetAuthEndpoint() string { 158 return m.server.URL + "/auth" 159 } 160 161 func (m *mockIDPServer) GetRegistrationEndpoint() string { 162 return m.server.URL + "/register" 163 } 164 165 func (m *mockIDPServer) SetMetadataResponseCode(statusCode int) { 166 m.metadataResponseCode = statusCode 167 } 168 169 func (m *mockIDPServer) SetTokenResponse(accessToken string, expiry time.Duration, statusCode int) { 170 m.accessToken = accessToken 171 m.tokenExpiry = expiry 172 m.tokenResponseCode = statusCode 173 } 174 175 func (m *mockIDPServer) SetRegistrationResponseCode(statusCode int) { 176 m.registerResponseCode = statusCode 177 } 178 179 func (m *mockIDPServer) SetUseRegistrationAccessToken(useRegistrationAccessToken bool) { 180 m.useRegistrationAccessToken = useRegistrationAccessToken 181 } 182 183 func (m *mockIDPServer) GetTokenRequestHeaders() http.Header { 184 return m.tokenReqHeaders 185 } 186 187 func (m *mockIDPServer) GetTokenQueryParams() url.Values { 188 return m.tokenQueryParams 189 } 190 191 func (m *mockIDPServer) GetTokenRequestValues() url.Values { 192 return m.tokenReqValues 193 } 194 195 func (m *mockIDPServer) GetRequestHeaders() http.Header { 196 return m.reqHeaders 197 } 198 199 func (m *mockIDPServer) GetQueryParams() url.Values { 200 return m.reqQueryParam 201 } 202 func (m *mockIDPServer) Close() { 203 m.server.Close() 204 }