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