Skip to content

Commit

Permalink
Fix AllowReauth reauthentication
Browse files Browse the repository at this point in the history
Due to an error in implementing the addition of `context.Context`, the
reauth function catched the context passed when generating the
ProviderClient, which could be long canceled when the reauthentication
takes place.

This is a breaking change: this patch changes the signature of the
reauthentication function in the ProviderClient to accept a context.
  • Loading branch information
pierreprinetti committed Feb 20, 2024
1 parent b11d9ad commit 7595af3
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 10 deletions.
3 changes: 2 additions & 1 deletion internal/acceptance/openstack/client_test.go
Expand Up @@ -4,6 +4,7 @@
package openstack

import (
"context"
"os"
"testing"
"time"
Expand Down Expand Up @@ -140,7 +141,7 @@ func TestReauth(t *testing.T) {
time.Sleep(1 * time.Second)
t.Logf("Attempting to reauthenticate")

err = provider.ReauthFunc()
err = provider.ReauthFunc(context.TODO())
if err != nil {
t.Fatalf("Unable to reauthenticate: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions openstack/client.go
Expand Up @@ -170,7 +170,7 @@ func v2auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st
tac.SetTokenAndAuthResult(nil)
tao := options
tao.AllowReauth = false
client.ReauthFunc = func() error {
client.ReauthFunc = func(ctx context.Context) error {
err := v2auth(ctx, &tac, endpoint, tao, eo)
if err != nil {
return err
Expand Down Expand Up @@ -293,7 +293,7 @@ func v3auth(ctx context.Context, client *gophercloud.ProviderClient, endpoint st
default:
tao = opts
}
client.ReauthFunc = func() error {
client.ReauthFunc = func(ctx context.Context) error {
err := v3auth(ctx, &tac, endpoint, tao, eo)
if err != nil {
return err
Expand Down
8 changes: 5 additions & 3 deletions provider_client.go
Expand Up @@ -83,7 +83,7 @@ type ProviderClient struct {
// ReauthFunc is the function used to re-authenticate the user if the request
// fails with a 401 HTTP response code. This a needed because there may be multiple
// authentication functions for different Identity service versions.
ReauthFunc func() error
ReauthFunc func(context.Context) error

// Throwaway determines whether if this client is a throw-away client. It's a copy of user's provider client
// with the token and reauth func zeroed. Such client can be used to perform reauthorization.
Expand Down Expand Up @@ -273,12 +273,14 @@ func (client *ProviderClient) SetThrowaway(v bool) {
// reauthenticated in the meantime. If no previous token is known, an empty
// string should be passed instead to force unconditional reauthentication.
func (client *ProviderClient) Reauthenticate(previousToken string) error {
ctx := context.TODO()

if client.ReauthFunc == nil {
return nil
}

if client.reauthmut == nil {
return client.ReauthFunc()
return client.ReauthFunc(ctx)
}

future := newReauthFuture()
Expand All @@ -299,7 +301,7 @@ func (client *ProviderClient) Reauthenticate(previousToken string) error {
// Perform the actual reauthentication.
var err error
if previousToken == "" || client.TokenID == previousToken {
err = client.ReauthFunc()
err = client.ReauthFunc(ctx)
} else {
err = nil
}
Expand Down
8 changes: 4 additions & 4 deletions testing/provider_client_test.go
Expand Up @@ -66,7 +66,7 @@ func TestConcurrentReauth(t *testing.T) {
p := new(gophercloud.ProviderClient)
p.UseTokenLock()
p.SetToken(prereauthTok)
p.ReauthFunc = func() error {
p.ReauthFunc = func(_ context.Context) error {
p.SetThrowaway(true)
time.Sleep(1 * time.Second)
p.AuthenticatedHeaders()
Expand Down Expand Up @@ -154,7 +154,7 @@ func TestReauthEndLoop(t *testing.T) {
p := new(gophercloud.ProviderClient)
p.UseTokenLock()
p.SetToken(client.TokenID)
p.ReauthFunc = func() error {
p.ReauthFunc = func(_ context.Context) error {
info.mut.Lock()
defer info.mut.Unlock()

Expand Down Expand Up @@ -237,7 +237,7 @@ func TestRequestThatCameDuringReauthWaitsUntilItIsCompleted(t *testing.T) {
p := new(gophercloud.ProviderClient)
p.UseTokenLock()
p.SetToken(prereauthTok)
p.ReauthFunc = func() error {
p.ReauthFunc = func(_ context.Context) error {
info.mut.RLock()
if info.numreauths == 0 {
info.mut.RUnlock()
Expand Down Expand Up @@ -331,7 +331,7 @@ func TestRequestReauthsAtMostOnce(t *testing.T) {
p := new(gophercloud.ProviderClient)
p.UseTokenLock()
p.SetToken(client.TokenID)
p.ReauthFunc = func() error {
p.ReauthFunc = func(_ context.Context) error {
reauthCounterMutex.Lock()
reauthCounter++
reauthCounterMutex.Unlock()
Expand Down

0 comments on commit 7595af3

Please sign in to comment.