func authTokenPostErr(t *testing.T, options gophercloud.AuthOptions, scope *tokens.Scope, includeToken bool, expectedErr error) { testhelper.SetupHTTP() defer testhelper.TeardownHTTP() client := gophercloud.ServiceClient{ ProviderClient: &gophercloud.ProviderClient{}, Endpoint: testhelper.Endpoint(), } if includeToken { client.TokenID = "abcdef123456" } _, err := tokens.Create(&client, AuthOptionsExt{AuthOptions: tokens.AuthOptions{options}, TrustID: "123456"}, scope).Extract() if err == nil { t.Errorf("Create did NOT return an error") } if err != expectedErr { t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err) } }
func (options AuthOptions) ToAuthOptionsV3Map(c *gophercloud.ServiceClient, scope *Scope) (map[string]interface{}, error) { // tokens3.Create logic // Populate the request structure based on the provided arguments. Create and return an error // if insufficient or incompatible information is present. authMap := make(map[string]interface{}) // Test first for unrecognized arguments. if options.APIKey != "" { return nil, ErrAPIKeyProvided } if options.TenantID != "" { return nil, ErrTenantIDProvided } if options.TenantName != "" { return nil, ErrTenantNameProvided } if options.Password == "" { if options.TokenID != "" { c.TokenID = options.TokenID } if c.TokenID != "" { // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication // parameters. if options.Username != "" { return nil, ErrUsernameWithToken } if options.UserID != "" { return nil, ErrUserIDWithToken } // Configure the request for Token authentication. authMap["identity"] = map[string]interface{}{ "methods": []string{"token"}, "token": map[string]interface{}{ "id": c.TokenID, }, } } else { // If no password or token ID are available, authentication can't continue. return nil, ErrMissingPassword } } else { // Password authentication. // At least one of Username and UserID must be specified. if options.Username == "" && options.UserID == "" { return nil, ErrUsernameOrUserID } if options.Username != "" { // If Username is provided, UserID may not be provided. if options.UserID != "" { return nil, ErrUsernameOrUserID } // Either DomainID or DomainName must also be specified. if options.DomainID == "" && options.DomainName == "" { return nil, ErrDomainIDOrDomainName } if options.DomainID != "" { if options.DomainName != "" { return nil, ErrDomainIDOrDomainName } // Configure the request for Username and Password authentication with a DomainID. authMap["identity"] = map[string]interface{}{ "methods": []string{"password"}, "password": map[string]interface{}{ "user": map[string]interface{}{ "name": &options.Username, "password": options.Password, "domain": map[string]interface{}{ "id": &options.DomainID, }, }, }, } } if options.DomainName != "" { // Configure the request for Username and Password authentication with a DomainName. authMap["identity"] = map[string]interface{}{ "methods": []string{"password"}, "password": map[string]interface{}{ "user": map[string]interface{}{ "name": &options.Username, "password": options.Password, "domain": map[string]interface{}{ "name": &options.DomainName, }, }, }, } } } if options.UserID != "" { // If UserID is specified, neither DomainID nor DomainName may be. if options.DomainID != "" { return nil, ErrDomainIDWithUserID } if options.DomainName != "" { return nil, ErrDomainNameWithUserID } // Configure the request for UserID and Password authentication. authMap["identity"] = map[string]interface{}{ "methods": []string{"password"}, "password": map[string]interface{}{ "user": map[string]interface{}{ "id": &options.UserID, "password": options.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 authMap["scope"] = map[string]interface{}{ "project": map[string]interface{}{ "domain": map[string]interface{}{ "id": &scope.DomainID, }, "name": &scope.ProjectName, }, } } if scope.DomainName != "" { // ProjectName + DomainName authMap["scope"] = map[string]interface{}{ "project": map[string]interface{}{ "domain": map[string]interface{}{ "name": &scope.DomainName, }, "name": &scope.ProjectName, }, } } } 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 authMap["scope"] = map[string]interface{}{ "project": map[string]interface{}{ "id": &scope.ProjectID, }, } } else if scope.DomainID != "" { // DomainID provided. ProjectID, ProjectName, and DomainName may not be provided. if scope.DomainName != "" { return nil, ErrScopeDomainIDOrDomainName } // DomainID authMap["scope"] = map[string]interface{}{ "domain": map[string]interface{}{ "id": &scope.DomainID, }, } } else if scope.DomainName != "" { return nil, ErrScopeDomainName } else { return nil, ErrScopeEmpty } } return map[string]interface{}{"auth": authMap}, nil }
// Create authenticates and either generates a new token, or changes the Scope of an existing token. func Create(c *gophercloud.ServiceClient, options gophercloud.AuthOptions, scope *Scope) CreateResult { 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 options.APIKey != "" { return createErr(ErrAPIKeyProvided) } if options.TenantID != "" { return createErr(ErrTenantIDProvided) } if options.TenantName != "" { return createErr(ErrTenantNameProvided) } if options.Password == "" { if options.TokenID != "" { c.TokenID = options.TokenID } if c.TokenID != "" { // Because we aren't using password authentication, it's an error to also provide any of the user-based authentication // parameters. if options.Username != "" { return createErr(ErrUsernameWithToken) } if options.UserID != "" { return createErr(ErrUserIDWithToken) } // Configure the request for Token authentication. req.Auth.Identity.Methods = []string{"token"} req.Auth.Identity.Token = &tokenReq{ ID: c.TokenID, } } else { // If no password or token ID are available, authentication can't continue. return createErr(ErrMissingPassword) } } else { // Password authentication. req.Auth.Identity.Methods = []string{"password"} // At least one of Username and UserID must be specified. if options.Username == "" && options.UserID == "" { return createErr(ErrUsernameOrUserID) } if options.Username != "" { // If Username is provided, UserID may not be provided. if options.UserID != "" { return createErr(ErrUsernameOrUserID) } // Either DomainID or DomainName must also be specified. if options.DomainID == "" && options.DomainName == "" { return createErr(ErrDomainIDOrDomainName) } if options.DomainID != "" { if options.DomainName != "" { return createErr(ErrDomainIDOrDomainName) } // Configure the request for Username and Password authentication with a DomainID. req.Auth.Identity.Password = &passwordReq{ User: userReq{ Name: &options.Username, Password: options.Password, Domain: &domainReq{ID: &options.DomainID}, }, } } if options.DomainName != "" { // Configure the request for Username and Password authentication with a DomainName. req.Auth.Identity.Password = &passwordReq{ User: userReq{ Name: &options.Username, Password: options.Password, Domain: &domainReq{Name: &options.DomainName}, }, } } } if options.UserID != "" { // If UserID is specified, neither DomainID nor DomainName may be. if options.DomainID != "" { return createErr(ErrDomainIDWithUserID) } if options.DomainName != "" { return createErr(ErrDomainNameWithUserID) } // Configure the request for UserID and Password authentication. req.Auth.Identity.Password = &passwordReq{ User: userReq{ID: &options.UserID, Password: options.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 createErr(ErrScopeDomainIDOrDomainName) } if scope.ProjectID != "" { return createErr(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 createErr(ErrScopeProjectIDAlone) } if scope.DomainName != "" { return createErr(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 createErr(ErrScopeDomainIDOrDomainName) } // DomainID req.Auth.Scope = &scopeReq{ Domain: &domainReq{ID: &scope.DomainID}, } } else if scope.DomainName != "" { return createErr(ErrScopeDomainName) } else { return createErr(ErrScopeEmpty) } } var result CreateResult var response *http.Response response, result.Err = c.Post(tokenURL(c), req, &result.Body, nil) if result.Err != nil { return result } result.Header = response.Header return result }