go_study/fabric-main/common/deliver/acl_test.go

137 lines
3.9 KiB
Go

/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package deliver_test
import (
"time"
cb "github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric/common/deliver"
"github.com/hyperledger/fabric/common/deliver/mock"
"github.com/hyperledger/fabric/protoutil"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
)
var _ = Describe("SessionAccessControl", func() {
var (
fakeChain *mock.Chain
envelope *cb.Envelope
fakePolicyChecker *mock.PolicyChecker
expiresAt deliver.ExpiresAtFunc
)
BeforeEach(func() {
envelope = &cb.Envelope{
Payload: protoutil.MarshalOrPanic(&cb.Payload{
Header: &cb.Header{},
}),
}
fakeChain = &mock.Chain{}
fakePolicyChecker = &mock.PolicyChecker{}
expiresAt = func([]byte) time.Time { return time.Time{} }
})
It("evaluates the policy", func() {
sac, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).NotTo(HaveOccurred())
err = sac.Evaluate()
Expect(err).NotTo(HaveOccurred())
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(1))
env, cid := fakePolicyChecker.CheckPolicyArgsForCall(0)
Expect(env).To(Equal(envelope))
Expect(cid).To(Equal("chain-id"))
})
Context("when policy evaluation returns an error", func() {
BeforeEach(func() {
fakePolicyChecker.CheckPolicyReturns(errors.New("no-access-for-you"))
})
It("returns the evaluation error", func() {
sac, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).NotTo(HaveOccurred())
err = sac.Evaluate()
Expect(err).To(MatchError("no-access-for-you"))
})
})
It("caches positive policy evaluation", func() {
sac, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).NotTo(HaveOccurred())
for i := 0; i < 5; i++ {
err = sac.Evaluate()
Expect(err).NotTo(HaveOccurred())
}
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(1))
})
Context("when the config sequence changes", func() {
BeforeEach(func() {
fakePolicyChecker.CheckPolicyReturnsOnCall(2, errors.New("access-now-denied"))
})
It("re-evaluates the policy", func() {
sac, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).NotTo(HaveOccurred())
Expect(sac.Evaluate()).To(Succeed())
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(1))
Expect(sac.Evaluate()).To(Succeed())
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(1))
fakeChain.SequenceReturns(2)
Expect(sac.Evaluate()).To(Succeed())
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(2))
Expect(sac.Evaluate()).To(Succeed())
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(2))
fakeChain.SequenceReturns(3)
Expect(sac.Evaluate()).To(MatchError("access-now-denied"))
Expect(fakePolicyChecker.CheckPolicyCallCount()).To(Equal(3))
})
})
Context("when an identity expires", func() {
BeforeEach(func() {
expiresAt = func([]byte) time.Time {
return time.Now().Add(250 * time.Millisecond)
}
})
It("returns an identity expired error", func() {
sac, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).NotTo(HaveOccurred())
err = sac.Evaluate()
Expect(err).NotTo(HaveOccurred())
Eventually(sac.Evaluate).Should(MatchError(ContainSubstring("deliver client identity expired")))
})
})
Context("when the envelope cannot be represented as signed data", func() {
BeforeEach(func() {
envelope = &cb.Envelope{}
})
It("returns an error", func() {
_, expectedError := protoutil.EnvelopeAsSignedData(envelope)
Expect(expectedError).To(HaveOccurred())
_, err := deliver.NewSessionAC(fakeChain, envelope, fakePolicyChecker, "chain-id", expiresAt)
Expect(err).To(Equal(expectedError))
})
})
})