github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/edgeworkers/edgekv_access_tokens_test.go (about) 1 package edgeworkers 2 3 import ( 4 "context" 5 "errors" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "strconv" 10 "testing" 11 12 "github.com/stretchr/testify/assert" 13 "github.com/stretchr/testify/require" 14 ) 15 16 func TestCreateEdgeKVAccessToken(t *testing.T) { 17 tests := map[string]struct { 18 params CreateEdgeKVAccessTokenRequest 19 expectedRequestBody string 20 responseStatus int 21 responseBody string 22 expectedPath string 23 expectedResponse *CreateEdgeKVAccessTokenResponse 24 withError error 25 }{ 26 "200 OK - create token": { 27 params: CreateEdgeKVAccessTokenRequest{ 28 AllowOnProduction: false, 29 AllowOnStaging: true, 30 Expiry: "2022-03-30", 31 Name: "devexp-token-1", 32 NamespacePermissions: NamespacePermissions{ 33 "default": []Permission{"r", "w", "d"}, 34 "devexp-jsmith-test": []Permission{"r", "w"}, 35 }, 36 }, 37 expectedRequestBody: `{"allowOnProduction":false,"allowOnStaging":true,"expiry":"2022-03-30","name":"devexp-token-1","namespacePermissions":{"default":["r","w","d"],"devexp-jsmith-test":["r","w"]}}`, 38 responseStatus: http.StatusOK, 39 responseBody: ` 40 { 41 "name": "devexp-token-1", 42 "uuid": "1ab0e94b-c47e-568e-ab3e-1921ffcefe0c", 43 "expiry": "2022-03-30", 44 "value": "eyJ0eXAiOxJKV1QxLCJhbGciOiJSUzI1NiJ9.eyJld2lkcyI6ImFsbCIsInN1YiI6IjUwMCIsIm5hbWVzcGFjZS1kZWZhdWx0IjpbInIiLCJkIiwidyJdLCJjcGMiOiI5NzEwNTIiLCJpc3MiOiJha2FtYWkuY29tL0VkZ2VEQi9QdWxzYXIvdjAuMTEuMCIsIm5hbWVzcGFjZS1kZXZleHAtcm9iZXJ0by10ZXN0IjpbInIiLCJ3Il0sImV4cCI6MTY0ODY4NDc5OSwiZW52IjpbInAiLCJzIl0sImlhdCI6MTY0MDg1ODIzNywianRpIjoiMTBiMGU5NGItYzQ3ZS01NjhlLWFiM2UtMTkyMWZmY2VmZTBjIiwicmVxaWQiOiJha2FtYWkiLCJub2VjbCI6dHJ1ZX0.AZfP-VFqDKNWcu1Or73EFfjG_GBDdJUP81Zs0BnNs_bScc8oyBAEiBjxwEsUxrvRRr7rSu-BxFjiDpxx5DlfbgEwd8H2DFV08cfQFqs7aab4WYLrx4ZweD9Hbg2gGLA-dRAbtSrq_FQKQysOvO2ymPn13E78PvK96t8r4cnN1irXbfyBUOXOE3OVOAKsk-w0Ig7qFDa_4o6YyDMPTpwEQ34T1cVqRYStIVzjSaCwgSfdaQG5qzTzTlFoDzG24tz8YlLgoM5OQf9xgsTsisCOF2jf44VWMu2S0e6MIC5gg7zXx7X2t59Y8TsAd0VqqB37y0AzEXkJblbZUlO9HcGebg" 45 }`, 46 expectedPath: "/edgekv/v1/tokens", 47 expectedResponse: &CreateEdgeKVAccessTokenResponse{ 48 Name: "devexp-token-1", 49 UUID: "1ab0e94b-c47e-568e-ab3e-1921ffcefe0c", 50 Expiry: "2022-03-30", 51 Value: "eyJ0eXAiOxJKV1QxLCJhbGciOiJSUzI1NiJ9.eyJld2lkcyI6ImFsbCIsInN1YiI6IjUwMCIsIm5hbWVzcGFjZS1kZWZhdWx0IjpbInIiLCJkIiwidyJdLCJjcGMiOiI5NzEwNTIiLCJpc3MiOiJha2FtYWkuY29tL0VkZ2VEQi9QdWxzYXIvdjAuMTEuMCIsIm5hbWVzcGFjZS1kZXZleHAtcm9iZXJ0by10ZXN0IjpbInIiLCJ3Il0sImV4cCI6MTY0ODY4NDc5OSwiZW52IjpbInAiLCJzIl0sImlhdCI6MTY0MDg1ODIzNywianRpIjoiMTBiMGU5NGItYzQ3ZS01NjhlLWFiM2UtMTkyMWZmY2VmZTBjIiwicmVxaWQiOiJha2FtYWkiLCJub2VjbCI6dHJ1ZX0.AZfP-VFqDKNWcu1Or73EFfjG_GBDdJUP81Zs0BnNs_bScc8oyBAEiBjxwEsUxrvRRr7rSu-BxFjiDpxx5DlfbgEwd8H2DFV08cfQFqs7aab4WYLrx4ZweD9Hbg2gGLA-dRAbtSrq_FQKQysOvO2ymPn13E78PvK96t8r4cnN1irXbfyBUOXOE3OVOAKsk-w0Ig7qFDa_4o6YyDMPTpwEQ34T1cVqRYStIVzjSaCwgSfdaQG5qzTzTlFoDzG24tz8YlLgoM5OQf9xgsTsisCOF2jf44VWMu2S0e6MIC5gg7zXx7X2t59Y8TsAd0VqqB37y0AzEXkJblbZUlO9HcGebg", 52 }, 53 }, 54 "at least one allow is required": { 55 params: CreateEdgeKVAccessTokenRequest{ 56 AllowOnProduction: false, 57 AllowOnStaging: false, 58 Expiry: "2022-03-30", 59 Name: "name", 60 NamespacePermissions: NamespacePermissions{ 61 "default": []Permission{"r", "w", "d"}, 62 "devexp-jsmith-test": []Permission{"r", "w"}, 63 }, 64 }, 65 withError: ErrStructValidation, 66 }, 67 "missing Name": { 68 params: CreateEdgeKVAccessTokenRequest{ 69 AllowOnProduction: true, 70 AllowOnStaging: true, 71 Expiry: "2022-03-30", 72 Name: "", 73 NamespacePermissions: NamespacePermissions{ 74 "default": []Permission{"r", "w", "d"}, 75 "devexp-jsmith-test": []Permission{"r", "w"}, 76 }, 77 }, withError: ErrStructValidation, 78 }, 79 "invalid date": { 80 params: CreateEdgeKVAccessTokenRequest{ 81 AllowOnProduction: true, 82 AllowOnStaging: true, 83 Expiry: "30/09/2021", 84 Name: "name", 85 NamespacePermissions: NamespacePermissions{ 86 "default": []Permission{"r", "w", "d"}, 87 "devexp-jsmith-test": []Permission{"r", "w"}, 88 }, 89 }, withError: ErrStructValidation, 90 }, 91 "invalid permission": { 92 params: CreateEdgeKVAccessTokenRequest{ 93 AllowOnProduction: true, 94 AllowOnStaging: true, 95 Expiry: "2022-03-30", 96 Name: "devexp-token-1", 97 NamespacePermissions: NamespacePermissions{ 98 "default": []Permission{"a", "w", "d"}, 99 }, 100 }, withError: ErrStructValidation, 101 }, 102 "empty namespace": { 103 params: CreateEdgeKVAccessTokenRequest{ 104 AllowOnProduction: true, 105 AllowOnStaging: true, 106 Expiry: "2022-03-30", 107 Name: "devexp-token-1", 108 NamespacePermissions: NamespacePermissions{ 109 "": []Permission{"r", "w", "d"}, 110 }, 111 }, withError: ErrStructValidation, 112 }, 113 "missing permission": { 114 params: CreateEdgeKVAccessTokenRequest{ 115 AllowOnProduction: true, 116 AllowOnStaging: true, 117 Expiry: "2022-03-30", 118 Name: "devexp-token-1", 119 NamespacePermissions: NamespacePermissions{ 120 "default": []Permission{}, 121 }, 122 }, withError: ErrStructValidation, 123 }, 124 "missing NamespacePermissions": { 125 params: CreateEdgeKVAccessTokenRequest{ 126 AllowOnProduction: true, 127 AllowOnStaging: true, 128 Expiry: "2022-03-30", 129 Name: "devexp-token-1", 130 }, withError: ErrStructValidation, 131 }, 132 "400 bad request": { 133 params: CreateEdgeKVAccessTokenRequest{ 134 AllowOnProduction: true, 135 AllowOnStaging: true, 136 Expiry: "2022-03-30", 137 Name: "devexp-token-1", 138 NamespacePermissions: NamespacePermissions{ 139 "default": []Permission{"r", "w", "d"}, 140 }, 141 }, 142 responseStatus: http.StatusConflict, 143 responseBody: ` 144 { 145 "detail": "Invalid permission", 146 "errorCode": "EKV_2000", 147 "instance": "/edgeKV/error-instances/1f2a46ed-b6e8-4f50-b4db-102e260c1753", 148 "status": 400, 149 "title": "Bad Request", 150 "type": "https://learn.akamai.com", 151 "additionalDetail": { 152 "requestId": "f60f61cda34a0657" 153 } 154 }`, 155 expectedPath: "/edgekv/v1/tokens", 156 withError: &Error{ 157 Detail: "Invalid permission", 158 ErrorCode: "EKV_2000", 159 Instance: "/edgeKV/error-instances/1f2a46ed-b6e8-4f50-b4db-102e260c1753", 160 Status: 400, 161 Title: "Bad Request", 162 Type: "https://learn.akamai.com", 163 AdditionalDetail: Additional{ 164 RequestID: "f60f61cda34a0657", 165 }, 166 }, 167 }, 168 "401 Not authorized - incorrect credentials": { 169 params: CreateEdgeKVAccessTokenRequest{ 170 AllowOnProduction: true, 171 AllowOnStaging: true, 172 Expiry: "2022-03-30", 173 Name: "devexp-token-1", 174 NamespacePermissions: NamespacePermissions{ 175 "default": []Permission{"r", "w", "d"}, 176 "devexp-jsmith-test": []Permission{"r", "w"}, 177 }, 178 }, 179 responseStatus: http.StatusUnauthorized, 180 responseBody: ` 181 { 182 "type": "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 183 "title": "Not authorized", 184 "status": 401, 185 "detail": "Inactive client token", 186 "instance": "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens", 187 "method": "POST", 188 "serverIp": "104.81.220.242", 189 "clientIp": "22.22.22.22", 190 "requestId": "1e7f0f0f", 191 "requestTime": "2021-12-30T14:12:50Z" 192 }`, 193 expectedPath: "/edgekv/v1/tokens", 194 withError: &Error{ 195 Type: "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 196 Title: "Not authorized", 197 Status: 401, 198 Detail: "Inactive client token", 199 Instance: "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens", 200 Method: "POST", 201 ServerIP: "104.81.220.242", 202 ClientIP: "22.22.22.22", 203 RequestID: "1e7f0f0f", 204 RequestTime: "2021-12-30T14:12:50Z", 205 }, 206 }, 207 "409 duplicated token name": { 208 params: CreateEdgeKVAccessTokenRequest{ 209 AllowOnProduction: true, 210 AllowOnStaging: true, 211 Expiry: "2022-03-30", 212 Name: "devexp-token-1", 213 NamespacePermissions: NamespacePermissions{ 214 "default": []Permission{"r", "w", "d"}, 215 "devexp-jsmith-test": []Permission{"r", "w"}, 216 }, 217 }, 218 responseStatus: http.StatusConflict, 219 responseBody: ` 220 { 221 "detail": "Token with name devexp-token-1 is already stored.", 222 "errorCode": "EKV_3000", 223 "instance": "/edgeKV/error-instances/e82edcd9-498e-42f9-a078-6d9c4f9dbcb9", 224 "status": 409, 225 "title": "Conflict", 226 "type": "https://learn.akamai.com", 227 "additionalDetail": { 228 "requestId": "bc7561cda1f3021b" 229 } 230 }`, 231 expectedPath: "/edgekv/v1/tokens", 232 withError: &Error{ 233 Detail: "Token with name devexp-token-1 is already stored.", 234 ErrorCode: "EKV_3000", 235 Instance: "/edgeKV/error-instances/e82edcd9-498e-42f9-a078-6d9c4f9dbcb9", 236 Status: 409, 237 Title: "Conflict", 238 Type: "https://learn.akamai.com", 239 AdditionalDetail: Additional{ 240 RequestID: "bc7561cda1f3021b", 241 }, 242 }, 243 }, 244 "500 internal server error": { 245 params: CreateEdgeKVAccessTokenRequest{ 246 AllowOnProduction: true, 247 AllowOnStaging: true, 248 Expiry: "2022-03-30", 249 Name: "devexp-token-1", 250 NamespacePermissions: NamespacePermissions{ 251 "default": []Permission{"r", "w", "d"}, 252 "devexp-jsmith-test": []Permission{"r", "w"}, 253 }, 254 }, 255 responseStatus: http.StatusInternalServerError, 256 responseBody: ` 257 { 258 "detail": "An internal error occurred.", 259 "errorCode": "EKV_0000", 260 "instance": "/edgeKV/error-instances/e9bc19b5-ec1e-485d-80d0-20237a928684", 261 "status": 500, 262 "title": "Internal Server Error", 263 "type": "https://learn.akamai.com", 264 "additionalDetail": { 265 "requestId": "b2f461d47426558c" 266 } 267 }`, 268 expectedPath: "/edgekv/v1/tokens", 269 withError: &Error{ 270 Detail: "An internal error occurred.", 271 ErrorCode: "EKV_0000", 272 Instance: "/edgeKV/error-instances/e9bc19b5-ec1e-485d-80d0-20237a928684", 273 Status: 500, 274 Title: "Internal Server Error", 275 Type: "https://learn.akamai.com", 276 AdditionalDetail: Additional{ 277 RequestID: "b2f461d47426558c", 278 }, 279 }, 280 }, 281 } 282 for name, test := range tests { 283 t.Run(name, func(t *testing.T) { 284 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 285 assert.Equal(t, test.expectedPath, r.URL.String()) 286 assert.Equal(t, http.MethodPost, r.Method) 287 w.WriteHeader(test.responseStatus) 288 _, err := w.Write([]byte(test.responseBody)) 289 assert.NoError(t, err) 290 291 if len(test.expectedRequestBody) > 0 { 292 body, err := ioutil.ReadAll(r.Body) 293 require.NoError(t, err) 294 assert.Equal(t, test.expectedRequestBody, string(body)) 295 } 296 297 })) 298 client := mockAPIClient(t, mockServer) 299 result, err := client.CreateEdgeKVAccessToken(context.Background(), test.params) 300 if test.withError != nil { 301 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 302 return 303 } 304 require.NoError(t, err) 305 assert.Equal(t, test.expectedResponse, result) 306 }) 307 } 308 } 309 310 func TestGetEdgeKVAccessToken(t *testing.T) { 311 tests := map[string]struct { 312 params GetEdgeKVAccessTokenRequest 313 responseStatus int 314 responseBody string 315 expectedPath string 316 expectedResponse *GetEdgeKVAccessTokenResponse 317 withError error 318 }{ 319 "200 OK - get token": { 320 params: GetEdgeKVAccessTokenRequest{ 321 TokenName: "devexp-token-1", 322 }, 323 responseStatus: http.StatusOK, 324 responseBody: ` 325 { 326 "name": "devexp-token-1", 327 "uuid": "10b0e94b-c47e-568e-ab3e-1921ffcefe0c", 328 "expiry": "2022-03-30", 329 "value": "eyJ0eXAxOxJKV1QxLCJhbGciOiJSUzI1NiJ9.eyJld2lkcyI6ImFsbCIsInN1YiI6IjUwMCIsIm5hbWVzcGFjZS1kZWZhdWx0IjpbInIiLCJkIiwidyJdLCJjcGMiOiI5NzEwNTIiLCJpc3MiOiJha2FtYWkuY29tL0VkZ2VEQi9QdWxzYXIvdjAuMTEuMCIsIm5hbWVzcGFjZS1kZXZleHAtcm9iZXJ0by10ZXN0IjpbInIiLCJ3Il0sImV4cCI6MTY0ODY4NDc5OSwiZW52IjpbInAiLCJzIl0sImlhdCI6MTY0MDg1ODIzNywianRpIjoiMTBiMGU5NGItYzQ3ZS01NjhlLWFiM2UtMTkyMWZmY2VmZTBjIiwicmVxaWQiOiJha2FtYWkiLCJub2VjbCI6dHJ1ZX0.AZfP-VFqDKNWcu1Or73EFfjG_GBDdJUP81Zs0BnNs_bScc8oyBAEiBjxwEsUxrvRRr7rSu-BxFjiDpxx5DlfbgEwd8H2DFV08cfQFqs7aab4WYLrx4ZweD9Hbg2gGLA-dRAbtSrq_FQKQysOvO2ymPn13E78PvK96t8r4cnN1irXbfyBUOXOE3OVOAKsk-w0Ig7qFDa_4o6YyDMPTpwEQ34T1cVqRYStIVzjSaCwgSfdaQG5qzTzTlFoDzG24tz8YlLgoM5OQf9xgsTsisCOF2jf44VWMu2S0e6MIC5gg7zXx7X2t59Y8TsAd0VqqB37y0AzEXkJblbZUlO9HcGebg" 330 }`, 331 expectedPath: "/edgekv/v1/tokens/devexp-token-1", 332 expectedResponse: &GetEdgeKVAccessTokenResponse{ 333 Name: "devexp-token-1", 334 UUID: "10b0e94b-c47e-568e-ab3e-1921ffcefe0c", 335 Expiry: "2022-03-30", 336 Value: "eyJ0eXAxOxJKV1QxLCJhbGciOiJSUzI1NiJ9.eyJld2lkcyI6ImFsbCIsInN1YiI6IjUwMCIsIm5hbWVzcGFjZS1kZWZhdWx0IjpbInIiLCJkIiwidyJdLCJjcGMiOiI5NzEwNTIiLCJpc3MiOiJha2FtYWkuY29tL0VkZ2VEQi9QdWxzYXIvdjAuMTEuMCIsIm5hbWVzcGFjZS1kZXZleHAtcm9iZXJ0by10ZXN0IjpbInIiLCJ3Il0sImV4cCI6MTY0ODY4NDc5OSwiZW52IjpbInAiLCJzIl0sImlhdCI6MTY0MDg1ODIzNywianRpIjoiMTBiMGU5NGItYzQ3ZS01NjhlLWFiM2UtMTkyMWZmY2VmZTBjIiwicmVxaWQiOiJha2FtYWkiLCJub2VjbCI6dHJ1ZX0.AZfP-VFqDKNWcu1Or73EFfjG_GBDdJUP81Zs0BnNs_bScc8oyBAEiBjxwEsUxrvRRr7rSu-BxFjiDpxx5DlfbgEwd8H2DFV08cfQFqs7aab4WYLrx4ZweD9Hbg2gGLA-dRAbtSrq_FQKQysOvO2ymPn13E78PvK96t8r4cnN1irXbfyBUOXOE3OVOAKsk-w0Ig7qFDa_4o6YyDMPTpwEQ34T1cVqRYStIVzjSaCwgSfdaQG5qzTzTlFoDzG24tz8YlLgoM5OQf9xgsTsisCOF2jf44VWMu2S0e6MIC5gg7zXx7X2t59Y8TsAd0VqqB37y0AzEXkJblbZUlO9HcGebg", 337 }, 338 }, 339 "missing token name": { 340 params: GetEdgeKVAccessTokenRequest{}, 341 withError: ErrStructValidation, 342 }, 343 "403 Forbidden - incorrect credentials": { 344 params: GetEdgeKVAccessTokenRequest{ 345 TokenName: "devexp-token-1", 346 }, 347 responseStatus: http.StatusForbidden, 348 responseBody: ` 349 { 350 "type": "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 351 "title": "Not authorized", 352 "status": 401, 353 "detail": "Inactive client token", 354 "instance": "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens/devexp-token-99", 355 "method": "GET", 356 "serverIp": "104.81.220.242", 357 "clientIp": "22.22.22.22", 358 "requestId": "cb5cd20", 359 "requestTime": "2022-01-03T07:46:28Z" 360 }`, 361 expectedPath: "/edgekv/v1/tokens/devexp-token-1", 362 withError: &Error{ 363 Type: "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 364 Title: "Not authorized", 365 Status: 401, 366 Detail: "Inactive client token", 367 Instance: "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens/devexp-token-99", 368 Method: "GET", 369 ServerIP: "104.81.220.242", 370 ClientIP: "22.22.22.22", 371 RequestID: "cb5cd20", 372 RequestTime: "2022-01-03T07:46:28Z", 373 }, 374 }, 375 "404 Not Found - Token doesn't exist": { 376 params: GetEdgeKVAccessTokenRequest{ 377 TokenName: "devexp-token-99", 378 }, 379 responseStatus: http.StatusNotFound, 380 responseBody: ` 381 { 382 "detail": "Token with name devexp-token-99 does not exist.", 383 "errorCode": "EKV_3000", 384 "instance": "/edgeKV/error-instances/add4ab5a-48b0-4350-aa8b-7f64e9b6a5ea", 385 "status": 404, 386 "title": "Not Found", 387 "type": "https://learn.akamai.com", 388 "additionalDetail": { 389 "requestId": "ae9061cddea87d94" 390 } 391 }`, 392 expectedPath: "/edgekv/v1/tokens/devexp-token-99", 393 withError: &Error{ 394 Detail: "Token with name devexp-token-99 does not exist.", 395 ErrorCode: "EKV_3000", 396 Instance: "/edgeKV/error-instances/add4ab5a-48b0-4350-aa8b-7f64e9b6a5ea", 397 Status: 404, 398 Title: "Not Found", 399 Type: "https://learn.akamai.com", 400 AdditionalDetail: Additional{ 401 RequestID: "ae9061cddea87d94", 402 }, 403 }, 404 }, 405 "500 Internal server error": { 406 params: GetEdgeKVAccessTokenRequest{ 407 TokenName: ";", 408 }, 409 responseStatus: http.StatusInternalServerError, 410 responseBody: ` 411 { 412 "type": "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 413 "title": "Server Error", 414 "status": 500, 415 "instance": "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 416 "method": "GET", 417 "serverIp": "104.81.220.242", 418 "clientIp": "22.22.22.22", 419 "requestId": "e98b01a", 420 "requestTime": "2022-01-03T11:13:00Z" 421 }`, 422 expectedPath: "/edgekv/v1/tokens/;", 423 withError: &Error{ 424 Type: "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 425 Title: "Server Error", 426 Status: 500, 427 Instance: "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 428 Method: "GET", 429 ServerIP: "104.81.220.242", 430 ClientIP: "22.22.22.22", 431 RequestID: "e98b01a", 432 RequestTime: "2022-01-03T11:13:00Z", 433 }, 434 }, 435 } 436 437 for name, test := range tests { 438 t.Run(name, func(t *testing.T) { 439 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 440 assert.Equal(t, test.expectedPath, r.URL.String()) 441 assert.Equal(t, http.MethodGet, r.Method) 442 w.WriteHeader(test.responseStatus) 443 _, err := w.Write([]byte(test.responseBody)) 444 assert.NoError(t, err) 445 })) 446 client := mockAPIClient(t, mockServer) 447 result, err := client.GetEdgeKVAccessToken(context.Background(), test.params) 448 if test.withError != nil { 449 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 450 return 451 } 452 require.NoError(t, err) 453 assert.Equal(t, test.expectedResponse, result) 454 }) 455 } 456 } 457 458 func TestListEdgeKVAccessTokens(t *testing.T) { 459 tests := map[string]struct { 460 params ListEdgeKVAccessTokensRequest 461 responseStatus int 462 responseBody string 463 expectedPath string 464 expectedResponse *ListEdgeKVAccessTokensResponse 465 withError error 466 }{ 467 "200 OK - list EdgeKV tokens": { 468 responseStatus: http.StatusOK, 469 responseBody: ` 470 { 471 "tokens": [ 472 { 473 "name": "my_token", 474 "uuid": "8301fef4-80e5-5efb-9bfb-8f5869a5df7b", 475 "expiry": "2022-03-30" 476 }, 477 { 478 "name": "token1", 479 "uuid": "5b5d3bfb-8d2e-5fbb-858d-33807edc9554", 480 "expiry": "2022-01-22" 481 }, 482 { 483 "name": "token2", 484 "uuid": "62181cfe-268a-5302-8834-67c67ec86efd", 485 "expiry": "2022-01-22" 486 }, 487 { 488 "name": "token3", 489 "uuid": "edb02678-ae1c-564c-8f73-c977ffdfe016", 490 "expiry": "2022-01-22" 491 } 492 ] 493 }`, 494 expectedPath: "/edgekv/v1/tokens", 495 expectedResponse: &ListEdgeKVAccessTokensResponse{ 496 []EdgeKVAccessToken{ 497 { 498 Name: "my_token", 499 UUID: "8301fef4-80e5-5efb-9bfb-8f5869a5df7b", 500 Expiry: "2022-03-30", 501 }, 502 { 503 Name: "token1", 504 UUID: "5b5d3bfb-8d2e-5fbb-858d-33807edc9554", 505 Expiry: "2022-01-22", 506 }, 507 { 508 Name: "token2", 509 UUID: "62181cfe-268a-5302-8834-67c67ec86efd", 510 Expiry: "2022-01-22", 511 }, 512 { 513 Name: "token3", 514 UUID: "edb02678-ae1c-564c-8f73-c977ffdfe016", 515 Expiry: "2022-01-22", 516 }, 517 }, 518 }, 519 }, 520 "200 OK - list EdgeKV tokens including expired": { 521 params: ListEdgeKVAccessTokensRequest{ 522 IncludeExpired: true, 523 }, 524 responseStatus: http.StatusOK, 525 responseBody: ` 526 { 527 "tokens": [ 528 { 529 "name": "my_token", 530 "uuid": "8301fef4-80e5-5efb-9bfb-8f5869a5df7b", 531 "expiry": "2022-03-30" 532 }, 533 { 534 "name": "token1", 535 "uuid": "5b5d3bfb-8d2e-5fbb-858d-33807edc9554", 536 "expiry": "2022-01-22" 537 }, 538 { 539 "name": "token2", 540 "uuid": "62181cfe-268a-5302-8834-67c67ec86efd", 541 "expiry": "2022-01-22" 542 }, 543 { 544 "name": "token3", 545 "uuid": "edb02678-ae1c-564c-8f73-c977ffdfe016", 546 "expiry": "2022-01-22" 547 }, 548 { 549 "name": "preexistingTokenTest", 550 "uuid": "7a14da8c-1709-570b-9535-2cc6e2ee5a8a", 551 "expiry": "2021-12-21" 552 } 553 ] 554 }`, 555 expectedPath: "/edgekv/v1/tokens?includeExpired=true", 556 expectedResponse: &ListEdgeKVAccessTokensResponse{ 557 []EdgeKVAccessToken{ 558 { 559 Name: "my_token", 560 UUID: "8301fef4-80e5-5efb-9bfb-8f5869a5df7b", 561 Expiry: "2022-03-30", 562 }, 563 { 564 Name: "token1", 565 UUID: "5b5d3bfb-8d2e-5fbb-858d-33807edc9554", 566 Expiry: "2022-01-22", 567 }, 568 { 569 Name: "token2", 570 UUID: "62181cfe-268a-5302-8834-67c67ec86efd", 571 Expiry: "2022-01-22", 572 }, 573 { 574 Name: "token3", 575 UUID: "edb02678-ae1c-564c-8f73-c977ffdfe016", 576 Expiry: "2022-01-22", 577 }, 578 { 579 Name: "preexistingTokenTest", 580 UUID: "7a14da8c-1709-570b-9535-2cc6e2ee5a8a", 581 Expiry: "2021-12-21", 582 }, 583 }, 584 }, 585 }, 586 "401 Forbidden - incorrect credentials": { 587 responseStatus: http.StatusForbidden, 588 responseBody: ` 589 { 590 "type": "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 591 "title": "Not authorized", 592 "status": 401, 593 "detail": "Inactive client token", 594 "instance": "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens", 595 "method": "GET", 596 "serverIp": "104.81.220.242", 597 "clientIp": "22.22.22.22", 598 "requestId": "d64edd6", 599 "requestTime": "2022-01-03T09:01:30Z" 600 }`, 601 expectedPath: "/edgekv/v1/tokens", 602 withError: &Error{ 603 Type: "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 604 Title: "Not authorized", 605 Status: 401, 606 Detail: "Inactive client token", 607 Instance: "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens", 608 Method: "GET", 609 ServerIP: "104.81.220.242", 610 ClientIP: "22.22.22.22", 611 RequestID: "d64edd6", 612 RequestTime: "2022-01-03T09:01:30Z", 613 }, 614 }, 615 "500 internal server error": { 616 responseStatus: http.StatusInternalServerError, 617 responseBody: ` 618 { 619 "type": "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 620 "title": "Server Error", 621 "status": 500, 622 "instance": "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 623 "method": "GET", 624 "serverIp": "104.81.220.242", 625 "clientIp": "22.22.22.22", 626 "requestId": "e98b01a", 627 "requestTime": "2022-01-03T11:13:00Z" 628 }`, 629 expectedPath: "/edgekv/v1/tokens", 630 withError: &Error{ 631 Type: "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 632 Title: "Server Error", 633 Status: 500, 634 Instance: "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 635 Method: "GET", 636 ServerIP: "104.81.220.242", 637 ClientIP: "22.22.22.22", 638 RequestID: "e98b01a", 639 RequestTime: "2022-01-03T11:13:00Z", 640 }, 641 }, 642 } 643 for name, test := range tests { 644 t.Run(name, func(t *testing.T) { 645 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 646 assert.Equal(t, test.expectedPath, r.URL.String()) 647 assert.Equal(t, http.MethodGet, r.Method) 648 w.WriteHeader(test.responseStatus) 649 _, err := w.Write([]byte(test.responseBody)) 650 assert.NoError(t, err) 651 })) 652 client := mockAPIClient(t, mockServer) 653 result, err := client.ListEdgeKVAccessTokens(context.Background(), test.params) 654 if test.withError != nil { 655 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 656 return 657 } 658 require.NoError(t, err) 659 assert.Equal(t, test.expectedResponse, result) 660 }) 661 } 662 } 663 664 func TestDeleteEdgeKVAccessToken(t *testing.T) { 665 tests := map[string]struct { 666 params DeleteEdgeKVAccessTokenRequest 667 withError error 668 expectedPath string 669 responseStatus int 670 responseBody string 671 expectedResponse *DeleteEdgeKVAccessTokenResponse 672 }{ 673 "200 Deleted": { 674 params: DeleteEdgeKVAccessTokenRequest{ 675 TokenName: "devexp-token-3", 676 }, 677 expectedPath: "/edgekv/v1/tokens/devexp-token-3", 678 responseBody: ` 679 { 680 "name": "devexp-token-3", 681 "uuid": "cc0a9045-e654-5f17-9b37-6ab6e565803f" 682 }`, 683 expectedResponse: &DeleteEdgeKVAccessTokenResponse{ 684 Name: "devexp-token-3", 685 UUID: "cc0a9045-e654-5f17-9b37-6ab6e565803f", 686 }, 687 responseStatus: http.StatusOK, 688 }, 689 "missing token name": { 690 params: DeleteEdgeKVAccessTokenRequest{ 691 TokenName: "", 692 }, 693 withError: ErrStructValidation, 694 }, 695 "401 not authorized": { 696 responseStatus: http.StatusUnauthorized, 697 params: DeleteEdgeKVAccessTokenRequest{ 698 TokenName: "devexp-token-99", 699 }, 700 expectedPath: "/edgekv/v1/tokens/devexp-token-99", 701 responseBody: `{ 702 "type": "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 703 "title": "Not authorized", 704 "status": 401, 705 "detail": "Inactive client token", 706 "instance": "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens/devexp-token-3", 707 "method": "DELETE", 708 "serverIp": "104.81.220.242", 709 "clientIp": "22.22.22.22", 710 "requestId": "ddc683c", 711 "requestTime": "2022-01-03T09:51:55Z" 712 }`, 713 withError: &Error{ 714 Type: "https://problems.luna-dev.akamaiapis.net/-/pep-authn/deny", 715 Title: "Not authorized", 716 Status: 401, 717 Detail: "Inactive client token", 718 Instance: "https://akaa-p3wvjp6bqtotgpjh-fbk2vczjtq7b5l6a.luna-dev.akamaiapis.net/edgekv/v1/tokens/devexp-token-3", 719 Method: "DELETE", 720 ServerIP: "104.81.220.242", 721 ClientIP: "22.22.22.22", 722 RequestID: "ddc683c", 723 RequestTime: "2022-01-03T09:51:55Z", 724 }, 725 }, 726 "404 Not Found": { 727 params: DeleteEdgeKVAccessTokenRequest{ 728 TokenName: "devexp-token-99", 729 }, 730 expectedPath: "/edgekv/v1/tokens/devexp-token-99", 731 responseStatus: http.StatusNotFound, 732 responseBody: ` 733 { 734 "detail": "Token with name devexp-token-99 does not exist.", 735 "errorCode": "EKV_3000", 736 "instance": "/edgeKV/error-instances/d4d7171f-2ef9-4e60-96ba-1ad74e35bb39", 737 "status": 404, 738 "title": "Not Found", 739 "type": "https://learn.akamai.com", 740 "additionalDetail": { 741 "requestId": "a46f61d2c9539c77" 742 } 743 }`, 744 withError: &Error{ 745 Detail: "Token with name devexp-token-99 does not exist.", 746 ErrorCode: "EKV_3000", 747 Instance: "/edgeKV/error-instances/d4d7171f-2ef9-4e60-96ba-1ad74e35bb39", 748 Status: 404, 749 Title: "Not Found", 750 Type: "https://learn.akamai.com", 751 AdditionalDetail: Additional{ 752 RequestID: "a46f61d2c9539c77", 753 }, 754 }, 755 }, 756 "500 internal server error": { 757 params: DeleteEdgeKVAccessTokenRequest{ 758 TokenName: ";", 759 }, 760 responseStatus: http.StatusInternalServerError, 761 responseBody: ` 762 { 763 "type": "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 764 "title": "Server Error", 765 "status": 500, 766 "instance": "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 767 "method": "DELETE", 768 "serverIp": "104.81.220.242", 769 "clientIp": "22.22.22.22", 770 "requestId": "e6f4e86", 771 "requestTime": "2022-01-03T10:55:00Z" 772 }`, 773 expectedPath: "/edgekv/v1/tokens/;", 774 withError: &Error{ 775 Type: "https://problems.luna-dev.akamaiapis.net/-/resource-impl/forward-origin-error", 776 Title: "Server Error", 777 Status: 500, 778 Instance: "https://akaa-7udtftgmvpnmsbwx-noxd5uwfehzxv4rj.luna-dev.akamaiapis.net/edgekv/v1/tokens/;", 779 Method: "DELETE", 780 ServerIP: "104.81.220.242", 781 ClientIP: "22.22.22.22", 782 RequestID: "e6f4e86", 783 RequestTime: "2022-01-03T10:55:00Z", 784 }, 785 }, 786 } 787 for name, test := range tests { 788 t.Run(name, func(t *testing.T) { 789 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 790 assert.Equal(t, test.expectedPath, r.URL.String()) 791 assert.Equal(t, http.MethodDelete, r.Method) 792 w.WriteHeader(test.responseStatus) 793 _, err := w.Write([]byte(test.responseBody)) 794 assert.NoError(t, err) 795 })) 796 client := mockAPIClient(t, mockServer) 797 _, err := client.DeleteEdgeKVAccessToken(context.Background(), test.params) 798 if test.withError != nil { 799 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 800 if test.responseStatus != 0 { 801 assert.Contains(t, err.Error(), strconv.FormatInt(int64(test.responseStatus), 10)) 802 } 803 804 return 805 } 806 require.NoError(t, err) 807 }) 808 } 809 }