rclone/backend/s3/ibm_signer.go

60 lines
1.7 KiB
Go

package s3
import (
"context"
"net/http"
"time"
"github.com/IBM/go-sdk-core/v5/core"
"github.com/aws/aws-sdk-go-v2/aws"
v4signer "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
)
// Authenticator defines an interface for obtaining an IAM token.
type Authenticator interface {
GetToken() (string, error)
}
// IbmIamSigner is a structure for signing requests using IBM IAM.
// Requeres APIKey and Resource InstanceID
type IbmIamSigner struct {
APIKey string
InstanceID string
Auth Authenticator
}
// SignHTTP signs requests using IBM IAM token.
func (signer *IbmIamSigner) SignHTTP(ctx context.Context, credentials aws.Credentials, req *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4signer.SignerOptions)) error {
var authenticator Authenticator
if signer.Auth != nil {
authenticator = signer.Auth
} else {
authenticator = &core.IamAuthenticator{ApiKey: signer.APIKey}
}
token, err := authenticator.GetToken()
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+token)
req.Header.Set("ibm-service-instance-id", signer.InstanceID)
return nil
}
// NoOpCredentialsProvider is needed since S3 SDK requires having credentials, eventhough authentication is happening via IBM IAM.
type NoOpCredentialsProvider struct{}
// Retrieve returns mock credentials for the NoOpCredentialsProvider.
func (n *NoOpCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) {
return aws.Credentials{
AccessKeyID: "NoOpAccessKey",
SecretAccessKey: "NoOpSecretKey",
SessionToken: "",
Source: "NoOpCredentialsProvider",
}, nil
}
// IsExpired always returns false
func (n *NoOpCredentialsProvider) IsExpired() bool {
return false
}