github.com/zcqzcg/fabric-ca@v2.0.0-alpha.0.20200416163940-d878ee6db75a+incompatible/lib/serveridentities_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  package lib
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/json"
    11  	"io"
    12  	"os"
    13  	"path/filepath"
    14  	"strings"
    15  	"testing"
    16  
    17  	"github.com/hyperledger/fabric-ca/api"
    18  	"github.com/hyperledger/fabric-ca/lib/attr"
    19  	"github.com/hyperledger/fabric-ca/lib/server/user"
    20  	cadbuser "github.com/hyperledger/fabric-ca/lib/server/user"
    21  	"github.com/hyperledger/fabric-ca/util"
    22  	"github.com/stretchr/testify/assert"
    23  	"golang.org/x/crypto/ocsp"
    24  )
    25  
    26  func TestGetAllIDs(t *testing.T) {
    27  	os.RemoveAll(rootDir)
    28  	defer os.RemoveAll(rootDir)
    29  
    30  	var err error
    31  
    32  	srv := TestGetRootServer(t)
    33  	err = srv.Start()
    34  	util.FatalError(t, err, "Failed to start server")
    35  	defer srv.Stop()
    36  
    37  	client := getTestClient(7075)
    38  	resp, err := client.Enroll(&api.EnrollmentRequest{
    39  		Name:   "admin",
    40  		Secret: "adminpw",
    41  	})
    42  	util.FatalError(t, err, "Failed to enroll user 'admin'")
    43  
    44  	// Register several users
    45  	admin := resp.Identity
    46  	_, err = admin.Register(&api.RegistrationRequest{
    47  		Name:        "admin2",
    48  		Secret:      "admin2pw",
    49  		Type:        "peer",
    50  		Affiliation: "org2",
    51  		Attributes: []api.Attribute{
    52  			api.Attribute{
    53  				Name:  "hf.Registrar.Roles",
    54  				Value: "peer",
    55  			},
    56  		},
    57  	})
    58  	util.FatalError(t, err, "Failed to register user 'admin2'")
    59  	_, err = admin.Register(&api.RegistrationRequest{
    60  		Name:        "testuser",
    61  		Type:        "client",
    62  		Affiliation: "hyperledger",
    63  	})
    64  	util.FatalError(t, err, "Failed to register user 'testuser'")
    65  	_, err = admin.Register(&api.RegistrationRequest{
    66  		Name:        "testuser2",
    67  		Type:        "peer",
    68  		Affiliation: "org2",
    69  	})
    70  	util.FatalError(t, err, "Failed to register user 'testuser'")
    71  	_, err = admin.Register(&api.RegistrationRequest{
    72  		Name:        "testuser3",
    73  		Type:        "peer",
    74  		Affiliation: "org2.dept1",
    75  	})
    76  	util.FatalError(t, err, "Failed to register user 'testuser2'")
    77  	_, err = admin.Register(&api.RegistrationRequest{
    78  		Name:        "testuser4",
    79  		Type:        "client",
    80  		Affiliation: "org2",
    81  	})
    82  	util.FatalError(t, err, "Failed to register user 'testuser3'")
    83  
    84  	os.Setenv("FABRIC_CA_SERVER_MAX_IDS_PER_CHUNK", "2")
    85  	// As bootstrap user that has all root permission, should get back all the users in the database
    86  	result, err := captureOutput(admin.GetAllIdentities, "", IdentityDecoder)
    87  	assert.NoError(t, err, "Failed to get all the appropriate identities")
    88  
    89  	// Check to make sure that right users got returned
    90  	expectedIDs := []string{"admin", "admin2", "testuser", "testuser2", "testuser3", "testuser4"}
    91  	for _, id := range expectedIDs {
    92  		if !strings.Contains(result, id) {
    93  			t.Error("Failed to get all appropriate IDs")
    94  		}
    95  	}
    96  
    97  	resp, err = client.Enroll(&api.EnrollmentRequest{
    98  		Name:   "admin2",
    99  		Secret: "admin2pw",
   100  	})
   101  	util.FatalError(t, err, "Failed to enroll user 'admin2'")
   102  
   103  	admin2 := resp.Identity
   104  	os.Unsetenv("FABRIC_CA_SERVER_MAX_IDS_PER_CHUNK")
   105  	result, err = captureOutput(admin2.GetAllIdentities, "", IdentityDecoder)
   106  	assert.NoError(t, err, "Failed to get all the appropriate identities")
   107  
   108  	// Check to make sure that right users got returned
   109  	expectedIDs = []string{"admin2", "testuser2", "testuser3"}
   110  	for _, id := range expectedIDs {
   111  		if !strings.Contains(result, id) {
   112  			t.Error("Failed to get all appropriate IDs")
   113  		}
   114  	}
   115  
   116  	regResp, err := admin.Register(&api.RegistrationRequest{
   117  		Name: "notregistrar",
   118  		Type: "client",
   119  	})
   120  
   121  	resp, err = client.Enroll(&api.EnrollmentRequest{
   122  		Name:   "notregistrar",
   123  		Secret: regResp.Secret,
   124  	})
   125  	util.FatalError(t, err, "Failed to enroll user 'notregistrar'")
   126  
   127  	notregistrar := resp.Identity
   128  
   129  	err = notregistrar.GetAllIdentities("", IdentityDecoder)
   130  	if assert.Error(t, err, "Should have failed, caller is not a registrar") {
   131  		assert.Contains(t, err.Error(), "Authorization failure")
   132  	}
   133  }
   134  
   135  func TestGetID(t *testing.T) {
   136  	os.RemoveAll(rootDir)
   137  	defer os.RemoveAll(rootDir)
   138  
   139  	var err error
   140  
   141  	srv := TestGetRootServer(t)
   142  	err = srv.Start()
   143  	util.FatalError(t, err, "Failed to start server")
   144  	defer srv.Stop()
   145  
   146  	client := getTestClient(7075)
   147  	resp, err := client.Enroll(&api.EnrollmentRequest{
   148  		Name:   "admin",
   149  		Secret: "adminpw",
   150  	})
   151  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   152  
   153  	// Register several users
   154  	admin := resp.Identity
   155  	_, err = admin.Register(&api.RegistrationRequest{
   156  		Name:        "admin2",
   157  		Secret:      "admin2pw",
   158  		Type:        "peer",
   159  		Affiliation: "org2",
   160  		Attributes: []api.Attribute{
   161  			api.Attribute{
   162  				Name:  "hf.Registrar.Roles",
   163  				Value: "peer",
   164  			},
   165  		},
   166  	})
   167  	util.FatalError(t, err, "Failed to register user 'admin2'")
   168  	_, err = admin.Register(&api.RegistrationRequest{
   169  		Name:        "testuser",
   170  		Type:        "client",
   171  		Affiliation: "hyperledger",
   172  	})
   173  	util.FatalError(t, err, "Failed to register user 'testuser'")
   174  	_, err = admin.Register(&api.RegistrationRequest{
   175  		Name:        "testuser2",
   176  		Type:        "peer",
   177  		Affiliation: "org2",
   178  	})
   179  	util.FatalError(t, err, "Failed to register user 'testuser'")
   180  	_, err = admin.Register(&api.RegistrationRequest{
   181  		Name:        "testuser3",
   182  		Type:        "peer",
   183  		Affiliation: "org2.dept1",
   184  	})
   185  	util.FatalError(t, err, "Failed to register user 'testuser2'")
   186  	_, err = admin.Register(&api.RegistrationRequest{
   187  		Name:        "testuser4",
   188  		Type:        "client",
   189  		Affiliation: "org2",
   190  	})
   191  	util.FatalError(t, err, "Failed to register user 'testuser3'")
   192  
   193  	// admin has all root permissions and should be able to get any user
   194  	_, err = admin.GetIdentity("testuser", "")
   195  	assert.NoError(t, err, "Failed to get user")
   196  
   197  	_, err = admin.GetIdentity("testuser3", "")
   198  	assert.NoError(t, err, "Failed to get user")
   199  
   200  	resp, err = client.Enroll(&api.EnrollmentRequest{
   201  		Name:   "admin2",
   202  		Secret: "admin2pw",
   203  	})
   204  	util.FatalError(t, err, "Failed to enroll user 'admin2'")
   205  
   206  	admin2 := resp.Identity
   207  
   208  	_, err = admin2.GetIdentity("testuser3", "")
   209  	assert.NoError(t, err, "Failed to get user")
   210  
   211  	// 'admin2' with affiliation of 'org2' is not authorized to get 'testuser' with affiliation of 'hyperledger'
   212  	_, err = admin2.GetIdentity("testuser", "")
   213  	assert.Error(t, err, "'admin2' with affiliation of 'org2' is not authorized to get 'testuser' with affiliation of 'hyperledger'")
   214  
   215  	// 'admin2' of type 'peer' is not authorized to get 'testuser4' of type 'client'
   216  	_, err = admin2.GetIdentity("testuser4", "")
   217  	assert.Error(t, err, "'admin2' of type 'peer' is not authorized to get 'testuser4' of type 'client'")
   218  
   219  	regResp, err := admin.Register(&api.RegistrationRequest{
   220  		Name: "notregistrar",
   221  		Type: "client",
   222  	})
   223  
   224  	resp, err = client.Enroll(&api.EnrollmentRequest{
   225  		Name:   "notregistrar",
   226  		Secret: regResp.Secret,
   227  	})
   228  	util.FatalError(t, err, "Failed to enroll user 'notregistrar'")
   229  
   230  	notregistrar := resp.Identity
   231  
   232  	_, err = notregistrar.GetIdentity("testuser", "")
   233  	if assert.Error(t, err, "Should have failed, caller is not a registrar") {
   234  		assert.Contains(t, err.Error(), "Authorization failure")
   235  	}
   236  
   237  }
   238  
   239  func TestDynamicAddIdentity(t *testing.T) {
   240  	os.RemoveAll(rootDir)
   241  	defer os.RemoveAll(rootDir)
   242  
   243  	var err error
   244  
   245  	srv := TestGetRootServer(t)
   246  	err = srv.Start()
   247  	util.FatalError(t, err, "Failed to start server")
   248  	defer srv.Stop()
   249  
   250  	client := getTestClient(7075)
   251  	resp, err := client.Enroll(&api.EnrollmentRequest{
   252  		Name:   "admin",
   253  		Secret: "adminpw",
   254  	})
   255  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   256  
   257  	admin := resp.Identity
   258  
   259  	regResp, err := admin.Register(&api.RegistrationRequest{
   260  		Name: "notregistrar",
   261  		Type: "client",
   262  	})
   263  
   264  	resp, err = client.Enroll(&api.EnrollmentRequest{
   265  		Name:   "notregistrar",
   266  		Secret: regResp.Secret,
   267  	})
   268  	util.FatalError(t, err, "Failed to enroll user 'notregistrar'")
   269  
   270  	notregistrar := resp.Identity
   271  
   272  	addReq := &api.AddIdentityRequest{}
   273  	_, err = admin.AddIdentity(addReq)
   274  	assert.Error(t, err, "Should have failed, no name specified in request")
   275  
   276  	modReq := &api.ModifyIdentityRequest{}
   277  	_, err = admin.ModifyIdentity(modReq)
   278  	assert.Error(t, err, "Should have failed, no name specified in request")
   279  
   280  	addReq.ID = "testuser"
   281  	addReq.Type = "client"
   282  	addReq.Affiliation = "org2"
   283  	_, err = notregistrar.AddIdentity(addReq)
   284  	if assert.Error(t, err, "Should have failed, caller is not a registrar") {
   285  		assert.Contains(t, err.Error(), "Authorization failure")
   286  	}
   287  
   288  	_, err = admin.AddIdentity(addReq)
   289  	assert.NoError(t, err, "Failed to add identity")
   290  }
   291  
   292  func TestDynamicRemoveIdentity(t *testing.T) {
   293  	os.RemoveAll(rootDir)
   294  	defer os.RemoveAll(rootDir)
   295  
   296  	var err error
   297  
   298  	srv := TestGetRootServer(t)
   299  	err = srv.Start()
   300  	util.FatalError(t, err, "Failed to start server")
   301  	defer srv.Stop()
   302  
   303  	client := getTestClient(7075)
   304  	resp, err := client.Enroll(&api.EnrollmentRequest{
   305  		Name:   "admin",
   306  		Secret: "adminpw",
   307  	})
   308  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   309  
   310  	admin := resp.Identity
   311  
   312  	// Register and enroll a user that is not a registrar
   313  	regResp, err := admin.Register(&api.RegistrationRequest{
   314  		Name: "notregistrar",
   315  		Type: "client",
   316  	})
   317  
   318  	resp, err = client.Enroll(&api.EnrollmentRequest{
   319  		Name:   "notregistrar",
   320  		Secret: regResp.Secret,
   321  	})
   322  	util.FatalError(t, err, "Failed to enroll user 'notregistrar'")
   323  
   324  	notregistrar := resp.Identity
   325  
   326  	// Register and enroll a registrar that is has limited ability
   327  	// to act on identities
   328  	regResp, err = admin.Register(&api.RegistrationRequest{
   329  		Name:        "admin2",
   330  		Secret:      "admin2pw",
   331  		Type:        "peer",
   332  		Affiliation: "org2",
   333  		Attributes: []api.Attribute{
   334  			api.Attribute{
   335  				Name:  "hf.Registrar.Roles",
   336  				Value: "peer",
   337  			},
   338  		},
   339  	})
   340  	resp, err = client.Enroll(&api.EnrollmentRequest{
   341  		Name:   "admin2",
   342  		Secret: "admin2pw",
   343  	})
   344  	util.FatalError(t, err, "Failed to enroll user 'admin2'")
   345  	admin2 := resp.Identity
   346  
   347  	// Registers users that will be removed
   348  	regResp, err = admin.Register(&api.RegistrationRequest{
   349  		Name:        "testuser",
   350  		Type:        "client",
   351  		Affiliation: "org2",
   352  	})
   353  
   354  	regResp, err = admin.Register(&api.RegistrationRequest{
   355  		Name:        "testuser2",
   356  		Type:        "peer",
   357  		Affiliation: "hyperledger",
   358  	})
   359  	_, err = client.Enroll(&api.EnrollmentRequest{
   360  		Name:   "testuser2",
   361  		Secret: regResp.Secret,
   362  	})
   363  	util.FatalError(t, err, "Failed to enroll user 'testuser2'")
   364  
   365  	remReq := &api.RemoveIdentityRequest{}
   366  	remReq.ID = "testuser"
   367  	_, err = admin.RemoveIdentity(remReq)
   368  	assert.Error(t, err, "Should have failed to remove identities; identity removal is not enabled on server")
   369  
   370  	srv.CA.Config.Cfg.Identities.AllowRemove = true
   371  
   372  	remReq.ID = ""
   373  	_, err = admin.RemoveIdentity(remReq)
   374  	assert.Error(t, err, "Should have failed; no name specified in request")
   375  
   376  	remReq.ID = "testuser"
   377  	_, err = admin2.RemoveIdentity(remReq)
   378  	assert.Error(t, err, "Should have failed to remove identity; caller does not have the right type")
   379  
   380  	remReq.ID = "testuser2"
   381  	_, err = admin2.RemoveIdentity(remReq)
   382  	assert.Error(t, err, "Should have failed to remove identity; caller does not have the right affiliation")
   383  
   384  	_, err = notregistrar.RemoveIdentity(remReq)
   385  	if assert.Error(t, err, "Should have failed, caller is not a registrar") {
   386  		assert.Contains(t, err.Error(), "Authorization failure")
   387  	}
   388  
   389  	_, err = admin.RemoveIdentity(remReq)
   390  	assert.NoError(t, err, "Failed to remove user")
   391  
   392  	registry := srv.CA.registry
   393  	_, err = registry.GetUser(remReq.ID, nil)
   394  	assert.Error(t, err, "User should not exist")
   395  
   396  	certs, err := srv.CA.certDBAccessor.GetCertificatesByID(remReq.ID)
   397  	if certs[0].Status != "revoked" || certs[0].Reason != ocsp.CessationOfOperation {
   398  		t.Error("Failed to correctly revoke certificate for an identity whose affiliation was removed")
   399  	}
   400  }
   401  
   402  func TestDynamicModifyIdentity(t *testing.T) {
   403  	os.RemoveAll(rootDir)
   404  	defer os.RemoveAll(rootDir)
   405  
   406  	var err error
   407  
   408  	srv := TestGetRootServer(t)
   409  	srv.RegisterBootstrapUser("admin2", "admin2pw", "hyperledger")
   410  	err = srv.Start()
   411  	util.FatalError(t, err, "Failed to start server")
   412  	defer srv.Stop()
   413  
   414  	client := getTestClient(7075)
   415  	resp, err := client.Enroll(&api.EnrollmentRequest{
   416  		Name:   "admin",
   417  		Secret: "adminpw",
   418  	})
   419  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   420  
   421  	admin := resp.Identity
   422  
   423  	resp, err = client.Enroll(&api.EnrollmentRequest{
   424  		Name:   "admin2",
   425  		Secret: "admin2pw",
   426  	})
   427  	util.FatalError(t, err, "Failed to enroll user 'admin2'")
   428  
   429  	admin2 := resp.Identity
   430  
   431  	_, err = admin.Register(&api.RegistrationRequest{
   432  		Name:           "admin3",
   433  		Type:           "client",
   434  		Secret:         "admin3pw",
   435  		MaxEnrollments: 10,
   436  		Attributes: []api.Attribute{
   437  			api.Attribute{
   438  				Name:  attr.Roles,
   439  				Value: "client,orderer,peer",
   440  			},
   441  			api.Attribute{
   442  				Name:  attr.DelegateRoles,
   443  				Value: "client,orderer,peer",
   444  			},
   445  			api.Attribute{
   446  				Name:  attr.Revoker,
   447  				Value: "true",
   448  			},
   449  			api.Attribute{
   450  				Name:  attr.RegistrarAttr,
   451  				Value: "foo, custom.*, hf.Registrar.Roles, hf.Registrar.DelegateRoles, hf.Revoker, hf.Registrar.Attributes",
   452  			},
   453  		},
   454  	})
   455  	util.FatalError(t, err, "Failed to register user 'testuser'")
   456  
   457  	resp, err = client.Enroll(&api.EnrollmentRequest{
   458  		Name:   "admin3",
   459  		Secret: "admin3pw",
   460  	})
   461  	util.FatalError(t, err, "Failed to enroll user 'admin3'")
   462  
   463  	admin3 := resp.Identity
   464  
   465  	_, err = admin.Register(&api.RegistrationRequest{
   466  		Name:           "testuser",
   467  		Type:           "peer",
   468  		Secret:         "testuserpw",
   469  		MaxEnrollments: 10,
   470  		Affiliation:    "org2",
   471  		Attributes: []api.Attribute{
   472  			api.Attribute{
   473  				Name:  "foo",
   474  				Value: "bar",
   475  			},
   476  		},
   477  	})
   478  	util.FatalError(t, err, "Failed to register user 'testuser'")
   479  
   480  	_, err = admin.Register(&api.RegistrationRequest{
   481  		Name:           "testuser2",
   482  		Type:           "client",
   483  		Secret:         "testuserpw",
   484  		MaxEnrollments: 10,
   485  		Affiliation:    "hyperledger",
   486  		Attributes: []api.Attribute{
   487  			api.Attribute{
   488  				Name:  "foo",
   489  				Value: "bar",
   490  			},
   491  			api.Attribute{
   492  				Name:  attr.Roles,
   493  				Value: "client,peer",
   494  			},
   495  		},
   496  	})
   497  	util.FatalError(t, err, "Failed to register user 'testuser2'")
   498  
   499  	registry := srv.CA.registry
   500  
   501  	modifyTypeAndAffiliation(t, registry, admin2, admin3)
   502  	modifyFixedValueAttrs(t, admin)
   503  	modifyAttributes(t, registry, admin, admin3)
   504  	modifySecretAndMaxEnroll(t, registry, admin)
   505  
   506  	regResp, err := admin.Register(&api.RegistrationRequest{
   507  		Name: "notregistrar",
   508  		Type: "client",
   509  	})
   510  
   511  	resp, err = client.Enroll(&api.EnrollmentRequest{
   512  		Name:   "notregistrar",
   513  		Secret: regResp.Secret,
   514  	})
   515  	util.FatalError(t, err, "Failed to enroll user 'notregistrar'")
   516  
   517  	notregistrar := resp.Identity
   518  
   519  	modReq := &api.ModifyIdentityRequest{
   520  		ID: "testuser2",
   521  	}
   522  	_, err = notregistrar.ModifyIdentity(modReq)
   523  	if assert.Error(t, err, "Should have failed, caller is not a registrar") {
   524  		assert.Contains(t, err.Error(), "Authorization failure")
   525  	}
   526  }
   527  
   528  func modifyTypeAndAffiliation(t *testing.T, registry user.Registry, admin2, admin3 *Identity) {
   529  	modReq := &api.ModifyIdentityRequest{
   530  		ID: "testuser",
   531  	}
   532  
   533  	// Should error, caller is not part of the right affiliation
   534  	_, err := admin2.ModifyIdentity(modReq)
   535  	assert.Error(t, err, "Should have failed, caller is not part of the right affiliation")
   536  
   537  	// Should error, caller is not allowed to act on type
   538  	modReq.ID = "testuser2"
   539  	modReq.Type = "user"
   540  	_, err = admin3.ModifyIdentity(modReq)
   541  	assert.Error(t, err, "Should have failed, caller is not allowed to act on type")
   542  
   543  	// Should error, caller is not allowed to change to the requested affiliation.
   544  	// Caller is part of the 'hyperledger' affiliation
   545  	modReq.ID = "testuser2"
   546  	modReq.Affiliation = "org2"
   547  	_, err = admin2.ModifyIdentity(modReq)
   548  	assert.Error(t, err, "Should have failed, caller is not allowed to change to the requested affiliation")
   549  
   550  	// Check that updating identity's type also updates the corresponding attribute 'hf.Type'
   551  	modReq.Type = "orderer"
   552  	_, err = admin3.ModifyIdentity(modReq)
   553  	assert.NoError(t, err, "Failed to modify identity")
   554  
   555  	user, err := registry.GetUser("testuser2", nil)
   556  	assert.NoError(t, err, "Failed to get user 'testuser2'")
   557  
   558  	userTypeAttr, err := user.GetAttribute("hf.Type")
   559  	assert.NoError(t, err, "Failed to get attribute")
   560  
   561  	if userTypeAttr.GetValue() != "orderer" {
   562  		t.Error("Failed to update 'hf.Type' attribute when identity's type was updated")
   563  	}
   564  
   565  	userAffAttr, err := user.GetAttribute("hf.Affiliation")
   566  	assert.NoError(t, err, "Failed to get attribute 'hf.Affiliation'")
   567  	if userAffAttr.Value != "org2" {
   568  		t.Errorf("Failed to correctly update 'hf.Affiliation' when affiliation of identity was modified to 'org2'")
   569  	}
   570  
   571  	modReq.Affiliation = "hyperledger.fake"
   572  	_, err = admin2.ModifyIdentity(modReq)
   573  	assert.Error(t, err, "Should have failed, affiliation does not exist")
   574  }
   575  
   576  func modifyFixedValueAttrs(t *testing.T, admin *Identity) {
   577  	modReq := &api.ModifyIdentityRequest{
   578  		ID: "testuser2",
   579  	}
   580  
   581  	modReq.Attributes = []api.Attribute{api.Attribute{
   582  		Name:  attr.EnrollmentID,
   583  		Value: "nottestuser2",
   584  	}}
   585  	_, err := admin.ModifyIdentity(modReq)
   586  	assert.Error(t, err, "Should have failed, caller is not allowed to register/modify 'hf.Type' attribute")
   587  
   588  	modReq.Attributes = []api.Attribute{api.Attribute{
   589  		Name:  attr.Type,
   590  		Value: "peer",
   591  	}}
   592  	_, err = admin.ModifyIdentity(modReq)
   593  	assert.Error(t, err, "Should have failed, caller is not allowed to register/modify 'hf.Type' attribute")
   594  
   595  	modReq.Attributes = []api.Attribute{api.Attribute{
   596  		Name:  attr.Affiliation,
   597  		Value: "org1",
   598  	}}
   599  	_, err = admin.ModifyIdentity(modReq)
   600  	assert.Error(t, err, "Should have failed, caller is not allowed to register/modify 'hf.Type' attribute")
   601  }
   602  
   603  func modifyAttributes(t *testing.T, registry user.Registry, admin, admin3 *Identity) {
   604  	modReq := &api.ModifyIdentityRequest{
   605  		ID: "testuser2",
   606  	}
   607  
   608  	// Should error, caller is not allowed to register this attribute. Caller does not posses hf.IntermediateCA.
   609  	modReq.Attributes = []api.Attribute{api.Attribute{
   610  		Name:  "hf.IntermediateCA",
   611  		Value: "true",
   612  	}}
   613  	_, err := admin3.ModifyIdentity(modReq)
   614  	assert.Error(t, err, "Should have failed, caller does not own this attribute and thus is not allowed to register this attribute")
   615  
   616  	// Should error, caller is not allowed to register attribute 'hf.Registrar.DeletegateRoles' with a value that
   617  	// is not equal to or a subset of 'hf.Registrar.Roles'. In this case: client,peer
   618  	modReq.Attributes = []api.Attribute{
   619  		api.Attribute{
   620  			Name:  attr.DelegateRoles,
   621  			Value: "client,peer,orderer",
   622  		},
   623  	}
   624  	_, err = admin3.ModifyIdentity(modReq)
   625  	assert.Error(t, err, "Should have failed, caller is not allowed to register attribute 'hf.Registrar.DeletegateRoles' with a value that is not equal to or a subset of 'hf.Registrar.Roles'")
   626  
   627  	// Caller is allowed to register attribute 'hf.Registrar.DeletegateRoles' with a value that
   628  	// equal to or a subset of 'hf.Registrar.Roles'. In this case: client,peer,orderer
   629  	modReq.Attributes = []api.Attribute{
   630  		api.Attribute{
   631  			Name:  attr.Roles,
   632  			Value: "client,peer,orderer",
   633  		},
   634  		api.Attribute{
   635  			Name:  attr.DelegateRoles,
   636  			Value: "client,peer,orderer",
   637  		},
   638  	}
   639  	_, err = admin3.ModifyIdentity(modReq)
   640  	assert.NoError(t, err, "Failed to register attribute 'hf.Registrar.DeletegateRoles' with a value that is equal to or a subset of 'hf.Registrar.Roles'")
   641  
   642  	// Should error, caller is not allowed to register attribute 'hf.Registrar.Attribute' with a value of 'hf.Revoker'. Identity being modified does not posses
   643  	// the attribute 'hf.Revoker'
   644  	modReq.Attributes = []api.Attribute{
   645  		api.Attribute{
   646  			Name:  attr.RegistrarAttr,
   647  			Value: "hf.Revoker",
   648  		},
   649  	}
   650  	_, err = admin3.ModifyIdentity(modReq)
   651  	assert.Error(t, err, "Should have failed, caller is not allowed to register attribute 'hf.Registrar.Attribute' with a value of 'hf.Revoker'")
   652  
   653  	// Should not error, caller is  allowed to register attribute 'hf.Registrar.Attribute' with a value of 'hf.Revoker'. Identity being modified does posses
   654  	// the attribute 'hf.Revoker'
   655  	modReq.Attributes = []api.Attribute{
   656  		api.Attribute{
   657  			Name:  attr.Revoker,
   658  			Value: "true",
   659  		},
   660  		api.Attribute{
   661  			Name:  attr.RegistrarAttr,
   662  			Value: "hf.Revoker",
   663  		},
   664  	}
   665  	_, err = admin3.ModifyIdentity(modReq)
   666  	assert.NoError(t, err, "Should not have failed, caller is allowed to register attribute 'hf.Registrar.Attribute' with a value of 'hf.Revoker'")
   667  
   668  	// Should error, caller is not allowed to register attribute 'hf.Registrar.Attribute' with greater
   669  	// registering abilities than caller
   670  	modReq.Attributes = []api.Attribute{
   671  		api.Attribute{
   672  			Name:  "foo",
   673  			Value: "bar2",
   674  		},
   675  		api.Attribute{
   676  			Name:  attr.RegistrarAttr,
   677  			Value: "foo,custom",
   678  		},
   679  	}
   680  	_, err = admin3.ModifyIdentity(modReq)
   681  	assert.Error(t, err, "Should have failed, caller is allowed to register attribute 'hf.Registrar.Attribute' with greater registering abilities than caller")
   682  
   683  	modReq.Attributes = []api.Attribute{
   684  		api.Attribute{
   685  			Name:  "foo",
   686  			Value: "bar2",
   687  		},
   688  		api.Attribute{
   689  			Name:  attr.RegistrarAttr,
   690  			Value: "foo,custom.attr",
   691  		},
   692  	}
   693  	_, err = admin3.ModifyIdentity(modReq)
   694  	assert.NoError(t, err, "Failed to modify identity, unable to register attributes")
   695  
   696  	user, err := registry.GetUser("testuser2", nil)
   697  	assert.NoError(t, err, "Failed to get user 'testuser2'")
   698  
   699  	attr, err := user.GetAttribute("foo")
   700  	assert.NoError(t, err, "Failed to get attribute 'foo'")
   701  	if attr.Value != "bar2" {
   702  		t.Errorf("Failed to correctly modify existing attribute for user 'testuser2'")
   703  	}
   704  	attr, err = user.GetAttribute("hf.Revoker")
   705  	assert.NoError(t, err, "Failed to get attribute 'hf.Revoker'")
   706  	if attr.Value != "true" {
   707  		t.Errorf("Failed to correctly add a new attribute for user 'testuser2'")
   708  	}
   709  
   710  	// Delete attribute 'foo'
   711  	modReq.Attributes = []api.Attribute{
   712  		api.Attribute{
   713  			Name:  "foo",
   714  			Value: "",
   715  		},
   716  	}
   717  	_, err = admin.ModifyIdentity(modReq)
   718  	assert.NoError(t, err, "Failed to modify identity")
   719  
   720  	user, err = registry.GetUser("testuser2", nil)
   721  	assert.NoError(t, err, "Failed to get user 'testuser2'")
   722  
   723  	_, err = user.GetAttribute("foo")
   724  	assert.Error(t, err, "Should have failed to get attribute 'foo', should have been deleted")
   725  }
   726  
   727  func modifySecretAndMaxEnroll(t *testing.T, registry user.Registry, admin *Identity) {
   728  	modReq := &api.ModifyIdentityRequest{
   729  		ID: "testuser2",
   730  	}
   731  
   732  	modReq.MaxEnrollments = -2
   733  	modReq.Secret = "password"
   734  	_, err := admin.ModifyIdentity(modReq)
   735  	assert.NoError(t, err, "Failed to modify identity")
   736  
   737  	user, err := registry.GetUser("testuser2", nil)
   738  	assert.NoError(t, err, "Failed to get user 'testuser2'")
   739  
   740  	maxEnroll := user.(*cadbuser.Impl).Info.MaxEnrollments
   741  	if maxEnroll != 0 {
   742  		t.Error("Failed to correctly modify max enrollments for user 'testuser2'")
   743  	}
   744  
   745  	userAff := cadbuser.GetAffiliation(user)
   746  	if userAff != "org2" {
   747  		t.Errorf("Failed to correctly modify affiliation for user 'testuser2'")
   748  	}
   749  
   750  	modReq.MaxEnrollments = 5
   751  	modReq.Affiliation = "."
   752  	_, err = admin.ModifyIdentity(modReq)
   753  	assert.NoError(t, err, "Failed to modify identity")
   754  
   755  	user, err = registry.GetUser("testuser2", nil)
   756  	assert.NoError(t, err, "Failed to get user 'testuser2'")
   757  
   758  	maxEnroll = user.(*cadbuser.Impl).Info.MaxEnrollments
   759  	if maxEnroll != 5 {
   760  		t.Error("Failed to correctly modify max enrollments for user 'testuser2'")
   761  	}
   762  
   763  	userAff = strings.Join(user.GetAffiliationPath(), ".")
   764  	if userAff != "" {
   765  		t.Errorf("Failed to correctly modify affiliation to root affiliation for user 'testuser2'")
   766  	}
   767  }
   768  
   769  func TestDynamicWithMultCA(t *testing.T) {
   770  	os.RemoveAll(rootDir)
   771  	defer os.RemoveAll(rootDir)
   772  	os.RemoveAll("../testdata/msp")
   773  	defer os.RemoveAll("../testdata/msp")
   774  	defer cleanMultiCADir(t)
   775  
   776  	var err error
   777  
   778  	srv := TestGetRootServer(t)
   779  	srv.Config.CAfiles = []string{"../../testdata/ca/rootca/ca1/fabric-ca-server-config.yaml", "../../testdata/ca/rootca/ca2/fabric-ca-server-config.yaml"}
   780  	err = srv.Start()
   781  	util.FatalError(t, err, "Failed to start server")
   782  	defer srv.Stop()
   783  
   784  	client := getTestClient(7075)
   785  	resp, err := client.Enroll(&api.EnrollmentRequest{
   786  		Name:   "admin",
   787  		Secret: "adminpw",
   788  		CAName: "rootca2",
   789  	})
   790  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   791  
   792  	admin := resp.Identity
   793  
   794  	addReq := &api.AddIdentityRequest{}
   795  	addReq.ID = "testuser"
   796  	addReq.Type = "client"
   797  	addReq.Affiliation = "org2"
   798  	addReq.CAName = "rootca2"
   799  	resp2, err := admin.AddIdentity(addReq)
   800  	assert.NoError(t, err, "Failed to add identity")
   801  
   802  	if resp2.CAName != "rootca2" {
   803  		t.Error("Failed to get response back from the right ca")
   804  	}
   805  
   806  	modReq := &api.ModifyIdentityRequest{}
   807  	modReq.ID = "testuser"
   808  	modReq.Type = "peer"
   809  	modReq.CAName = "rootca2"
   810  	resp2, err = admin.ModifyIdentity(modReq)
   811  	assert.NoError(t, err, "Failed to modify identity")
   812  
   813  	if resp2.CAName != "rootca2" {
   814  		t.Error("Failed to get response back from the right ca")
   815  	}
   816  
   817  	srv.caMap["rootca2"].Config.Cfg.Identities.AllowRemove = true
   818  
   819  	remReq := &api.RemoveIdentityRequest{}
   820  	remReq.ID = "testuser"
   821  	remReq.CAName = "rootca2"
   822  	resp2, err = admin.RemoveIdentity(remReq)
   823  	assert.NoError(t, err, "Failed to remove identity")
   824  
   825  	if resp2.CAName != "rootca2" {
   826  		t.Error("Failed to get response back from the right ca")
   827  	}
   828  
   829  }
   830  
   831  func TestBootstrapUserAddingRoles(t *testing.T) {
   832  	os.RemoveAll(rootDir)
   833  	defer os.RemoveAll(rootDir)
   834  	os.RemoveAll("../testdata/msp")
   835  	defer os.RemoveAll("../testdata/msp")
   836  
   837  	var err error
   838  
   839  	srv := TestGetRootServer(t)
   840  	err = srv.Start()
   841  	util.FatalError(t, err, "Failed to start server")
   842  	defer srv.Stop()
   843  
   844  	client := getTestClient(7075)
   845  	resp, err := client.Enroll(&api.EnrollmentRequest{
   846  		Name:   "admin",
   847  		Secret: "adminpw",
   848  	})
   849  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   850  
   851  	admin := resp.Identity
   852  
   853  	// Bootstrap user with '*' for hf.Registrar.Roles should be able to register any type
   854  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   855  		ID:   "testuser",
   856  		Type: "newType",
   857  	})
   858  	assert.NoError(t, err, "Bootstrap user with '*' for hf.Registrar.Roles should be able to register any type")
   859  
   860  	// Bootstrap user with '*' for hf.Registrar.Roles should be able to register any value for hf.Registrar.Roles
   861  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   862  		ID:   "testuser2",
   863  		Type: "client",
   864  		Attributes: []api.Attribute{
   865  			api.Attribute{
   866  				Name:  "hf.Registrar.Roles",
   867  				Value: "peer,client,user,orderer,newType",
   868  			},
   869  		},
   870  	})
   871  	assert.NoError(t, err, "Bootstrap user with '*' for hf.Registrar.Roles should be able to register any value for hf.Registrar.Roles")
   872  
   873  	// Bootstrap user should be able to register any value for hf.Registrar.Roles, but not be able to specify '*' for
   874  	// hf.Registrar.DelegateRoles if hf.Registrar.Roles is not a '*'
   875  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   876  		ID:   "testuser2",
   877  		Type: "client",
   878  		Attributes: []api.Attribute{
   879  			api.Attribute{
   880  				Name:  "hf.Registrar.Roles",
   881  				Value: "peer,client,user,orderer,newType",
   882  			},
   883  			api.Attribute{
   884  				Name:  "hf.Registrar.DelegateRoles",
   885  				Value: "*",
   886  			},
   887  		},
   888  	})
   889  	assert.Error(t, err, "Bootstrap user should be able to register any value for hf.Registrar.Roles, but not be able to specify '*' for hf.Registrar.DelegateRoles if hf.Registrar.Roles is not a '*'")
   890  
   891  	// Bootstrap should fail to register hf.Registrar.DelegateRoles without giving hf.Registrar.Roles attribute to the identity being registered
   892  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   893  		ID:   "testuser3",
   894  		Type: "client",
   895  		Attributes: []api.Attribute{
   896  			api.Attribute{
   897  				Name:  "hf.Registrar.DelegateRoles",
   898  				Value: "peer,client,user,orderer,newType",
   899  			},
   900  		},
   901  	})
   902  	assert.Error(t, err, "Should fail to register hf.Registrar.DelegateRoles without having hf.Registrar.Roles")
   903  
   904  	// Bootstrap should be able to register '*' for hf.Registrar.Roles and provide any value for hf.Registrar.DelegateRoles
   905  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   906  		ID:   "testuser3",
   907  		Type: "client",
   908  		Attributes: []api.Attribute{
   909  			api.Attribute{
   910  				Name:  "hf.Registrar.Roles",
   911  				Value: "*",
   912  			},
   913  			api.Attribute{
   914  				Name:  "hf.Registrar.DelegateRoles",
   915  				Value: "peer,client,user,orderer,newType",
   916  			},
   917  		},
   918  	})
   919  	assert.NoError(t, err, "Bootstrap should be able to register star for hf.Registrar.Roles and provide any value for hf.Registrar.DelegateRoles")
   920  
   921  	// Bootstrap user should be able to register '*' for hf.Registrar.Roles and hf.Registrar.DelegateRoles
   922  	_, err = admin.AddIdentity(&api.AddIdentityRequest{
   923  		ID:   "testuser4",
   924  		Type: "client",
   925  		Attributes: []api.Attribute{
   926  			api.Attribute{
   927  				Name:  "hf.Registrar.Roles",
   928  				Value: "*",
   929  			},
   930  			api.Attribute{
   931  				Name:  "hf.Registrar.DelegateRoles",
   932  				Value: "*",
   933  			},
   934  		},
   935  	})
   936  	assert.NoError(t, err, "Bootstrap user should be able to register '*' for hf.Registrar.Roles and hf.Registrar.DelegateRoles")
   937  }
   938  
   939  func cleanMultiCADir(t *testing.T) {
   940  	var err error
   941  	caFolder := "../testdata/ca"
   942  	toplevelFolders := []string{"rootca"}
   943  	nestedFolders := []string{"ca1", "ca2"}
   944  	removeFiles := []string{"ca-cert.pem", "ca-key.pem", "fabric-ca-server.db", "fabric-ca2-server.db", "ca-chain.pem"}
   945  
   946  	for _, topFolder := range toplevelFolders {
   947  		for _, nestedFolder := range nestedFolders {
   948  			path := filepath.Join(caFolder, topFolder, nestedFolder)
   949  			for _, file := range removeFiles {
   950  				err = os.RemoveAll(filepath.Join(path, file))
   951  				if err != nil {
   952  					t.Errorf("RemoveAll failed: %s", err)
   953  				}
   954  			}
   955  			err = os.RemoveAll(filepath.Join(path, "msp"))
   956  			if err != nil {
   957  				t.Errorf("RemoveAll failed: %s", err)
   958  			}
   959  		}
   960  	}
   961  }
   962  
   963  func captureOutput(f func(string, func(*json.Decoder) error) error, caname string, cb func(*json.Decoder) error) (string, error) {
   964  	old := os.Stdout
   965  	r, w, err := os.Pipe()
   966  	if err != nil {
   967  		panic(err)
   968  	}
   969  	os.Stdout = w
   970  	err = f(caname, cb)
   971  	if err != nil {
   972  		return "", err
   973  	}
   974  	w.Close()
   975  	os.Stdout = old
   976  	var buf bytes.Buffer
   977  	io.Copy(&buf, r)
   978  	return buf.String(), nil
   979  }