github.com/opentelekomcloud/gophertelekomcloud@v0.9.3/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/opentelekomcloud/gophertelekomcloud"
    10  	"github.com/opentelekomcloud/gophertelekomcloud/openstack/identity/v3/tokens"
    11  	"github.com/opentelekomcloud/gophertelekomcloud/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.Fprint(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.Fprint(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 TestCreateFailureScopeProjectNameAlone(t *testing.T) {
   354  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   355  	scope := &tokens.Scope{ProjectName: "notenough"}
   356  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeDomainIDOrDomainName{})
   357  }
   358  
   359  func TestCreateFailureScopeProjectNameAndID(t *testing.T) {
   360  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   361  	scope := &tokens.Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"}
   362  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDOrProjectName{})
   363  }
   364  
   365  func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) {
   366  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   367  	scope := &tokens.Scope{ProjectID: "toomuch", DomainID: "notneeded"}
   368  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDAlone{})
   369  }
   370  
   371  func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) {
   372  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   373  	scope := &tokens.Scope{ProjectID: "toomuch", DomainName: "notneeded"}
   374  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeProjectIDAlone{})
   375  }
   376  
   377  func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) {
   378  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   379  	scope := &tokens.Scope{DomainID: "toomuch", DomainName: "notneeded"}
   380  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeDomainIDOrDomainName{})
   381  }
   382  
   383  /*
   384  func TestCreateFailureEmptyScope(t *testing.T) {
   385  	options := tokens.AuthOptions{UserID: "myself", Password: "swordfish"}
   386  	scope := &tokens.Scope{}
   387  	authTokenPostErr(t, options, scope, false, golangsdk.ErrScopeEmpty{})
   388  }
   389  */
   390  
   391  func TestGetRequest(t *testing.T) {
   392  	testhelper.SetupHTTP()
   393  	defer testhelper.TeardownHTTP()
   394  
   395  	client := golangsdk.ServiceClient{
   396  		ProviderClient: &golangsdk.ProviderClient{
   397  			TokenID: "12345abcdef",
   398  		},
   399  		Endpoint: testhelper.Endpoint(),
   400  	}
   401  
   402  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   403  		testhelper.TestMethod(t, r, "GET")
   404  		testhelper.TestHeader(t, r, "Content-Type", "")
   405  		testhelper.TestHeader(t, r, "Accept", "application/json")
   406  		testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef")
   407  		testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345")
   408  
   409  		w.WriteHeader(http.StatusOK)
   410  		_, _ = fmt.Fprint(w, `
   411  			{ "token": { "expires_at": "2014-08-29T13:10:01.000000Z" } }
   412  		`)
   413  	})
   414  
   415  	token, err := tokens.Get(&client, "abcdef12345").Extract()
   416  	if err != nil {
   417  		t.Errorf("Info returned an error: %v", err)
   418  	}
   419  
   420  	expected, _ := time.Parse(time.UnixDate, "Fri Aug 29 13:10:01 UTC 2014")
   421  	if token.ExpiresAt != expected {
   422  		t.Errorf("Expected expiration time %s, but was %s", expected.Format(time.UnixDate), token.ExpiresAt.Format(time.UnixDate))
   423  	}
   424  }
   425  
   426  func prepareAuthTokenHandler(t *testing.T, expectedMethod string, status int) golangsdk.ServiceClient {
   427  	client := golangsdk.ServiceClient{
   428  		ProviderClient: &golangsdk.ProviderClient{
   429  			TokenID: "12345abcdef",
   430  		},
   431  		Endpoint: testhelper.Endpoint(),
   432  	}
   433  
   434  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   435  		testhelper.TestMethod(t, r, expectedMethod)
   436  		testhelper.TestHeader(t, r, "Content-Type", "")
   437  		testhelper.TestHeader(t, r, "Accept", "application/json")
   438  		testhelper.TestHeader(t, r, "X-Auth-Token", "12345abcdef")
   439  		testhelper.TestHeader(t, r, "X-Subject-Token", "abcdef12345")
   440  
   441  		w.WriteHeader(status)
   442  	})
   443  
   444  	return client
   445  }
   446  
   447  func TestValidateRequestSuccessful(t *testing.T) {
   448  	testhelper.SetupHTTP()
   449  	defer testhelper.TeardownHTTP()
   450  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNoContent)
   451  
   452  	ok, err := tokens.Validate(&client, "abcdef12345")
   453  	if err != nil {
   454  		t.Errorf("Unexpected error from Validate: %v", err)
   455  	}
   456  
   457  	if !ok {
   458  		t.Errorf("Validate returned false for a valid token")
   459  	}
   460  }
   461  
   462  func TestValidateRequestFailure(t *testing.T) {
   463  	testhelper.SetupHTTP()
   464  	defer testhelper.TeardownHTTP()
   465  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusNotFound)
   466  
   467  	ok, err := tokens.Validate(&client, "abcdef12345")
   468  	if err != nil {
   469  		t.Errorf("Unexpected error from Validate: %v", err)
   470  	}
   471  
   472  	if ok {
   473  		t.Errorf("Validate returned true for an invalid token")
   474  	}
   475  }
   476  
   477  func TestValidateRequestError(t *testing.T) {
   478  	testhelper.SetupHTTP()
   479  	defer testhelper.TeardownHTTP()
   480  	client := prepareAuthTokenHandler(t, "HEAD", http.StatusMethodNotAllowed)
   481  
   482  	_, err := tokens.Validate(&client, "abcdef12345")
   483  	if err == nil {
   484  		t.Errorf("Missing expected error from Validate")
   485  	}
   486  }
   487  
   488  func TestRevokeRequestSuccessful(t *testing.T) {
   489  	testhelper.SetupHTTP()
   490  	defer testhelper.TeardownHTTP()
   491  	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNoContent)
   492  
   493  	res := tokens.Revoke(&client, "abcdef12345")
   494  	testhelper.AssertNoErr(t, res.Err)
   495  }
   496  
   497  func TestRevokeRequestError(t *testing.T) {
   498  	testhelper.SetupHTTP()
   499  	defer testhelper.TeardownHTTP()
   500  	client := prepareAuthTokenHandler(t, "DELETE", http.StatusNotFound)
   501  
   502  	res := tokens.Revoke(&client, "abcdef12345")
   503  	if res.Err == nil {
   504  		t.Errorf("Missing expected error from Revoke")
   505  	}
   506  }
   507  
   508  func TestNoTokenInResponse(t *testing.T) {
   509  	testhelper.SetupHTTP()
   510  	defer testhelper.TeardownHTTP()
   511  
   512  	client := golangsdk.ServiceClient{
   513  		ProviderClient: &golangsdk.ProviderClient{},
   514  		Endpoint:       testhelper.Endpoint(),
   515  	}
   516  
   517  	testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
   518  		w.WriteHeader(http.StatusCreated)
   519  		_, _ = fmt.Fprint(w, `{}`)
   520  	})
   521  
   522  	options := tokens.AuthOptions{UserID: "me", Password: "squirrel!"}
   523  	_, err := tokens.Create(&client, &options).Extract()
   524  	testhelper.AssertNoErr(t, err)
   525  }