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  }