3 import "github.com/gophercloud/gophercloud"
5 // Scope allows a created token to be limited to a specific domain or project.
13 // AuthOptionsBuilder provides the ability for extensions to add additional
14 // parameters to AuthOptions. Extensions must satisfy all required methods.
15 type AuthOptionsBuilder interface {
16 // ToTokenV3CreateMap assembles the Create request body, returning an error
17 // if parameters are missing or inconsistent.
18 ToTokenV3CreateMap(map[string]interface{}) (map[string]interface{}, error)
19 ToTokenV3ScopeMap() (map[string]interface{}, error)
23 // AuthOptions represents options for authenticating a user.
24 type AuthOptions struct {
25 // IdentityEndpoint specifies the HTTP endpoint that is required to work with
26 // the Identity API of the appropriate version. While it's ultimately needed
27 // by all of the identity services, it will often be populated by a
28 // provider-level function.
29 IdentityEndpoint string `json:"-"`
31 // Username is required if using Identity V2 API. Consult with your provider's
32 // control panel to discover your account's username. In Identity V3, either
33 // UserID or a combination of Username and DomainID or DomainName are needed.
34 Username string `json:"username,omitempty"`
35 UserID string `json:"id,omitempty"`
37 Password string `json:"password,omitempty"`
39 // At most one of DomainID and DomainName must be provided if using Username
40 // with Identity V3. Otherwise, either are optional.
41 DomainID string `json:"-"`
42 DomainName string `json:"name,omitempty"`
44 // AllowReauth should be set to true if you grant permission for Gophercloud
45 // to cache your credentials in memory, and to allow Gophercloud to attempt
46 // to re-authenticate automatically if/when your token expires. If you set
47 // it to false, it will not cache these settings, but re-authentication will
48 // not be possible. This setting defaults to false.
49 AllowReauth bool `json:"-"`
51 // TokenID allows users to authenticate (possibly as another user) with an
52 // authentication token ID.
53 TokenID string `json:"-"`
55 // Authentication through Application Credentials requires supplying name, project and secret
56 // For project we can use TenantID
57 ApplicationCredentialID string `json:"-"`
58 ApplicationCredentialName string `json:"-"`
59 ApplicationCredentialSecret string `json:"-"`
61 Scope Scope `json:"-"`
64 // ToTokenV3CreateMap builds a request body from AuthOptions.
65 func (opts *AuthOptions) ToTokenV3CreateMap(scope map[string]interface{}) (map[string]interface{}, error) {
66 gophercloudAuthOpts := gophercloud.AuthOptions{
67 Username: opts.Username,
69 Password: opts.Password,
70 DomainID: opts.DomainID,
71 DomainName: opts.DomainName,
72 AllowReauth: opts.AllowReauth,
73 TokenID: opts.TokenID,
74 ApplicationCredentialID: opts.ApplicationCredentialID,
75 ApplicationCredentialName: opts.ApplicationCredentialName,
76 ApplicationCredentialSecret: opts.ApplicationCredentialSecret,
79 return gophercloudAuthOpts.ToTokenV3CreateMap(scope)
82 // ToTokenV3CreateMap builds a scope request body from AuthOptions.
83 func (opts *AuthOptions) ToTokenV3ScopeMap() (map[string]interface{}, error) {
84 scope := gophercloud.AuthScope(opts.Scope)
86 gophercloudAuthOpts := gophercloud.AuthOptions{
88 DomainID: opts.DomainID,
89 DomainName: opts.DomainName,
92 return gophercloudAuthOpts.ToTokenV3ScopeMap()
95 func (opts *AuthOptions) CanReauth() bool {
96 return opts.AllowReauth
99 func subjectTokenHeaders(c *gophercloud.ServiceClient, subjectToken string) map[string]string {
100 return map[string]string{
101 "X-Subject-Token": subjectToken,
105 // Create authenticates and either generates a new token, or changes the Scope
106 // of an existing token.
107 func Create(c *gophercloud.ServiceClient, opts AuthOptionsBuilder) (r CreateResult) {
108 scope, err := opts.ToTokenV3ScopeMap()
114 b, err := opts.ToTokenV3CreateMap(scope)
120 resp, err := c.Post(tokenURL(c), b, &r.Body, &gophercloud.RequestOpts{
121 MoreHeaders: map[string]string{"X-Auth-Token": ""},
125 r.Header = resp.Header
130 // Get validates and retrieves information about another token.
131 func Get(c *gophercloud.ServiceClient, token string) (r GetResult) {
132 resp, err := c.Get(tokenURL(c), &r.Body, &gophercloud.RequestOpts{
133 MoreHeaders: subjectTokenHeaders(c, token),
134 OkCodes: []int{200, 203},
138 r.Header = resp.Header
143 // Validate determines if a specified token is valid or not.
144 func Validate(c *gophercloud.ServiceClient, token string) (bool, error) {
145 resp, err := c.Head(tokenURL(c), &gophercloud.RequestOpts{
146 MoreHeaders: subjectTokenHeaders(c, token),
147 OkCodes: []int{200, 204, 404},
153 return resp.StatusCode == 200 || resp.StatusCode == 204, nil
156 // Revoke immediately makes specified token invalid.
157 func Revoke(c *gophercloud.ServiceClient, token string) (r RevokeResult) {
158 _, r.Err = c.Delete(tokenURL(c), &gophercloud.RequestOpts{
159 MoreHeaders: subjectTokenHeaders(c, token),