Skip to content

Commit

Permalink
[v1] identity: use AuthOptionsBuilder for v2 auth
Browse files Browse the repository at this point in the history
Rather than creating a tokens2.AuthOptions inside the authentication
flow for identity v2, allow any structure that implements the
tokens2.AuthBuilderOptions interface to be used. The
gophercloud.AuthOptions already implements this interface so there
is no change to the API. To avoid any API change, add
AuthenticateV2Ext() as a version of AuthenticateV2() accepting the
interface. This will allow an out of tree identity v2 auth mechanism
to be implemented, just like the v3. fixes gophercloud#2651. ref gophercloud#1330.
  • Loading branch information
cardoe committed Apr 14, 2024
1 parent fab2a6e commit 92421bd
Showing 1 changed file with 23 additions and 15 deletions.
38 changes: 23 additions & 15 deletions openstack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ func AuthenticateV2(client *gophercloud.ProviderClient, options gophercloud.Auth
return v2auth(client, "", options, eo)
}

func v2auth(client *gophercloud.ProviderClient, endpoint string, options gophercloud.AuthOptions, eo gophercloud.EndpointOpts) error {
func AuthenticateV2Ext(client *gophercloud.ProviderClient, options tokens2.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
return v2auth(client, "", options, eo)
}

func v2auth(client *gophercloud.ProviderClient, endpoint string, options tokens2.AuthOptionsBuilder, eo gophercloud.EndpointOpts) error {
v2Client, err := NewIdentityV2(client, eo)
if err != nil {
return err
Expand All @@ -126,17 +130,7 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc
v2Client.Endpoint = endpoint
}

v2Opts := tokens2.AuthOptions{
IdentityEndpoint: options.IdentityEndpoint,
Username: options.Username,
Password: options.Password,
TenantID: options.TenantID,
TenantName: options.TenantName,
AllowReauth: options.AllowReauth,
TokenID: options.TokenID,
}

result := tokens2.Create(v2Client, v2Opts)
result := tokens2.Create(v2Client, options)

err = client.SetTokenAndAuthResult(result)
if err != nil {
Expand All @@ -148,16 +142,30 @@ func v2auth(client *gophercloud.ProviderClient, endpoint string, options gopherc
return err
}

if options.AllowReauth {
// use if the client's ReauthFunc is set to avoid needing to copy the AuthOptions and mutating the AllowReauth value
// when creating the reauthentication function below. this allows breaking of the loop without v2auth having to have
// knowledge of the supplied struct, allowing for out of tree extensions
if client.ReauthFunc != nil {
// here we're creating a throw-away client (tac). it's a copy of the user's provider client, but
// with the token and reauth func zeroed out. combined with setting `AllowReauth` to `false`,
// this should retry authentication only once
tac := *client
tac.SetThrowaway(true)
tac.ReauthFunc = nil
tac.SetTokenAndAuthResult(nil)
tao := options
tao.AllowReauth = false
var tao tokens2.AuthOptionsBuilder
switch ot := options.(type) {
case *gophercloud.AuthOptions:
o := *ot
o.AllowReauth = false
tao = &o
case *tokens2.AuthOptions:
o := *ot
o.AllowReauth = false
tao = &o
default:
tao = options
}
client.ReauthFunc = func() error {
err := v2auth(&tac, endpoint, tao, eo)
if err != nil {
Expand Down

0 comments on commit 92421bd

Please sign in to comment.