package v2 import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "testing" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/acl" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session" bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test" aclsdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl" cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test" oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test" sessionSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session" sessiontest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session/test" "github.com/stretchr/testify/require" ) func TestOriginalTokens(t *testing.T) { sToken := sessiontest.ObjectSigned() bToken := bearertest.Token() pk, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) require.NoError(t, bToken.Sign(*pk)) var bTokenV2 acl.BearerToken bToken.WriteToV2(&bTokenV2) // This line is needed because SDK uses some custom format for // reserved filters, so `cid.ID` is not converted to string immediately. require.NoError(t, bToken.ReadFromV2(bTokenV2)) var sTokenV2 session.Token sToken.WriteToV2(&sTokenV2) for i := 0; i < 10; i++ { metaHeaders := testGenerateMetaHeader(uint32(i), &bTokenV2, &sTokenV2) res, err := originalSessionToken(metaHeaders) require.NoError(t, err) require.Equal(t, sToken, res, i) bTok, err := originalBearerToken(metaHeaders) require.NoError(t, err) require.Equal(t, &bToken, bTok, i) } } func testGenerateMetaHeader(depth uint32, b *acl.BearerToken, s *session.Token) *session.RequestMetaHeader { metaHeader := new(session.RequestMetaHeader) metaHeader.SetBearerToken(b) metaHeader.SetSessionToken(s) for i := uint32(0); i < depth; i++ { link := metaHeader metaHeader = new(session.RequestMetaHeader) metaHeader.SetOrigin(link) } return metaHeader } func TestIsVerbCompatible(t *testing.T) { // Source: https://nspcc.ru/upload/frostfs-spec-latest.pdf#page=28 table := map[aclsdk.Op][]sessionSDK.ObjectVerb{ aclsdk.OpObjectPut: {sessionSDK.VerbObjectPut, sessionSDK.VerbObjectDelete}, aclsdk.OpObjectDelete: {sessionSDK.VerbObjectDelete}, aclsdk.OpObjectGet: {sessionSDK.VerbObjectGet}, aclsdk.OpObjectHead: { sessionSDK.VerbObjectHead, sessionSDK.VerbObjectGet, sessionSDK.VerbObjectDelete, sessionSDK.VerbObjectRange, sessionSDK.VerbObjectRangeHash, }, aclsdk.OpObjectRange: {sessionSDK.VerbObjectRange, sessionSDK.VerbObjectRangeHash}, aclsdk.OpObjectHash: {sessionSDK.VerbObjectRangeHash}, aclsdk.OpObjectSearch: {sessionSDK.VerbObjectSearch, sessionSDK.VerbObjectDelete}, } verbs := []sessionSDK.ObjectVerb{ sessionSDK.VerbObjectPut, sessionSDK.VerbObjectDelete, sessionSDK.VerbObjectHead, sessionSDK.VerbObjectRange, sessionSDK.VerbObjectRangeHash, sessionSDK.VerbObjectGet, sessionSDK.VerbObjectSearch, } var tok sessionSDK.Object for op, list := range table { for _, verb := range verbs { var contains bool for _, v := range list { if v == verb { contains = true break } } tok.ForVerb(verb) require.Equal(t, contains, assertVerb(tok, op), "%v in token, %s executing", verb, op) } } } func TestAssertSessionRelation(t *testing.T) { var tok sessionSDK.Object cnr := cidtest.ID() cnrOther := cidtest.ID() obj := oidtest.ID() objOther := oidtest.ID() // make sure ids differ, otherwise test won't work correctly require.False(t, cnrOther.Equals(cnr)) require.False(t, objOther.Equals(obj)) // bind session to the container (required) tok.BindContainer(cnr) // test container-global session require.NoError(t, assertSessionRelation(tok, cnr, nil)) require.NoError(t, assertSessionRelation(tok, cnr, &obj)) require.Error(t, assertSessionRelation(tok, cnrOther, nil)) require.Error(t, assertSessionRelation(tok, cnrOther, &obj)) // limit the session to the particular object tok.LimitByObjects(obj) // test fixed object session (here obj arg must be non-nil everywhere) require.NoError(t, assertSessionRelation(tok, cnr, &obj)) require.Error(t, assertSessionRelation(tok, cnr, &objOther)) }