github.com/silveraid/fabric-ca@v1.1.0-preview.0.20180127000700-71974f53ab08/lib/attr/attribute_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8                   http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package attr
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/hyperledger/fabric-ca/api"
    23  	"github.com/pkg/errors"
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  type testUser struct {
    28  	name       string
    29  	attributes []api.Attribute
    30  }
    31  
    32  func getUser(name string, attrs []api.Attribute) AttributeControl {
    33  	return &testUser{
    34  		name:       name,
    35  		attributes: attrs,
    36  	}
    37  }
    38  
    39  func (tu *testUser) GetAttribute(name string) (*api.Attribute, error) {
    40  	attrs := make(map[string]api.Attribute)
    41  	for _, attr := range tu.attributes {
    42  		attrs[attr.Name] = api.Attribute{
    43  			Name:  attr.Name,
    44  			Value: attr.Value,
    45  			ECert: attr.ECert,
    46  		}
    47  	}
    48  	value, hasAttr := attrs[name]
    49  	if !hasAttr {
    50  		return nil, errors.Errorf("User does not have attribute '%s'", name)
    51  	}
    52  	return &value, nil
    53  }
    54  
    55  func TestCanRegisterAttributes(t *testing.T) {
    56  	negativeTests(t)
    57  	positiveTests(t)
    58  }
    59  
    60  func negativeTests(t *testing.T) {
    61  	var err error
    62  
    63  	requestedAttrs := []api.Attribute{}
    64  	user := getUser("testuser", []api.Attribute{})
    65  	registrar := getUser("admin", []api.Attribute{})
    66  
    67  	// Negative Case: Registrar does not have 'hf.Registrar.Attribute'
    68  	requestedAttrs = []api.Attribute{
    69  		api.Attribute{
    70  			Name:  Roles,
    71  			Value: "peer,client",
    72  		},
    73  	}
    74  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    75  	assert.Error(t, err, "Should fail, registrar does not have 'hf.Registrar.Attribute'")
    76  
    77  	// Negative Case: Registrar does not have any value for 'hf.Registrar.Attribute'
    78  	registrar = getUser("admin", []api.Attribute{
    79  		api.Attribute{
    80  			Name:  RegistrarAttr,
    81  			Value: "",
    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 does not have 'hf.Registrar.Roles' as a value for 'hf.Registrar.Attribute'
    88  	registrar = getUser("admin", []api.Attribute{
    89  		api.Attribute{
    90  			Name:  RegistrarAttr,
    91  			Value: "hf.Revoker",
    92  		},
    93  	})
    94  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
    95  	assert.Error(t, err, "Should fail, registrar does not have any value for 'hf.Registrar.Attribute'")
    96  
    97  	// Negative Case: Registrar has 'hf.Registrar.Roles' as a value for 'hf.Registrar.Attribute' but does not own 'hf.Registrar.Roles'
    98  	registrar = getUser("admin", []api.Attribute{
    99  		api.Attribute{
   100  			Name:  RegistrarAttr,
   101  			Value: "hf.Registrar.Roles",
   102  		},
   103  	})
   104  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   105  	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'")
   106  
   107  	// Negative Case: Registrar has 'hf.Registrar.Roles' with a value of 'peer', can't register a request for 'hf.Registrar.Roles=peer,client'. Must
   108  	// be a equal or subset.
   109  	registrar = getUser("admin", []api.Attribute{
   110  		api.Attribute{
   111  			Name:  Roles,
   112  			Value: "peer",
   113  		},
   114  		api.Attribute{
   115  			Name:  RegistrarAttr,
   116  			Value: "hf.Registrar.Roles",
   117  		},
   118  	})
   119  	requestedAttrs = []api.Attribute{
   120  		api.Attribute{
   121  			Name:  Roles,
   122  			Value: "peer,client",
   123  		},
   124  	}
   125  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   126  	assert.Error(t, err, "Should fail, registrar can't register a request for 'hf.Registrar.Roles=peer,client'")
   127  
   128  	// Negative Case: User has 'hf.Registrar.Roles' with a value of 'peer', can't register a request for 'hf.Registrar.DeletgateRoles=peer,client'. Must
   129  	// be a equal or subset.
   130  	registrar = getUser("admin", []api.Attribute{
   131  		api.Attribute{
   132  			Name:  DelegateRoles,
   133  			Value: "client,peer",
   134  		},
   135  		api.Attribute{
   136  			Name:  RegistrarAttr,
   137  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles",
   138  		},
   139  	})
   140  	requestedAttrs = []api.Attribute{
   141  		api.Attribute{
   142  			Name:  DelegateRoles,
   143  			Value: "peer,client",
   144  		},
   145  	}
   146  	user = getUser("testuser", []api.Attribute{
   147  		api.Attribute{
   148  			Name:  Roles,
   149  			Value: "peer",
   150  		},
   151  	})
   152  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   153  	assert.Error(t, err, "Should fail, registrar can't register a request for 'hf.Registrar.DeletgateRoles=peer,client'")
   154  
   155  	// Negative Case: Registrar does not have 'hf.Revoker' as a value for 'hf.Registrar.Attributes'
   156  	registrar = getUser("admin", []api.Attribute{
   157  		api.Attribute{
   158  			Name:  DelegateRoles,
   159  			Value: "client,peer",
   160  		},
   161  		api.Attribute{
   162  			Name:  RegistrarAttr,
   163  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Registrar.Attributes",
   164  		},
   165  	})
   166  	requestedAttrs = []api.Attribute{
   167  		api.Attribute{
   168  			Name:  RegistrarAttr,
   169  			Value: "hf.Revoker",
   170  		},
   171  	}
   172  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   173  	assert.Error(t, err, "Should fail, registrar does not have 'hf.Revoker' as a value for 'hf.Registrar.Attributes'")
   174  
   175  	// Negative Case: User requesting value of 'hf.Revoker' for 'hf.Registrar.Attribute' attribute, but the
   176  	// user does not own 'hf.Revoker'
   177  	registrar = getUser("admin", []api.Attribute{
   178  		api.Attribute{
   179  			Name:  DelegateRoles,
   180  			Value: "client,peer",
   181  		},
   182  		api.Attribute{
   183  			Name:  RegistrarAttr,
   184  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles,hf.Registrar.Attributes,hf.Revoker",
   185  		},
   186  	})
   187  	requestedAttrs = []api.Attribute{
   188  		api.Attribute{
   189  			Name:  RegistrarAttr,
   190  			Value: "hf.Revoker",
   191  		},
   192  	}
   193  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   194  	assert.Error(t, err, "Should fail, user does not own 'hf.Revoker'")
   195  
   196  	// 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
   197  	// user is not being registered with 'hf.Revoker'
   198  	requestedAttrs = []api.Attribute{
   199  		api.Attribute{
   200  			Name:  RegistrarAttr,
   201  			Value: "hf.Revoker",
   202  		},
   203  	}
   204  	user = nil
   205  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   206  	assert.Error(t, err, "Should fail, user not being registered with 'hf.Revoker', must possess attribute to have as value for 'hf.Registrar.Attribute'")
   207  
   208  	// Negative Case: User requesting attribute 'hf.FakeAttribute' using reserved 'hf.' attribute fix for an
   209  	// invalid attribute name
   210  	registrar = getUser("admin", []api.Attribute{
   211  		api.Attribute{
   212  			Name:  "hf.FakeAttribute",
   213  			Value: "fakeValue",
   214  		},
   215  		api.Attribute{
   216  			Name:  RegistrarAttr,
   217  			Value: "*",
   218  		},
   219  	})
   220  	requestedAttrs = []api.Attribute{
   221  		api.Attribute{
   222  			Name:  "hf.FakeAttribute",
   223  			Value: "fakeValue2",
   224  		},
   225  	}
   226  	user = getUser("testuser", []api.Attribute{
   227  		api.Attribute{
   228  			Name:  Roles,
   229  			Value: "peer",
   230  		},
   231  	})
   232  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   233  	assert.Error(t, err, "Should fail, 'hf.FakeAttribute' is not existing reservered attribute")
   234  
   235  	// BOOLEAN ATTRIBUTES
   236  	// Negative Case: Registrar registered with a non-bool value, should result in an error when registering
   237  	// a boolean attribute
   238  	registrar = getUser("admin", []api.Attribute{
   239  		api.Attribute{
   240  			Name:  IntermediateCA,
   241  			Value: "nonbool_value",
   242  		},
   243  		api.Attribute{
   244  			Name:  RegistrarAttr,
   245  			Value: "*",
   246  		},
   247  	})
   248  	requestedAttrs = []api.Attribute{
   249  		api.Attribute{
   250  			Name:  IntermediateCA,
   251  			Value: "false",
   252  		},
   253  	}
   254  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   255  	assert.Error(t, err, "Should fail, registrar registered with a non-bool value")
   256  
   257  	// Negative Case: Registrar registered with a false value, should result in an error when registering
   258  	// a boolean attribute as true
   259  	registrar = getUser("admin", []api.Attribute{
   260  		api.Attribute{
   261  			Name:  IntermediateCA,
   262  			Value: "false",
   263  		},
   264  		api.Attribute{
   265  			Name:  RegistrarAttr,
   266  			Value: "*",
   267  		},
   268  	})
   269  	requestedAttrs = []api.Attribute{
   270  		api.Attribute{
   271  			Name:  IntermediateCA,
   272  			Value: "true",
   273  		},
   274  	}
   275  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   276  	assert.Error(t, err, "Should fail, registrar registered with a false value")
   277  
   278  	// Negative Case: Registrar requesting a non-boolean value
   279  	registrar = getUser("admin", []api.Attribute{
   280  		api.Attribute{
   281  			Name:  IntermediateCA,
   282  			Value: "true",
   283  		},
   284  		api.Attribute{
   285  			Name:  RegistrarAttr,
   286  			Value: "*",
   287  		},
   288  	})
   289  	requestedAttrs = []api.Attribute{
   290  		api.Attribute{
   291  			Name:  IntermediateCA,
   292  			Value: "nonbool_value",
   293  		},
   294  	}
   295  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   296  	assert.Error(t, err, "Should fail, registrar requesting a non-boolean value")
   297  
   298  	// Negative Case: Registrar requesting to delete an attribute it doesn't posses
   299  	registrar = getUser("admin", []api.Attribute{
   300  		api.Attribute{
   301  			Name:  RegistrarAttr,
   302  			Value: "*",
   303  		},
   304  	})
   305  	requestedAttrs = []api.Attribute{
   306  		api.Attribute{
   307  			Name:  IntermediateCA,
   308  			Value: "",
   309  		},
   310  	}
   311  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   312  	assert.Error(t, err, "Should fail, registrar requesting to delete an attribute it doesn't posses")
   313  
   314  	// Negative Case: Registrar requesting to modify a fixed attribute
   315  	registrar = getUser("admin", []api.Attribute{
   316  		api.Attribute{
   317  			Name:  RegistrarAttr,
   318  			Value: "*",
   319  		},
   320  	})
   321  	requestedAttrs = []api.Attribute{
   322  		api.Attribute{
   323  			Name:  Type,
   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:  Affiliation,
   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  	// Negative Case: Registrar requesting to modify a fixed attribute
   341  	requestedAttrs = []api.Attribute{
   342  		api.Attribute{
   343  			Name:  EnrollmentID,
   344  			Value: "client",
   345  		},
   346  	}
   347  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   348  	assert.Error(t, err, "Should fail, registrar requesting an attribute that cannot be modified")
   349  
   350  	// CUSTOM ATTRIBUTE
   351  	// Registrar requesting custom attribute that does not match pattern that is allowed
   352  	registrar = getUser("admin", []api.Attribute{
   353  		api.Attribute{
   354  			Name:  RegistrarAttr,
   355  			Value: "custom.*",
   356  		},
   357  	})
   358  	requestedAttrs = []api.Attribute{
   359  		api.Attribute{
   360  			Name:  "CustomAttr",
   361  			Value: "CustomValue",
   362  		},
   363  	}
   364  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   365  	assert.Error(t, err, "Should fail, requested attribute does not match pattern")
   366  }
   367  
   368  func positiveTests(t *testing.T) {
   369  	var err error
   370  
   371  	requestedAttrs := []api.Attribute{}
   372  	user := getUser("testuser", []api.Attribute{})
   373  	registrar := getUser("admin", []api.Attribute{})
   374  
   375  	// Requesting no attributes
   376  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   377  	assert.NoError(t, err, "Failed to register attribute")
   378  
   379  	// Registrar owns hf.IntermediateCA and is allowed to register it
   380  	registrar = getUser("admin", []api.Attribute{
   381  		api.Attribute{
   382  			Name:  IntermediateCA,
   383  			Value: "true",
   384  		},
   385  		api.Attribute{
   386  			Name:  RegistrarAttr,
   387  			Value: "hf.*",
   388  		},
   389  	})
   390  	requestedAttrs = []api.Attribute{
   391  		api.Attribute{
   392  			Name:  IntermediateCA,
   393  			Value: "true",
   394  		},
   395  	}
   396  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   397  	assert.NoError(t, err, "Failed to register attribute")
   398  
   399  	// Registrar can give user to permission to register 'hf.IntermediateCA'
   400  	registrar = getUser("admin", []api.Attribute{
   401  		api.Attribute{
   402  			Name:  IntermediateCA,
   403  			Value: "true",
   404  		},
   405  		api.Attribute{
   406  			Name:  RegistrarAttr,
   407  			Value: "hf.*",
   408  		},
   409  	})
   410  	requestedAttrs = []api.Attribute{
   411  		api.Attribute{
   412  			Name:  IntermediateCA,
   413  			Value: "true",
   414  		},
   415  		api.Attribute{
   416  			Name:  RegistrarAttr,
   417  			Value: "hf.IntermediateCA",
   418  		},
   419  	}
   420  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   421  	assert.NoError(t, err, "Failed to register attribute")
   422  
   423  	// Valid value for hf.Registrar.DelegateRoles requested
   424  	registrar = getUser("admin", []api.Attribute{
   425  		api.Attribute{
   426  			Name:  DelegateRoles,
   427  			Value: "client,peer",
   428  		},
   429  		api.Attribute{
   430  			Name:  RegistrarAttr,
   431  			Value: "hf.Registrar.Roles,hf.Registrar.DelegateRoles",
   432  		},
   433  	})
   434  	requestedAttrs = []api.Attribute{
   435  		api.Attribute{
   436  			Name:  DelegateRoles,
   437  			Value: "peer",
   438  		},
   439  	}
   440  	user = getUser("testuser", []api.Attribute{
   441  		api.Attribute{
   442  			Name:  Roles,
   443  			Value: "peer",
   444  		},
   445  	})
   446  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   447  	assert.NoError(t, err, "Failed to register attribute")
   448  
   449  	// Registrar requesting to delete an attribute it
   450  	registrar = getUser("admin", []api.Attribute{
   451  		api.Attribute{
   452  			Name:  IntermediateCA,
   453  			Value: "true",
   454  		},
   455  		api.Attribute{
   456  			Name:  RegistrarAttr,
   457  			Value: "*",
   458  		},
   459  	})
   460  	requestedAttrs = []api.Attribute{
   461  		api.Attribute{
   462  			Name:  IntermediateCA,
   463  			Value: "",
   464  		},
   465  	}
   466  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   467  	assert.NoError(t, err, "Registrar failed to delete attribute")
   468  
   469  	// Registrar requesting to delete an attribute it
   470  	registrar = getUser("admin", []api.Attribute{
   471  		api.Attribute{
   472  			Name:  Roles,
   473  			Value: "peer,client",
   474  		},
   475  		api.Attribute{
   476  			Name:  RegistrarAttr,
   477  			Value: "*",
   478  		},
   479  	})
   480  	requestedAttrs = []api.Attribute{
   481  		api.Attribute{
   482  			Name:  Roles,
   483  			Value: "",
   484  		},
   485  	}
   486  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   487  	assert.NoError(t, err, "Registrar failed to delete attribute")
   488  
   489  	// Registrar requesting to register a custom attribute, no ownership required
   490  	registrar = getUser("admin", []api.Attribute{
   491  		api.Attribute{
   492  			Name:  RegistrarAttr,
   493  			Value: "custom.*",
   494  		},
   495  	})
   496  	requestedAttrs = []api.Attribute{
   497  		api.Attribute{
   498  			Name:  "custom.Attr",
   499  			Value: "customValue",
   500  		},
   501  	}
   502  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   503  	assert.NoError(t, err, "Registrar failed to register custom attribute")
   504  
   505  	registrar = getUser("admin", []api.Attribute{
   506  		api.Attribute{
   507  			Name:  Revoker,
   508  			Value: "true",
   509  		},
   510  		api.Attribute{
   511  			Name:  RegistrarAttr,
   512  			Value: "*",
   513  		},
   514  	})
   515  	requestedAttrs = []api.Attribute{
   516  		api.Attribute{
   517  			Name:  Revoker,
   518  			Value: "true",
   519  		},
   520  		api.Attribute{
   521  			Name:  RegistrarAttr,
   522  			Value: "hf.Revoker",
   523  		},
   524  	}
   525  	user = nil
   526  	err = CanRegisterRequestedAttributes(requestedAttrs, user, registrar)
   527  	assert.NoError(t, err, "Should not fail, user being registered with 'hf.Revoker', must possess attribute to have as value for 'hf.Registrar.Attribute'")
   528  }