github.com/simranvc/fabric-ca@v0.0.0-20191030094829-acc364294dde/lib/serveraffiliations_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lib
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  
    13  	"github.com/hyperledger/fabric-ca/api"
    14  	"github.com/hyperledger/fabric-ca/lib/server/db"
    15  	cadbuser "github.com/hyperledger/fabric-ca/lib/server/user"
    16  	"github.com/hyperledger/fabric-ca/util"
    17  	"github.com/stretchr/testify/assert"
    18  	"golang.org/x/crypto/ocsp"
    19  )
    20  
    21  func TestGetAllAffiliations(t *testing.T) {
    22  	os.RemoveAll(rootDir)
    23  	defer os.RemoveAll(rootDir)
    24  
    25  	var err error
    26  
    27  	srv := TestGetRootServer(t)
    28  	srv.RegisterBootstrapUser("admin2", "admin2pw", "org2")
    29  	err = srv.Start()
    30  	util.FatalError(t, err, "Failed to start server")
    31  
    32  	client := getTestClient(7075)
    33  	resp, err := client.Enroll(&api.EnrollmentRequest{
    34  		Name:   "admin",
    35  		Secret: "adminpw",
    36  	})
    37  	util.FatalError(t, err, "Failed to enroll user 'admin'")
    38  
    39  	admin := resp.Identity
    40  
    41  	resp, err = client.Enroll(&api.EnrollmentRequest{
    42  		Name:   "admin2",
    43  		Secret: "admin2pw",
    44  	})
    45  
    46  	admin2 := resp.Identity
    47  
    48  	getResp, err := admin.GetAllAffiliations("")
    49  	assert.NoError(t, err, "Failed to get all affiliations")
    50  
    51  	affiliations := []db.AffiliationRecord{}
    52  	err = srv.CA.db.Select("", &affiliations, srv.CA.db.Rebind("SELECT * FROM affiliations"))
    53  	if err != nil {
    54  		t.Error("Failed to get all affiliations in database")
    55  	}
    56  
    57  	for _, aff := range affiliations {
    58  		if !searchTree(getResp, aff.Name) {
    59  			t.Error("Failed to get all appropriate affiliations")
    60  		}
    61  	}
    62  
    63  	// admin2's affilations is "org2"
    64  	getResp, err = admin2.GetAllAffiliations("")
    65  	assert.NoError(t, err, "Failed to get all affiliations for admin2")
    66  
    67  	if !searchTree(getResp, "org2") {
    68  		t.Error("Failed to get all appropriate affiliations")
    69  	}
    70  
    71  	notAffMgr, err := admin.RegisterAndEnroll(&api.RegistrationRequest{
    72  		Name: "notAffMgr",
    73  	})
    74  	util.FatalError(t, err, "Failed to register a user that is not affiliation manager")
    75  
    76  	_, err = notAffMgr.GetAllAffiliations("")
    77  	if assert.Error(t, err, "Should have failed, as the caller does not have the attribute 'hf.AffiliationMgr'") {
    78  		assert.Contains(t, err.Error(), "User does not have attribute 'hf.AffiliationMgr'")
    79  	}
    80  
    81  	err = srv.Stop()
    82  	util.FatalError(t, err, "Failed to stop server")
    83  
    84  	srv = TestGetRootServer(t)
    85  	srv.CA.Config.Affiliations = nil
    86  	err = srv.Start()
    87  	util.FatalError(t, err, "Failed to start server")
    88  	defer srv.Stop()
    89  
    90  	client = getTestClient(7075)
    91  	resp, err = client.Enroll(&api.EnrollmentRequest{
    92  		Name:   "admin",
    93  		Secret: "adminpw",
    94  	})
    95  	util.FatalError(t, err, "Failed to enroll user 'admin'")
    96  	admin = resp.Identity
    97  
    98  	getResp, err = admin.GetAllAffiliations("")
    99  	util.ErrorContains(t, err, "16", "If no affiliations are configured, should throw an error")
   100  }
   101  
   102  func TestGetAffiliation(t *testing.T) {
   103  	os.RemoveAll(rootDir)
   104  	defer os.RemoveAll(rootDir)
   105  
   106  	var err error
   107  
   108  	srv := TestGetRootServer(t)
   109  	srv.RegisterBootstrapUser("admin2", "admin2pw", "org2")
   110  	err = srv.Start()
   111  	util.FatalError(t, err, "Failed to start server")
   112  	defer srv.Stop()
   113  
   114  	client := getTestClient(7075)
   115  	resp, err := client.Enroll(&api.EnrollmentRequest{
   116  		Name:   "admin",
   117  		Secret: "adminpw",
   118  	})
   119  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   120  
   121  	admin := resp.Identity
   122  
   123  	resp, err = client.Enroll(&api.EnrollmentRequest{
   124  		Name:   "admin2",
   125  		Secret: "admin2pw",
   126  	})
   127  
   128  	admin2 := resp.Identity
   129  
   130  	getAffResp, err := admin.GetAffiliation("org2", "")
   131  	assert.NoError(t, err, "Failed to get requested affiliations")
   132  	assert.Equal(t, "org2", getAffResp.Name)
   133  	assert.Equal(t, "org2.dept1", getAffResp.Affiliations[0].Name)
   134  
   135  	getAffResp, err = admin.GetAffiliation("org2.dept1", "")
   136  	assert.NoError(t, err, "Failed to get requested affiliations")
   137  	assert.Equal(t, "org2.dept1", getAffResp.Name)
   138  
   139  	getAffResp, err = admin2.GetAffiliation("org1", "")
   140  	assert.Error(t, err, "Should have failed, caller not authorized to get affiliation")
   141  
   142  	getAffResp, err = admin2.GetAffiliation("org2.dept2", "")
   143  	assert.Error(t, err, "Should have returned an error, requested affiliation does not exist")
   144  
   145  	getAffResp, err = admin2.GetAffiliation("org2.dept1", "")
   146  	assert.NoError(t, err, "Failed to get requested affiliation")
   147  
   148  	notAffMgr, err := admin.RegisterAndEnroll(&api.RegistrationRequest{
   149  		Name: "notAffMgr",
   150  	})
   151  	util.FatalError(t, err, "Failed to register a user that is not affiliation manager")
   152  
   153  	_, err = notAffMgr.GetAffiliation("org2", "")
   154  	assert.Error(t, err, "Should have failed, as the caller does not have the attribute 'hf.AffiliationMgr'")
   155  }
   156  
   157  func TestDynamicAddAffiliation(t *testing.T) {
   158  	os.RemoveAll(rootDir)
   159  	defer os.RemoveAll(rootDir)
   160  
   161  	var err error
   162  
   163  	srv := TestGetRootServer(t)
   164  	srv.RegisterBootstrapUser("admin2", "admin2pw", "org2")
   165  	err = srv.Start()
   166  	util.FatalError(t, err, "Failed to start server")
   167  	defer srv.Stop()
   168  
   169  	client := getTestClient(7075)
   170  	resp, err := client.Enroll(&api.EnrollmentRequest{
   171  		Name:   "admin",
   172  		Secret: "adminpw",
   173  	})
   174  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   175  
   176  	admin := resp.Identity
   177  
   178  	// Register an admin with "hf.AffiliationMgr" role
   179  	notAffMgr, err := admin.RegisterAndEnroll(&api.RegistrationRequest{
   180  		Name: "notAffMgr",
   181  		Attributes: []api.Attribute{
   182  			api.Attribute{
   183  				Name:  "hf.AffiliationMgr",
   184  				Value: "false",
   185  			},
   186  		},
   187  	})
   188  
   189  	resp, err = client.Enroll(&api.EnrollmentRequest{
   190  		Name:   "admin2",
   191  		Secret: "admin2pw",
   192  	})
   193  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   194  
   195  	admin2 := resp.Identity
   196  
   197  	addAffReq := &api.AddAffiliationRequest{
   198  		Name: "org3",
   199  	}
   200  
   201  	addAffResp, err := notAffMgr.AddAffiliation(addAffReq)
   202  	assert.Error(t, err, "Should have failed, caller does not have 'hf.AffiliationMgr' attribute")
   203  
   204  	addAffResp, err = admin2.AddAffiliation(addAffReq)
   205  	assert.Error(t, err, "Should have failed affiliation, caller's affilation is 'org2'. Caller can't add affiliation 'org3'")
   206  
   207  	addAffResp, err = admin.AddAffiliation(addAffReq)
   208  	util.FatalError(t, err, "Failed to add affiliation 'org3'")
   209  	assert.Equal(t, "org3", addAffResp.Name)
   210  
   211  	addAffResp, err = admin.AddAffiliation(addAffReq)
   212  	assert.Error(t, err, "Should have failed affiliation 'org3' already exists")
   213  
   214  	addAffReq.Name = "org3.dept1"
   215  	addAffResp, err = admin.AddAffiliation(addAffReq)
   216  	assert.NoError(t, err, "Failed to affiliation")
   217  
   218  	registry := srv.registry
   219  	_, err = registry.GetAffiliation("org3.dept1")
   220  	assert.NoError(t, err, "Failed to add affiliation correctly")
   221  
   222  	addAffReq.Name = "org4.dept1.team2"
   223  	addAffResp, err = admin.AddAffiliation(addAffReq)
   224  	assert.Error(t, err, "Should have failed, parent affiliation does not exist. Force option is required")
   225  
   226  	addAffReq.Force = true
   227  	addAffResp, err = admin.AddAffiliation(addAffReq)
   228  	assert.NoError(t, err, "Failed to add multiple affiliations with force option")
   229  
   230  	_, err = registry.GetAffiliation("org4.dept1.team2")
   231  	assert.NoError(t, err, "Failed to add affiliation correctly")
   232  
   233  	_, err = registry.GetAffiliation("org4.dept1")
   234  	assert.NoError(t, err, "Failed to add affiliation correctly")
   235  	assert.Equal(t, "org4.dept1.team2", addAffResp.Name)
   236  }
   237  
   238  func TestDynamicRemoveAffiliation(t *testing.T) {
   239  	os.RemoveAll(rootDir)
   240  	defer os.RemoveAll(rootDir)
   241  
   242  	var err error
   243  
   244  	srv := TestGetRootServer(t)
   245  	srv.RegisterBootstrapUser("admin2", "admin2pw", "org2")
   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  	resp, err = client.Enroll(&api.EnrollmentRequest{
   260  		Name:   "admin2",
   261  		Secret: "admin2pw",
   262  	})
   263  	util.FatalError(t, err, "Failed to enroll user 'admin2'")
   264  
   265  	admin2 := resp.Identity
   266  
   267  	_, err = admin.RegisterAndEnroll(&api.RegistrationRequest{
   268  		Name:        "testuser1",
   269  		Affiliation: "org2",
   270  	})
   271  	assert.NoError(t, err, "Failed to register and enroll 'testuser1'")
   272  
   273  	notRegistrar, err := admin.RegisterAndEnroll(&api.RegistrationRequest{
   274  		Name: "notregistrar",
   275  		Attributes: []api.Attribute{
   276  			api.Attribute{
   277  				Name:  "hf.AffiliationMgr",
   278  				Value: "true",
   279  			},
   280  		},
   281  	})
   282  	assert.NoError(t, err, "Failed to register and enroll 'notregistrar'")
   283  
   284  	registry := srv.CA.registry
   285  	_, err = registry.GetUser("testuser1", nil)
   286  	assert.NoError(t, err, "User should exist")
   287  
   288  	certdbregistry := srv.CA.certDBAccessor
   289  	certs, err := certdbregistry.GetCertificatesByID("testuser1")
   290  	if len(certs) != 1 {
   291  		t.Error("Failed to correctly enroll identity")
   292  	}
   293  
   294  	_, err = admin.RegisterAndEnroll(&api.RegistrationRequest{
   295  		Name:        "testuser2",
   296  		Affiliation: "org2",
   297  	})
   298  	assert.NoError(t, err, "Failed to register and enroll 'testuser1'")
   299  
   300  	_, err = admin.Register(&api.RegistrationRequest{
   301  		Name:        "testuser3",
   302  		Affiliation: "org2.dept1",
   303  	})
   304  
   305  	_, err = registry.GetUser("testuser2", nil)
   306  	assert.NoError(t, err, "User should exist")
   307  
   308  	certs, err = certdbregistry.GetCertificatesByID("testuser2")
   309  	if len(certs) != 1 {
   310  		t.Error("Failed to correctly enroll identity")
   311  	}
   312  
   313  	removeAffReq := &api.RemoveAffiliationRequest{
   314  		Name: "org2",
   315  	}
   316  
   317  	_, err = admin.RemoveAffiliation(removeAffReq)
   318  	assert.Error(t, err, "Should have failed, affiliation removal not allowed")
   319  
   320  	srv.CA.Config.Cfg.Affiliations.AllowRemove = true
   321  
   322  	_, err = admin2.RemoveAffiliation(removeAffReq)
   323  	assert.Error(t, err, "Should have failed, can't remove affiliation as the same level as caller")
   324  
   325  	_, err = admin.RemoveAffiliation(removeAffReq)
   326  	assert.Error(t, err, "Should have failed, there is an identity associated with affiliation. Need to use force option")
   327  
   328  	removeAffReq.Force = true
   329  	_, err = admin.RemoveAffiliation(removeAffReq)
   330  	assert.Error(t, err, "Should have failed, there is an identity associated with affiliation but identity removal is not allowed")
   331  
   332  	srv.CA.Config.Cfg.Identities.AllowRemove = true
   333  
   334  	_, err = notRegistrar.RemoveAffiliation(removeAffReq)
   335  	if assert.Error(t, err, "Should have failed, there is an identity associated with affiliation but caller is not a registrar") {
   336  		assert.Contains(t, err.Error(), "Authorization failure")
   337  	}
   338  
   339  	removeResp, err := admin.RemoveAffiliation(removeAffReq)
   340  	assert.NoError(t, err, "Failed to remove affiliation")
   341  
   342  	_, err = registry.GetUser("testuser1", nil)
   343  	assert.Error(t, err, "User should not exist")
   344  
   345  	_, err = registry.GetUser("testuser2", nil)
   346  	assert.Error(t, err, "User should not exist")
   347  
   348  	certs, err = certdbregistry.GetCertificatesByID("testuser1")
   349  	if certs[0].Status != "revoked" && certs[0].Reason != ocsp.AffiliationChanged {
   350  		t.Error("Failed to correctly revoke certificate for an identity whose affiliation was removed")
   351  	}
   352  
   353  	certs, err = certdbregistry.GetCertificatesByID("testuser2")
   354  	if certs[0].Status != "revoked" || certs[0].Reason != ocsp.AffiliationChanged {
   355  		t.Error("Failed to correctly revoke certificate for an identity whose affiliation was removed")
   356  	}
   357  
   358  	assert.Equal(t, "org2", removeResp.Name)
   359  	assert.Equal(t, "org2.dept1", removeResp.Affiliations[0].Name)
   360  	assert.Equal(t, "testuser3", removeResp.Affiliations[0].Identities[0].ID)
   361  	assert.Equal(t, "admin2", removeResp.Identities[0].ID)
   362  
   363  	_, err = admin.RemoveAffiliation(removeAffReq)
   364  	assert.Error(t, err, "Should have failed, trying to remove an affiliation that does not exist")
   365  }
   366  
   367  func TestDynamicModifyAffiliation(t *testing.T) {
   368  	os.RemoveAll(rootDir)
   369  	defer os.RemoveAll(rootDir)
   370  
   371  	var err error
   372  
   373  	srv := TestGetRootServer(t)
   374  	srv.RegisterBootstrapUser("admin2", "admin2pw", "hyperledger")
   375  	err = srv.Start()
   376  	util.FatalError(t, err, "Failed to start server")
   377  	defer srv.Stop()
   378  
   379  	client := getTestClient(7075)
   380  	resp, err := client.Enroll(&api.EnrollmentRequest{
   381  		Name:   "admin",
   382  		Secret: "adminpw",
   383  	})
   384  	util.FatalError(t, err, "Failed to enroll user 'admin'")
   385  
   386  	admin := resp.Identity
   387  
   388  	notRegistrar, err := admin.RegisterAndEnroll(&api.RegistrationRequest{
   389  		Name:        "testuser1",
   390  		Affiliation: "org2",
   391  		Attributes: []api.Attribute{
   392  			api.Attribute{
   393  				Name:  "hf.AffiliationMgr",
   394  				Value: "true",
   395  			},
   396  		},
   397  	})
   398  
   399  	_, err = admin.AddAffiliation(&api.AddAffiliationRequest{
   400  		Name: "org2.dept1.team1",
   401  	})
   402  	assert.NoError(t, err, "Failed to add new affiliation")
   403  
   404  	_, err = admin.Register(&api.RegistrationRequest{
   405  		Name:        "testuser2",
   406  		Affiliation: "org2.dept1.team1",
   407  	})
   408  	assert.NoError(t, err, "Failed to register new user")
   409  
   410  	modifyAffReq := &api.ModifyAffiliationRequest{
   411  		Name:    "org2",
   412  		NewName: "org3",
   413  	}
   414  
   415  	_, err = admin.ModifyAffiliation(modifyAffReq)
   416  	assert.Error(t, err, "Should have failed, there is an identity associated with affiliation. Need to use force option")
   417  
   418  	modifyAffReq.Force = true
   419  	modifyResp, err := notRegistrar.ModifyAffiliation(modifyAffReq)
   420  	if assert.Error(t, err, "Should have failed to modify affiliation, identities are affected but caller is not a registrar") {
   421  		assert.Contains(t, err.Error(), "Authorization failure")
   422  	}
   423  
   424  	modifyResp, err = admin.ModifyAffiliation(modifyAffReq)
   425  	assert.NoError(t, err, "Failed to modify affiliation")
   426  
   427  	registry := srv.registry
   428  	_, err = registry.GetAffiliation("org3")
   429  	assert.NoError(t, err, "Failed to modify affiliation to 'org3'")
   430  
   431  	user, err := registry.GetUser("testuser1", nil)
   432  	util.FatalError(t, err, "Failed to get user")
   433  
   434  	userAff := cadbuser.GetAffiliation(user)
   435  	assert.Equal(t, "org3", userAff)
   436  
   437  	assert.Equal(t, "org3", modifyResp.Name)
   438  	assert.Equal(t, "org3.dept1", modifyResp.Affiliations[0].Name)
   439  	assert.Equal(t, "testuser1", modifyResp.Identities[0].ID)
   440  }
   441  
   442  func TestAffiliationNode(t *testing.T) {
   443  	an := &affiliationNode{}
   444  	an.insertByName("a.b.c")
   445  	an.insertByName("a")
   446  	an.insertByName("a.c.b")
   447  	an.insertByName("a.d.b.c.e.f.g.h.i.j.z")
   448  	root := an.GetRoot()
   449  	assert.Equal(t, root.Name, "a")
   450  	assert.True(t, searchChildren(root.Affiliations, "a.b"))
   451  	assert.True(t, searchChildren(root.Affiliations, "a.b.c"))
   452  	assert.True(t, searchChildren(root.Affiliations, "a.c"))
   453  	assert.True(t, searchChildren(root.Affiliations, "a.d.b.c.e.f.g.h.i.j"))
   454  	assert.False(t, searchChildren(root.Affiliations, "b"))
   455  	assert.False(t, searchChildren(root.Affiliations, "c.b"))
   456  	assert.False(t, searchChildren(root.Affiliations, "z"))
   457  	an.insertByName("x")
   458  	root = an.GetRoot()
   459  	assert.Equal(t, root.Name, "")
   460  }
   461  
   462  func searchTree(resp *api.AffiliationResponse, find string) bool {
   463  	if resp.Name == find {
   464  		return true
   465  	}
   466  	return searchChildren(resp.Affiliations, find)
   467  }
   468  
   469  func searchChildren(children []api.AffiliationInfo, find string) bool {
   470  	for _, child := range children {
   471  		if child.Name == find {
   472  			return true
   473  		}
   474  		if searchChildren(child.Affiliations, find) {
   475  			return true
   476  		}
   477  	}
   478  	return false
   479  }