gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/server/user/user_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package user_test
     8  
     9  import (
    10  	"errors"
    11  
    12  	"gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/api"
    13  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user"
    14  	"gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user/mocks"
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/gomega"
    17  	"golang.org/x/crypto/bcrypt"
    18  )
    19  
    20  var _ = Describe("user", func() {
    21  	var (
    22  		userRecord *user.Record
    23  		mockUserDB *mocks.UserDB
    24  		mockResult *mocks.Result
    25  		u          *user.Impl
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		mockUserDB = &mocks.UserDB{}
    30  		mockResult = &mocks.Result{}
    31  
    32  		pass, err := bcrypt.GenerateFromPassword([]byte("password"), 1)
    33  		Expect(err).NotTo(HaveOccurred())
    34  
    35  		attributes := `[{"name": "hf.Registrar.Roles", "value": "peer", "ecert": false},{"name": "attr0", "value": "attr0Value", "ecert": false}]`
    36  		userRecord = &user.Record{
    37  			Name:           "testuser",
    38  			Type:           "client",
    39  			Pass:           pass,
    40  			MaxEnrollments: 100,
    41  			Attributes:     attributes,
    42  		}
    43  
    44  		u = user.New(userRecord, mockUserDB)
    45  	})
    46  
    47  	It("creates a new user", func() {
    48  		Expect(u).NotTo(BeNil())
    49  		Expect(u.GetName()).To(Equal("testuser"))
    50  		Expect(u.GetType()).To(Equal("client"))
    51  		Expect(u.GetMaxEnrollments()).To(Equal(100))
    52  	})
    53  
    54  	Context("Setlevel", func() {
    55  		It("returns an error if db fails to execute query", func() {
    56  			mockUserDB.ExecReturns(nil, errors.New("failed to execute"))
    57  
    58  			err := u.SetLevel(2)
    59  			Expect(err).To(HaveOccurred())
    60  			Expect(err.Error()).To(Equal("failed to execute"))
    61  		})
    62  
    63  		It("returns an error if failed to get number of rows affected", func() {
    64  			mockResult.RowsAffectedReturns(int64(1), errors.New("error"))
    65  			mockUserDB.ExecReturns(mockResult, nil)
    66  
    67  			err := u.SetLevel(2)
    68  			Expect(err).To(HaveOccurred())
    69  			Expect(err.Error()).To(Equal("Failed to get number of rows affected: error"))
    70  		})
    71  
    72  		It("returns an error if number of rows affected equals 0", func() {
    73  			mockResult.RowsAffectedReturns(int64(0), nil)
    74  			mockUserDB.ExecReturns(mockResult, nil)
    75  			err := u.SetLevel(2)
    76  			Expect(err).To(HaveOccurred())
    77  			Expect(err.Error()).To(Equal("No rows were affected when updating the state of identity testuser"))
    78  		})
    79  
    80  		It("returns an error if number of rows affected is not 1", func() {
    81  			mockResult.RowsAffectedReturns(int64(3), nil)
    82  			mockUserDB.ExecReturns(mockResult, nil)
    83  			err := u.SetLevel(2)
    84  			Expect(err).To(HaveOccurred())
    85  			Expect(err.Error()).To(Equal("3 rows were affected when updating the state of identity testuser"))
    86  		})
    87  
    88  		It("sets the user's level", func() {
    89  			mockResult.RowsAffectedReturns(int64(1), nil)
    90  			mockUserDB.ExecReturns(mockResult, nil)
    91  			err := u.SetLevel(2)
    92  			Expect(err).NotTo(HaveOccurred())
    93  		})
    94  	})
    95  
    96  	Context("Login", func() {
    97  		It("returns an error if incorrect password used", func() {
    98  			mockResult.RowsAffectedReturns(int64(1), nil)
    99  			mockUserDB.ExecReturns(mockResult, nil)
   100  
   101  			err := u.Login("badpass", -1)
   102  			Expect(err).To(HaveOccurred())
   103  			Expect(err.Error()).To(ContainSubstring("Password mismatch"))
   104  		})
   105  
   106  		It("returns an error if trying to enroll with max enrollment value of 0", func() {
   107  			u.MaxEnrollments = 0
   108  			mockResult.RowsAffectedReturns(int64(1), nil)
   109  			mockUserDB.ExecReturns(mockResult, nil)
   110  
   111  			err := u.Login("password", -1)
   112  			Expect(err).To(HaveOccurred())
   113  			Expect(err.Error()).To(ContainSubstring("Zero is an invalid value for maximum enrollments on identity 'testuser'"))
   114  		})
   115  
   116  		It("returns an error if user is revoked", func() {
   117  			u.MaxEnrollments = 1
   118  			u.State = -1
   119  
   120  			mockResult.RowsAffectedReturns(int64(1), nil)
   121  			mockUserDB.ExecReturns(mockResult, nil)
   122  
   123  			err := u.Login("password", -1)
   124  			Expect(err).To(HaveOccurred())
   125  			Expect(err.Error()).To(ContainSubstring("User testuser is revoked; access denied"))
   126  		})
   127  
   128  		It("sets the max enrollment value of the user greater than the ca's max enrollment value to be ca's max value", func() {
   129  			u.MaxEnrollments = 4
   130  			mockResult.RowsAffectedReturns(int64(1), nil)
   131  			mockUserDB.ExecReturns(mockResult, nil)
   132  
   133  			u.Login("password", 2)
   134  			Expect(u.MaxEnrollments).To(Equal(2))
   135  		})
   136  
   137  		It("returns an if user's state value exceeds or is equal to user's max enrollment value", func() {
   138  			u.MaxEnrollments = 4
   139  			u.State = 4
   140  			mockResult.RowsAffectedReturns(int64(1), nil)
   141  			mockUserDB.ExecReturns(mockResult, nil)
   142  
   143  			err := u.Login("password", -1)
   144  			Expect(err).To(HaveOccurred())
   145  			Expect(err.Error()).To(Equal("The identity testuser has already enrolled 4 times, it has reached its maximum enrollment allowance"))
   146  		})
   147  
   148  		It("logins in user", func() {
   149  			u.MaxEnrollments = 4
   150  			mockResult.RowsAffectedReturns(int64(1), nil)
   151  			mockUserDB.ExecReturns(mockResult, nil)
   152  			err := u.Login("password", -1)
   153  			Expect(err).NotTo(HaveOccurred())
   154  		})
   155  	})
   156  
   157  	Context("IncrementIncorrectPasswordAttempts", func() {
   158  		It("returns an error if db fails to execute query", func() {
   159  			mockUserDB.ExecReturns(nil, errors.New("failed to execute"))
   160  
   161  			err := u.IncrementIncorrectPasswordAttempts()
   162  			Expect(err).To(HaveOccurred())
   163  			Expect(err.Error()).To(Equal("failed to execute"))
   164  		})
   165  
   166  		It("returns an error if failed to get number of rows affected", func() {
   167  			mockResult.RowsAffectedReturns(int64(1), errors.New("error"))
   168  			mockUserDB.ExecReturns(mockResult, nil)
   169  
   170  			err := u.IncrementIncorrectPasswordAttempts()
   171  			Expect(err).To(HaveOccurred())
   172  			Expect(err.Error()).To(Equal("Failed to get number of rows affected: error"))
   173  		})
   174  
   175  		It("returns an error if number of rows affected equals 0", func() {
   176  			mockResult.RowsAffectedReturns(int64(0), nil)
   177  			mockUserDB.ExecReturns(mockResult, nil)
   178  			err := u.IncrementIncorrectPasswordAttempts()
   179  			Expect(err).To(HaveOccurred())
   180  			Expect(err.Error()).To(Equal("No rows were affected when updating the state of identity testuser"))
   181  		})
   182  
   183  		It("returns an error if number of rows affected is not 1", func() {
   184  			mockResult.RowsAffectedReturns(int64(3), nil)
   185  			mockUserDB.ExecReturns(mockResult, nil)
   186  			err := u.IncrementIncorrectPasswordAttempts()
   187  			Expect(err).To(HaveOccurred())
   188  			Expect(err.Error()).To(Equal("3 rows were affected when updating the state of identity testuser"))
   189  		})
   190  
   191  	})
   192  
   193  	Context("LoginComplete", func() {
   194  		It("returns an error if db fails to execute query", func() {
   195  			mockUserDB.ExecReturns(nil, errors.New("failed to execute"))
   196  
   197  			err := u.LoginComplete()
   198  			Expect(err).To(HaveOccurred())
   199  			Expect(err.Error()).To(Equal("Failed to update state of identity testuser to 1: failed to execute"))
   200  		})
   201  
   202  		It("returns an error if failed to get number of rows affected", func() {
   203  			mockResult.RowsAffectedReturns(int64(1), errors.New("error"))
   204  			mockUserDB.ExecReturns(mockResult, nil)
   205  
   206  			err := u.LoginComplete()
   207  			Expect(err).To(HaveOccurred())
   208  			Expect(err.Error()).To(Equal("Failed to get number of rows affected: error"))
   209  		})
   210  
   211  		It("returns an error if number of rows affected equals 0", func() {
   212  			mockResult.RowsAffectedReturns(int64(0), nil)
   213  			mockUserDB.ExecReturns(mockResult, nil)
   214  			err := u.LoginComplete()
   215  			Expect(err).To(HaveOccurred())
   216  			Expect(err.Error()).To(Equal("No rows were affected when updating the state of identity testuser"))
   217  		})
   218  
   219  		It("returns an error if number of rows affected is not 1", func() {
   220  			mockResult.RowsAffectedReturns(int64(3), nil)
   221  			mockUserDB.ExecReturns(mockResult, nil)
   222  			err := u.LoginComplete()
   223  			Expect(err).To(HaveOccurred())
   224  			Expect(err.Error()).To(Equal("3 rows were affected when updating the state of identity testuser"))
   225  		})
   226  
   227  		It("updates the state of the user by 1", func() {
   228  			mockResult.RowsAffectedReturns(int64(1), nil)
   229  			mockUserDB.ExecReturns(mockResult, nil)
   230  
   231  			state := u.State
   232  			err := u.LoginComplete()
   233  			Expect(err).NotTo(HaveOccurred())
   234  			Expect(u.State).To(Equal(state + 1))
   235  		})
   236  	})
   237  
   238  	It("splits affiliation on dots and returns a string slice", func() {
   239  		u.Affiliation = "foo.bar.xyz"
   240  		aff := u.GetAffiliationPath()
   241  		Expect(aff).To(Equal([]string{"foo", "bar", "xyz"}))
   242  	})
   243  
   244  	Context("revoke", func() {
   245  		It("returns an error if fails to execute revoke query", func() {
   246  			mockUserDB.ExecReturns(nil, errors.New("failed to execute"))
   247  
   248  			err := u.Revoke()
   249  			Expect(err).To(HaveOccurred())
   250  			Expect(err.Error()).To(Equal("Failed to update state of identity testuser to -1: failed to execute"))
   251  		})
   252  
   253  		It("returns an error if failed to get number of rows affected", func() {
   254  			mockResult.RowsAffectedReturns(int64(1), errors.New("error"))
   255  			mockUserDB.ExecReturns(mockResult, nil)
   256  
   257  			err := u.Revoke()
   258  			Expect(err).To(HaveOccurred())
   259  			Expect(err.Error()).To(Equal("Failed to get number of rows affected: error"))
   260  		})
   261  
   262  		It("returns an error if number of rows affected equals 0", func() {
   263  			mockResult.RowsAffectedReturns(int64(0), nil)
   264  			mockUserDB.ExecReturns(mockResult, nil)
   265  			err := u.Revoke()
   266  			Expect(err).To(HaveOccurred())
   267  			Expect(err.Error()).To(Equal("No rows were affected when updating the state of identity testuser"))
   268  		})
   269  
   270  		It("returns an error if number of rows affected is not 1", func() {
   271  			mockResult.RowsAffectedReturns(int64(3), nil)
   272  			mockUserDB.ExecReturns(mockResult, nil)
   273  			err := u.Revoke()
   274  			Expect(err).To(HaveOccurred())
   275  			Expect(err.Error()).To(Equal("3 rows were affected when updating the state of identity testuser"))
   276  		})
   277  
   278  		It("updates the state of the user to -1", func() {
   279  			mockResult.RowsAffectedReturns(int64(1), nil)
   280  			mockUserDB.ExecReturns(mockResult, nil)
   281  			err := u.Revoke()
   282  			Expect(err).NotTo(HaveOccurred())
   283  			Expect(u.State).To(Equal(-1))
   284  		})
   285  	})
   286  
   287  	Context("is revoked", func() {
   288  		It("returns true if user is revoked", func() {
   289  			u.State = -1
   290  			Expect(u.IsRevoked()).To(Equal(true))
   291  		})
   292  
   293  		It("returns false if user is not revoked", func() {
   294  			Expect(u.IsRevoked()).To(Equal(false))
   295  		})
   296  	})
   297  
   298  	Context("get attributes", func() {
   299  		It("returns all attributes if passed nil", func() {
   300  			attrs, err := u.GetAttributes(nil)
   301  			Expect(err).NotTo(HaveOccurred())
   302  			Expect(len(attrs)).To(Equal(2))
   303  		})
   304  
   305  		It("returns only attributes that are requested", func() {
   306  			attrs, err := u.GetAttributes([]string{"attr0"})
   307  			Expect(err).NotTo(HaveOccurred())
   308  			Expect(len(attrs)).To(Equal(1))
   309  			Expect(attrs[0].Name).To(Equal("attr0"))
   310  		})
   311  
   312  		It("returns an error if requested attribute does not exist", func() {
   313  			_, err := u.GetAttributes([]string{"fakeAttr"})
   314  			Expect(err).To(HaveOccurred())
   315  		})
   316  	})
   317  
   318  	Context("get new attributes", func() {
   319  		var modifyAttributes []api.Attribute
   320  
   321  		BeforeEach(func() {
   322  			modifyAttributes = []api.Attribute{
   323  				api.Attribute{
   324  					Name:  "attr1",
   325  					Value: "attr1_value",
   326  				},
   327  			}
   328  		})
   329  
   330  		It("modifies existing attributes", func() {
   331  			newAttributes := []api.Attribute{
   332  				api.Attribute{
   333  					Name:  "attr1",
   334  					Value: "attr1_newvalue",
   335  				},
   336  			}
   337  
   338  			attrs := user.GetNewAttributes(modifyAttributes, newAttributes)
   339  			Expect(attrs).To(Equal([]api.Attribute{api.Attribute{Name: "attr1", Value: "attr1_newvalue", ECert: false}}))
   340  		})
   341  
   342  		It("add attributes if not found", func() {
   343  			newAttributes := []api.Attribute{
   344  				api.Attribute{
   345  					Name:  "attr2",
   346  					Value: "attr2_value",
   347  				},
   348  			}
   349  
   350  			attrs := user.GetNewAttributes(modifyAttributes, newAttributes)
   351  			Expect(attrs).To(Equal([]api.Attribute{api.Attribute{Name: "attr1", Value: "attr1_value", ECert: false}, api.Attribute{Name: "attr2", Value: "attr2_value", ECert: false}}))
   352  		})
   353  
   354  		It("deletes attribute if value specified for attribute is empty string", func() {
   355  			newAttributes := []api.Attribute{
   356  				api.Attribute{
   357  					Name:  "attr1",
   358  					Value: "",
   359  				},
   360  			}
   361  
   362  			attrs := user.GetNewAttributes(modifyAttributes, newAttributes)
   363  			Expect(attrs).To(Equal([]api.Attribute{}))
   364  		})
   365  	})
   366  
   367  	Context("modify attributes", func() {
   368  		var newAttributes []api.Attribute
   369  
   370  		It("returns an error if fails to execute modify query", func() {
   371  			mockUserDB.ExecReturns(nil, errors.New("failed to execute"))
   372  
   373  			err := u.ModifyAttributesTx(mockUserDB, newAttributes)
   374  			Expect(err).To(HaveOccurred())
   375  			Expect(err.Error()).To(Equal("failed to execute"))
   376  		})
   377  
   378  		It("returns an error if failed to get number of rows affected", func() {
   379  			mockResult.RowsAffectedReturns(int64(1), errors.New("error"))
   380  			mockUserDB.ExecReturns(mockResult, nil)
   381  			err := u.ModifyAttributes(newAttributes)
   382  			Expect(err).To(HaveOccurred())
   383  			Expect(err.Error()).To(Equal("Failed to get number of rows affected: error"))
   384  		})
   385  
   386  		It("returns an error if number of rows affected equals 0", func() {
   387  			mockResult.RowsAffectedReturns(int64(0), nil)
   388  			mockUserDB.ExecReturns(mockResult, nil)
   389  			err := u.ModifyAttributes(newAttributes)
   390  			Expect(err).To(HaveOccurred())
   391  			Expect(err.Error()).To(Equal("No rows were affected when updating the state of identity testuser"))
   392  		})
   393  
   394  		It("returns an error if number of rows affected is not 1", func() {
   395  			mockResult.RowsAffectedReturns(int64(3), nil)
   396  			mockUserDB.ExecReturns(mockResult, nil)
   397  			err := u.ModifyAttributes(newAttributes)
   398  			Expect(err).To(HaveOccurred())
   399  			Expect(err.Error()).To(Equal("3 rows were affected when updating the state of identity testuser"))
   400  		})
   401  
   402  		It("modifies existing attributes", func() {
   403  			newAttributes = []api.Attribute{
   404  				api.Attribute{
   405  					Name:  "attr1",
   406  					Value: "attr1_newvalue",
   407  				},
   408  			}
   409  
   410  			mockResult.RowsAffectedReturns(int64(1), nil)
   411  			mockUserDB.ExecReturns(mockResult, nil)
   412  
   413  			err := u.ModifyAttributes(newAttributes)
   414  			Expect(err).NotTo(HaveOccurred())
   415  		})
   416  
   417  		It("modifies existing attributes using transaction", func() {
   418  			newAttributes = []api.Attribute{
   419  				api.Attribute{
   420  					Name:  "attr1",
   421  					Value: "attr1_newvalue",
   422  				},
   423  			}
   424  
   425  			mockResult.RowsAffectedReturns(int64(1), nil)
   426  			mockUserDB.ExecReturns(mockResult, nil)
   427  
   428  			err := u.ModifyAttributesTx(mockUserDB, newAttributes)
   429  			Expect(err).NotTo(HaveOccurred())
   430  		})
   431  
   432  	})
   433  
   434  	Context("migrate", func() {
   435  		It("adds new attributes to user", func() {
   436  			_, err := u.GetAttribute("hf.Registrar.Attributes")
   437  			Expect(err).To(HaveOccurred())
   438  			_, err = u.GetAttribute("hf.AffiliationMgr")
   439  			Expect(err).To(HaveOccurred())
   440  			_, err = u.GetAttribute("hf.GenCRL")
   441  			Expect(err).To(HaveOccurred())
   442  
   443  			mockResult.RowsAffectedReturns(int64(1), nil)
   444  			mockUserDB.ExecReturns(mockResult, nil)
   445  			err = u.Migrate(mockUserDB)
   446  			Expect(err).NotTo(HaveOccurred())
   447  			val, err := u.GetAttribute("hf.Registrar.Attributes")
   448  			Expect(err).NotTo(HaveOccurred())
   449  			Expect(val.Value).To(Equal("*"))
   450  			val, err = u.GetAttribute("hf.AffiliationMgr")
   451  			Expect(err).NotTo(HaveOccurred())
   452  			Expect(val.Value).To(Equal("true"))
   453  			val, err = u.GetAttribute("hf.GenCRL")
   454  			Expect(err).NotTo(HaveOccurred())
   455  			Expect(val.Value).To(Equal("true"))
   456  		})
   457  	})
   458  
   459  	Context("get user less than level", func() {
   460  		It("returns users below level", func() {
   461  			_, err := user.GetUserLessThanLevel(mockUserDB, 1)
   462  			Expect(err).NotTo(HaveOccurred())
   463  		})
   464  	})
   465  })