Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit de52b8a

Browse files
gopherchaigotoxu
authored andcommitted
[FABG-779]Add an function to modify enroll request
With function type EnrollmentRequestOption, you can modify enrollment request's profile,type and attrReqs before enrolling. Change-Id: I756d0e3f488136ad443d192442159762f9d2ffa6 Signed-off-by: baoyangc <cxyboy_1@aliyun.com> Signed-off-by: 乔伦 徐 <jamesxql@gmail.com>
1 parent 6a3c34e commit de52b8a

File tree

10 files changed

+508
-49
lines changed

10 files changed

+508
-49
lines changed

pkg/client/msp/client.go

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ func newCAClient(ctx context.Client, orgName string) (mspapi.CAClient, error) {
105105

106106
// enrollmentOptions represent enrollment options
107107
type enrollmentOptions struct {
108-
secret string
108+
secret string
109+
profile string
110+
label string
111+
typ string
112+
attrReqs []*AttributeRequest
109113
}
110114

111115
// EnrollmentOption describes a functional parameter for Enroll
@@ -119,6 +123,38 @@ func WithSecret(secret string) EnrollmentOption {
119123
}
120124
}
121125

126+
// WithProfile enrollment option
127+
func WithProfile(profile string) EnrollmentOption {
128+
return func(o *enrollmentOptions) error {
129+
o.profile = profile
130+
return nil
131+
}
132+
}
133+
134+
// WithType enrollment option
135+
func WithType(typ string) EnrollmentOption {
136+
return func(o *enrollmentOptions) error {
137+
o.typ = typ
138+
return nil
139+
}
140+
}
141+
142+
// WithLabel enrollment option
143+
func WithLabel(label string) EnrollmentOption {
144+
return func(o *enrollmentOptions) error {
145+
o.label = label
146+
return nil
147+
}
148+
}
149+
150+
// WithAttributeRequests enrollment option
151+
func WithAttributeRequests(attrReqs []*AttributeRequest) EnrollmentOption {
152+
return func(o *enrollmentOptions) error {
153+
o.attrReqs = attrReqs
154+
return nil
155+
}
156+
}
157+
122158
// CreateIdentity creates a new identity with the Fabric CA server. An enrollment secret is returned which can then be used,
123159
// along with the enrollment ID, to enroll a new identity.
124160
// Parameters:
@@ -328,7 +364,24 @@ func (c *Client) Enroll(enrollmentID string, opts ...EnrollmentOption) error {
328364
if err != nil {
329365
return err
330366
}
331-
return ca.Enroll(enrollmentID, eo.secret)
367+
368+
req := &mspapi.EnrollmentRequest{
369+
Name: enrollmentID,
370+
Secret: eo.secret,
371+
Profile: eo.profile,
372+
Type: eo.typ,
373+
Label: eo.label,
374+
}
375+
376+
if len(eo.attrReqs) > 0 {
377+
attrs := make([]*mspapi.AttributeRequest, 0)
378+
for _, attr := range eo.attrReqs {
379+
attrs = append(attrs, &mspapi.AttributeRequest{Name: attr.Name, Optional: attr.Optional})
380+
}
381+
req.AttrReqs = attrs
382+
}
383+
384+
return ca.Enroll(req)
332385
}
333386

334387
// Reenroll reenrolls an enrolled user in order to obtain a new signed X509 certificate
@@ -337,12 +390,33 @@ func (c *Client) Enroll(enrollmentID string, opts ...EnrollmentOption) error {
337390
//
338391
// Returns:
339392
// an error if re-enrollment fails
340-
func (c *Client) Reenroll(enrollmentID string) error {
393+
func (c *Client) Reenroll(enrollmentID string, opts ...EnrollmentOption) error {
394+
eo := enrollmentOptions{}
395+
for _, param := range opts {
396+
err := param(&eo)
397+
if err != nil {
398+
return errors.WithMessage(err, "failed to enroll")
399+
}
400+
}
401+
341402
ca, err := newCAClient(c.ctx, c.orgName)
342403
if err != nil {
343404
return err
344405
}
345-
return ca.Reenroll(enrollmentID)
406+
407+
req := &mspapi.ReenrollmentRequest{
408+
Name: enrollmentID,
409+
Profile: eo.profile,
410+
Label: eo.label,
411+
}
412+
if len(eo.attrReqs) > 0 {
413+
attrs := make([]*mspapi.AttributeRequest, 0)
414+
for _, attr := range eo.attrReqs {
415+
attrs = append(attrs, &mspapi.AttributeRequest{Name: attr.Name, Optional: attr.Optional})
416+
}
417+
req.AttrReqs = attrs
418+
}
419+
return ca.Reenroll(req)
346420
}
347421

348422
// Register registers a User with the Fabric CA

pkg/client/msp/client_test.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"github.com/hyperledger/fabric-sdk-go/pkg/fabsdk"
2828
mspImpl "github.com/hyperledger/fabric-sdk-go/pkg/msp"
2929
"github.com/hyperledger/fabric-sdk-go/pkg/msp/test/mockmsp"
30+
"github.com/stretchr/testify/assert"
31+
"github.com/stretchr/testify/require"
3032
)
3133

3234
const (
@@ -90,6 +92,123 @@ func TestMSP(t *testing.T) {
9092

9193
}
9294

95+
func TestMSPWithProfile(t *testing.T) {
96+
f := testFixture{}
97+
sdk := f.setup()
98+
defer sdk.Close()
99+
100+
ctxProvider := sdk.Context()
101+
msp, err := New(ctxProvider)
102+
require.NoError(t, err)
103+
104+
enrollUsername := randomUsername()
105+
_, err = msp.GetSigningIdentity(enrollUsername)
106+
if err != ErrUserNotFound {
107+
t.Fatal("Expected to not find user")
108+
}
109+
110+
err = msp.Enroll(enrollUsername, WithSecret("enrollmentSecret"), WithProfile("tls"))
111+
require.NoError(t, err)
112+
113+
enrolledUser, err := msp.GetSigningIdentity(enrollUsername)
114+
require.NoError(t, err)
115+
116+
assert.Equal(t, enrollUsername, enrolledUser.Identifier().ID)
117+
assert.Equal(t, "Org1MSP", enrolledUser.Identifier().MSPID)
118+
119+
err = msp.Reenroll(enrolledUser.Identifier().ID, WithProfile("tls"))
120+
if err != nil {
121+
t.Fatalf("Reenroll return error %s", err)
122+
}
123+
}
124+
125+
func TestMSPWithType(t *testing.T) {
126+
f := testFixture{}
127+
sdk := f.setup()
128+
defer sdk.Close()
129+
130+
ctxProvider := sdk.Context()
131+
msp, err := New(ctxProvider)
132+
require.NoError(t, err)
133+
134+
enrollUsername := randomUsername()
135+
_, err = msp.GetSigningIdentity(enrollUsername)
136+
if err != ErrUserNotFound {
137+
t.Fatal("Expected to not find user")
138+
}
139+
140+
err = msp.Enroll(enrollUsername, WithSecret("enrollmentSecret"), WithType("idemix"))
141+
if err == nil {
142+
t.Fatal("idemix enroll not supported")
143+
}
144+
145+
err = msp.Reenroll(enrollUsername, WithType("idemix"))
146+
if err == nil {
147+
t.Fatal("idemix enroll not supported")
148+
}
149+
}
150+
151+
func TestMSPWithLabel(t *testing.T) {
152+
f := testFixture{}
153+
sdk := f.setup()
154+
defer sdk.Close()
155+
156+
ctxProvider := sdk.Context()
157+
msp, err := New(ctxProvider)
158+
require.NoError(t, err)
159+
160+
enrollUsername := randomUsername()
161+
_, err = msp.GetSigningIdentity(enrollUsername)
162+
if err != ErrUserNotFound {
163+
t.Fatal("Expected to not find user")
164+
}
165+
166+
err = msp.Enroll(enrollUsername, WithSecret("enrollmentSecret"), WithLabel("ForFabric"))
167+
require.NoError(t, err)
168+
169+
enrolledUser, err := msp.GetSigningIdentity(enrollUsername)
170+
require.NoError(t, err)
171+
172+
assert.Equal(t, enrollUsername, enrolledUser.Identifier().ID)
173+
assert.Equal(t, "Org1MSP", enrolledUser.Identifier().MSPID)
174+
175+
err = msp.Reenroll(enrolledUser.Identifier().ID, WithLabel("ForFabric"))
176+
if err != nil {
177+
t.Fatalf("Reenroll return error %s", err)
178+
}
179+
}
180+
181+
func TestMSPWithAttributeRequests(t *testing.T) {
182+
f := testFixture{}
183+
sdk := f.setup()
184+
defer sdk.Close()
185+
186+
ctxProvider := sdk.Context()
187+
msp, err := New(ctxProvider)
188+
require.NoError(t, err)
189+
190+
enrollUsername := randomUsername()
191+
_, err = msp.GetSigningIdentity(enrollUsername)
192+
if err != ErrUserNotFound {
193+
t.Fatal("Expected to not find user")
194+
}
195+
196+
attrReqs := []*AttributeRequest{{Name: "name1", Optional: true}}
197+
err = msp.Enroll(enrollUsername, WithSecret("enrollmentSecret"), WithAttributeRequests(attrReqs))
198+
require.NoError(t, err)
199+
200+
enrolledUser, err := msp.GetSigningIdentity(enrollUsername)
201+
require.NoError(t, err)
202+
203+
assert.Equal(t, enrollUsername, enrolledUser.Identifier().ID)
204+
assert.Equal(t, "Org1MSP", enrolledUser.Identifier().MSPID)
205+
206+
err = msp.Reenroll(enrolledUser.Identifier().ID, WithAttributeRequests(attrReqs))
207+
if err != nil {
208+
t.Fatalf("Reenroll return error %s", err)
209+
}
210+
}
211+
93212
func TestWithNonExistentOrganization(t *testing.T) {
94213
// Instantiate the SDK
95214
sdk, err := fabsdk.New(config.FromFile(configPath))

pkg/client/msp/example_test.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,87 @@ func ExampleWithSecret() {
103103

104104
}
105105

106+
func ExampleWithProfile() {
107+
ctx := mockClientProvider()
108+
109+
// Create msp client
110+
c, err := New(ctx)
111+
if err != nil {
112+
fmt.Println("failed to create msp client")
113+
return
114+
}
115+
116+
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithProfile("tls"))
117+
if err != nil {
118+
fmt.Printf("failed to enroll user: %s\n", err)
119+
return
120+
}
121+
fmt.Println("enroll user is completed")
122+
123+
// Output: enroll user is completed
124+
}
125+
126+
func ExampleWithType() {
127+
ctx := mockClientProvider()
128+
129+
// Create msp client
130+
c, err := New(ctx)
131+
if err != nil {
132+
fmt.Println("failed to create msp client")
133+
return
134+
}
135+
136+
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithType("x509") /*or idemix, which is not support now*/)
137+
if err != nil {
138+
fmt.Printf("failed to enroll user: %s\n", err)
139+
return
140+
}
141+
fmt.Println("enroll user is completed")
142+
143+
// Output: enroll user is completed
144+
}
145+
146+
func ExampleWithLabel() {
147+
ctx := mockClientProvider()
148+
149+
// Create msp client
150+
c, err := New(ctx)
151+
if err != nil {
152+
fmt.Println("failed to create msp client")
153+
return
154+
}
155+
156+
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithLabel("ForFabric"))
157+
if err != nil {
158+
fmt.Printf("failed to enroll user: %s\n", err)
159+
return
160+
}
161+
fmt.Println("enroll user is completed")
162+
163+
// Output: enroll user is completed
164+
}
165+
166+
func ExampleWithAttributeRequests() {
167+
ctx := mockClientProvider()
168+
169+
// Create msp client
170+
c, err := New(ctx)
171+
if err != nil {
172+
fmt.Println("failed to create msp client")
173+
return
174+
}
175+
176+
attrs := []*AttributeRequest{{Name: "name1", Optional: true}, {Name: "name2", Optional: true}}
177+
err = c.Enroll(randomUsername(), WithSecret("enrollmentSecret"), WithAttributeRequests(attrs))
178+
if err != nil {
179+
fmt.Printf("failed to enroll user: %s\n", err)
180+
return
181+
}
182+
fmt.Println("enroll user is completed")
183+
184+
// Output: enroll user is completed
185+
}
186+
106187
func ExampleClient_Register() {
107188

108189
ctx := mockClientProvider()

pkg/fab/mocks/mockcaclient.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,12 @@ func NewMockCAClient(orgName string, cryptoProvider core.CryptoSuite) (api.CACli
2323
}
2424

2525
// Enroll enrolls a user with a Fabric network
26-
func (mgr *MockCAClient) Enroll(enrollmentID string, enrollmentSecret string) error {
26+
func (mgr *MockCAClient) Enroll(request *api.EnrollmentRequest) error {
2727
return errors.New("not implemented")
2828
}
2929

3030
// Reenroll re-enrolls a user
31-
func (mgr *MockCAClient) Reenroll(enrollmentID string) error {
31+
func (mgr *MockCAClient) Reenroll(request *api.ReenrollmentRequest) error {
3232
return errors.New("not implemented")
3333
}
3434

pkg/msp/api/api.go

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ var (
1717

1818
// CAClient provides management of identities in a Fabric network
1919
type CAClient interface {
20-
Enroll(enrollmentID string, enrollmentSecret string) error
21-
Reenroll(enrollmentID string) error
20+
Enroll(request *EnrollmentRequest) error
21+
Reenroll(request *ReenrollmentRequest) error
2222
Register(request *RegistrationRequest) (string, error)
2323
Revoke(request *RevocationRequest) (*RevocationResponse, error)
2424
CreateIdentity(request *IdentityRequest) (*IdentityResponse, error)
@@ -55,6 +55,38 @@ type RegistrationRequest struct {
5555
Secret string
5656
}
5757

58+
// EnrollmentRequest is a request to enroll an identity
59+
type EnrollmentRequest struct {
60+
// The identity name to enroll
61+
Name string
62+
// The secret returned via Register
63+
Secret string
64+
// AttrReqs are requests for attributes to add to the certificate.
65+
// Each attribute is added only if the requestor owns the attribute.
66+
AttrReqs []*AttributeRequest
67+
// Profile is the name of the signing profile to use in issuing the X509 certificate
68+
Profile string
69+
// Label is the label to use in HSM operations
70+
Label string
71+
// The type of the enrollment request: x509 or idemix
72+
// The default is a request for an X509 enrollment certificate
73+
Type string
74+
}
75+
76+
// ReenrollmentRequest is a request to reenroll an identity.
77+
// This is useful to renew a certificate before it has expired.
78+
type ReenrollmentRequest struct {
79+
// The identity name to enroll
80+
Name string
81+
// Profile is the name of the signing profile to use in issuing the certificate
82+
Profile string
83+
// Label is the label to use in HSM operations
84+
Label string
85+
// AttrReqs are requests for attributes to add to the certificate.
86+
// Each attribute is added only if the requestor owns the attribute.
87+
AttrReqs []*AttributeRequest
88+
}
89+
5890
// Attribute defines additional attributes that may be passed along during registration
5991
type Attribute struct {
6092
Name string

0 commit comments

Comments
 (0)