diff --git a/swift/auth.go b/swift/auth.go index 1eecdbce6..8e222b271 100644 --- a/swift/auth.go +++ b/swift/auth.go @@ -1,29 +1,76 @@ package swift -import "github.com/ncw/swift" +import ( + "net/http" -// auth is an authenticator for swift + "github.com/ncw/swift" +) + +// auth is an authenticator for swift. It overrides the StorageUrl +// and AuthToken with fixed values. type auth struct { - swift.Authenticator + parentAuth swift.Authenticator storageURL string + authToken string } // newAuth creates a swift authenticator wrapper to override the -// StorageUrl method. -func newAuth(Authenticator swift.Authenticator, storageURL string) *auth { +// StorageUrl and AuthToken values. +// +// Note that parentAuth can be nil +func newAuth(parentAuth swift.Authenticator, storageURL string, authToken string) *auth { return &auth{ - Authenticator: Authenticator, - storageURL: storageURL, + parentAuth: parentAuth, + storageURL: storageURL, + authToken: authToken, } } +// Request creates an http.Request for the auth - return nil if not needed +func (a *auth) Request(c *swift.Connection) (*http.Request, error) { + if a.parentAuth == nil { + return nil, nil + } + return a.parentAuth.Request(c) +} + +// Response parses the http.Response +func (a *auth) Response(resp *http.Response) error { + if a.parentAuth == nil { + return nil + } + return a.parentAuth.Response(resp) +} + // The public storage URL - set Internal to true to read // internal/service net URL func (a *auth) StorageUrl(Internal bool) string { if a.storageURL != "" { return a.storageURL } - return a.Authenticator.StorageUrl(Internal) + if a.parentAuth == nil { + return "" + } + return a.parentAuth.StorageUrl(Internal) +} + +// The access token +func (a *auth) Token() string { + if a.authToken != "" { + return a.authToken + } + if a.parentAuth == nil { + return "" + } + return a.parentAuth.Token() +} + +// The CDN url if available +func (a *auth) CdnUrl() string { + if a.parentAuth == nil { + return "" + } + return a.parentAuth.CdnUrl() } // Check the interfaces are satisfied diff --git a/swift/swift.go b/swift/swift.go index d84cc5b5a..da058e3be 100644 --- a/swift/swift.go +++ b/swift/swift.go @@ -191,17 +191,15 @@ func parsePath(path string) (container, directory string, err error) { func swiftConnection(name string) (*swift.Connection, error) { c := &swift.Connection{ // Keep these in the same order as the Config for ease of checking - UserName: fs.ConfigFileGet(name, "user"), - ApiKey: fs.ConfigFileGet(name, "key"), - AuthUrl: fs.ConfigFileGet(name, "auth"), - UserId: fs.ConfigFileGet(name, "user_id"), - Domain: fs.ConfigFileGet(name, "domain"), - Tenant: fs.ConfigFileGet(name, "tenant"), - TenantId: fs.ConfigFileGet(name, "tenant_id"), - TenantDomain: fs.ConfigFileGet(name, "tenant_domain"), - Region: fs.ConfigFileGet(name, "region"), - // I get the StorageUrl already here, in case the user wants to set it manually - // (e.g. when using alternate authentication) + UserName: fs.ConfigFileGet(name, "user"), + ApiKey: fs.ConfigFileGet(name, "key"), + AuthUrl: fs.ConfigFileGet(name, "auth"), + UserId: fs.ConfigFileGet(name, "user_id"), + Domain: fs.ConfigFileGet(name, "domain"), + Tenant: fs.ConfigFileGet(name, "tenant"), + TenantId: fs.ConfigFileGet(name, "tenant_id"), + TenantDomain: fs.ConfigFileGet(name, "tenant_domain"), + Region: fs.ConfigFileGet(name, "region"), StorageUrl: fs.ConfigFileGet(name, "storage_url"), AuthToken: fs.ConfigFileGet(name, "auth_token"), AuthVersion: fs.ConfigFileGetInt(name, "auth_version", 0), @@ -231,6 +229,11 @@ func swiftConnection(name string) (*swift.Connection, error) { return nil, err } } + // Make sure we re-auth with the AuthToken and StorageUrl + // provided by wrapping the existing auth + if c.StorageUrl != "" || c.AuthToken != "" { + c.Auth = newAuth(c.Auth, c.StorageUrl, c.AuthToken) + } return c, nil } @@ -257,12 +260,6 @@ func NewFsWithConnection(name, root string, c *swift.Connection, noCheckContaine WriteMimeType: true, BucketBased: true, }).Fill(f) - // StorageURL overloading - storageURL := fs.ConfigFileGet(name, "storage_url") - if storageURL != "" { - f.c.StorageUrl = storageURL - f.c.Auth = newAuth(f.c.Auth, storageURL) - } if f.root != "" { f.root += "/" // Check to see if the object exists - ignoring directory markers