github.com/simranvc/fabric-ca@v0.0.0-20191030094829-acc364294dde/lib/serverregister_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  	"os"
    10  	"strconv"
    11  	"testing"
    12  
    13  	"github.com/hyperledger/fabric-ca/api"
    14  	"github.com/hyperledger/fabric-ca/lib/attr"
    15  	"github.com/hyperledger/fabric-ca/lib/caerrors"
    16  	"github.com/hyperledger/fabric-ca/lib/mocks"
    17  	cadbuser "github.com/hyperledger/fabric-ca/lib/server/user"
    18  	"github.com/hyperledger/fabric-ca/util"
    19  	"github.com/stretchr/testify/assert"
    20  )
    21  
    22  func TestRegistrarAttribute(t *testing.T) {
    23  	os.RemoveAll(rootDir)
    24  	os.RemoveAll("../testdata/msp")
    25  	defer os.RemoveAll(rootDir)
    26  	defer os.RemoveAll("../testdata/msp")
    27  
    28  	var err error
    29  
    30  	srv := TestGetRootServer(t)
    31  	registry := &srv.CA.Config.Registry
    32  
    33  	// admin2 own attributes but does not have 'hf.Registrar.Attributes' attribute
    34  	id := CAConfigIdentity{
    35  		Name:           "admin2",
    36  		Pass:           "admin2pw",
    37  		Type:           "user",
    38  		Affiliation:    "org2",
    39  		MaxEnrollments: -1,
    40  		Attrs: map[string]string{
    41  			attr.Roles:   "user,peer",
    42  			attr.Revoker: "false",
    43  			"a.b":        "val1",
    44  		},
    45  	}
    46  	registry.Identities = append(registry.Identities, id)
    47  
    48  	// admin3 has 'hf.Registrar.Attributes' attribute
    49  	id = CAConfigIdentity{
    50  		Name:           "admin3",
    51  		Pass:           "admin3pw",
    52  		Type:           "user",
    53  		Affiliation:    "org2",
    54  		MaxEnrollments: -1,
    55  		Attrs: map[string]string{
    56  			attr.Roles:          allRoles,
    57  			attr.DelegateRoles:  allRoles,
    58  			attr.Revoker:        "true",
    59  			attr.IntermediateCA: "true",
    60  			attr.RegistrarAttr:  "a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker",
    61  		},
    62  	}
    63  	registry.Identities = append(registry.Identities, id)
    64  
    65  	// admin4 has 'hf.Registrar.Attributes' attribute but can only register 'hf.' attributes
    66  	id = CAConfigIdentity{
    67  		Name:           "admin4",
    68  		Pass:           "admin4pw",
    69  		Type:           "user",
    70  		Affiliation:    "org2",
    71  		MaxEnrollments: -1,
    72  		Attrs: map[string]string{
    73  			attr.Roles:         "user,peer",
    74  			attr.Revoker:       "false",
    75  			attr.RegistrarAttr: "hf.*",
    76  		},
    77  	}
    78  	registry.Identities = append(registry.Identities, id)
    79  
    80  	err = srv.Start()
    81  	util.FatalError(t, err, "Failed to start server")
    82  	defer srv.Stop()
    83  
    84  	// Enroll admin2
    85  	client := getTestClient(rootPort)
    86  
    87  	negativeCases(t, client)
    88  	positiveCases(t, client)
    89  }
    90  
    91  func negativeCases(t *testing.T, client *Client) {
    92  	enrollResp, err := client.Enroll(&api.EnrollmentRequest{
    93  		Name:   "admin2",
    94  		Secret: "admin2pw",
    95  	})
    96  	util.FatalError(t, err, "Failed to enroll 'admin2' user")
    97  	registrar := enrollResp.Identity
    98  
    99  	missingHfRegistrarAttr(t, registrar)
   100  
   101  	enrollResp, err = client.Enroll(&api.EnrollmentRequest{
   102  		Name:   "admin4",
   103  		Secret: "admin4pw",
   104  	})
   105  	util.FatalError(t, err, "Failed to enroll 'admin4' user")
   106  	registrar = enrollResp.Identity
   107  
   108  	invalidAttrRequestValues(t, registrar)
   109  
   110  	// Enroll request for admin3
   111  	enrollResp, err = client.Enroll(&api.EnrollmentRequest{
   112  		Name:   "admin3",
   113  		Secret: "admin3pw",
   114  	})
   115  	assert.NoError(t, err, "Failed to enroll 'admin3' user")
   116  	registrar = enrollResp.Identity
   117  
   118  	invalidAttrRequest(t, registrar)
   119  	invalidHfRegistrarAttrRequest(t, registrar)
   120  
   121  }
   122  
   123  func missingHfRegistrarAttr(t *testing.T, registrar *Identity) {
   124  	// Negative case: Registrar does not have the attribute 'hf.Registrar.Attributes'
   125  	_, err := registrar.Register(registerTestUser("user1",
   126  		[]api.Attribute{
   127  			api.Attribute{
   128  				Name:  "fake.attribute",
   129  				Value: "val1",
   130  			},
   131  		}),
   132  	)
   133  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   134  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   135  	}
   136  
   137  	// Negative case: Registrar does not own 'hf.Registrar.Attributes'
   138  	_, err = registrar.Register(registerTestUser("user1",
   139  		[]api.Attribute{
   140  			api.Attribute{
   141  				Name:  attr.RegistrarAttr,
   142  				Value: "val1",
   143  			},
   144  		}),
   145  	)
   146  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   147  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   148  	}
   149  }
   150  
   151  func invalidAttrRequestValues(t *testing.T, registrar *Identity) {
   152  	_, err := registrar.Register(registerTestUser("user1",
   153  		[]api.Attribute{
   154  			api.Attribute{
   155  				Name:  attr.Roles,
   156  				Value: "user,peer,client",
   157  			},
   158  		}),
   159  	)
   160  	if assert.Errorf(t, err, "Should have failed to register an identity with inappropriate values for '%s', can only register a subset", attr.Roles) {
   161  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   162  	}
   163  
   164  	// Negative case: Registrar owns this attribute but with a value of 'false', can't register with a value of 'true'
   165  	_, err = registrar.Register(registerTestUser("user1",
   166  		[]api.Attribute{
   167  			api.Attribute{
   168  				Name:  attr.Revoker,
   169  				Value: "true",
   170  			},
   171  		}),
   172  	)
   173  	if assert.Error(t, err, "Should have failed to register an identity with an attribute that is not part of 'hf.Registrar.Attributes'") {
   174  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   175  	}
   176  
   177  	// Negative case: Registrar owns this attribute but with a value of 'false', can't register with a value of 'true'
   178  	_, err = registrar.Register(registerTestUser("user1",
   179  		[]api.Attribute{
   180  			api.Attribute{
   181  				Name:  "hf.FakeAttr",
   182  				Value: "true",
   183  			},
   184  		}),
   185  	)
   186  	if assert.Error(t, err, "Should have failed to register an identity with an attribute invalid attribute with prefix 'hf.'") {
   187  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   188  	}
   189  }
   190  
   191  func invalidAttrRequest(t *testing.T, registrar *Identity) {
   192  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   193  	_, err := registrar.Register(registerTestUser("user2",
   194  		[]api.Attribute{
   195  			api.Attribute{
   196  				Name:  "a.b.*",
   197  				Value: "val1",
   198  			},
   199  		}),
   200  	)
   201  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   202  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   203  	}
   204  
   205  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   206  	_, err = registrar.Register(registerTestUser("user2",
   207  		[]api.Attribute{
   208  			api.Attribute{
   209  				Name:  "a.b.c.d",
   210  				Value: "val1",
   211  			},
   212  		}),
   213  	)
   214  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   215  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   216  	}
   217  
   218  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   219  	_, err = registrar.Register(registerTestUser("user2",
   220  		[]api.Attribute{
   221  			api.Attribute{
   222  				Name:  "test",
   223  				Value: "val1",
   224  			},
   225  		}),
   226  	)
   227  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   228  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   229  	}
   230  
   231  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   232  	_, err = registrar.Register(registerTestUser("user11",
   233  		[]api.Attribute{
   234  			api.Attribute{
   235  				Name:  "*",
   236  				Value: "val1",
   237  			},
   238  		}),
   239  	)
   240  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   241  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   242  	}
   243  
   244  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   245  	_, err = registrar.Register(registerTestUser("user12",
   246  		[]api.Attribute{
   247  			api.Attribute{
   248  				Name:  "w.x.y.z",
   249  				Value: "val1",
   250  			},
   251  		}),
   252  	)
   253  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   254  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   255  	}
   256  
   257  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   258  	_, err = registrar.Register(registerTestUser("user13",
   259  		[]api.Attribute{
   260  			api.Attribute{
   261  				Name:  "hf.fakeAttr",
   262  				Value: "val1",
   263  			},
   264  		}),
   265  	)
   266  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes (hf.fakeAttr)") {
   267  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   268  	}
   269  }
   270  
   271  func invalidHfRegistrarAttrRequest(t *testing.T, registrar *Identity) {
   272  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   273  	_, err := registrar.Register(registerTestUser("user7",
   274  		[]api.Attribute{
   275  			api.Attribute{
   276  				Name:  attr.RegistrarAttr,
   277  				Value: "a.b, x.y",
   278  			},
   279  		}),
   280  	)
   281  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   282  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   283  	}
   284  
   285  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   286  	_, err = registrar.Register(registerTestUser("user7",
   287  		[]api.Attribute{
   288  			api.Attribute{
   289  				Name:  attr.RegistrarAttr,
   290  				Value: "a.b.c, x.y",
   291  			},
   292  		}),
   293  	)
   294  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes") {
   295  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   296  	}
   297  
   298  	// Negative case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   299  	_, err = registrar.Register(registerTestUser("user7",
   300  		[]api.Attribute{
   301  			api.Attribute{
   302  				Name:  attr.RegistrarAttr,
   303  				Value: "hf.Revoker",
   304  			},
   305  		}),
   306  	)
   307  	if assert.Error(t, err, "Should have failed to register an identity with inappropriate attributes, identity does not posses 'hf.Revoker'") {
   308  		assert.Contains(t, err.Error(), strconv.Itoa(caerrors.ErrAuthorizationFailure))
   309  	}
   310  }
   311  
   312  func positiveCases(t *testing.T, client *Client) {
   313  	enrollResp, err := client.Enroll(&api.EnrollmentRequest{
   314  		Name:   "admin3",
   315  		Secret: "admin3pw",
   316  	})
   317  	assert.NoError(t, err, "Failed to enroll 'admin' user")
   318  
   319  	registrar := enrollResp.Identity
   320  
   321  	registerCustomAttr(t, registrar)
   322  	registerHfRegistrarAttr(t, registrar)
   323  
   324  	// Enroll request for admin
   325  	enrollResp, err = client.Enroll(&api.EnrollmentRequest{
   326  		Name:   "admin",
   327  		Secret: "adminpw",
   328  	})
   329  	assert.NoError(t, err, "Failed to enroll 'admin' user")
   330  
   331  	registrar = enrollResp.Identity
   332  
   333  	// Positive case: Registrar's hf.Registrar.Attribute = *
   334  	_, err = registrar.Register(registerTestUser("user14",
   335  		[]api.Attribute{
   336  			api.Attribute{
   337  				Name:  "*",
   338  				Value: "val1",
   339  			},
   340  		}),
   341  	)
   342  	assert.NoError(t, err, "Failed to register an identity with appropriate attributes")
   343  }
   344  
   345  func registerCustomAttr(t *testing.T, registrar *Identity) {
   346  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   347  	_, err := registrar.Register(registerTestUser("user2",
   348  		[]api.Attribute{
   349  			api.Attribute{
   350  				Name:  "a.b.c",
   351  				Value: "val1",
   352  			},
   353  		}),
   354  	)
   355  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   356  
   357  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   358  	_, err = registrar.Register(registerTestUser("user3",
   359  		[]api.Attribute{
   360  			api.Attribute{
   361  				Name:  "testattr1",
   362  				Value: "val1",
   363  			},
   364  		}),
   365  	)
   366  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   367  
   368  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   369  	_, err = registrar.Register(registerTestUser("user4",
   370  		[]api.Attribute{
   371  			api.Attribute{
   372  				Name:  "x.y.*",
   373  				Value: "val1",
   374  			},
   375  		}),
   376  	)
   377  	assert.NoError(t, err, "Failed to register an identity with appropriate attributes")
   378  
   379  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   380  	_, err = registrar.Register(registerTestUser("user5",
   381  		[]api.Attribute{
   382  			api.Attribute{
   383  				Name:  "x.y.z",
   384  				Value: "val1",
   385  			},
   386  		}),
   387  	)
   388  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   389  }
   390  
   391  func registerHfRegistrarAttr(t *testing.T, registrar *Identity) {
   392  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   393  	_, err := registrar.Register(registerTestUser("user6",
   394  		[]api.Attribute{
   395  			api.Attribute{
   396  				Name:  attr.RegistrarAttr,
   397  				Value: "a.b.c, x.y.*",
   398  			},
   399  		}),
   400  	)
   401  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   402  
   403  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   404  	_, err = registrar.Register(registerTestUser("user7",
   405  		[]api.Attribute{
   406  			api.Attribute{
   407  				Name:  attr.RegistrarAttr,
   408  				Value: "a.b.c",
   409  			},
   410  		}),
   411  	)
   412  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   413  
   414  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   415  	_, err = registrar.Register(registerTestUser("user8",
   416  		[]api.Attribute{
   417  			api.Attribute{
   418  				Name:  attr.RegistrarAttr,
   419  				Value: "x.y.z.z",
   420  			},
   421  		}),
   422  	)
   423  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   424  
   425  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, attr, hf.Registrar.Attributes
   426  	_, err = registrar.Register(registerTestUser("user9",
   427  		[]api.Attribute{
   428  			api.Attribute{
   429  				Name:  "attr$",
   430  				Value: "val1",
   431  			},
   432  		}),
   433  	)
   434  	assert.NoError(t, err, "Should have succeeded to register an identity with appropriate attributes")
   435  
   436  	// Positive case: Registrar's hf.Registrar.Attribute = a.b.c, x.y.*, testattr*, attr$, hf.Registrar.Attributes, hf.Revoker
   437  	_, err = registrar.Register(registerTestUser("user10",
   438  		[]api.Attribute{
   439  			api.Attribute{
   440  				Name:  attr.RegistrarAttr,
   441  				Value: "x.y.z.*",
   442  			},
   443  		}),
   444  	)
   445  	assert.NoError(t, err, "Should not have failed to register appropriate command")
   446  }
   447  
   448  func registerTestUser(username string, attribute []api.Attribute) *api.RegistrationRequest {
   449  	return &api.RegistrationRequest{
   450  		Name:        username,
   451  		Affiliation: "org2",
   452  		Attributes:  attribute,
   453  	}
   454  }
   455  
   456  func TestAffiliationAndTypeCheck(t *testing.T) {
   457  	os.RemoveAll(rootDir)
   458  	os.RemoveAll("../testdata/msp")
   459  	defer os.RemoveAll(rootDir)
   460  	defer os.RemoveAll("../testdata/msp")
   461  
   462  	var err error
   463  
   464  	srv := TestGetRootServer(t)
   465  
   466  	registry := &srv.CA.Config.Registry
   467  
   468  	// admin2 own attributes but does not have 'hf.Registrar.Attributes' attribute
   469  	id := CAConfigIdentity{
   470  		Name:           "admin2",
   471  		Pass:           "admin2pw",
   472  		Type:           "user",
   473  		Affiliation:    "org2",
   474  		MaxEnrollments: -1,
   475  		Attrs: map[string]string{
   476  			attr.Roles: allRoles,
   477  		},
   478  	}
   479  	registry.Identities = append(registry.Identities, id)
   480  
   481  	err = srv.Start()
   482  	if !assert.NoError(t, err, "Failed to start server") {
   483  		t.Fatal("Failed to start server: ", err)
   484  	}
   485  
   486  	// Enroll admin2
   487  	client := getTestClient(rootPort)
   488  	enrollResp, err := client.Enroll(&api.EnrollmentRequest{
   489  		Name:   "admin2",
   490  		Secret: "admin2pw",
   491  	})
   492  	assert.NoError(t, err, "Failed to enroll 'admin' user")
   493  
   494  	registrar := enrollResp.Identity
   495  
   496  	_, err = registrar.Register(&api.RegistrationRequest{
   497  		Name:        "testuser",
   498  		Affiliation: "org2dept1",
   499  	})
   500  	assert.Error(t, err, "Should have failed to register, registrar with affiliation 'org1' can't register 'org1dept1'")
   501  
   502  	_, err = registrar.Register(&api.RegistrationRequest{
   503  		Name:        "testuser",
   504  		Affiliation: "org2",
   505  	})
   506  	assert.NoError(t, err, "Failed to register user 'testuser' with appropriate affiliation")
   507  
   508  	_, err = registrar.Register(&api.RegistrationRequest{
   509  		Name:        "testuser2",
   510  		Affiliation: "org2.dept1",
   511  	})
   512  	assert.NoError(t, err, "Failed to register user 'testuser2' with appropriate affiliation")
   513  
   514  	_, err = registrar.Register(&api.RegistrationRequest{
   515  		Name: "testuser3",
   516  	})
   517  	assert.NoError(t, err, "Failed to register user 'testuser2' with appropriate affiliation")
   518  
   519  	db := srv.CA.registry
   520  
   521  	user, err := db.GetUser("testuser3", nil)
   522  	assert.NoError(t, err, "Failed to get user")
   523  
   524  	assert.Equal(t, "user", user.GetType(), "Failed to set correct default type for a registering user")
   525  	assert.Equal(t, "org2", cadbuser.GetAffiliation(user), "Failed to set correct default affiliation for a registering userr")
   526  
   527  	err = srv.Stop()
   528  	assert.NoError(t, err, "Failed to start server")
   529  }
   530  
   531  func TestRegisterWithLDAP(t *testing.T) {
   532  	ctxMock := new(mocks.ServerRequestContext)
   533  	ctxMock.On("ReadBody", &api.RegistrationRequestNet{}).Return(nil)
   534  	ctxMock.On("TokenAuthentication").Return("", nil)
   535  	ctxMock.On("IsLDAPEnabled").Return(true)
   536  
   537  	_, err := register(ctxMock, &CA{})
   538  	util.ErrorContains(t, err, "72", "Failed to get back write error for registering identities with LDAP")
   539  }