github.com/huaweicloud/golangsdk@v0.0.0-20210831081626-d823fe11ceba/openstack/identity/v3/tokens/testing/requests_test.go (about)

     1  package testing
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/huaweicloud/golangsdk"
    10  	"github.com/huaweicloud/golangsdk/openstack/identity/v3/tokens"
    11  	"github.com/huaweicloud/golangsdk/testhelper"
    12  )
    13  
    14  // authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
    15  func authTokenPost(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, requestJSON string) {
    16  	testhelper.SetupHTTP()
    17  	defer testhelper.TeardownHTTP()
    18  
    19  	client := golangsdk.ServiceClient{
    20  		ProviderClient: &golangsdk.ProviderClient{},
    21  		Endpoint:       testhelper.Endpoint(),
    22  	}
    23  
    24  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
    25  		testhelper.TestMethod(t, r, "POST")
    26  		testhelper.TestHeader(t, r, "Content-Type", "application/json")
    27  		testhelper.TestHeader(t, r, "Accept", "application/json")
    28  		testhelper.TestJSONRequest(t, r, requestJSON)
    29  
    30  		w.WriteHeader(http.StatusCreated)
    31  		fmt.Fprintf(w, `{
    32  			"token": {
    33  				"expires_at": "2014-10-02T13:45:00.000000Z"
    34  			}
    35  		}`)
    36  	})
    37  
    38  	if scope != nil {
    39  		options.Scope = *scope
    40  	}
    41  
    42  	expected := &tokens.Token{
    43  		ExpiresAt: time.Date(2014, 10, 2, 13, 45, 0, 0, time.UTC),
    44  	}
    45  	actual, err := tokens.Create(&client, &options).Extract()
    46  	testhelper.AssertNoErr(t, err)
    47  	testhelper.CheckDeepEquals(t, expected, actual)
    48  }
    49  
    50  func authTokenPostErr(t *testing.T, options tokens.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) {
    51  	testhelper.SetupHTTP()
    52  	defer testhelper.TeardownHTTP()
    53  
    54  	client := golangsdk.ServiceClient{
    55  		ProviderClient: &golangsdk.ProviderClient{},
    56  		Endpoint:       testhelper.Endpoint(),
    57  	}
    58  	if includeToken {
    59  		client.TokenID = "abcdef123456"
    60  	}
    61  
    62  	if scope != nil {
    63  		options.Scope = *scope
    64  	}
    65  
    66  	_, err := tokens.Create(&client, &options).Extract()
    67  	if err == nil {
    68  		t.Errorf("Create did NOT return an error")
    69  	}
    70  	if err != expectedErr {
    71  		t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err)
    72  	}
    73  }
    74  
    75  func TestCreateUserIDAndPassword(t *testing.T) {
    76  	authTokenPost(t, tokens.AuthOptions{UserID: "me", Password: "squirrel!"}, nil, `
    77  		{
    78  			"auth": {
    79  				"identity": {
    80  					"methods": ["password"],
    81  					"password": {
    82  						"user": { "id": "me", "password": "squirrel!" }
    83  					}
    84  				}
    85  			}
    86  		}
    87  	`)
    88  }
    89  
    90  func TestCreateUsernameDomainIDPassword(t *testing.T) {
    91  	authTokenPost(t, tokens.AuthOptions{Username: "fakey", Password: "notpassword", DomainID: "abc123"}, nil, `
    92  		{
    93  			"auth": {
    94  				"identity": {
    95  					"methods": ["password"],
    96  					"password": {
    97  						"user": {
    98  							"domain": {
    99  								"id": "abc123"
   100  							},
   101  							"name": "fakey",
   102  							"password": "notpassword"
   103  						}
   104  					}
   105  				}
   106  			}
   107  		}
   108  	`)
   109  }
   110  
   111  func TestCreateUsernameDomainNamePassword(t *testing.T) {
   112  	authTokenPost(t, tokens.AuthOptions{Username: "frank", Password: "swordfish", DomainName: "spork.net"}, nil, `
   113  		{
   114  			"auth": {
   115  				"identity": {
   116  					"methods": ["password"],
   117  					"password": {
   118  						"user": {
   119  							"domain": {
   120  								"name": "spork.net"
   121  							},
   122  							"name": "frank",
   123  							"password": "swordfish"
   124  						}
   125  					}
   126  				}
   127  			}
   128  		}
   129  	`)
   130  }
   131  
   132  func TestCreateTokenID(t *testing.T) {
   133  	authTokenPost(t, tokens.AuthOptions{TokenID: "12345abcdef"}, nil, `
   134  		{
   135  			"auth": {
   136  				"identity": {
   137  					"methods": ["token"],
   138  					"token": {
   139  						"id": "12345abcdef"
   140  					}
   141  				}
   142  			}
   143  		}
   144  	`)
   145  }
   146  
   147  func TestCreateProjectIDScope(t *testing.T) {
   148  	options := tokens.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
   149  	scope := &tokens.Scope{ProjectID: "123456"}
   150  	authTokenPost(t, options, scope, `
   151  		{
   152  			"auth": {
   153  				"identity": {
   154  					"methods": ["password"],
   155  					"password": {
   156  						"user": {
   157  							"id": "fenris",
   158  							"password": "g0t0h311"
   159  						}
   160  					}
   161  				},
   162  				"scope": {
   163  					"project": {
   164  						"id": "123456"
   165  					}
   166  				}
   167  			}
   168  		}
   169  	`)
   170  }
   171  
   172  func TestCreateDomainIDScope(t *testing.T) {
   173  	options := tokens.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
   174  	scope := &tokens.Scope{DomainID: "1000"}
   175  	authTokenPost(t, options, scope, `
   176  		{
   177  			"auth": {
   178  				"identity": {
   179  					"methods": ["password"],
   180  					"password": {
   181  						"user": {
   182  							"id": "fenris",
   183  							"password": "g0t0h311"
   184  						}
   185  					}
   186  				},
   187  				"scope": {
   188  					"domain": {
   189  						"id": "1000"
   190  					}
   191  				}
   192  			}
   193  		}
   194  	`)
   195  }
   196  
   197  func TestCreateDomainNameScope(t *testing.T) {
   198  	options := tokens.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
   199  	scope := &tokens.Scope{DomainName: "evil-plans"}
   200  	authTokenPost(t, options, scope, `
   201                  {
   202                          "auth": {
   203                                  "identity": {
   204                                          "methods": ["password"],
   205                                          "password": {
   206                                                  "user": {
   207                                                          "id": "fenris",
   208                                                          "password": "g0t0h311"
   209                                                  }
   210                                          }
   211                                  },
   212                                  "scope": {
   213                                          "domain": {
   214                                                  "name": "evil-plans"
   215                                          }
   216                                  }
   217                          }
   218                  }
   219          `)
   220  }
   221  
   222  func TestCreateProjectNameAndDomainIDScope(t *testing.T) {
   223  	options := tokens.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
   224  	scope := &tokens.Scope{ProjectName: "world-domination", DomainID: "1000"}
   225  	authTokenPost(t, options, scope, `
   226  		{
   227  			"auth": {
   228  				"identity": {
   229  					"methods": ["password"],
   230  					"password": {
   231  						"user": {
   232  							"id": "fenris",
   233  							"password": "g0t0h311"
   234  						}
   235  					}
   236  				},
   237  				"scope": {
   238  					"project": {
   239  						"domain": {
   240  							"id": "1000"
   241  						},
   242  						"name": "world-domination"
   243  					}
   244  				}
   245  			}
   246  		}
   247  	`)
   248  }
   249  
   250  func TestCreateProjectNameAndDomainNameScope(t *testing.T) {
   251  	options := tokens.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
   252  	scope := &tokens.Scope{ProjectName: "world-domination", DomainName: "evil-plans"}
   253  	authTokenPost(t, options, scope, `
   254  		{
   255  			"auth": {
   256  				"identity": {
   257  					"methods": ["password"],
   258  					"password": {
   259  						"user": {
   260  							"id": "fenris",
   261  							"password": "g0t0h311"
   262  						}
   263  					}
   264  				},
   265  				"scope": {
   266  					"project": {
   267  						"domain": {
   268  							"name": "evil-plans"
   269  						},
   270  						"name": "world-domination"
   271  					}
   272  				}
   273  			}
   274  		}
   275  	`)
   276  }
   277  
   278  func TestCreateExtractsTokenFromResponse(t *testing.T) {
   279  	testhelper.SetupHTTP()
   280  	defer testhelper.TeardownHTTP()
   281  
   282  	client := golangsdk.ServiceClient{
   283  		ProviderClient: &golangsdk.ProviderClient{},
   284  		Endpoint:       testhelper.Endpoint(),
   285  	}
   286  
   287  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   288  		w.Header().Add("X-Subject-Token", "aaa111")
   289  
   290  		w.WriteHeader(http.StatusCreated)
   291  		fmt.Fprintf(w, `{
   292  			"token": {
   293  				"expires_at": "2014-10-02T13:45:00.000000Z"
   294  			}
   295  		}`)
   296  	})
   297  
   298  	options := tokens.AuthOptions{UserID: "me", Password: "shhh"}
   299  	token, err := tokens.Create(&client, &options).Extract()
   300  	if err != nil {
   301  		t.Fatalf("Create returned an error: %v", err)
   302  	}
   303  
   304  	if token.ID != "aaa111" {
   305  		t.Errorf("Expected token to be aaa111, but was %s", token.ID)
   306  	}
   307  }
   308  
   309  func TestCreateFailureEmptyAuth(t *testing.T) {
   310  	authTokenPostErr(t, tokens.AuthOptions{}, nil, false, golangsdk.ErrMissingPassword{})
   311  }
   312  
   313  func TestCreateFailureTokenIDUsername(t *testing.T) {
   314  	authTokenPostErr(t, tokens.AuthOptions{Username: "something", TokenID: "12345"}, nil, true, golangsdk.ErrUsernameWithToken{})
   315  }
   316  
   317  func TestCreateFailureTokenIDUserID(t *testing.T) {
   318  	authTokenPostErr(t, tokens.AuthOptions{UserID: "something", TokenID: "12345"}, nil, true, golangsdk.ErrUserIDWithToken{})
   319  }
   320  
   321  func TestCreateFailureMissingUser(t *testing.T) {
   322  	options := tokens.AuthOptions{Password: "supersecure"}
   323  	authTokenPostErr(t, options, nil, false, golangsdk.ErrUsernameOrUserID{})
   324  }
   325  
   326  func TestCreateFailureBothUser(t *testing.T) {
   327  	options := tokens.AuthOptions{
   328  		Password: "supersecure",
   329  		Username: "oops",
   330  		UserID:   "redundancy",
   331  	}
   332  	authTokenPostErr(t, options, nil, false, golangsdk.ErrUsernameOrUserID{})
   333  }
   334  
   335  func TestCreateFailureMissingDomain(t *testing.T) {
   336  	options := tokens.AuthOptions{
   337  		Password: "supersecure",
   338  		Username: "notuniqueenough",
   339  	}
   340  	authTokenPostErr(t, options, nil, false, golangsdk.ErrDomainIDOrDomainName{})
   341  }
   342  
   343  func TestCreateFailureBothDomain(t *testing.T) {
   344  	options := tokens.AuthOptions{
   345  		Password:   "supersecure",
   346  		Username:   "someone",
   347  		DomainID:   "hurf",
   348  		DomainName: "durf",
   349  	}
   350  	authTokenPostErr(t, options, nil, false, golangsdk.ErrDomainIDOrDomainName{})
   351  }
   352  
   353  func TestCreateFailureUserIDDomainID(t *testing.T) {
   354  	options := tokens.AuthOptions{
   355  		UserID:   "100",
   356  		Password: "stuff",
   357  		DomainID: "oops",
   358  	}
   359  	authTokenPostErr(t, options, nil, false, golangsdk.ErrDomainIDWithUserID{})
   360  }
   361  
   362  func TestCreateFailureUserIDDomainName(t *testing.T) {
   363  	options := tokens.AuthOptions{
   364  		UserID:     "100",
   365  		Password:   "sssh",
   366  		DomainName: "oops",
   367  	}
   368  	authTokenPostErr(t, options, nil, false, golangsdk.ErrDomainNameWithUserID{})
   369  }
   370  
   371  func TestCreateFailureScopeProjectNameAlone(t *testing.T) {
   372  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   373  	scope := &tokens.Scope{ProjectName: "notenough"}
   374  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeDomainIDOrDomainName{})
   375  }
   376  
   377  func TestCreateFailureScopeProjectNameAndID(t *testing.T) {
   378  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   379  	scope := &tokens.Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"}
   380  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDOrProjectName{})
   381  }
   382  
   383  func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) {
   384  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   385  	scope := &tokens.Scope{ProjectID: "toomuch", DomainID: "notneeded"}
   386  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDAlone{})
   387  }
   388  
   389  func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) {
   390  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   391  	scope := &tokens.Scope{ProjectID: "toomuch", DomainName: "notneeded"}
   392  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDAlone{})
   393  }
   394  
   395  func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) {
   396  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   397  	scope := &tokens.Scope{DomainID: "toomuch", DomainName: "notneeded"}
   398  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeDomainIDOrDomainName{})
   399  }
   400  
   401  /*
   402  func TestCreateFailureEmptyScope(t *testing.T) {
   403  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   404  	scope := &tokens.Scope{}
   405  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeEmpty{})
   406  }
   407  */
   408  
   409  func TestGetRequest(t *testing.T) {
   410  	testhelper.SetupHTTP()
   411  	defer testhelper.TeardownHTTP()
   412  
   413  	client := golangsdk.ServiceClient{
   414  		ProviderClient: &golangsdk.ProviderClient{
   415  			TokenID: "12345abcdef",
   416  		},
   417  		Endpoint: testhelper.Endpoint(),
   418  	}
   419  
   420  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   421  		testhelper.TestMethod(t, r, "GET")
   422  		testhelper.TestHeader(t, r, "Content-Type", "")
   423  		testhelper.TestHeader(t, r, "Accept", "application/json")
   424  		testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef")
   425  		testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345")
   426  
   427  		w.WriteHeader(http.StatusOK)
   428  		fmt.Fprintf(w, `
   429  			{ "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } }
   430  		`)
   431  	})
   432  
   433  	token, err := tokens.Get(&client, "abcdef12345").Extract()
   434  	if err != nil {
   435  		t.Errorf("Info returned an error: %v", err)
   436  	}
   437  
   438  	expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014")
   439  	if token.ExpiresAt != expected {
   440  		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), time.Time(token.ExpiresAt).Format(time.UnixDate))
   441  	}
   442  }
   443  
   444  func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) golangsdk.ServiceClient {
   445  	client := golangsdk.ServiceClient{
   446  		ProviderClient: &golangsdk.ProviderClient{
   447  			TokenID: "12345abcdef",
   448  		},
   449  		Endpoint: testhelper.Endpoint(),
   450  	}
   451  
   452  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   453  		testhelper.TestMethod(t, r, expectedMethod)
   454  		testhelper.TestHeader(t, r, "Content-Type", "")
   455  		testhelper.TestHeader(t, r, "Accept", "application/json")
   456  		testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef")
   457  		testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345")
   458  
   459  		w.WriteHeader(status)
   460  	})
   461  
   462  	return client
   463  }
   464  
   465  func TestValidateRequestSuccessful(t *testing.T) {
   466  	testhelper.SetupHTTP()
   467  	defer testhelper.TeardownHTTP()
   468  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent)
   469  
   470  	ok, err := tokens.Validate(&client, "abcdef12345")
   471  	if err != nil {
   472  		t.Errorf("Unexpected error from Validate: %v", err)
   473  	}
   474  
   475  	if !ok {
   476  		t.Errorf("Validate returned false for a valid token")
   477  	}
   478  }
   479  
   480  func TestValidateRequestFailure(t *testing.T) {
   481  	testhelper.SetupHTTP()
   482  	defer testhelper.TeardownHTTP()
   483  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound)
   484  
   485  	ok, err := tokens.Validate(&client, "abcdef12345")
   486  	if err != nil {
   487  		t.Errorf("Unexpected error from Validate: %v", err)
   488  	}
   489  
   490  	if ok {
   491  		t.Errorf("Validate returned true for an invalid token")
   492  	}
   493  }
   494  
   495  func TestValidateRequestError(t *testing.T) {
   496  	testhelper.SetupHTTP()
   497  	defer testhelper.TeardownHTTP()
   498  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusMethodNotAllowed)
   499  
   500  	_, err := tokens.Validate(&client, "abcdef12345")
   501  	if err == nil {
   502  		t.Errorf("Missing expected error from Validate")
   503  	}
   504  }
   505  
   506  func TestRevokeRequestSuccessful(t *testing.T) {
   507  	testhelper.SetupHTTP()
   508  	defer testhelper.TeardownHTTP()
   509  	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent)
   510  
   511  	res := tokens.Revoke(&client, "abcdef12345")
   512  	testhelper.AssertNoErr(t, res.Err)
   513  }
   514  
   515  func TestRevokeRequestError(t *testing.T) {
   516  	testhelper.SetupHTTP()
   517  	defer testhelper.TeardownHTTP()
   518  	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound)
   519  
   520  	res := tokens.Revoke(&client, "abcdef12345")
   521  	if res.Err == nil {
   522  		t.Errorf("Missing expected error from Revoke")
   523  	}
   524  }
   525  
   526  func TestNoTokenInResponse(t *testing.T) {
   527  	testhelper.SetupHTTP()
   528  	defer testhelper.TeardownHTTP()
   529  
   530  	client := golangsdk.ServiceClient{
   531  		ProviderClient: &golangsdk.ProviderClient{},
   532  		Endpoint:       testhelper.Endpoint(),
   533  	}
   534  
   535  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   536  		w.WriteHeader(http.StatusCreated)
   537  		fmt.Fprintf(w, `{}`)
   538  	})
   539  
   540  	options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"}
   541  	_, err := tokens.Create(&client, &options).Extract()
   542  	testhelper.AssertNoErr(t, err)
   543  }