202 lines
5.7 KiB
Go
202 lines
5.7 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
v4a "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/auth/signer/v4asdk2"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
|
"github.com/aws/aws-sdk-go-v2/aws"
|
|
credentialsv2 "github.com/aws/aws-sdk-go-v2/credentials"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap/zaptest"
|
|
)
|
|
|
|
var _ tokens.Credentials = (*credentialsMock)(nil)
|
|
|
|
type credentialsMock struct {
|
|
boxes map[string]*accessbox.Box
|
|
}
|
|
|
|
func newTokensFrostfsMock() *credentialsMock {
|
|
return &credentialsMock{
|
|
boxes: make(map[string]*accessbox.Box),
|
|
}
|
|
}
|
|
|
|
func (m credentialsMock) addBox(addr oid.Address, box *accessbox.Box) {
|
|
m.boxes[getAccessKeyID(addr)] = box
|
|
}
|
|
|
|
func (m credentialsMock) GetBox(_ context.Context, _ cid.ID, accessKeyID string) (*accessbox.Box, []object.Attribute, error) {
|
|
box, ok := m.boxes[accessKeyID]
|
|
if !ok {
|
|
return nil, nil, &apistatus.ObjectNotFound{}
|
|
}
|
|
|
|
return box, nil, nil
|
|
}
|
|
|
|
func (m credentialsMock) Put(context.Context, tokens.CredentialsParam) (oid.Address, error) {
|
|
return oid.Address{}, nil
|
|
}
|
|
|
|
func (m credentialsMock) Update(context.Context, tokens.CredentialsParam) (oid.Address, error) {
|
|
return oid.Address{}, nil
|
|
}
|
|
|
|
func TestCheckSign(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
var accessKeyAddr oid.Address
|
|
err := accessKeyAddr.DecodeString("8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto")
|
|
require.NoError(t, err)
|
|
|
|
accessKeyID := strings.ReplaceAll(accessKeyAddr.String(), "/", "0")
|
|
secretKey := "713d0a0b9efc7d22923e17b0402a6a89b4273bc711c8bacb2da1b643d0006aeb"
|
|
awsCreds := aws.Credentials{AccessKeyID: accessKeyID, SecretAccessKey: secretKey}
|
|
|
|
reqData := RequestData{
|
|
Method: "GET",
|
|
Endpoint: "http://localhost:8084",
|
|
Bucket: "my-bucket",
|
|
Object: "@obj/name",
|
|
}
|
|
presignData := PresignData{
|
|
Service: "s3",
|
|
Region: "spb",
|
|
Lifetime: 10 * time.Minute,
|
|
SignTime: time.Now().UTC(),
|
|
Headers: map[string]string{
|
|
ContentTypeHdr: "text/plain",
|
|
AmzContentSHA256: UnsignedPayload,
|
|
},
|
|
}
|
|
|
|
req, err := PresignRequest(ctx, awsCreds, reqData, presignData, zaptest.NewLogger(t))
|
|
require.NoError(t, err)
|
|
|
|
expBox := &accessbox.Box{
|
|
Gate: &accessbox.GateData{
|
|
SecretKey: secretKey,
|
|
},
|
|
}
|
|
|
|
mock := newTokensFrostfsMock()
|
|
mock.addBox(accessKeyAddr, expBox)
|
|
|
|
c := &Center{
|
|
cli: mock,
|
|
reg: NewRegexpMatcher(AuthorizationFieldRegexp),
|
|
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
|
|
settings: ¢erSettingsMock{},
|
|
}
|
|
box, err := c.Authenticate(req)
|
|
require.NoError(t, err)
|
|
require.EqualValues(t, expBox, box.AccessBox)
|
|
}
|
|
|
|
func TestCheckSignV4a(t *testing.T) {
|
|
var accessKeyAddr oid.Address
|
|
err := accessKeyAddr.DecodeString("8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto")
|
|
require.NoError(t, err)
|
|
|
|
accessKeyID := strings.ReplaceAll(accessKeyAddr.String(), "/", "0")
|
|
secretKey := "713d0a0b9efc7d22923e17b0402a6a89b4273bc711c8bacb2da1b643d0006aeb"
|
|
awsCreds := aws.Credentials{AccessKeyID: accessKeyID, SecretAccessKey: secretKey}
|
|
|
|
reqData := RequestData{
|
|
Method: "GET",
|
|
Endpoint: "http://localhost:8084",
|
|
Bucket: "my-bucket",
|
|
Object: "@obj/name",
|
|
}
|
|
presignData := PresignData{
|
|
Service: "s3",
|
|
Region: "spb",
|
|
Lifetime: 10 * time.Minute,
|
|
SignTime: time.Now().UTC(),
|
|
Headers: map[string]string{
|
|
ContentTypeHdr: "text/plain",
|
|
},
|
|
}
|
|
|
|
req, err := PresignRequestV4a(awsCreds, reqData, presignData, zaptest.NewLogger(t))
|
|
require.NoError(t, err)
|
|
|
|
req.Header.Set(ContentTypeHdr, "text/plain")
|
|
|
|
expBox := &accessbox.Box{
|
|
Gate: &accessbox.GateData{
|
|
SecretKey: secretKey,
|
|
},
|
|
}
|
|
|
|
mock := newTokensFrostfsMock()
|
|
mock.addBox(accessKeyAddr, expBox)
|
|
|
|
c := &Center{
|
|
cli: mock,
|
|
regV4a: NewRegexpMatcher(authorizationFieldV4aRegexp),
|
|
postReg: NewRegexpMatcher(postPolicyCredentialRegexp),
|
|
}
|
|
box, err := c.Authenticate(req)
|
|
require.NoError(t, err)
|
|
require.EqualValues(t, expBox, box.AccessBox)
|
|
}
|
|
|
|
func TestPresignRequestV4a(t *testing.T) {
|
|
var accessKeyAddr oid.Address
|
|
err := accessKeyAddr.DecodeString("8N7CYBY74kxZXoyvA5UNdmovaXqFpwNfvEPsqaN81es2/3tDwq5tR8fByrJcyJwyiuYX7Dae8tyDT7pd8oaL1MBto")
|
|
require.NoError(t, err)
|
|
|
|
accessKeyID := strings.ReplaceAll(accessKeyAddr.String(), "/", "0")
|
|
secretKey := "713d0a0b9efc7d22923e17b0402a6a89b4273bc711c8bacb2da1b643d0006aeb"
|
|
|
|
signer := v4a.NewSigner(func(options *v4a.SignerOptions) {
|
|
options.DisableURIPathEscaping = true
|
|
options.LogSigning = true
|
|
options.Logger = zaptest.NewLogger(t)
|
|
})
|
|
|
|
credAdapter := v4a.SymmetricCredentialAdaptor{
|
|
SymmetricProvider: credentialsv2.NewStaticCredentialsProvider(accessKeyID, secretKey, ""),
|
|
}
|
|
|
|
creds, err := credAdapter.RetrievePrivateKey(context.TODO())
|
|
require.NoError(t, err)
|
|
|
|
signingTime := time.Now()
|
|
service := "s3"
|
|
regionSet := []string{"spb"}
|
|
|
|
req, err := http.NewRequest("GET", "http://localhost:8084/bucket/object", nil)
|
|
require.NoError(t, err)
|
|
req.Header.Set(AmzExpires, "600")
|
|
|
|
presignedURL, hdr, err := signer.PresignHTTP(req.Context(), creds, req, "", service, regionSet, signingTime)
|
|
require.NoError(t, err)
|
|
|
|
fmt.Println(presignedURL)
|
|
fmt.Println(hdr)
|
|
|
|
signature := req.URL.Query().Get(AmzSignature)
|
|
|
|
r, err := http.NewRequest("GET", presignedURL, nil)
|
|
require.NoError(t, err)
|
|
query := r.URL.Query()
|
|
query.Del(AmzSignature)
|
|
r.URL.RawQuery = query.Encode()
|
|
|
|
err = signer.VerifyPresigned(creds, r, "", service, regionSet, signingTime, signature)
|
|
require.NoError(t, err)
|
|
}
|