no naked returns in go; fix auth v3 unit tests
diff --git a/openstack/identity/v3/endpoints/requests.go b/openstack/identity/v3/endpoints/requests.go
index 30ceacf..fc44365 100644
--- a/openstack/identity/v3/endpoints/requests.go
+++ b/openstack/identity/v3/endpoints/requests.go
@@ -31,6 +31,7 @@
return
}
_, r.Err = client.Post(listURL(client), &b, &r.Body, nil)
+ return
}
type ListOptsBuilder interface {
@@ -91,9 +92,11 @@
return
}
_, r.Err = client.Patch(endpointURL(client, endpointID), &b, &r.Body, nil)
+ return
}
// Delete removes an endpoint from the service catalog.
func Delete(client *gophercloud.ServiceClient, endpointID string) (r DeleteResult) {
_, r.Err = client.Delete(endpointURL(client, endpointID), nil)
+ return
}
diff --git a/openstack/identity/v3/services/requests.go b/openstack/identity/v3/services/requests.go
index 81c8960..bb7bb04 100644
--- a/openstack/identity/v3/services/requests.go
+++ b/openstack/identity/v3/services/requests.go
@@ -9,6 +9,7 @@
func Create(client *gophercloud.ServiceClient, serviceType string) (r CreateResult) {
b := map[string]string{"type": serviceType}
_, r.Err = client.Post(listURL(client), b, &r.Body, nil)
+ return
}
type ListOptsBuilder interface {
@@ -45,16 +46,19 @@
// Get returns additional information about a service, given its ID.
func Get(client *gophercloud.ServiceClient, serviceID string) (r GetResult) {
_, r.Err = client.Get(serviceURL(client, serviceID), &r.Body, nil)
+ return
}
// Update changes the service type of an existing service.
func Update(client *gophercloud.ServiceClient, serviceID string, serviceType string) (r UpdateResult) {
b := map[string]string{"type": serviceType}
_, r.Err = client.Patch(serviceURL(client, serviceID), &b, &r.Body, nil)
+ return
}
// Delete removes an existing service.
// It either deletes all associated endpoints, or fails until all endpoints are deleted.
func Delete(client *gophercloud.ServiceClient, serviceID string) (r DeleteResult) {
_, r.Err = client.Delete(serviceURL(client, serviceID), nil)
+ return
}
diff --git a/openstack/identity/v3/tokens/errors.go b/openstack/identity/v3/tokens/errors.go
index 4476109..9cc1d59 100644
--- a/openstack/identity/v3/tokens/errors.go
+++ b/openstack/identity/v3/tokens/errors.go
@@ -1,72 +1,139 @@
package tokens
import (
- "errors"
"fmt"
+
+ "github.com/gophercloud/gophercloud"
)
-func unacceptedAttributeErr(attribute string) error {
- return fmt.Errorf("The base Identity V3 API does not accept authentication by %s", attribute)
+func unacceptedAttributeErr(attribute string) string {
+ return fmt.Sprintf("The base Identity V3 API does not accept authentication by %s", attribute)
}
-func redundantWithTokenErr(attribute string) error {
- return fmt.Errorf("%s may not be provided when authenticating with a TokenID", attribute)
+func redundantWithTokenErr(attribute string) string {
+ return fmt.Sprintf("%s may not be provided when authenticating with a TokenID", attribute)
}
-func redundantWithUserID(attribute string) error {
- return fmt.Errorf("%s may not be provided when authenticating with a UserID", attribute)
+func redundantWithUserID(attribute string) string {
+ return fmt.Sprintf("%s may not be provided when authenticating with a UserID", attribute)
}
-var (
- // ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
- ErrAPIKeyProvided = unacceptedAttributeErr("APIKey")
+// ErrAPIKeyProvided indicates that an APIKey was provided but can't be used.
+type ErrAPIKeyProvided struct{ gophercloud.BaseError }
- // ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
- ErrTenantIDProvided = unacceptedAttributeErr("TenantID")
+func (e ErrAPIKeyProvided) Error() string {
+ return unacceptedAttributeErr("APIKey")
+}
- // ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
- ErrTenantNameProvided = unacceptedAttributeErr("TenantName")
+// ErrTenantIDProvided indicates that a TenantID was provided but can't be used.
+type ErrTenantIDProvided struct{ gophercloud.BaseError }
- // ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
- ErrUsernameWithToken = redundantWithTokenErr("Username")
+func (e ErrTenantIDProvided) Error() string {
+ return unacceptedAttributeErr("TenantID")
+}
- // ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
- ErrUserIDWithToken = redundantWithTokenErr("UserID")
+// ErrTenantNameProvided indicates that a TenantName was provided but can't be used.
+type ErrTenantNameProvided struct{ gophercloud.BaseError }
- // ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
- ErrDomainIDWithToken = redundantWithTokenErr("DomainID")
+func (e ErrTenantNameProvided) Error() string {
+ return unacceptedAttributeErr("TenantName")
+}
- // ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
- ErrDomainNameWithToken = redundantWithTokenErr("DomainName")
+// ErrUsernameWithToken indicates that a Username was provided, but token authentication is being used instead.
+type ErrUsernameWithToken struct{ gophercloud.BaseError }
- // ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
- ErrUsernameOrUserID = errors.New("Exactly one of Username and UserID must be provided for password authentication")
+func (e ErrUsernameWithToken) Error() string {
+ return redundantWithTokenErr("Username")
+}
- // ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
- ErrDomainIDWithUserID = redundantWithUserID("DomainID")
+// ErrUserIDWithToken indicates that a UserID was provided, but token authentication is being used instead.
+type ErrUserIDWithToken struct{ gophercloud.BaseError }
- // ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
- ErrDomainNameWithUserID = redundantWithUserID("DomainName")
+func (e ErrUserIDWithToken) Error() string {
+ return redundantWithTokenErr("UserID")
+}
- // ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
- // It may also indicate that both a DomainID and a DomainName were provided at once.
- ErrDomainIDOrDomainName = errors.New("You must provide exactly one of DomainID or DomainName to authenticate by Username")
+// ErrDomainIDWithToken indicates that a DomainID was provided, but token authentication is being used instead.
+type ErrDomainIDWithToken struct{ gophercloud.BaseError }
- // ErrMissingPassword indicates that no password was provided and no token is available.
- ErrMissingPassword = errors.New("You must provide a password to authenticate")
+func (e ErrDomainIDWithToken) Error() string {
+ return redundantWithTokenErr("DomainID")
+}
- // ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
- ErrScopeDomainIDOrDomainName = errors.New("You must provide exactly one of DomainID or DomainName in a Scope with ProjectName")
+// ErrDomainNameWithToken indicates that a DomainName was provided, but token authentication is being used instead.s
+type ErrDomainNameWithToken struct{ gophercloud.BaseError }
- // ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
- ErrScopeProjectIDOrProjectName = errors.New("You must provide at most one of ProjectID or ProjectName in a Scope")
+func (e ErrDomainNameWithToken) Error() string {
+ return redundantWithTokenErr("DomainName")
+}
- // ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
- ErrScopeProjectIDAlone = errors.New("ProjectID must be supplied alone in a Scope")
+// ErrUsernameOrUserID indicates that neither username nor userID are specified, or both are at once.
+type ErrUsernameOrUserID struct{ gophercloud.BaseError }
- // ErrScopeDomainName indicates that a DomainName was provided alone in a Scope.
- ErrScopeDomainName = errors.New("DomainName must be supplied with a ProjectName or ProjectID in a Scope.")
+func (e ErrUsernameOrUserID) Error() string {
+ return "Exactly one of Username and UserID must be provided for password authentication"
+}
- // ErrScopeEmpty indicates that no credentials were provided in a Scope.
- ErrScopeEmpty = errors.New("You must provide either a Project or Domain in a Scope")
-)
+// ErrDomainIDWithUserID indicates that a DomainID was provided, but unnecessary because a UserID is being used.
+type ErrDomainIDWithUserID struct{ gophercloud.BaseError }
+
+func (e ErrDomainIDWithUserID) Error() string {
+ return redundantWithUserID("DomainID")
+}
+
+// ErrDomainNameWithUserID indicates that a DomainName was provided, but unnecessary because a UserID is being used.
+type ErrDomainNameWithUserID struct{ gophercloud.BaseError }
+
+func (e ErrDomainNameWithUserID) Error() string {
+ return redundantWithUserID("DomainName")
+}
+
+// ErrDomainIDOrDomainName indicates that a username was provided, but no domain to scope it.
+// It may also indicate that both a DomainID and a DomainName were provided at once.
+type ErrDomainIDOrDomainName struct{ gophercloud.BaseError }
+
+func (e ErrDomainIDOrDomainName) Error() string {
+ return "You must provide exactly one of DomainID or DomainName to authenticate by Username"
+}
+
+// ErrMissingPassword indicates that no password was provided and no token is available.
+type ErrMissingPassword struct{ gophercloud.BaseError }
+
+func (e ErrMissingPassword) Error() string {
+ return "You must provide a password to authenticate"
+}
+
+// ErrScopeDomainIDOrDomainName indicates that a domain ID or Name was required in a Scope, but not present.
+type ErrScopeDomainIDOrDomainName struct{ gophercloud.BaseError }
+
+func (e ErrScopeDomainIDOrDomainName) Error() string {
+ return "You must provide exactly one of DomainID or DomainName in a Scope with ProjectName"
+}
+
+// ErrScopeProjectIDOrProjectName indicates that both a ProjectID and a ProjectName were provided in a Scope.
+type ErrScopeProjectIDOrProjectName struct{ gophercloud.BaseError }
+
+func (e ErrScopeProjectIDOrProjectName) Error() string {
+ return "You must provide at most one of ProjectID or ProjectName in a Scope"
+}
+
+// ErrScopeProjectIDAlone indicates that a ProjectID was provided with other constraints in a Scope.
+type ErrScopeProjectIDAlone struct{ gophercloud.BaseError }
+
+func (e ErrScopeProjectIDAlone) Error() string {
+ return "ProjectID must be supplied alone in a Scope"
+}
+
+// ErrScopeDomainName indicates that a DomainName was provided alone in a Scope.
+type ErrScopeDomainName struct{ gophercloud.BaseError }
+
+func (e ErrScopeDomainName) Error() string {
+ return "DomainName must be supplied with a ProjectName or ProjectID in a Scope"
+}
+
+// ErrScopeEmpty indicates that no credentials were provided in a Scope.
+type ErrScopeEmpty struct{ gophercloud.BaseError }
+
+func (e ErrScopeEmpty) Error() string {
+ return "You must provide either a Project or Domain in a Scope"
+}
diff --git a/openstack/identity/v3/tokens/requests.go b/openstack/identity/v3/tokens/requests.go
index 6978186..12930f9 100644
--- a/openstack/identity/v3/tokens/requests.go
+++ b/openstack/identity/v3/tokens/requests.go
@@ -1,16 +1,275 @@
package tokens
-import (
- "net/http"
+import "github.com/gophercloud/gophercloud"
- "github.com/gophercloud/gophercloud"
-)
+// Scope allows a created token to be limited to a specific domain or project.
+type Scope struct {
+ ProjectID string `json:"scope.project.id,omitempty" not:"ProjectName,DomainID,DomainName"`
+ ProjectName string `json:"scope.project.name,omitempty"`
+ DomainID string `json:"scope.project.id,omitempty" not:"ProjectName,ProjectID,DomainName"`
+ DomainName string `json:"scope.project.id,omitempty"`
+}
// AuthOptionsBuilder describes any argument that may be passed to the Create call.
type AuthOptionsBuilder interface {
// ToTokenV3CreateMap assembles the Create request body, returning an error if parameters are
// missing or inconsistent.
- ToTokenV3CreateMap(*gophercloud.ScopeOptsV3) (map[string]interface{}, error)
+ ToTokenV3CreateMap(*Scope) (map[string]interface{}, error)
+}
+
+type AuthOptions struct {
+ // IdentityEndpoint specifies the HTTP endpoint that is required to work with
+ // the Identity API of the appropriate version. While it's ultimately needed by
+ // all of the identity services, it will often be populated by a provider-level
+ // function.
+ IdentityEndpoint string `json:"-"`
+
+ // Username is required if using Identity V2 API. Consult with your provider's
+ // control panel to discover your account's username. In Identity V3, either
+ // UserID or a combination of Username and DomainID or DomainName are needed.
+ Username string `json:"username,omitempty"`
+ UserID string `json:"id,omitempty"`
+
+ Password string `json:"password,omitempty"`
+
+ // At most one of DomainID and DomainName must be provided if using Username
+ // with Identity V3. Otherwise, either are optional.
+ DomainID string `json:"id,omitempty"`
+ DomainName string `json:"name,omitempty"`
+
+ // The TenantID and TenantName fields are optional for the Identity V2 API.
+ // Some providers allow you to specify a TenantName instead of the TenantId.
+ // Some require both. Your provider's authentication policies will determine
+ // how these fields influence authentication.
+ TenantID string `json:"tenantId,omitempty"`
+ TenantName string `json:"tenantName,omitempty"`
+
+ // AllowReauth should be set to true if you grant permission for Gophercloud to
+ // cache your credentials in memory, and to allow Gophercloud to attempt to
+ // re-authenticate automatically if/when your token expires. If you set it to
+ // false, it will not cache these settings, but re-authentication will not be
+ // possible. This setting defaults to false.
+ AllowReauth bool `json:"-"`
+
+ // TokenID allows users to authenticate (possibly as another user) with an
+ // authentication token ID.
+ TokenID string
+}
+
+func (opts AuthOptions) ToTokenV3CreateMap(scope *Scope) (map[string]interface{}, error) {
+ type domainReq struct {
+ ID *string `json:"id,omitempty"`
+ Name *string `json:"name,omitempty"`
+ }
+
+ type projectReq struct {
+ Domain *domainReq `json:"domain,omitempty"`
+ Name *string `json:"name,omitempty"`
+ ID *string `json:"id,omitempty"`
+ }
+
+ type userReq struct {
+ ID *string `json:"id,omitempty"`
+ Name *string `json:"name,omitempty"`
+ Password string `json:"password"`
+ Domain *domainReq `json:"domain,omitempty"`
+ }
+
+ type passwordReq struct {
+ User userReq `json:"user"`
+ }
+
+ type tokenReq struct {
+ ID string `json:"id"`
+ }
+
+ type identityReq struct {
+ Methods []string `json:"methods"`
+ Password *passwordReq `json:"password,omitempty"`
+ Token *tokenReq `json:"token,omitempty"`
+ }
+
+ type scopeReq struct {
+ Domain *domainReq `json:"domain,omitempty"`
+ Project *projectReq `json:"project,omitempty"`
+ }
+
+ type authReq struct {
+ Identity identityReq `json:"identity"`
+ Scope *scopeReq `json:"scope,omitempty"`
+ }
+
+ type request struct {
+ Auth authReq `json:"auth"`
+ }
+
+ // Populate the request structure based on the provided arguments. Create and return an error
+ // if insufficient or incompatible information is present.
+ var req request
+
+ // Test first for unrecognized arguments.
+ if opts.TenantID != "" {
+ return nil, ErrTenantIDProvided{}
+ }
+ if opts.TenantName != "" {
+ return nil, ErrTenantNameProvided{}
+ }
+
+ if opts.Password == "" {
+ if opts.TokenID != "" {
+ // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication
+ // parameters.
+ if opts.Username != "" {
+ return nil, ErrUsernameWithToken{}
+ }
+ if opts.UserID != "" {
+ return nil, ErrUserIDWithToken{}
+ }
+ if opts.DomainID != "" {
+ return nil, ErrDomainIDWithToken{}
+ }
+ if opts.DomainName != "" {
+ return nil, ErrDomainNameWithToken{}
+ }
+
+ // Configure the request for Token authentication.
+ req.Auth.Identity.Methods = []string{"token"}
+ req.Auth.Identity.Token = &tokenReq{
+ ID: opts.TokenID,
+ }
+ } else {
+ // If no password or token ID are available, authentication can't continue.
+ return nil, ErrMissingPassword{}
+ }
+ } else {
+ // Password authentication.
+ req.Auth.Identity.Methods = []string{"password"}
+
+ // At least one of Username and UserID must be specified.
+ if opts.Username == "" && opts.UserID == "" {
+ return nil, ErrUsernameOrUserID{}
+ }
+
+ if opts.Username != "" {
+ // If Username is provided, UserID may not be provided.
+ if opts.UserID != "" {
+ return nil, ErrUsernameOrUserID{}
+ }
+
+ // Either DomainID or DomainName must also be specified.
+ if opts.DomainID == "" && opts.DomainName == "" {
+ return nil, ErrDomainIDOrDomainName{}
+ }
+
+ if opts.DomainID != "" {
+ if opts.DomainName != "" {
+ return nil, ErrDomainIDOrDomainName{}
+ }
+
+ // Configure the request for Username and Password authentication with a DomainID.
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{
+ Name: &opts.Username,
+ Password: opts.Password,
+ Domain: &domainReq{ID: &opts.DomainID},
+ },
+ }
+ }
+
+ if opts.DomainName != "" {
+ // Configure the request for Username and Password authentication with a DomainName.
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{
+ Name: &opts.Username,
+ Password: opts.Password,
+ Domain: &domainReq{Name: &opts.DomainName},
+ },
+ }
+ }
+ }
+
+ if opts.UserID != "" {
+ // If UserID is specified, neither DomainID nor DomainName may be.
+ if opts.DomainID != "" {
+ return nil, ErrDomainIDWithUserID{}
+ }
+ if opts.DomainName != "" {
+ return nil, ErrDomainNameWithUserID{}
+ }
+
+ // Configure the request for UserID and Password authentication.
+ req.Auth.Identity.Password = &passwordReq{
+ User: userReq{ID: &opts.UserID, Password: opts.Password},
+ }
+ }
+ }
+
+ // Add a "scope" element if a Scope has been provided.
+ if scope != nil {
+ if scope.ProjectName != "" {
+ // ProjectName provided: either DomainID or DomainName must also be supplied.
+ // ProjectID may not be supplied.
+ if scope.DomainID == "" && scope.DomainName == "" {
+ return nil, ErrScopeDomainIDOrDomainName{}
+ }
+ if scope.ProjectID != "" {
+ return nil, ErrScopeProjectIDOrProjectName{}
+ }
+
+ if scope.DomainID != "" {
+ // ProjectName + DomainID
+ req.Auth.Scope = &scopeReq{
+ Project: &projectReq{
+ Name: &scope.ProjectName,
+ Domain: &domainReq{ID: &scope.DomainID},
+ },
+ }
+ }
+
+ if scope.DomainName != "" {
+ // ProjectName + DomainName
+ req.Auth.Scope = &scopeReq{
+ Project: &projectReq{
+ Name: &scope.ProjectName,
+ Domain: &domainReq{Name: &scope.DomainName},
+ },
+ }
+ }
+ } else if scope.ProjectID != "" {
+ // ProjectID provided. ProjectName, DomainID, and DomainName may not be provided.
+ if scope.DomainID != "" {
+ return nil, ErrScopeProjectIDAlone{}
+ }
+ if scope.DomainName != "" {
+ return nil, ErrScopeProjectIDAlone{}
+ }
+
+ // ProjectID
+ req.Auth.Scope = &scopeReq{
+ Project: &projectReq{ID: &scope.ProjectID},
+ }
+ } else if scope.DomainID != "" {
+ // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided.
+ if scope.DomainName != "" {
+ return nil, ErrScopeDomainIDOrDomainName{}
+ }
+
+ // DomainID
+ req.Auth.Scope = &scopeReq{
+ Domain: &domainReq{ID: &scope.DomainID},
+ }
+ } else if scope.DomainName != "" {
+ return nil, ErrScopeDomainName{}
+ } else {
+ return nil, ErrScopeEmpty{}
+ }
+ }
+
+ b, err2 := gophercloud.BuildRequestBody(req, "")
+ if err2 != nil {
+ return nil, err2
+ }
+ return b, nil
}
func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
@@ -20,34 +279,36 @@
}
// Create authenticates and either generates a new token, or changes the Scope of an existing token.
-func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder, scopeOpts *gophercloud.ScopeOptsV3) (r CreateResult) {
+func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder, scopeOpts *Scope) (r CreateResult) {
b, err := opts.ToTokenV3CreateMap(scopeOpts)
if err != nil {
r.Err = err
return
}
- var resp *http.Response
- resp, r.Err = c.Post(tokenURL(c), b, &r.Body, nil)
+ resp, err := c.Post(tokenURL(c), b, &r.Body, nil)
if resp != nil {
+ r.Err = err
r.Header = resp.Header
}
+ return
}
// Get validates and retrieves information about another token.
func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
- var resp *http.Response
- resp, r.Err = c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
+ resp, err := c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{200, 203},
})
if resp != nil {
+ r.Err = err
r.Header = resp.Header
}
+ return
}
// Validate determines if a specified token is valid or not.
func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
- response, err := c.Request("HEAD", tokenURL(c), &gophercloud.RequestOpts{
+ resp, err := c.Request("HEAD", tokenURL(c), &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{204, 404},
})
@@ -55,7 +316,7 @@
return false, err
}
- return response.StatusCode == 204, nil
+ return resp.StatusCode == 204, nil
}
// Revoke immediately makes specified token invalid.
@@ -63,4 +324,5 @@
_, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token),
})
+ return
}
diff --git a/openstack/identity/v3/tokens/requests_test.go b/openstack/identity/v3/tokens/requests_test.go
index a39a6f4..faa79e0 100644
--- a/openstack/identity/v3/tokens/requests_test.go
+++ b/openstack/identity/v3/tokens/requests_test.go
@@ -11,15 +11,13 @@
)
// authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
-func authTokenPost(t *testing.T, options AuthOptionsBuilder, scope *gophercloud.ScopeOptsV3, requestJSON string) {
+func authTokenPost(t *testing.T, options AuthOptions, scope *Scope, requestJSON string) {
testhelper.SetupHTTP()
defer testhelper.TeardownHTTP()
client := gophercloud.ServiceClient{
- ProviderClient: &gophercloud.ProviderClient{
- TokenID: "12345abcdef",
- },
- Endpoint: testhelper.Endpoint(),
+ ProviderClient: &gophercloud.ProviderClient{},
+ Endpoint: testhelper.Endpoint(),
}
testhelper.Mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
@@ -42,7 +40,7 @@
}
}
-func authTokenPostErr(t *testing.T, options AuthOptionsBuilder, scope *gophercloud.ScopeOptsV3, includeToken bool, expectedErr error) {
+func authTokenPostErr(t *testing.T, options AuthOptions, scope *Scope, includeToken bool, expectedErr error) {
testhelper.SetupHTTP()
defer testhelper.TeardownHTTP()
@@ -64,10 +62,7 @@
}
func TestCreateUserIDAndPassword(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "me"
- ao.Password = "squirrel!"
- authTokenPost(t, ao, nil, `
+ authTokenPost(t, AuthOptions{UserID: "me", Password: "squirrel!"}, nil, `
{
"auth": {
"identity": {
@@ -82,10 +77,7 @@
}
func TestCreateUsernameDomainIDPassword(t *testing.T) {
- ao := gophercloud.AuthOptions{DomainID: "abc123"}
- ao.Username = "fakey"
- ao.Password = "notpassword"
- authTokenPost(t, ao, nil, `
+ authTokenPost(t, AuthOptions{Username: "fakey", Password: "notpassword", DomainID: "abc123"}, nil, `
{
"auth": {
"identity": {
@@ -106,10 +98,7 @@
}
func TestCreateUsernameDomainNamePassword(t *testing.T) {
- ao := gophercloud.AuthOptions{DomainName: "spork.net"}
- ao.Username = "frank"
- ao.Password = "swordfish"
- authTokenPost(t, ao, nil, `
+ authTokenPost(t, AuthOptions{Username: "frank", Password: "swordfish", DomainName: "spork.net"}, nil, `
{
"auth": {
"identity": {
@@ -130,7 +119,7 @@
}
func TestCreateTokenID(t *testing.T) {
- authTokenPost(t, gophercloud.AuthOptions{TokenID: "12345abcdef"}, nil, `
+ authTokenPost(t, AuthOptions{TokenID: "12345abcdef"}, nil, `
{
"auth": {
"identity": {
@@ -145,11 +134,9 @@
}
func TestCreateProjectIDScope(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "fenris"
- ao.Password = "g0t0h311"
- scope := &gophercloud.ScopeOptsV3{ProjectID: "123456"}
- authTokenPost(t, ao, scope, `
+ options := AuthOptions{UserID: "fenris", Password: "g0t0h311"}
+ scope := &Scope{ProjectID: "123456"}
+ authTokenPost(t, options, scope, `
{
"auth": {
"identity": {
@@ -172,11 +159,9 @@
}
func TestCreateDomainIDScope(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "fenris"
- ao.Password = "g0t0h311"
- scope := &gophercloud.ScopeOptsV3{DomainID: "1000"}
- authTokenPost(t, ao, scope, `
+ options := AuthOptions{UserID: "fenris", Password: "g0t0h311"}
+ scope := &Scope{DomainID: "1000"}
+ authTokenPost(t, options, scope, `
{
"auth": {
"identity": {
@@ -199,11 +184,9 @@
}
func TestCreateProjectNameAndDomainIDScope(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "fenris"
- ao.Password = "g0t0h311"
- scope := &gophercloud.ScopeOptsV3{ProjectName: "world-domination", DomainID: "1000"}
- authTokenPost(t, ao, scope, `
+ options := AuthOptions{UserID: "fenris", Password: "g0t0h311"}
+ scope := &Scope{ProjectName: "world-domination", DomainID: "1000"}
+ authTokenPost(t, options, scope, `
{
"auth": {
"identity": {
@@ -229,11 +212,9 @@
}
func TestCreateProjectNameAndDomainNameScope(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "fenris"
- ao.Password = "g0t0h311"
- scope := &gophercloud.ScopeOptsV3{ProjectName: "world-domination", DomainName: "evil-plans"}
- authTokenPost(t, ao, scope, `
+ options := AuthOptions{UserID: "fenris", Password: "g0t0h311"}
+ scope := &Scope{ProjectName: "world-domination", DomainName: "evil-plans"}
+ authTokenPost(t, options, scope, `
{
"auth": {
"identity": {
@@ -278,10 +259,8 @@
}`)
})
- ao := gophercloud.AuthOptions{}
- ao.UserID = "me"
- ao.Password = "shhh"
- token, err := Create(&client, ao, nil).Extract()
+ options := AuthOptions{UserID: "me", Password: "shhh"}
+ token, err := Create(&client, options, nil).Extract()
if err != nil {
t.Fatalf("Create returned an error: %v", err)
}
@@ -292,127 +271,123 @@
}
func TestCreateFailureEmptyAuth(t *testing.T) {
- authTokenPostErr(t, gophercloud.AuthOptions{}, nil, false, ErrMissingPassword)
+ authTokenPostErr(t, AuthOptions{}, nil, false, ErrMissingPassword{})
+}
+
+func TestCreateFailureTenantID(t *testing.T) {
+ authTokenPostErr(t, AuthOptions{TenantID: "something"}, nil, false, ErrTenantIDProvided{})
+}
+
+func TestCreateFailureTenantName(t *testing.T) {
+ authTokenPostErr(t, AuthOptions{TenantName: "something"}, nil, false, ErrTenantNameProvided{})
}
func TestCreateFailureTokenIDUsername(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.Username = "somthing"
- authTokenPostErr(t, ao, nil, true, ErrUsernameWithToken)
+ authTokenPostErr(t, AuthOptions{Username: "something", TokenID: "12345"}, nil, true, ErrUsernameWithToken{})
}
func TestCreateFailureTokenIDUserID(t *testing.T) {
- authTokenPostErr(t, gophercloud.AuthOptions{UserID: "something"}, nil, true, ErrUserIDWithToken)
+ authTokenPostErr(t, AuthOptions{UserID: "something", TokenID: "12345"}, nil, true, ErrUserIDWithToken{})
}
func TestCreateFailureTokenIDDomainID(t *testing.T) {
- authTokenPostErr(t, gophercloud.AuthOptions{DomainID: "something"}, nil, true, ErrDomainIDWithToken)
+ authTokenPostErr(t, AuthOptions{DomainID: "something", TokenID: "12345"}, nil, true, ErrDomainIDWithToken{})
}
func TestCreateFailureTokenIDDomainName(t *testing.T) {
- authTokenPostErr(t, gophercloud.AuthOptions{DomainName: "something"}, nil, true, ErrDomainNameWithToken)
+ authTokenPostErr(t, AuthOptions{DomainName: "something", TokenID: "12345"}, nil, true, ErrDomainNameWithToken{})
}
func TestCreateFailureMissingUser(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.Password = "supersecure"
- authTokenPostErr(t, ao, nil, false, ErrUsernameOrUserID)
+ options := AuthOptions{Password: "supersecure"}
+ authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID{})
}
func TestCreateFailureBothUser(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "redundancy"
- ao.Username = "oops"
- ao.Password = "supersecure"
- authTokenPostErr(t, ao, nil, false, ErrUsernameOrUserID)
+ options := AuthOptions{
+ Password: "supersecure",
+ Username: "oops",
+ UserID: "redundancy",
+ }
+ authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID{})
}
func TestCreateFailureMissingDomain(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.Username = "notuniqueenough"
- ao.Password = "supersecure"
- authTokenPostErr(t, ao, nil, false, ErrDomainIDOrDomainName)
+ options := AuthOptions{
+ Password: "supersecure",
+ Username: "notuniqueenough",
+ }
+ authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName{})
}
func TestCreateFailureBothDomain(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.Username = "someone"
- ao.Password = "supersecure"
- ao.DomainID = "hurf"
- ao.DomainName = "durf"
- authTokenPostErr(t, ao, nil, false, ErrDomainIDOrDomainName)
+ options := AuthOptions{
+ Password: "supersecure",
+ Username: "someone",
+ DomainID: "hurf",
+ DomainName: "durf",
+ }
+ authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName{})
}
func TestCreateFailureUserIDDomainID(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "100"
- ao.Password = "stuff"
- ao.DomainID = "oops"
- authTokenPostErr(t, ao, nil, false, ErrDomainIDWithUserID)
+ options := AuthOptions{
+ UserID: "100",
+ Password: "stuff",
+ DomainID: "oops",
+ }
+ authTokenPostErr(t, options, nil, false, ErrDomainIDWithUserID{})
}
func TestCreateFailureUserIDDomainName(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "100"
- ao.Password = "sssh"
- ao.DomainName = "oops"
- authTokenPostErr(t, ao, nil, false, ErrDomainNameWithUserID)
+ options := AuthOptions{
+ UserID: "100",
+ Password: "sssh",
+ DomainName: "oops",
+ }
+ authTokenPostErr(t, options, nil, false, ErrDomainNameWithUserID{})
}
func TestCreateFailureScopeProjectNameAlone(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{ProjectName: "notenough"}
- authTokenPostErr(t, ao, scope, false, ErrScopeDomainIDOrDomainName)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{ProjectName: "notenough"}
+ authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName{})
}
func TestCreateFailureScopeProjectNameAndID(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"}
- authTokenPostErr(t, ao, scope, false, ErrScopeProjectIDOrProjectName)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"}
+ authTokenPostErr(t, options, scope, false, ErrScopeProjectIDOrProjectName{})
}
func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{ProjectID: "toomuch", DomainID: "notneeded"}
- authTokenPostErr(t, ao, scope, false, ErrScopeProjectIDAlone)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{ProjectID: "toomuch", DomainID: "notneeded"}
+ authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone{})
}
func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{ProjectID: "toomuch", DomainName: "notneeded"}
- authTokenPostErr(t, ao, scope, false, ErrScopeProjectIDAlone)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{ProjectID: "toomuch", DomainName: "notneeded"}
+ authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone{})
}
func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{DomainID: "toomuch", DomainName: "notneeded"}
- authTokenPostErr(t, ao, scope, false, ErrScopeDomainIDOrDomainName)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{DomainID: "toomuch", DomainName: "notneeded"}
+ authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName{})
}
func TestCreateFailureScopeDomainNameAlone(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{DomainName: "notenough"}
- authTokenPostErr(t, ao, scope, false, ErrScopeDomainName)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{DomainName: "notenough"}
+ authTokenPostErr(t, options, scope, false, ErrScopeDomainName{})
}
func TestCreateFailureEmptyScope(t *testing.T) {
- ao := gophercloud.AuthOptions{}
- ao.UserID = "myself"
- ao.Password = "swordfish"
- scope := &gophercloud.ScopeOptsV3{}
- authTokenPostErr(t, ao, scope, false, ErrScopeEmpty)
+ options := AuthOptions{UserID: "myself", Password: "swordfish"}
+ scope := &Scope{}
+ authTokenPostErr(t, options, scope, false, ErrScopeEmpty{})
}
func TestGetRequest(t *testing.T) {