dsl struct tags; wip
diff --git a/openstack/identity/v3/tokens/requests.go b/openstack/identity/v3/tokens/requests.go
index 4b87311..e7320fd 100644
--- a/openstack/identity/v3/tokens/requests.go
+++ b/openstack/identity/v3/tokens/requests.go
@@ -6,12 +6,11 @@
"github.com/gophercloud/gophercloud"
)
-// Scope allows a created token to be limited to a specific domain or project.
-type Scope struct {
- ProjectID string
- ProjectName string
- DomainID string
- DomainName string
+// 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)
}
func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
@@ -21,241 +20,33 @@
}
// 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"`
+func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder, scopeOpts *gophercloud.ScopeOptsV3) CreateResult {
+ var r CreateResult
+ b, err := opts.ToTokenV3CreateMap(scopeOpts)
+ if err != nil {
+ r.Err = err
+ return r
}
-
- type projectReq struct {
- Domain *domainReq `json:"domain,omitempty"`
- Name *string `json:"name,omitempty"`
- ID *string `json:"id,omitempty"`
+ var resp *http.Response
+ resp, r.Err = c.Post(tokenURL(c), b, &r.Body, nil)
+ if resp != nil {
+ r.Header = resp.Header
}
-
- 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 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)
- }
- if options.DomainID != "" {
- return createErr(ErrDomainIDWithToken)
- }
- if options.DomainName != "" {
- return createErr(ErrDomainNameWithToken)
- }
-
- // 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
+ return r
}
// Get validates and retrieves information about another token.
func Get(c *gophercloud.ServiceClient, token string) GetResult {
- var result GetResult
- var response *http.Response
- response, result.Err = c.Get(tokenURL(c), &result.Body, &gophercloud.RequestOpts{
+ var r GetResult
+ var resp *http.Response
+ resp, r.Err = c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token),
OkCodes: []int{200, 203},
})
- if result.Err != nil {
- return result
+ if resp != nil {
+ r.Header = resp.Header
}
- result.Header = response.Header
- return result
+ return r
}
// Validate determines if a specified token is valid or not.
@@ -273,9 +64,9 @@
// Revoke immediately makes specified token invalid.
func Revoke(c *gophercloud.ServiceClient, token string) RevokeResult {
- var res RevokeResult
- _, res.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
+ var r RevokeResult
+ _, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
MoreHeaders: subjectTokenHeaders(c, token),
})
- return res
+ return r
}