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