github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/lib/serveridentities_test.go (about)

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