Convert ListImages to use reauth.
This commit does not work -- acceptance test 08-... is broken.
diff --git a/authenticate.go b/authenticate.go
index edd447c..f98c4cc 100644
--- a/authenticate.go
+++ b/authenticate.go
@@ -2,6 +2,7 @@
import (
"github.com/racker/perigee"
+ "fmt"
)
// AuthOptions lets anyone calling Authenticate() supply the required access credentials.
@@ -16,6 +17,13 @@
// The TenantId field is optional for the Identity V2 API.
TenantId string
+
+ // 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
}
// AuthContainer provides a JSON encoding wrapper for passing credentials to the Identity
@@ -45,6 +53,8 @@
ServiceCatalog []CatalogEntry
User User
provider Provider `json:"-"`
+ options AuthOptions `json:"-"`
+ context *Context `json:"-"`
}
// Token encapsulates an authentication token and when it expires. It also includes
@@ -86,30 +96,18 @@
VersionId, VersionInfo, VersionList string
}
-// Authenticate() grants access to the OpenStack-compatible provider API.
-//
-// Providers are identified through a unique key string.
-// See the RegisterProvider() method for more details.
-//
-// The supplied AuthOptions instance allows the client to specify only those credentials
-// relevant for the authentication request. At present, support exists for OpenStack
-// Identity V2 API only; support for V3 will become available as soon as documentation for it
-// becomes readily available.
-//
-// For Identity V2 API requirements, you must provide at least the Username and Password
-// options. The TenantId field is optional, and defaults to "".
-func (c *Context) Authenticate(provider string, options AuthOptions) (*Access, error) {
+// papersPlease contains the common logic between authentication and re-authentication.
+// The name, obviously a joke on the process of authentication, was chosen because
+// of how many other entities exist in the program containing the word Auth or Authorization.
+// I didn't need another one.
+func (c *Context) papersPlease(p Provider, options AuthOptions) (*Access, error) {
var access *Access
- p, err := c.ProviderByName(provider)
- if err != nil {
- return nil, err
- }
if (options.Username == "") || (options.Password == "") {
return nil, ErrCredentials
}
- err = perigee.Post(p.AuthEndpoint, perigee.Options{
+ err := perigee.Post(p.AuthEndpoint, perigee.Options{
CustomClient: c.httpClient,
ReqBody: &AuthContainer{
Auth: Auth{
@@ -127,11 +125,51 @@
},
})
if err == nil {
+ access.options = options
access.provider = p
+ access.context = c
}
return access, err
}
+// Authenticate() grants access to the OpenStack-compatible provider API.
+//
+// Providers are identified through a unique key string.
+// See the RegisterProvider() method for more details.
+//
+// The supplied AuthOptions instance allows the client to specify only those credentials
+// relevant for the authentication request. At present, support exists for OpenStack
+// Identity V2 API only; support for V3 will become available as soon as documentation for it
+// becomes readily available.
+//
+// For Identity V2 API requirements, you must provide at least the Username and Password
+// options. The TenantId field is optional, and defaults to "".
+func (c *Context) Authenticate(provider string, options AuthOptions) (*Access, error) {
+ p, err := c.ProviderByName(provider)
+ if err != nil {
+ return nil, err
+ }
+ return c.papersPlease(p, options)
+}
+
+// Reauthenticate attempts to reauthenticate using the configured access credentials, if
+// allowed. This method takes no action unless your AuthOptions has the AllowReauth flag
+// set to true.
+func (a *Access) Reauthenticate() error {
+ var other *Access
+ var err error
+
+ fmt.Printf("**\n %#v\n", a.options)
+ if a.options.AllowReauth {
+ other, err = a.context.papersPlease(a.provider, a.options)
+ if err != nil {
+ fmt.Println("NEW NEW: ", other.AuthToken())
+ *a = *other
+ }
+ }
+ return err
+}
+
// See AccessProvider interface definition for details.
func (a *Access) FirstEndpointUrlByCriteria(ac ApiCriteria) string {
ep := FindFirstEndpointByCriteria(a.ServiceCatalog, ac)