gitee.com/zhaochuninhefei/fabric-ca-gm@v0.0.2/lib/dbaccessor_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package lib_test 8 9 import ( 10 "fmt" 11 "os" 12 "strings" 13 "testing" 14 15 "gitee.com/zhaochuninhefei/fabric-ca-gm/internal/pkg/api" 16 . "gitee.com/zhaochuninhefei/fabric-ca-gm/lib" 17 "gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db" 18 "gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/db/sqlite" 19 cadbuser "gitee.com/zhaochuninhefei/fabric-ca-gm/lib/server/user" 20 "github.com/jmoiron/sqlx" 21 _ "github.com/mattn/go-sqlite3" 22 "github.com/stretchr/testify/assert" 23 ) 24 25 const ( 26 dbPath = "/tmp/dbtesting" 27 28 sqliteTruncateTables = ` 29 DELETE FROM Users; 30 DELETE FROM affiliations; 31 ` 32 33 rootDB = "rootDir/fabric_ca.db" 34 ) 35 36 type TestAccessor struct { 37 Accessor *Accessor 38 DB *db.DB 39 } 40 41 func (ta *TestAccessor) Truncate() { 42 Truncate(ta.DB) 43 } 44 45 func TestSQLite(t *testing.T) { 46 cleanTestSlateSQ(t) 47 defer cleanTestSlateSQ(t) 48 49 if _, err := os.Stat(dbPath); err != nil { 50 if os.IsNotExist(err) { 51 os.MkdirAll(dbPath, 0755) 52 } 53 } else { 54 err = os.RemoveAll(dbPath) 55 if err != nil { 56 t.Errorf("RemoveAll failed: %s", err) 57 } 58 os.MkdirAll(dbPath, 0755) 59 } 60 dataSource := dbPath + "/fabric-ca.db" 61 sqlitedb, err := getSqliteDb(dataSource) 62 if err != nil { 63 t.Error("Failed to open connection to DB") 64 } 65 accessor := NewDBAccessor(sqlitedb) 66 67 ta := TestAccessor{ 68 Accessor: accessor, 69 DB: sqlitedb, 70 } 71 testEverything(ta, t) 72 } 73 74 // Truncate truncates the DB 75 func Truncate(db *db.DB) { 76 if len(strings.TrimSpace(sqliteTruncateTables)) == 0 { 77 return 78 } 79 if _, err := db.Exec("", sqliteTruncateTables); err != nil { 80 panic(err) 81 } 82 } 83 84 func TestEmptyAccessor(t *testing.T) { 85 a := &Accessor{} 86 ui := cadbuser.Info{} 87 err := a.InsertUser(nil) 88 if err == nil { 89 t.Error("Passing in nil should have resulted in an error") 90 } 91 92 err = a.InsertUser(&ui) 93 if err == nil { 94 t.Error("Empty Accessor InsertUser should have failed") 95 } 96 } 97 98 func TestDBCreation(t *testing.T) { 99 cleanTestSlateSQ(t) 100 defer cleanTestSlateSQ(t) 101 102 os.Mkdir(rootDir, 0755) 103 104 testWithExistingDbAndTablesAndUser(t) 105 testWithExistingDbAndTable(t) 106 testWithExistingDb(t) 107 } 108 109 func createSQLiteDB(path string, t *testing.T) (*db.DB, *TestAccessor) { 110 sqlxdb, err := sqlx.Open("sqlite3", path) 111 assert.NoError(t, err, "Failed to open SQLite database") 112 113 sqlitedb := db.New(sqlxdb, "", nil) 114 accessor := NewDBAccessor(sqlitedb) 115 116 ta := &TestAccessor{ 117 Accessor: accessor, 118 DB: sqlitedb, 119 } 120 121 return sqlitedb, ta 122 } 123 124 // Test that an already bootstrapped database properly get inspected and bootstrapped with any new identities on the 125 // next server start 126 func testWithExistingDbAndTablesAndUser(t *testing.T) { 127 var err error 128 129 err = os.RemoveAll(rootDB) 130 if err != nil { 131 t.Errorf("RemoveAll failed: %s", err) 132 } 133 db, acc := createSQLiteDB(rootDB, t) 134 135 _, err = db.Exec("", "CREATE TABLE IF NOT EXISTS users (id VARCHAR(64), token bytea, type VARCHAR(64), affiliation VARCHAR(64), attributes VARCHAR(256), state INTEGER, max_enrollments INTEGER, level INTEGER DEFAULT 0)") 136 assert.NoError(t, err, "Error creating users table") 137 138 srv := TestGetServer2(false, rootPort, rootDir, "", -1, t) 139 srv.CA.Config.DB.Datasource = "fabric_ca.db" 140 141 err = srv.Start() 142 assert.NoError(t, err, "Failed to start server") 143 144 err = srv.Stop() 145 assert.NoError(t, err, "Failed to stop server") 146 147 // Add additional user to registry and start server and confirm that it correctly get added 148 srv.RegisterBootstrapUser("admin2", "admin2pw", "") 149 150 err = srv.Start() 151 assert.NoError(t, err, "Failed to start server") 152 153 _, err = acc.Accessor.GetUser("admin2", nil) 154 assert.NoError(t, err, "Failed to correctly insert 'admin2' during second server bootstrap") 155 156 err = srv.Stop() 157 assert.NoError(t, err, "Failed to stop server") 158 159 err = db.Close() 160 assert.NoError(t, err, "Failed to close DB") 161 } 162 163 // Test starting a server with an already existing database and tables, but not bootstrapped 164 func testWithExistingDbAndTable(t *testing.T) { 165 var err error 166 167 err = os.RemoveAll(rootDB) 168 if err != nil { 169 t.Errorf("RemoveAll failed: %s", err) 170 } 171 db, acc := createSQLiteDB(rootDB, t) 172 173 srv := TestGetServer2(false, rootPort, rootDir, "", -1, t) 174 srv.CA.Config.DB.Datasource = "fabric_ca.db" 175 176 _, err = db.Exec("", "CREATE TABLE IF NOT EXISTS users (id VARCHAR(64), token bytea, type VARCHAR(64), affiliation VARCHAR(64), attributes VARCHAR(256), state INTEGER, max_enrollments INTEGER, level INTEGER DEFAULT 0)") 177 assert.NoError(t, err, "Error creating users table") 178 179 err = srv.Start() 180 assert.NoError(t, err, "Failed to start server") 181 182 _, err = acc.Accessor.GetUser("admin", nil) 183 assert.NoError(t, err, "Failed to correctly insert 'admin' during second server bootstrap") 184 185 err = srv.Stop() 186 assert.NoError(t, err, "Failed to stop server") 187 188 err = db.Close() 189 assert.NoError(t, err, "Failed to close DB") 190 } 191 192 // Test starting a server with an already existing database, but no tables or users 193 func testWithExistingDb(t *testing.T) { 194 var err error 195 196 err = os.RemoveAll(rootDB) 197 if err != nil { 198 t.Errorf("RemoveAll failed: %s", err) 199 } 200 db, acc := createSQLiteDB(rootDB, t) 201 202 srv := TestGetServer2(false, rootPort, rootDir, "", -1, t) 203 srv.CA.Config.DB.Datasource = "fabric_ca.db" 204 205 err = srv.Start() 206 assert.NoError(t, err, "Failed to start server") 207 208 _, err = acc.Accessor.GetUser("admin", nil) 209 assert.NoError(t, err, "Failed to correctly insert 'admin' during second server bootstrap") 210 211 err = srv.Stop() 212 assert.NoError(t, err, "Failed to stop server") 213 214 err = db.Close() 215 assert.NoError(t, err, "Failed to close DB") 216 } 217 218 func cleanTestSlateSQ(t *testing.T) { 219 err := os.RemoveAll(rootDir) 220 if err != nil { 221 t.Errorf("RemoveAll failed: %s", err) 222 } 223 err = os.RemoveAll(dbPath) 224 if err != nil { 225 t.Errorf("RemoveAll failed: %s", err) 226 } 227 } 228 229 func testEverything(ta TestAccessor, t *testing.T) { 230 testInsertAndGetUser(ta, t) 231 testModifyAttribute(ta, t) 232 testDeleteUser(ta, t) 233 testUpdateUser(ta, t) 234 testInsertAndGetAffiliation(ta, t) 235 testDeleteAffiliation(ta, t) 236 testInsertAndGetFilteredUsers(ta, t) 237 } 238 239 func testInsertAndGetUser(ta TestAccessor, t *testing.T) { 240 t.Log("TestInsertAndGetUser") 241 ta.Truncate() 242 243 insert := cadbuser.Info{ 244 Name: "testId", 245 Pass: "123456", 246 Type: "client", 247 Attributes: []api.Attribute{ 248 api.Attribute{ 249 Name: "hf.Registrar.Roles", 250 Value: "peer,client,orderer,user", 251 }, 252 api.Attribute{ 253 Name: "hf.Revoker", 254 Value: "false", 255 }, 256 api.Attribute{ 257 Name: "hf.Registrar.Attributes", 258 Value: "*", 259 }, 260 api.Attribute{ 261 Name: "xyz", 262 Value: "xyz", 263 }, 264 }, 265 } 266 267 err := ta.Accessor.InsertUser(&insert) 268 if err != nil { 269 t.Errorf("Error occurred during insert query of ID: %s, error: %s", insert.Name, err) 270 } 271 272 user, err := ta.Accessor.GetUser(insert.Name, nil) 273 if err != nil { 274 t.Errorf("Error occurred during querying of id: %s, error: %s", insert.Name, err) 275 } 276 277 if user.GetName() != insert.Name { 278 t.Error("Incorrect ID retrieved") 279 } 280 } 281 282 func testInsertAndGetFilteredUsers(ta TestAccessor, t *testing.T) { 283 t.Log("TestInsertAndGetFilteredUsers") 284 ta.Truncate() 285 // create user 286 insert := cadbuser.Info{ 287 Name: "testTypesClient", 288 Pass: "123456", 289 Type: "client", 290 Attributes: []api.Attribute{ 291 api.Attribute{ 292 Name: "hf.Registrar.Roles", 293 Value: "peer,client,orderer,user", 294 }, 295 api.Attribute{ 296 Name: "hf.Revoker", 297 Value: "false", 298 }, 299 api.Attribute{ 300 Name: "hf.Registrar.Attributes", 301 Value: "*", 302 }, 303 api.Attribute{ 304 Name: "xyz", 305 Value: "xyz", 306 }, 307 }, 308 } 309 // insert user 310 err := ta.Accessor.InsertUser(&insert) 311 if err != nil { 312 t.Errorf("Error occurred during insert query of ID: %s, error: %s", insert.Name, err) 313 } 314 // test get the user 315 rows, err := ta.Accessor.GetFilteredUsers("", "client,orderer") 316 if err != nil { 317 t.Errorf("Failed to get users by affiliation: %s, and type: %s, error: %s", "", "client,orderer", err) 318 } 319 320 typesClientSuccessFlag := false 321 for rows.Next() { 322 var id cadbuser.Record 323 err := rows.StructScan(&id) 324 if err != nil { 325 t.Errorf("Failed to get read row! error: %s", err) 326 } 327 // get the target user 328 if id.Name == "testTypesClient" && id.Type == "client" { 329 typesClientSuccessFlag = true 330 } 331 } 332 // not success 333 if !typesClientSuccessFlag { 334 t.Errorf("Test InsertAndGetFilteredUsers Failed!") 335 } 336 337 // test type=* and affiliation is not nil 338 // insert affiliation 339 err = ta.Accessor.InsertAffiliation("Bank1", "Banks", 0) 340 if err != nil { 341 t.Errorf("Error occurred during insert query of group: %s, error: %s", "Bank1", err) 342 } 343 // change user info 344 insert.Name = "testTypesStar" 345 insert.Type = "*" 346 insert.Affiliation = "Bank1" 347 // insert user 348 err = ta.Accessor.InsertUser(&insert) 349 if err != nil { 350 t.Errorf("Error occurred during insert query of ID: %s, error: %s", insert.Name, err) 351 } 352 // test get the user 353 rows, err = ta.Accessor.GetFilteredUsers("Bank1", "*") 354 if err != nil { 355 t.Errorf("Failed to get users by affiliation: %s, and type: %s, error: %s", "Bank1", "*", err) 356 } 357 // use the success flag to tag success 358 affiliationsTypeStarSuccessFlag := false 359 for rows.Next() { 360 var id cadbuser.Record 361 err := rows.StructScan(&id) 362 if err != nil { 363 t.Errorf("Failed to get read row! error: %s", err) 364 } 365 // get the target user 366 if id.Affiliation == "Bank1" && id.Name == "testTypesStar" { 367 affiliationsTypeStarSuccessFlag = true 368 } 369 } 370 // not success 371 if !affiliationsTypeStarSuccessFlag { 372 t.Errorf("Test InsertAndGetFilteredUsers Failed!") 373 } 374 375 // test get all user 376 affiliationsTypeStarSuccessFlag = false 377 typesClientSuccessFlag = false 378 // test get all users 379 rows, err = ta.Accessor.GetFilteredUsers("", "*") 380 if err != nil { 381 t.Errorf("Failed to get users by affiliation: %s, and type: %s, error: %s", "", "*", err) 382 } 383 for rows.Next() { 384 var id cadbuser.Record 385 err := rows.StructScan(&id) 386 if err != nil { 387 t.Errorf("Failed to get read row! error: %s", err) 388 } 389 // get the target user 390 if id.Affiliation == "Bank1" && id.Name == "testTypesStar" { 391 affiliationsTypeStarSuccessFlag = true 392 } 393 if id.Name == "testTypesClient" && id.Type == "client" { 394 typesClientSuccessFlag = true 395 } 396 } 397 // not success 398 if !(affiliationsTypeStarSuccessFlag && typesClientSuccessFlag) { 399 t.Errorf("Test InsertAndGetFilteredUsers Failed!") 400 } 401 } 402 403 func testModifyAttribute(ta TestAccessor, t *testing.T) { 404 405 user, err := ta.Accessor.GetUser("testId", nil) 406 assert.NoError(t, err, "Failed to get user") 407 408 err = user.ModifyAttributes([]api.Attribute{ 409 api.Attribute{ 410 Name: "hf.Registrar.Roles", 411 Value: "peer", 412 }, 413 api.Attribute{ 414 Name: "hf.Revoker", 415 Value: "", 416 }, 417 api.Attribute{ 418 Name: "xyz", 419 Value: "", 420 }, 421 api.Attribute{ 422 Name: "hf.IntermediateCA", 423 Value: "true", 424 }, 425 }) 426 assert.NoError(t, err, "Failed to modify user's attributes") 427 428 user, err = ta.Accessor.GetUser("testId", nil) 429 assert.NoError(t, err, "Failed to get user") 430 431 _, err = user.GetAttribute("hf.Revoker") 432 assert.Error(t, err, "Should have returned an error, attribute should have been deleted") 433 434 // Removes last attribute in the slice, should have correctly removed it 435 _, err = user.GetAttribute("xyz") 436 assert.Error(t, err, "Should have returned an error, attribute should have been deleted") 437 438 attr, err := user.GetAttribute("hf.IntermediateCA") 439 assert.NoError(t, err, "Failed to add attribute") 440 assert.Equal(t, "true", attr.Value, "Incorrect value for attribute 'hf.IntermediateCA") 441 442 attr, err = user.GetAttribute("hf.Registrar.Roles") 443 assert.NoError(t, err, "Failed to get attribute") 444 assert.Equal(t, "peer", attr.Value, "Incorrect value for attribute 'hf.Registrar.Roles") 445 446 // Test to make sure that any existing attributes that were not modified continue to exist in there original state 447 attr, err = user.GetAttribute("hf.Registrar.Attributes") 448 assert.NoError(t, err, "Failed to get attribute") 449 assert.Equal(t, "*", attr.Value) 450 } 451 452 func testDeleteUser(ta TestAccessor, t *testing.T) { 453 t.Log("TestDeleteUser") 454 ta.Truncate() 455 456 insert := cadbuser.Info{ 457 Name: "testId", 458 Pass: "123456", 459 Type: "client", 460 Attributes: []api.Attribute{}, 461 } 462 463 err := ta.Accessor.InsertUser(&insert) 464 if err != nil { 465 t.Errorf("Error occurred during insert query of id: %s, error: %s", insert.Name, err) 466 } 467 468 _, err = ta.Accessor.DeleteUser(insert.Name) 469 if err != nil { 470 t.Errorf("Error occurred during deletion of ID: %s, error: %s", insert.Name, err) 471 } 472 473 _, err = ta.Accessor.GetUser(insert.Name, nil) 474 if err == nil { 475 t.Error("Should have errored, and not returned any results") 476 } 477 } 478 479 func testUpdateUser(ta TestAccessor, t *testing.T) { 480 t.Log("TestUpdateUser") 481 ta.Truncate() 482 483 insert := cadbuser.Info{ 484 Name: "testId", 485 Pass: "123456", 486 Type: "client", 487 Attributes: []api.Attribute{}, 488 MaxEnrollments: 1, 489 } 490 491 err := ta.Accessor.InsertUser(&insert) 492 if err != nil { 493 t.Errorf("Error occurred during insert query of ID: %s, error: %s", insert.Name, err) 494 } 495 496 insert.Pass = "654321" 497 498 err = ta.Accessor.UpdateUser(nil, true) 499 if err == nil { 500 t.Error("Passing in nil should have resulted in an error") 501 } 502 503 err = ta.Accessor.UpdateUser(&insert, true) 504 if err != nil { 505 t.Errorf("Error occurred during update query of ID: %s, error: %s", insert.Name, err) 506 } 507 508 user, err := ta.Accessor.GetUser(insert.Name, nil) 509 if err != nil { 510 t.Errorf("Error occurred during querying of ID: %s, error: %s", insert.Name, err) 511 } 512 513 err = user.Login(insert.Pass, -1) 514 if err != nil { 515 t.Error("Failed to login in user: ", err) 516 } 517 518 } 519 520 func testInsertAndGetAffiliation(ta TestAccessor, t *testing.T) { 521 ta.Truncate() 522 523 err := ta.Accessor.InsertAffiliation("Bank1", "Banks", 0) 524 if err != nil { 525 t.Errorf("Error occurred during insert query of group: %s, error: %s", "Bank1", err) 526 } 527 528 group, err := ta.Accessor.GetAffiliation("Bank1") 529 if err != nil { 530 t.Errorf("Error occurred during querying of name: %s, error: %s", "Bank1", err) 531 } 532 533 if group.GetName() != "Bank1" { 534 t.Error("Failed to query") 535 } 536 537 } 538 539 func testDeleteAffiliation(ta TestAccessor, t *testing.T) { 540 ta.Truncate() 541 542 err := ta.Accessor.InsertAffiliation("Banks.Bank2", "Banks", 0) 543 if err != nil { 544 t.Errorf("Error occurred during insert query of group: %s, error: %s", "Bank2", err) 545 } 546 547 _, err = ta.Accessor.DeleteAffiliation("Banks.Bank2", true, true, true) 548 if err != nil { 549 t.Errorf("Error occurred during deletion of group: %s, error: %s", "Bank2", err) 550 } 551 552 _, err = ta.Accessor.GetAffiliation("Banks.Bank2") 553 if err == nil { 554 t.Error("Should have errored, and not returned any results") 555 } 556 } 557 558 func TestDBErrorMessages(t *testing.T) { 559 var err error 560 561 cleanTestSlateSQ(t) 562 defer cleanTestSlateSQ(t) 563 564 if _, err = os.Stat(dbPath); err != nil { 565 if os.IsNotExist(err) { 566 os.MkdirAll(dbPath, 0755) 567 } 568 } else { 569 err = os.RemoveAll(dbPath) 570 if err != nil { 571 t.Errorf("RemoveAll failed: %s", err) 572 } 573 os.MkdirAll(dbPath, 0755) 574 } 575 576 dataSource := dbPath + "/fabric-ca.db" 577 sqlitedb, err := getSqliteDb(dataSource) 578 if err != nil { 579 t.Error("Failed to open connection to DB") 580 } 581 accessor := NewDBAccessor(sqlitedb) 582 583 ta := TestAccessor{ 584 Accessor: accessor, 585 DB: sqlitedb, 586 } 587 588 expectedErr := "Failed to get %s" 589 _, err = ta.Accessor.GetAffiliation("hyperledger") 590 if assert.Error(t, err, "Should have errored, and not returned any results") { 591 assert.Contains(t, err.Error(), fmt.Sprintf(expectedErr, "affiliation")) 592 } 593 594 _, err = ta.Accessor.GetUser("testuser", []string{}) 595 if assert.Error(t, err, "Should have errored, and not returned any results") { 596 assert.Contains(t, err.Error(), fmt.Sprintf(expectedErr, "User")) 597 } 598 599 newCertDBAcc := NewCertDBAccessor(sqlitedb, 0) 600 _, err = newCertDBAcc.GetCertificateWithID("serial", "aki") 601 if assert.Error(t, err, "Should have errored, and not returned any results") { 602 assert.Contains(t, err.Error(), fmt.Sprintf(expectedErr, "Certificate")) 603 } 604 } 605 606 func getSqliteDb(datasource string) (*db.DB, error) { 607 sqliteDB := sqlite.NewDB(datasource, "", nil) 608 err := sqliteDB.Connect() 609 if err != nil { 610 return nil, err 611 } 612 testdb, err := sqliteDB.Create() 613 if err != nil { 614 return nil, err 615 } 616 return testdb, nil 617 }