github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/ias/client_test.go (about) 1 package ias 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "strings" 11 "testing" 12 13 "github.com/gorilla/mux" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 const ( 18 companyID = "sandbox" 19 serviceProviderID = "5e8c5e9e5f25d83ebec7e89e" 20 clientID = "42" 21 clientSecret = "floda" 22 userForRest = "22b13c44-a1ae-41a5-b549-0649c4a5bd25" 23 ) 24 25 func TestClient_GetCompany(t *testing.T) { 26 // given 27 server := fixHTTPServer(t) 28 defer server.Close() 29 30 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 31 32 // when 33 company, err := client.GetCompany() 34 35 // then 36 assert.NoError(t, err) 37 assert.Len(t, company.ServiceProviders, 1) 38 assert.Len(t, company.IdentityProviders, 1) 39 } 40 41 func TestClient_CreateServiceProvider(t *testing.T) { 42 // given 43 server := fixHTTPServer(t) 44 defer server.Close() 45 46 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 47 48 // when 49 err := client.CreateServiceProvider("someName", companyID) 50 51 // then 52 assert.NoError(t, err) 53 54 response, err := server.Client().Get(fmt.Sprintf("%s/getSP", server.URL)) 55 assert.NoError(t, err) 56 57 body, err := ioutil.ReadAll(response.Body) 58 assert.NoError(t, err) 59 assert.Equal(t, "someName", string(body)) 60 } 61 62 func TestClient_SetOIDCConfiguration(t *testing.T) { 63 // given 64 server := fixHTTPServer(t) 65 defer server.Close() 66 67 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 68 69 // when 70 iasType := OIDCType{ 71 SsoType: "openID", 72 ServiceProviderName: "example.com", 73 OpenIDConnectConfig: OpenIDConnectConfig{ 74 RedirectURIs: []string{"https://example.com"}, 75 PostLogoutRedirectURIs: nil, 76 }, 77 } 78 err := client.SetOIDCConfiguration(serviceProviderID, iasType) 79 80 // then 81 assert.NoError(t, err) 82 83 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 84 assert.NoError(t, err) 85 86 var conf OIDCType 87 err = json.NewDecoder(response.Body).Decode(&conf) 88 assert.NoError(t, err) 89 90 assert.Equal(t, "openID", conf.SsoType) 91 assert.Equal(t, "example.com", conf.ServiceProviderName) 92 assert.Equal(t, "https://example.com", conf.OpenIDConnectConfig.RedirectURIs[0]) 93 } 94 95 func TestClient_SetSAMLConfiguration(t *testing.T) { 96 // given 97 server := fixHTTPServer(t) 98 defer server.Close() 99 100 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 101 102 // when 103 iasType := SAMLType{ 104 ServiceProviderName: "example.com", 105 ACSEndpoints: []ACSEndpoint{ 106 { 107 Location: "https://example.com", 108 Index: 0, 109 IsDefault: true, 110 }, 111 }, 112 } 113 err := client.SetSAMLConfiguration(serviceProviderID, iasType) 114 115 // then 116 assert.NoError(t, err) 117 118 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 119 assert.NoError(t, err) 120 121 var conf SAMLType 122 err = json.NewDecoder(response.Body).Decode(&conf) 123 assert.NoError(t, err) 124 125 assert.Equal(t, "example.com", conf.ServiceProviderName) 126 assert.Equal(t, "https://example.com", conf.ACSEndpoints[0].Location) 127 assert.Equal(t, int32(0), conf.ACSEndpoints[0].Index) 128 assert.Equal(t, true, conf.ACSEndpoints[0].IsDefault) 129 } 130 131 func TestClient_SetAssertionAttribute(t *testing.T) { 132 // given 133 server := fixHTTPServer(t) 134 defer server.Close() 135 136 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 137 138 // when 139 attributes := PostAssertionAttributes{ 140 AssertionAttributes: []AssertionAttribute{ 141 { 142 AssertionAttribute: "first_name", 143 UserAttribute: "firstName", 144 }, 145 }, 146 } 147 err := client.SetAssertionAttribute(serviceProviderID, attributes) 148 149 // then 150 assert.NoError(t, err) 151 152 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 153 assert.NoError(t, err) 154 155 var conf PostAssertionAttributes 156 err = json.NewDecoder(response.Body).Decode(&conf) 157 assert.NoError(t, err) 158 159 assert.Equal(t, "first_name", conf.AssertionAttributes[0].AssertionAttribute) 160 assert.Equal(t, "firstName", conf.AssertionAttributes[0].UserAttribute) 161 } 162 163 func TestClient_SetSubjectNameIdentifier(t *testing.T) { 164 // given 165 server := fixHTTPServer(t) 166 defer server.Close() 167 168 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 169 170 // when 171 sni := SubjectNameIdentifier{ 172 NameIDAttribute: "email", 173 } 174 err := client.SetSubjectNameIdentifier(serviceProviderID, sni) 175 176 // then 177 assert.NoError(t, err) 178 179 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 180 assert.NoError(t, err) 181 182 var conf SubjectNameIdentifier 183 err = json.NewDecoder(response.Body).Decode(&conf) 184 assert.NoError(t, err) 185 186 assert.Equal(t, "email", conf.NameIDAttribute) 187 } 188 189 func TestClient_SetAuthenticationAndAccess(t *testing.T) { 190 // given 191 server := fixHTTPServer(t) 192 defer server.Close() 193 194 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 195 196 // when 197 auth := AuthenticationAndAccess{ 198 ServiceProviderAccess: ServiceProviderAccess{ 199 RBAConfig: RBAConfig{ 200 RBARules: []RBARules{ 201 { 202 Action: "Allow", 203 Group: "admins", 204 GroupType: "cloud", 205 }, 206 }, 207 DefaultAction: "Allow", 208 }, 209 }, 210 } 211 err := client.SetAuthenticationAndAccess(serviceProviderID, auth) 212 213 // then 214 assert.NoError(t, err) 215 216 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 217 assert.NoError(t, err) 218 219 var conf AuthenticationAndAccess 220 err = json.NewDecoder(response.Body).Decode(&conf) 221 assert.NoError(t, err) 222 223 assert.Equal(t, "Allow", conf.ServiceProviderAccess.RBAConfig.DefaultAction) 224 assert.Equal(t, "Allow", conf.ServiceProviderAccess.RBAConfig.RBARules[0].Action) 225 assert.Equal(t, "admins", conf.ServiceProviderAccess.RBAConfig.RBARules[0].Group) 226 assert.Equal(t, "cloud", conf.ServiceProviderAccess.RBAConfig.RBARules[0].GroupType) 227 } 228 229 func TestClient_SetDefaultAuthenticatingIDP(t *testing.T) { 230 // given 231 server := fixHTTPServer(t) 232 defer server.Close() 233 234 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 235 236 // when 237 authIDP := DefaultAuthIDPConfig{ 238 Organization: companyID, 239 ID: serviceProviderID, 240 DefaultAuthIDP: "http://example.com", 241 } 242 err := client.SetDefaultAuthenticatingIDP(authIDP) 243 244 // then 245 assert.NoError(t, err) 246 response, err := server.Client().Get(fmt.Sprintf("%s/get", server.URL)) 247 assert.NoError(t, err) 248 249 var conf DefaultAuthIDPConfig 250 err = json.NewDecoder(response.Body).Decode(&conf) 251 assert.NoError(t, err) 252 253 assert.Equal(t, companyID, conf.Organization) 254 assert.Equal(t, serviceProviderID, conf.ID) 255 assert.Equal(t, "http://example.com", conf.DefaultAuthIDP) 256 } 257 258 func TestClient_GenerateServiceProviderSecret(t *testing.T) { 259 // given 260 server := fixHTTPServer(t) 261 defer server.Close() 262 263 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 264 265 // when 266 sc := SecretConfiguration{ 267 Organization: companyID, 268 ID: serviceProviderID, 269 RestAPIClientSecret: RestAPIClientSecret{ 270 Description: "test", 271 Scopes: []string{"OAuth"}, 272 }, 273 } 274 secret, err := client.GenerateServiceProviderSecret(sc) 275 276 // then 277 assert.NoError(t, err) 278 assert.Equal(t, clientID, secret.ClientID) 279 assert.Equal(t, clientSecret, secret.ClientSecret) 280 } 281 282 func TestClient_DeleteServiceProvider(t *testing.T) { 283 // given 284 server := fixHTTPServer(t) 285 defer server.Close() 286 287 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 288 289 err := client.CreateServiceProvider(serviceProviderID, companyID) 290 assert.NoError(t, err) 291 292 // when 293 err = client.DeleteServiceProvider(serviceProviderID) 294 295 // then 296 assert.NoError(t, err) 297 298 response, err := server.Client().Get(fmt.Sprintf("%s/getSP", server.URL)) 299 assert.NoError(t, err) 300 301 body, err := ioutil.ReadAll(response.Body) 302 assert.NoError(t, err) 303 assert.Equal(t, "", string(body)) 304 305 // when 306 err = client.DeleteServiceProvider(serviceProviderID) 307 308 // then 309 assert.NoError(t, err) 310 } 311 312 func TestClient_DeleteSecret(t *testing.T) { 313 // given 314 server := fixHTTPServer(t) 315 defer server.Close() 316 317 client := NewClient(server.Client(), ClientConfig{URL: server.URL, ID: "admin", Secret: "admin123"}) 318 319 for i := 0; i < 3; i++ { 320 sc := SecretConfiguration{ 321 Organization: companyID, 322 ID: serviceProviderID, 323 RestAPIClientSecret: RestAPIClientSecret{ 324 Description: "test", 325 Scopes: []string{"OAuth"}, 326 }, 327 } 328 _, err := client.GenerateServiceProviderSecret(sc) 329 assert.NoError(t, err) 330 } 331 332 // when 333 err := client.DeleteSecret(SecretsRef{ 334 ClientID: userForRest, 335 ClientSecretsIDs: []string{fmt.Sprintf("%s-next", clientID)}, 336 }) 337 338 // then 339 assert.NoError(t, err) 340 341 response, err := server.Client().Get(fmt.Sprintf("%s/getS", server.URL)) 342 assert.NoError(t, err) 343 344 var secrets []ServiceProviderSecret 345 err = json.NewDecoder(response.Body).Decode(&secrets) 346 assert.NoError(t, err) 347 348 assert.Len(t, secrets, 2) 349 } 350 351 var companies = `{ 352 "company_id" : "global", 353 "default_sso_domain" : "https://sandbox.accounts400.ondemand.com/service/idp/5e46ar7cc92eec206b93893b", 354 "service_providers" : [{ 355 "id" : "50c1bb7ce4b01ab0481c49a3", 356 "name" : "oac.accounts.sap.com", 357 "group" : "system", 358 "uri" : "https://sandbox.accounts400.ondemand.com/service/sps/50c1bb7ce5b01av0481c49a3", 359 "active_users" : "-1", 360 "self_registration" : "allowed", 361 "company_id" : "global" 362 }], 363 "certificates_counter_exceeded" : false, 364 "identity_providers" : [{ 365 "id" : "5e46ad8cc92edc106b93893b", 366 "display_name" : "SAP Cloud Platform Identity Authentication", 367 "name" : "https://sandbox.accounts400.ondemand.com", 368 "uri" : "https://sandbox.accounts400.ondemand.com/service/idp/5e46ad7cc92eec106b93893b", 369 "alias" : "sandbox" 370 }] 371 }` 372 373 type server struct { 374 t *testing.T 375 376 serviceProvider []byte 377 configuration []byte 378 secrets []ServiceProviderSecret 379 } 380 381 func fixHTTPServer(t *testing.T) *httptest.Server { 382 s := server{t: t} 383 384 r := mux.NewRouter() 385 r.HandleFunc("/service/company/global", s.authorized(s.companies)).Methods(http.MethodGet) 386 r.HandleFunc("/service/sps", s.authorized(s.createSP)).Methods(http.MethodPost) 387 r.HandleFunc("/service/sps", s.authorized(s.configureSPBody)).Methods(http.MethodPut) 388 r.HandleFunc("/service/sps/delete", s.authorized(s.deleteSP)).Methods(http.MethodPut) 389 r.HandleFunc("/service/sps/{spID}", s.authorized(s.configureSP)).Methods(http.MethodPut) 390 r.HandleFunc("/service/sps/{spID}/rba", s.authorized(s.configureSP)).Methods(http.MethodPut) 391 r.HandleFunc("/service/sps/clientSecret", s.authorized(s.deleteSecrets)).Methods(http.MethodDelete) 392 393 r.HandleFunc("/getSP", s.getServiceProvider).Methods(http.MethodGet) 394 r.HandleFunc("/getS", s.getSecrets).Methods(http.MethodGet) 395 r.HandleFunc("/get", s.getConfiguration).Methods(http.MethodGet) 396 397 return httptest.NewServer(r) 398 } 399 400 func (s *server) authorized(pass func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) { 401 return func(w http.ResponseWriter, r *http.Request) { 402 auth := strings.SplitN(r.Header.Get("Authorization"), " ", 2) 403 404 if len(auth) != 2 || auth[0] != "Basic" { 405 w.WriteHeader(http.StatusUnauthorized) 406 return 407 } 408 409 payload, _ := base64.StdEncoding.DecodeString(auth[1]) 410 pair := strings.SplitN(string(payload), ":", 2) 411 412 if len(pair) != 2 || !(pair[0] == "admin" && pair[1] == "admin123") { 413 w.WriteHeader(http.StatusUnauthorized) 414 return 415 } 416 pass(w, r) 417 } 418 } 419 420 func (s *server) companies(w http.ResponseWriter, _ *http.Request) { 421 _, err := w.Write([]byte(companies)) 422 if err != nil { 423 s.t.Errorf("test server cannot write response body: %s", err) 424 w.WriteHeader(http.StatusInternalServerError) 425 return 426 } 427 w.WriteHeader(http.StatusOK) 428 } 429 430 func (s *server) createSP(w http.ResponseWriter, r *http.Request) { 431 if err := r.ParseForm(); err != nil { 432 s.t.Errorf("cannot parse form: %s", err) 433 return 434 } 435 if r.FormValue("company_id") != companyID { 436 w.WriteHeader(http.StatusForbidden) 437 } 438 439 s.serviceProvider = []byte(r.FormValue("sp_name")) 440 w.WriteHeader(http.StatusCreated) 441 } 442 443 func (s *server) configureSP(w http.ResponseWriter, r *http.Request) { 444 val, ok := mux.Vars(r)["spID"] 445 if !ok { 446 w.WriteHeader(http.StatusNotFound) 447 return 448 } 449 if val != serviceProviderID { 450 w.WriteHeader(http.StatusNotFound) 451 return 452 } 453 454 body, err := ioutil.ReadAll(r.Body) 455 if err != nil { 456 w.WriteHeader(http.StatusBadRequest) 457 s.t.Errorf("test server cannot read request body: %s", err) 458 return 459 } 460 461 s.configuration = body 462 w.WriteHeader(http.StatusOK) 463 } 464 465 func (s *server) configureSPBody(w http.ResponseWriter, r *http.Request) { 466 var sc SecretConfiguration 467 var authIDP DefaultAuthIDPConfig 468 body, err := ioutil.ReadAll(r.Body) 469 if err != nil { 470 w.WriteHeader(http.StatusInternalServerError) 471 s.t.Errorf("test server cannot read request body: %s", err) 472 return 473 } 474 475 err = json.Unmarshal(body, &authIDP) 476 err2 := json.Unmarshal(body, &sc) 477 if err != nil || err2 != nil { 478 w.WriteHeader(http.StatusInternalServerError) 479 s.t.Errorf("test server cannot unmarshal request body: (%s;%s)", err, err2) 480 return 481 } 482 483 if authIDP.ID != serviceProviderID || authIDP.Organization != companyID { 484 w.WriteHeader(http.StatusNotFound) 485 return 486 } 487 488 if authIDP.DefaultAuthIDP != "" { 489 s.configuration = body 490 w.WriteHeader(http.StatusOK) 491 } else if sc.RestAPIClientSecret.Description != "" { 492 493 secret := ServiceProviderSecret{ 494 ClientID: s.generateSecretID(), 495 ClientSecret: clientSecret, 496 } 497 rawSecret, err := json.Marshal(secret) 498 if err != nil { 499 w.WriteHeader(http.StatusInternalServerError) 500 s.t.Errorf("test server cannot marshal secret struct: %s", err) 501 return 502 } 503 s.secrets = append(s.secrets, secret) 504 505 w.WriteHeader(http.StatusOK) 506 _, err = w.Write(rawSecret) 507 508 if err != nil { 509 w.WriteHeader(http.StatusInternalServerError) 510 s.t.Errorf("test server cannot write response body: %s", err) 511 return 512 } 513 } 514 } 515 516 func (s *server) generateSecretID() string { 517 if len(s.secrets) == 0 { 518 return clientID 519 } 520 return fmt.Sprintf("%s-next", s.secrets[len(s.secrets)-1].ClientID) 521 } 522 523 func (s *server) deleteSP(w http.ResponseWriter, r *http.Request) { 524 keys, ok := r.URL.Query()["sp_id"] 525 if !ok { 526 w.WriteHeader(http.StatusNotFound) 527 return 528 } 529 if keys[0] != serviceProviderID { 530 w.WriteHeader(http.StatusNotFound) 531 return 532 } 533 if string(s.serviceProvider) != serviceProviderID { 534 w.WriteHeader(http.StatusNotFound) 535 return 536 } 537 538 s.serviceProvider = []byte{} 539 w.WriteHeader(http.StatusOK) 540 } 541 542 func (s *server) deleteSecrets(w http.ResponseWriter, r *http.Request) { 543 var secretsRef SecretsRef 544 err := json.NewDecoder(r.Body).Decode(&secretsRef) 545 if err != nil { 546 w.WriteHeader(http.StatusInternalServerError) 547 s.t.Errorf("test server cannot decode request body: %s", err) 548 return 549 } 550 551 if secretsRef.ClientID != userForRest { 552 w.WriteHeader(http.StatusBadRequest) 553 return 554 } 555 556 for _, sID := range secretsRef.ClientSecretsIDs { 557 for index, secret := range s.secrets { 558 if secret.ClientID == sID { 559 s.secrets[index] = s.secrets[len(s.secrets)-1] 560 s.secrets[len(s.secrets)-1] = ServiceProviderSecret{} 561 s.secrets = s.secrets[:len(s.secrets)-1] 562 } 563 } 564 } 565 } 566 567 func (s *server) getServiceProvider(w http.ResponseWriter, r *http.Request) { 568 _, err := w.Write(s.serviceProvider) 569 if err != nil { 570 w.WriteHeader(http.StatusBadRequest) 571 s.t.Errorf("test server cannot write response body: %s", err) 572 return 573 } 574 w.WriteHeader(http.StatusOK) 575 } 576 577 func (s *server) getConfiguration(w http.ResponseWriter, r *http.Request) { 578 _, err := w.Write(s.configuration) 579 if err != nil { 580 w.WriteHeader(http.StatusBadRequest) 581 s.t.Errorf("test server cannot write response body: %s", err) 582 return 583 } 584 w.WriteHeader(http.StatusOK) 585 } 586 587 func (s *server) getSecrets(w http.ResponseWriter, r *http.Request) { 588 data, err := json.Marshal(s.secrets) 589 if err != nil { 590 w.WriteHeader(http.StatusBadRequest) 591 s.t.Errorf("test server cannot marshal secrets: %s", err) 592 return 593 } 594 595 _, err = w.Write(data) 596 if err != nil { 597 w.WriteHeader(http.StatusBadRequest) 598 s.t.Errorf("test server cannot write response body: %s", err) 599 return 600 } 601 w.WriteHeader(http.StatusOK) 602 }