Skip to content

Commit 3258f17

Browse files
committed
[FAB-8333] Make peer admin API work with envelopes
The peer admin currently deviates from the spirit of fabric APIs which involves envelopes containing marshaled payloads of proto messages which contain marshaled payloads of other proto messages, and that have channel headers and signature headers, etc. Therefore we should probably standardize the un-used admin API and this make it more robust and similar to other fabric APIs such as the endorser API, the deliver API, etc. Change-Id: If0ed81c6eed02457fda23e1d9359064187651d1d Signed-off-by: yacovm <yacovm@il.ibm.com>
1 parent 65de8e8 commit 3258f17

20 files changed

+1506
-280
lines changed

common/crypto/signer.go

+55-15
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,68 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
package crypto
188

19-
import cb "github.com/hyperledger/fabric/protos/common"
9+
import (
10+
cb "github.com/hyperledger/fabric/protos/common"
11+
)
2012

2113
// LocalSigner is a temporary stub interface which will be implemented by the local MSP
2214
type LocalSigner interface {
15+
SignatureHeaderMaker
16+
Signer
17+
}
18+
19+
// Signer signs messages
20+
type Signer interface {
21+
// Sign a message and return the signature over the digest, or error on failure
22+
Sign(message []byte) ([]byte, error)
23+
}
24+
25+
// IdentitySerializer serializes identities
26+
type IdentitySerializer interface {
27+
// Serialize converts an identity to bytes
28+
Serialize() ([]byte, error)
29+
}
30+
31+
// SignatureHeaderMaker creates a new SignatureHeader
32+
type SignatureHeaderMaker interface {
2333
// NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce
2434
NewSignatureHeader() (*cb.SignatureHeader, error)
35+
}
2536

26-
// Sign a message which should embed a signature header created by NewSignatureHeader
27-
Sign(message []byte) ([]byte, error)
37+
// SignatureHeaderCreator creates signature headers
38+
type SignatureHeaderCreator struct {
39+
SignerSupport
40+
}
41+
42+
// SignerSupport implements the needed support for LocalSigner
43+
type SignerSupport interface {
44+
Signer
45+
IdentitySerializer
46+
}
47+
48+
// NewSignatureHeaderCreator creates new signature headers
49+
func NewSignatureHeaderCreator(ss SignerSupport) *SignatureHeaderCreator {
50+
return &SignatureHeaderCreator{ss}
51+
}
52+
53+
// NewSignatureHeader creates a SignatureHeader with the correct signing identity and a valid nonce
54+
func (bs *SignatureHeaderCreator) NewSignatureHeader() (*cb.SignatureHeader, error) {
55+
creator, err := bs.Serialize()
56+
if err != nil {
57+
return nil, err
58+
}
59+
nonce, err := GetRandomNonce()
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
return &cb.SignatureHeader{
65+
Creator: creator,
66+
Nonce: nonce,
67+
}, nil
2868
}

common/crypto/signer_test.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package crypto
8+
9+
import (
10+
"testing"
11+
12+
"github.com/pkg/errors"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/mock"
15+
)
16+
17+
func bytesFromArgs(args mock.Arguments) ([]byte, error) {
18+
if args.Get(1) != nil {
19+
return nil, args.Error(1)
20+
}
21+
return args.Get(0).([]byte), nil
22+
}
23+
24+
type mockSigner struct {
25+
mock.Mock
26+
}
27+
28+
func (s *mockSigner) Sign(message []byte) ([]byte, error) {
29+
return bytesFromArgs(s.Called(message))
30+
}
31+
32+
type mockIdentitySerializer struct {
33+
mock.Mock
34+
}
35+
36+
func (is *mockIdentitySerializer) Serialize() ([]byte, error) {
37+
return bytesFromArgs(is.Called())
38+
}
39+
40+
type signerSupport struct {
41+
Signer
42+
IdentitySerializer
43+
}
44+
45+
func TestCLISignerNewSignatureHeader(t *testing.T) {
46+
tests := []struct {
47+
name string
48+
signError error
49+
serializeError error
50+
}{
51+
{
52+
name: "SerializeFailure",
53+
serializeError: errors.New("failed1"),
54+
},
55+
{
56+
name: "SignFailure",
57+
serializeError: errors.New("failed2"),
58+
},
59+
{
60+
name: "Success",
61+
},
62+
}
63+
64+
for _, test := range tests {
65+
test := test
66+
t.Run(test.name, func(t *testing.T) {
67+
s := &mockSigner{}
68+
s.On("Sign", mock.Anything).Return([]byte{1, 2, 3}, test.signError)
69+
is := &mockIdentitySerializer{}
70+
is.On("Serialize", mock.Anything).Return([]byte{1, 2, 3}, test.serializeError)
71+
signer := NewSignatureHeaderCreator(&signerSupport{
72+
Signer: s,
73+
IdentitySerializer: is,
74+
})
75+
sh, err := signer.NewSignatureHeader()
76+
if test.serializeError == nil && test.signError == nil {
77+
assert.NoError(t, err)
78+
assert.NotNil(t, sh)
79+
return
80+
}
81+
assert.Error(t, err)
82+
assert.Nil(t, sh)
83+
})
84+
}
85+
}

core/admin.go

+53-27
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,99 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
2+
Copyright IBM Corp. All Rights Reserved.
33
4-
Licensed under the Apache License, Version 2.0 (the "License");
5-
you may not use this file except in compliance with the License.
6-
You may obtain a copy of the License at
7-
8-
http://www.apache.org/licenses/LICENSE-2.0
9-
10-
Unless required by applicable law or agreed to in writing, software
11-
distributed under the License is distributed on an "AS IS" BASIS,
12-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
See the License for the specific language governing permissions and
14-
limitations under the License.
4+
SPDX-License-Identifier: Apache-2.0
155
*/
166

177
package core
188

199
import (
2010
"github.com/golang/protobuf/ptypes/empty"
2111
"github.com/hyperledger/fabric/common/flogging"
12+
"github.com/hyperledger/fabric/protos/common"
2213
pb "github.com/hyperledger/fabric/protos/peer"
14+
"github.com/pkg/errors"
2315
"golang.org/x/net/context"
2416
)
2517

2618
var logger = flogging.MustGetLogger("server")
2719

20+
type requestValidator interface {
21+
validate(ctx context.Context, env *common.Envelope) (*pb.AdminOperation, error)
22+
}
23+
24+
// AccessControlEvaluator evaluates whether the creator of the given SignedData
25+
// is eligible of using the admin service
26+
type AccessControlEvaluator interface {
27+
// Evaluate evaluates the eligibility of the creator of the given SignedData
28+
// for being serviced by the admin service
29+
Evaluate(signatureSet []*common.SignedData) error
30+
}
31+
2832
// NewAdminServer creates and returns a Admin service instance.
29-
func NewAdminServer() *ServerAdmin {
30-
s := new(ServerAdmin)
33+
func NewAdminServer(ace AccessControlEvaluator) *ServerAdmin {
34+
s := &ServerAdmin{
35+
v: &validator{
36+
ace: ace,
37+
},
38+
}
3139
return s
3240
}
3341

3442
// ServerAdmin implementation of the Admin service for the Peer
3543
type ServerAdmin struct {
44+
v requestValidator
3645
}
3746

38-
// GetStatus reports the status of the server
39-
func (*ServerAdmin) GetStatus(context.Context, *empty.Empty) (*pb.ServerStatus, error) {
47+
func (s *ServerAdmin) GetStatus(ctx context.Context, env *common.Envelope) (*pb.ServerStatus, error) {
48+
if _, err := s.v.validate(ctx, env); err != nil {
49+
return nil, err
50+
}
4051
status := &pb.ServerStatus{Status: pb.ServerStatus_STARTED}
4152
logger.Debugf("returning status: %s", status)
4253
return status, nil
4354
}
4455

45-
// StartServer starts the server
46-
func (*ServerAdmin) StartServer(context.Context, *empty.Empty) (*pb.ServerStatus, error) {
56+
func (s *ServerAdmin) StartServer(ctx context.Context, env *common.Envelope) (*pb.ServerStatus, error) {
57+
if _, err := s.v.validate(ctx, env); err != nil {
58+
return nil, err
59+
}
4760
status := &pb.ServerStatus{Status: pb.ServerStatus_STARTED}
4861
logger.Debugf("returning status: %s", status)
4962
return status, nil
5063
}
5164

52-
// GetModuleLogLevel gets the current logging level for the specified module
53-
// TODO Modify the signature so as to remove the error return - it's always been nil
54-
func (*ServerAdmin) GetModuleLogLevel(ctx context.Context, request *pb.LogLevelRequest) (*pb.LogLevelResponse, error) {
65+
func (s *ServerAdmin) GetModuleLogLevel(ctx context.Context, env *common.Envelope) (*pb.LogLevelResponse, error) {
66+
op, err := s.v.validate(ctx, env)
67+
if err != nil {
68+
return nil, err
69+
}
70+
request := op.GetLogReq()
71+
if request == nil {
72+
return nil, errors.New("request is nil")
73+
}
5574
logLevelString := flogging.GetModuleLevel(request.LogModule)
5675
logResponse := &pb.LogLevelResponse{LogModule: request.LogModule, LogLevel: logLevelString}
5776
return logResponse, nil
5877
}
5978

60-
// SetModuleLogLevel sets the logging level for the specified module
61-
func (*ServerAdmin) SetModuleLogLevel(ctx context.Context, request *pb.LogLevelRequest) (*pb.LogLevelResponse, error) {
79+
func (s *ServerAdmin) SetModuleLogLevel(ctx context.Context, env *common.Envelope) (*pb.LogLevelResponse, error) {
80+
op, err := s.v.validate(ctx, env)
81+
if err != nil {
82+
return nil, err
83+
}
84+
request := op.GetLogReq()
85+
if request == nil {
86+
return nil, errors.New("request is nil")
87+
}
6288
logLevelString, err := flogging.SetModuleLevel(request.LogModule, request.LogLevel)
6389
logResponse := &pb.LogLevelResponse{LogModule: request.LogModule, LogLevel: logLevelString}
6490
return logResponse, err
6591
}
6692

67-
// RevertLogLevels reverts the logger levels for all modules to the level
68-
// defined at the end of peer startup.
69-
func (*ServerAdmin) RevertLogLevels(context.Context, *empty.Empty) (*empty.Empty, error) {
93+
func (s *ServerAdmin) RevertLogLevels(ctx context.Context, env *common.Envelope) (*empty.Empty, error) {
94+
if _, err := s.v.validate(ctx, env); err != nil {
95+
return nil, err
96+
}
7097
err := flogging.RevertToPeerStartupLevels()
71-
7298
return &empty.Empty{}, err
7399
}

0 commit comments

Comments
 (0)