gitee.com/Mydawng/fabric-ca@v2.0.0-alpha.0.20201214145411-9ea68369cb61+incompatible/lib/attr/attribute_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package attr
     8  
     9  import (
    10  	"testing"
    11  
    12  	"github.com/hyperledger/fabric-ca/internal/pkg/api"
    13  	"github.com/pkg/errors"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  type testUser struct {
    18  	name       string
    19  	attributes []api.Attribute
    20  }
    21  
    22  func getUser(name string, attrs []api.Attribute) AttributeControl {
    23  	return &testUser{
    24  		name:       name,
    25  		attributes: attrs,
    26  	}
    27  }
    28  
    29  func (tu *testUser) GetAttribute(name string) (*api.Attribute, error) {
    30  	attrs := make(map[string]api.Attribute)
    31  	for _, attr := range tu.attributes {
    32  		attrs[attr.Name] = api.Attribute{
    33  			Name:  attr.Name,
    34  			Value: attr.Value,
    35  			ECert: attr.ECert,
    36  		}
    37  	}
    38  	value, hasAttr := attrs[name]
    39  	if !hasAttr {
    40  		return nil, errors.Errorf("User does not have attribute '%s'", name)
    41  	}
    42  	return &value, nil
    43  }
    44  
    45  func TestCanRegisterAttributes(t *testing.T) {
    46  	negativeTests(t)
    47  	positiveTests(t)
    48  }
    49  
    50  func negativeTests(t *testing.T) {
    51  	var err error
    52  
    53  	requestedAttrs := []api.Attribute{}
    54  	user := getUser("testuser", []api.Attribute{})
    55  	registrar := getUser("admin", []api.Attribute{})
    56  
    57  	// Negative Case: Registrar does not have 'hf.Registrar.Attribute'
    58  	requestedAttrs = []api.Attribute{
    59  		api.Attribute{
    60  			Name:  Roles,
    61  			Value: "peer,client",
    62  		},
    63  	}
    64  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    65  	assert.Error(t, err, "Should fail, registrar does not have 'hf.Registrar.Attribute'")
    66  
    67  	// Negative Case: Registrar does not have any value for 'hf.Registrar.Attribute'
    68  	registrar = getUser("admin", []api.Attribute{
    69  		api.Attribute{
    70  			Name:  RegistrarAttr,
    71  			Value: "",
    72  		},
    73  	})
    74  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    75  	assert.Error(t, err, "Should fail, registrar does not have any value for 'hf.Registrar.Attribute'")
    76  
    77  	// Negative Case: Registrar does not have 'hf.Registrar.Roles' as a value for 'hf.Registrar.Attribute'
    78  	registrar = getUser("admin", []api.Attribute{
    79  		api.Attribute{
    80  			Name:  RegistrarAttr,
    81  			Value: "hf.Revoker",
    82  		},
    83  	})
    84  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    85  	assert.Error(t, err, "Should fail, registrar does not have any value for 'hf.Registrar.Attribute'")
    86  
    87  	// Negative Case: Registrar has 'hf.Registrar.Roles' as a value for 'hf.Registrar.Attribute' but does not own 'hf.Registrar.Roles'
    88  	registrar = getUser("admin", []api.Attribute{
    89  		api.Attribute{
    90  			Name:  RegistrarAttr,
    91  			Value: "hf.Registrar.Roles",
    92  		},
    93  	})
    94  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    95  	assert.Error(t, err, "Should fail, registrar has 'hf.Registrar.Roles' as a value for 'hf.Registrar.Attribute' but does not own 'hf.Registrar.Roles'")
    96  
    97  	// Negative Case: Registrar has 'hf.Registrar.Roles' with a value of 'peer', can't register a request for 'hf.Registrar.Roles=peer,client'. Must
    98  	// be a equal or subset.
    99  	registrar = getUser("admin", []api.Attribute{
   100  		api.Attribute{
   101  			Name:  Roles,
   102  			Value: "peer",
   103  		},
   104  		api.Attribute{
   105  			Name:  RegistrarAttr,
   106  			Value: "hf.Registrar.Roles",
   107  		},
   108  	})
   109  	requestedAttrs = []api.Attribute{
   110  		api.Attribute{
   111  			Name:  Roles,
   112  			Value: "peer,client",
   113  		},
   114  	}
   115  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   116  	assert.Error(t, err, "Should fail, registrar can't register a request for 'hf.Registrar.Roles=peer,client'")
   117  
   118  	// Negative Case: User has 'hf.Registrar.Roles' with a value of 'peer', can't register a request for 'hf.Registrar.DeletgateRoles=peer,client'. Must
   119  	// be a equal or subset.
   120  	registrar = getUser("admin", []api.Attribute{
   121  		api.Attribute{
   122  			Name:  DelegateRoles,
   123  			Value: "client,peer",
   124  		},
   125  		api.Attribute{
   126  			Name:  RegistrarAttr,
   127  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles",
   128  		},
   129  	})
   130  	requestedAttrs = []api.Attribute{
   131  		api.Attribute{
   132  			Name:  DelegateRoles,
   133  			Value: "peer,client",
   134  		},
   135  	}
   136  	user = getUser("testuser", []api.Attribute{
   137  		api.Attribute{
   138  			Name:  Roles,
   139  			Value: "peer",
   140  		},
   141  	})
   142  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   143  	assert.Error(t, err, "Should fail, registrar can't register a request for 'hf.Registrar.DeletgateRoles=peer,client'")
   144  
   145  	// Negative Case: Registrar does not have 'hf.Revoker' as a value for 'hf.Registrar.Attributes'
   146  	registrar = getUser("admin", []api.Attribute{
   147  		api.Attribute{
   148  			Name:  DelegateRoles,
   149  			Value: "client,peer",
   150  		},
   151  		api.Attribute{
   152  			Name:  RegistrarAttr,
   153  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Registrar.Attributes",
   154  		},
   155  	})
   156  	requestedAttrs = []api.Attribute{
   157  		api.Attribute{
   158  			Name:  RegistrarAttr,
   159  			Value: "hf.Revoker",
   160  		},
   161  	}
   162  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   163  	assert.Error(t, err, "Should fail, registrar does not have 'hf.Revoker' as a value for 'hf.Registrar.Attributes'")
   164  
   165  	// Negative Case: User requesting value of 'hf.Revoker' for 'hf.Registrar.Attribute' attribute, but the
   166  	// user does not own 'hf.Revoker'
   167  	registrar = getUser("admin", []api.Attribute{
   168  		api.Attribute{
   169  			Name:  DelegateRoles,
   170  			Value: "client,peer",
   171  		},
   172  		api.Attribute{
   173  			Name:  RegistrarAttr,
   174  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Registrar.Attributes,hf.Revoker",
   175  		},
   176  	})
   177  	requestedAttrs = []api.Attribute{
   178  		api.Attribute{
   179  			Name:  RegistrarAttr,
   180  			Value: "hf.Revoker",
   181  		},
   182  	}
   183  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   184  	assert.Error(t, err, "Should fail, user does not own 'hf.Revoker'")
   185  
   186  	// Negative Case: User is nil (i.e. New registration request, not a modification) requesting value of 'hf.Revoker' for 'hf.Registrar.Attribute' attribute, but the
   187  	// user is not being registered with 'hf.Revoker'
   188  	requestedAttrs = []api.Attribute{
   189  		api.Attribute{
   190  			Name:  RegistrarAttr,
   191  			Value: "hf.Revoker",
   192  		},
   193  	}
   194  	user = nil
   195  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   196  	assert.Error(t, err, "Should fail, user not being registered with 'hf.Revoker', must possess attribute to have as value for 'hf.Registrar.Attribute'")
   197  
   198  	// Negative Case: User requesting attribute 'hf.FakeAttribute' using reserved 'hf.' attribute fix for an
   199  	// invalid attribute name
   200  	registrar = getUser("admin", []api.Attribute{
   201  		api.Attribute{
   202  			Name:  "hf.FakeAttribute",
   203  			Value: "fakeValue",
   204  		},
   205  		api.Attribute{
   206  			Name:  RegistrarAttr,
   207  			Value: "*",
   208  		},
   209  	})
   210  	requestedAttrs = []api.Attribute{
   211  		api.Attribute{
   212  			Name:  "hf.FakeAttribute",
   213  			Value: "fakeValue2",
   214  		},
   215  	}
   216  	user = getUser("testuser", []api.Attribute{
   217  		api.Attribute{
   218  			Name:  Roles,
   219  			Value: "peer",
   220  		},
   221  	})
   222  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   223  	assert.Error(t, err, "Should fail, 'hf.FakeAttribute' is not existing reservered attribute")
   224  
   225  	// BOOLEAN ATTRIBUTES
   226  	// Negative Case: Registrar registered with a non-bool value, should result in an error when registering
   227  	// a boolean attribute
   228  	registrar = getUser("admin", []api.Attribute{
   229  		api.Attribute{
   230  			Name:  IntermediateCA,
   231  			Value: "nonbool_value",
   232  		},
   233  		api.Attribute{
   234  			Name:  RegistrarAttr,
   235  			Value: "*",
   236  		},
   237  	})
   238  	requestedAttrs = []api.Attribute{
   239  		api.Attribute{
   240  			Name:  IntermediateCA,
   241  			Value: "false",
   242  		},
   243  	}
   244  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   245  	assert.Error(t, err, "Should fail, registrar registered with a non-bool value")
   246  
   247  	// Negative Case: Registrar registered with a false value, should result in an error when registering
   248  	// a boolean attribute as true
   249  	registrar = getUser("admin", []api.Attribute{
   250  		api.Attribute{
   251  			Name:  IntermediateCA,
   252  			Value: "false",
   253  		},
   254  		api.Attribute{
   255  			Name:  RegistrarAttr,
   256  			Value: "*",
   257  		},
   258  	})
   259  	requestedAttrs = []api.Attribute{
   260  		api.Attribute{
   261  			Name:  IntermediateCA,
   262  			Value: "true",
   263  		},
   264  	}
   265  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   266  	assert.Error(t, err, "Should fail, registrar registered with a false value")
   267  
   268  	// Negative Case: Registrar requesting a non-boolean value
   269  	registrar = getUser("admin", []api.Attribute{
   270  		api.Attribute{
   271  			Name:  IntermediateCA,
   272  			Value: "true",
   273  		},
   274  		api.Attribute{
   275  			Name:  RegistrarAttr,
   276  			Value: "*",
   277  		},
   278  	})
   279  	requestedAttrs = []api.Attribute{
   280  		api.Attribute{
   281  			Name:  IntermediateCA,
   282  			Value: "nonbool_value",
   283  		},
   284  	}
   285  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   286  	assert.Error(t, err, "Should fail, registrar requesting a non-boolean value")
   287  
   288  	// Negative Case: Registrar requesting to delete an attribute it doesn't posses
   289  	registrar = getUser("admin", []api.Attribute{
   290  		api.Attribute{
   291  			Name:  RegistrarAttr,
   292  			Value: "*",
   293  		},
   294  	})
   295  	requestedAttrs = []api.Attribute{
   296  		api.Attribute{
   297  			Name:  IntermediateCA,
   298  			Value: "",
   299  		},
   300  	}
   301  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   302  	assert.Error(t, err, "Should fail, registrar requesting to delete an attribute it doesn't posses")
   303  
   304  	// Negative Case: Registrar requesting to modify a fixed attribute
   305  	registrar = getUser("admin", []api.Attribute{
   306  		api.Attribute{
   307  			Name:  RegistrarAttr,
   308  			Value: "*",
   309  		},
   310  	})
   311  	requestedAttrs = []api.Attribute{
   312  		api.Attribute{
   313  			Name:  Type,
   314  			Value: "client",
   315  		},
   316  	}
   317  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   318  	assert.Error(t, err, "Should fail, registrar requesting an attribute that cannot be modified")
   319  
   320  	// Negative Case: Registrar requesting to modify a fixed attribute
   321  	requestedAttrs = []api.Attribute{
   322  		api.Attribute{
   323  			Name:  Affiliation,
   324  			Value: "client",
   325  		},
   326  	}
   327  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   328  	assert.Error(t, err, "Should fail, registrar requesting an attribute that cannot be modified")
   329  
   330  	// Negative Case: Registrar requesting to modify a fixed attribute
   331  	requestedAttrs = []api.Attribute{
   332  		api.Attribute{
   333  			Name:  EnrollmentID,
   334  			Value: "client",
   335  		},
   336  	}
   337  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   338  	assert.Error(t, err, "Should fail, registrar requesting an attribute that cannot be modified")
   339  
   340  	// CUSTOM ATTRIBUTE
   341  	// Registrar requesting custom attribute that does not match pattern that is allowed
   342  	registrar = getUser("admin", []api.Attribute{
   343  		api.Attribute{
   344  			Name:  RegistrarAttr,
   345  			Value: "custom.*",
   346  		},
   347  	})
   348  	requestedAttrs = []api.Attribute{
   349  		api.Attribute{
   350  			Name:  "CustomAttr",
   351  			Value: "CustomValue",
   352  		},
   353  	}
   354  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   355  	assert.Error(t, err, "Should fail, requested attribute does not match pattern")
   356  }
   357  
   358  func positiveTests(t *testing.T) {
   359  	var err error
   360  
   361  	requestedAttrs := []api.Attribute{}
   362  	user := getUser("testuser", []api.Attribute{})
   363  	registrar := getUser("admin", []api.Attribute{})
   364  
   365  	// Requesting no attributes
   366  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   367  	assert.NoError(t, err, "Failed to register attribute")
   368  
   369  	// Registrar owns hf.IntermediateCA and is allowed to register it
   370  	registrar = getUser("admin", []api.Attribute{
   371  		api.Attribute{
   372  			Name:  IntermediateCA,
   373  			Value: "true",
   374  		},
   375  		api.Attribute{
   376  			Name:  RegistrarAttr,
   377  			Value: "hf.*",
   378  		},
   379  	})
   380  	requestedAttrs = []api.Attribute{
   381  		api.Attribute{
   382  			Name:  IntermediateCA,
   383  			Value: "true",
   384  		},
   385  	}
   386  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   387  	assert.NoError(t, err, "Failed to register attribute")
   388  
   389  	// Registrar can give user to permission to register 'hf.IntermediateCA'
   390  	registrar = getUser("admin", []api.Attribute{
   391  		api.Attribute{
   392  			Name:  IntermediateCA,
   393  			Value: "true",
   394  		},
   395  		api.Attribute{
   396  			Name:  RegistrarAttr,
   397  			Value: "hf.*",
   398  		},
   399  	})
   400  	requestedAttrs = []api.Attribute{
   401  		api.Attribute{
   402  			Name:  IntermediateCA,
   403  			Value: "true",
   404  		},
   405  		api.Attribute{
   406  			Name:  RegistrarAttr,
   407  			Value: "hf.IntermediateCA",
   408  		},
   409  	}
   410  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   411  	assert.NoError(t, err, "Failed to register attribute")
   412  
   413  	// Valid value for hf.Registrar.DelegateRoles requested
   414  	registrar = getUser("admin", []api.Attribute{
   415  		api.Attribute{
   416  			Name:  DelegateRoles,
   417  			Value: "client,peer",
   418  		},
   419  		api.Attribute{
   420  			Name:  RegistrarAttr,
   421  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles",
   422  		},
   423  	})
   424  	requestedAttrs = []api.Attribute{
   425  		api.Attribute{
   426  			Name:  DelegateRoles,
   427  			Value: "peer",
   428  		},
   429  	}
   430  	user = getUser("testuser", []api.Attribute{
   431  		api.Attribute{
   432  			Name:  Roles,
   433  			Value: "peer",
   434  		},
   435  	})
   436  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   437  	assert.NoError(t, err, "Failed to register attribute")
   438  
   439  	// Registrar requesting to delete an attribute it
   440  	registrar = getUser("admin", []api.Attribute{
   441  		api.Attribute{
   442  			Name:  IntermediateCA,
   443  			Value: "true",
   444  		},
   445  		api.Attribute{
   446  			Name:  RegistrarAttr,
   447  			Value: "*",
   448  		},
   449  	})
   450  	requestedAttrs = []api.Attribute{
   451  		api.Attribute{
   452  			Name:  IntermediateCA,
   453  			Value: "",
   454  		},
   455  	}
   456  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   457  	assert.NoError(t, err, "Registrar failed to delete attribute")
   458  
   459  	// Registrar requesting to delete an attribute it
   460  	registrar = getUser("admin", []api.Attribute{
   461  		api.Attribute{
   462  			Name:  Roles,
   463  			Value: "peer,client",
   464  		},
   465  		api.Attribute{
   466  			Name:  RegistrarAttr,
   467  			Value: "*",
   468  		},
   469  	})
   470  	requestedAttrs = []api.Attribute{
   471  		api.Attribute{
   472  			Name:  Roles,
   473  			Value: "",
   474  		},
   475  	}
   476  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   477  	assert.NoError(t, err, "Registrar failed to delete attribute")
   478  
   479  	// Registrar requesting to register a custom attribute, no ownership required
   480  	registrar = getUser("admin", []api.Attribute{
   481  		api.Attribute{
   482  			Name:  RegistrarAttr,
   483  			Value: "custom.*",
   484  		},
   485  	})
   486  	requestedAttrs = []api.Attribute{
   487  		api.Attribute{
   488  			Name:  "custom.Attr",
   489  			Value: "customValue",
   490  		},
   491  	}
   492  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   493  	assert.NoError(t, err, "Registrar failed to register custom attribute")
   494  
   495  	registrar = getUser("admin", []api.Attribute{
   496  		api.Attribute{
   497  			Name:  Revoker,
   498  			Value: "true",
   499  		},
   500  		api.Attribute{
   501  			Name:  RegistrarAttr,
   502  			Value: "*",
   503  		},
   504  	})
   505  	requestedAttrs = []api.Attribute{
   506  		api.Attribute{
   507  			Name:  Revoker,
   508  			Value: "true",
   509  		},
   510  		api.Attribute{
   511  			Name:  RegistrarAttr,
   512  			Value: "hf.Revoker",
   513  		},
   514  	}
   515  	user = nil
   516  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   517  	assert.NoError(t, err, "Should not fail, user being registered with 'hf.Revoker', must possess attribute to have as value for 'hf.Registrar.Attribute'")
   518  }
   519  
   520  func TestConvertAttrs(t *testing.T) {
   521  	positiveAttrs := map[string]string{
   522  		"AttrList":              "peer,orderer,client,user",
   523  		"AttrListWithECertAttr": "peer,orderer,client,user:ecert",
   524  		"AttrTrue":              "true",
   525  		"AttrTrueWithECertAttr": "true:ecert",
   526  		"AttrFalse":             "false",
   527  		"AttrStar":              "*",
   528  		"AttrStarWithECertAttr": "*:ecert",
   529  	}
   530  	negativeAttrs1 := map[string]string{
   531  		"AttrTrueWithInvalidAttr": "true:invalid",
   532  	}
   533  	negativeAttrs2 := map[string]string{
   534  		"AttrTrueWithDuplicateAttrs": "true:ecert:ecert",
   535  	}
   536  
   537  	attrs, err := ConvertAttrs(positiveAttrs)
   538  	if err != nil {
   539  		t.Fatal(err)
   540  	}
   541  
   542  	for _, attr := range attrs {
   543  		switch attr.Name {
   544  		case "AttrList":
   545  			if attr.Value != "peer,orderer,client,user" || attr.ECert != false {
   546  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   547  					attr.Name, attr.Value, attr.ECert)
   548  			}
   549  		case "AttrListWithECertAttr":
   550  			if attr.Value != "peer,orderer,client,user" || attr.ECert != true {
   551  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   552  					attr.Name, attr.Value, attr.ECert)
   553  			}
   554  		case "AttrTrue":
   555  			if attr.Value != "true" || attr.ECert != false {
   556  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   557  					attr.Name, attr.Value, attr.ECert)
   558  			}
   559  		case "AttrTrueWithECertAttr":
   560  			if attr.Value != "true" || attr.ECert != true {
   561  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   562  					attr.Name, attr.Value, attr.ECert)
   563  			}
   564  		case "AttrFalse":
   565  			if attr.Value != "false" || attr.ECert != false {
   566  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   567  					attr.Name, attr.Value, attr.ECert)
   568  			}
   569  		case "AttrStar":
   570  			if attr.Value != "*" || attr.ECert != false {
   571  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   572  					attr.Name, attr.Value, attr.ECert)
   573  			}
   574  		case "AttrStarWithECertAttr":
   575  			if attr.Value != "*" || attr.ECert != true {
   576  				t.Fatalf("Attr conversion of '%s' failed (value='%s', ecert='%v')",
   577  					attr.Name, attr.Value, attr.ECert)
   578  			}
   579  		default:
   580  			t.Fatal("Unknown test case")
   581  
   582  		}
   583  	}
   584  
   585  	_, err = ConvertAttrs(negativeAttrs1)
   586  	if err == nil {
   587  		t.Fatal("Negative test case 1 should have failed")
   588  	}
   589  
   590  	_, err = ConvertAttrs(negativeAttrs2)
   591  	if err == nil {
   592  		t.Fatal("Negative test case 2 should have failed")
   593  	}
   594  }