zotregistry.dev/zot@v1.4.4-0.20240314164342-eec277e14d20/pkg/extensions/search/userprefs_test.go (about) 1 //go:build search && userprefs 2 3 package search_test 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "net/http" 9 "net/url" 10 "os" 11 "testing" 12 13 . "github.com/smartystreets/goconvey/convey" 14 "gopkg.in/resty.v1" 15 16 "zotregistry.dev/zot/pkg/api" 17 "zotregistry.dev/zot/pkg/api/config" 18 "zotregistry.dev/zot/pkg/api/constants" 19 "zotregistry.dev/zot/pkg/common" 20 extconf "zotregistry.dev/zot/pkg/extensions/config" 21 "zotregistry.dev/zot/pkg/log" 22 test "zotregistry.dev/zot/pkg/test/common" 23 . "zotregistry.dev/zot/pkg/test/image-utils" 24 . "zotregistry.dev/zot/pkg/test/oci-utils" 25 ) 26 27 //nolint:dupl 28 func TestUserData(t *testing.T) { 29 Convey("Test user stars and bookmarks", t, func(c C) { 30 port := test.GetFreePort() 31 baseURL := test.GetBaseURL(port) 32 defaultVal := true 33 34 accessibleRepo := "accessible-repo" 35 forbiddenRepo := "forbidden-repo" 36 tag := "0.0.1" 37 38 adminUser := "alice" 39 adminPassword := "deepGoesTheRabbitBurrow" 40 simpleUser := "test" 41 simpleUserPassword := "test123" 42 43 content := test.GetCredString(adminUser, adminPassword) + 44 test.GetCredString(simpleUser, simpleUserPassword) 45 htpasswdPath := test.MakeHtpasswdFileFromString(content) 46 defer os.Remove(htpasswdPath) 47 48 conf := config.New() 49 conf.Storage.RootDirectory = t.TempDir() 50 conf.HTTP.Port = port 51 conf.HTTP.Auth = &config.AuthConfig{ 52 HTPasswd: config.AuthHTPasswd{ 53 Path: htpasswdPath, 54 }, 55 } 56 conf.HTTP.AccessControl = &config.AccessControlConfig{ 57 Repositories: config.Repositories{ 58 "**": config.PolicyGroup{ 59 Policies: []config.Policy{ 60 { 61 Users: []string{simpleUser}, 62 Actions: []string{"read"}, 63 }, 64 }, 65 AnonymousPolicy: []string{"read"}, 66 DefaultPolicy: []string{}, 67 }, 68 forbiddenRepo: config.PolicyGroup{ 69 Policies: []config.Policy{ 70 { 71 Users: []string{}, 72 Actions: []string{}, 73 }, 74 }, 75 DefaultPolicy: []string{}, 76 }, 77 }, 78 AdminPolicy: config.Policy{ 79 Users: []string{adminUser}, 80 Actions: []string{"read", "create", "update"}, 81 }, 82 } 83 conf.Extensions = &extconf.ExtensionConfig{} 84 conf.Extensions.Search = &extconf.SearchConfig{} 85 conf.Extensions.Search.Enable = &defaultVal 86 conf.Extensions.Search.CVE = nil 87 conf.Extensions.UI = &extconf.UIConfig{} 88 conf.Extensions.UI.Enable = &defaultVal 89 90 ctlr := api.NewController(conf) 91 92 ctlrManager := test.NewControllerManager(ctlr) 93 ctlrManager.StartAndWait(port) 94 defer ctlrManager.StopServer() 95 96 image := CreateDefaultImage() 97 98 err := UploadImageWithBasicAuth( 99 image, baseURL, accessibleRepo, tag, 100 adminUser, adminPassword, 101 ) 102 So(err, ShouldBeNil) 103 104 err = UploadImageWithBasicAuth( 105 image, baseURL, forbiddenRepo, tag, 106 adminUser, adminPassword, 107 ) 108 So(err, ShouldBeNil) 109 110 userStaredReposQuery := `{ 111 StarredRepos { 112 Results { 113 Name StarCount IsStarred 114 NewestImage { Tag } 115 } 116 } 117 }` 118 119 userBookmarkedReposQuery := `{ 120 BookmarkedRepos { 121 Results { 122 Name IsBookmarked 123 NewestImage { Tag } 124 } 125 } 126 }` 127 128 userprefsBaseURL := baseURL + constants.FullUserPrefs 129 130 Convey("Flip starred repo authorized", func(c C) { 131 clientHTTP := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 132 133 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 134 "?query=" + url.QueryEscape(userStaredReposQuery)) 135 So(err, ShouldBeNil) 136 So(resp, ShouldNotBeNil) 137 So(resp.StatusCode(), ShouldEqual, 200) 138 139 responseStruct := common.StarredReposResponse{} 140 err = json.Unmarshal(resp.Body(), &responseStruct) 141 So(err, ShouldBeNil) 142 So(len(responseStruct.Results), ShouldEqual, 0) 143 144 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(accessibleRepo)) 145 So(err, ShouldBeNil) 146 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 147 148 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 149 "?query=" + url.QueryEscape(userStaredReposQuery)) 150 So(err, ShouldBeNil) 151 So(resp, ShouldNotBeNil) 152 So(resp.StatusCode(), ShouldEqual, 200) 153 154 responseStruct = common.StarredReposResponse{} 155 err = json.Unmarshal(resp.Body(), &responseStruct) 156 So(err, ShouldBeNil) 157 So(len(responseStruct.Results), ShouldEqual, 1) 158 So(responseStruct.Results[0].Name, ShouldEqual, accessibleRepo) 159 // need to update RepoSummary according to user settings 160 So(responseStruct.Results[0].IsStarred, ShouldEqual, true) 161 So(responseStruct.Results[0].StarCount, ShouldEqual, 1) 162 163 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(accessibleRepo)) 164 So(err, ShouldBeNil) 165 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 166 167 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 168 "?query=" + url.QueryEscape(userStaredReposQuery)) 169 So(err, ShouldBeNil) 170 So(resp, ShouldNotBeNil) 171 So(resp.StatusCode(), ShouldEqual, 200) 172 173 responseStruct = common.StarredReposResponse{} 174 err = json.Unmarshal(resp.Body(), &responseStruct) 175 So(err, ShouldBeNil) 176 So(len(responseStruct.Results), ShouldEqual, 0) 177 }) 178 179 Convey("Flip starred repo unauthenticated user", func(c C) { 180 clientHTTP := resty.R() 181 182 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 183 "?query=" + url.QueryEscape(userStaredReposQuery)) 184 So(err, ShouldBeNil) 185 So(resp, ShouldNotBeNil) 186 So(resp.StatusCode(), ShouldEqual, 200) 187 188 responseStruct := common.StarredReposResponse{} 189 err = json.Unmarshal(resp.Body(), &responseStruct) 190 So(err, ShouldBeNil) 191 So(len(responseStruct.Results), ShouldEqual, 0) 192 193 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(accessibleRepo)) 194 So(err, ShouldBeNil) 195 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 196 197 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 198 "?query=" + url.QueryEscape(userStaredReposQuery)) 199 So(err, ShouldBeNil) 200 So(resp, ShouldNotBeNil) 201 So(resp.StatusCode(), ShouldEqual, 200) 202 203 responseStruct = common.StarredReposResponse{} 204 err = json.Unmarshal(resp.Body(), &responseStruct) 205 So(err, ShouldBeNil) 206 So(len(responseStruct.Results), ShouldEqual, 0) 207 }) 208 209 Convey("Flip starred repo unauthorized", func(c C) { 210 clientHTTP := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 211 212 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 213 "?query=" + url.QueryEscape(userStaredReposQuery)) 214 So(err, ShouldBeNil) 215 So(resp, ShouldNotBeNil) 216 So(resp.StatusCode(), ShouldEqual, 200) 217 218 responseStruct := common.StarredReposResponse{} 219 err = json.Unmarshal(resp.Body(), &responseStruct) 220 So(err, ShouldBeNil) 221 So(len(responseStruct.Results), ShouldEqual, 0) 222 223 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(forbiddenRepo)) 224 So(err, ShouldBeNil) 225 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 226 227 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 228 "?query=" + url.QueryEscape(userStaredReposQuery)) 229 So(err, ShouldBeNil) 230 So(resp, ShouldNotBeNil) 231 So(resp.StatusCode(), ShouldEqual, 200) 232 233 responseStruct = common.StarredReposResponse{} 234 err = json.Unmarshal(resp.Body(), &responseStruct) 235 So(err, ShouldBeNil) 236 So(len(responseStruct.Results), ShouldEqual, 0) 237 }) 238 239 Convey("Flip starred repo with unauthorized repo and admin user", func(c C) { 240 clientHTTP := resty.R().SetBasicAuth(adminUser, adminPassword) 241 242 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 243 "?query=" + url.QueryEscape(userStaredReposQuery)) 244 So(err, ShouldBeNil) 245 So(resp, ShouldNotBeNil) 246 So(resp.StatusCode(), ShouldEqual, 200) 247 248 responseStruct := common.StarredReposResponse{} 249 err = json.Unmarshal(resp.Body(), &responseStruct) 250 So(err, ShouldBeNil) 251 So(len(responseStruct.Results), ShouldEqual, 0) 252 253 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(forbiddenRepo)) 254 So(err, ShouldBeNil) 255 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 256 257 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 258 "?query=" + url.QueryEscape(userStaredReposQuery)) 259 So(err, ShouldBeNil) 260 So(resp, ShouldNotBeNil) 261 So(resp.StatusCode(), ShouldEqual, 200) 262 263 responseStruct = common.StarredReposResponse{} 264 err = json.Unmarshal(resp.Body(), &responseStruct) 265 So(err, ShouldBeNil) 266 So(len(responseStruct.Results), ShouldEqual, 1) 267 So(responseStruct.Results[0].Name, ShouldEqual, forbiddenRepo) 268 // need to update RepoSummary according to user settings 269 So(responseStruct.Results[0].IsStarred, ShouldEqual, true) 270 So(responseStruct.Results[0].StarCount, ShouldEqual, 1) 271 272 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoStarURL(forbiddenRepo)) 273 So(err, ShouldBeNil) 274 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 275 276 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 277 "?query=" + url.QueryEscape(userStaredReposQuery)) 278 So(err, ShouldBeNil) 279 So(resp, ShouldNotBeNil) 280 So(resp.StatusCode(), ShouldEqual, 200) 281 282 responseStruct = common.StarredReposResponse{} 283 err = json.Unmarshal(resp.Body(), &responseStruct) 284 So(err, ShouldBeNil) 285 So(len(responseStruct.Results), ShouldEqual, 0) 286 }) 287 288 Convey("Flip bookmark repo authorized", func(c C) { 289 clientHTTP := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 290 291 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 292 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 293 So(err, ShouldBeNil) 294 So(resp, ShouldNotBeNil) 295 So(resp.StatusCode(), ShouldEqual, 200) 296 297 responseStruct := common.BookmarkedReposResponse{} 298 err = json.Unmarshal(resp.Body(), &responseStruct) 299 So(err, ShouldBeNil) 300 So(len(responseStruct.Results), ShouldEqual, 0) 301 302 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(accessibleRepo)) 303 So(err, ShouldBeNil) 304 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 305 306 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 307 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 308 So(err, ShouldBeNil) 309 So(resp, ShouldNotBeNil) 310 So(resp.StatusCode(), ShouldEqual, 200) 311 312 responseStruct = common.BookmarkedReposResponse{} 313 err = json.Unmarshal(resp.Body(), &responseStruct) 314 So(err, ShouldBeNil) 315 So(len(responseStruct.Results), ShouldEqual, 1) 316 So(responseStruct.Results[0].Name, ShouldEqual, accessibleRepo) 317 // need to update RepoSummary according to user settings 318 So(responseStruct.Results[0].IsBookmarked, ShouldEqual, true) 319 320 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(accessibleRepo)) 321 So(err, ShouldBeNil) 322 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 323 324 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 325 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 326 So(err, ShouldBeNil) 327 So(resp, ShouldNotBeNil) 328 So(resp.StatusCode(), ShouldEqual, 200) 329 330 responseStruct = common.BookmarkedReposResponse{} 331 err = json.Unmarshal(resp.Body(), &responseStruct) 332 So(err, ShouldBeNil) 333 So(len(responseStruct.Results), ShouldEqual, 0) 334 }) 335 336 Convey("Flip bookmark repo unauthenticated user", func(c C) { 337 clientHTTP := resty.R() 338 339 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 340 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 341 So(err, ShouldBeNil) 342 So(resp, ShouldNotBeNil) 343 So(resp.StatusCode(), ShouldEqual, 200) 344 345 responseStruct := common.BookmarkedReposResponse{} 346 err = json.Unmarshal(resp.Body(), &responseStruct) 347 So(err, ShouldBeNil) 348 So(len(responseStruct.Results), ShouldEqual, 0) 349 350 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(accessibleRepo)) 351 So(err, ShouldBeNil) 352 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 353 354 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 355 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 356 So(err, ShouldBeNil) 357 So(resp, ShouldNotBeNil) 358 So(resp.StatusCode(), ShouldEqual, 200) 359 360 responseStruct = common.BookmarkedReposResponse{} 361 err = json.Unmarshal(resp.Body(), &responseStruct) 362 So(err, ShouldBeNil) 363 So(len(responseStruct.Results), ShouldEqual, 0) 364 }) 365 366 Convey("Flip bookmark repo unauthorized", func(c C) { 367 clientHTTP := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 368 369 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 370 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 371 So(err, ShouldBeNil) 372 So(resp, ShouldNotBeNil) 373 So(resp.StatusCode(), ShouldEqual, 200) 374 375 responseStruct := common.BookmarkedReposResponse{} 376 err = json.Unmarshal(resp.Body(), &responseStruct) 377 So(err, ShouldBeNil) 378 So(len(responseStruct.Results), ShouldEqual, 0) 379 380 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(forbiddenRepo)) 381 So(err, ShouldBeNil) 382 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 383 384 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 385 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 386 So(err, ShouldBeNil) 387 So(resp, ShouldNotBeNil) 388 So(resp.StatusCode(), ShouldEqual, 200) 389 390 responseStruct = common.BookmarkedReposResponse{} 391 err = json.Unmarshal(resp.Body(), &responseStruct) 392 So(err, ShouldBeNil) 393 So(len(responseStruct.Results), ShouldEqual, 0) 394 }) 395 396 Convey("Flip bookmarked unauthorized repo and admin user", func(c C) { 397 clientHTTP := resty.R().SetBasicAuth(adminUser, adminPassword) 398 399 resp, err := clientHTTP.Get(baseURL + constants.FullSearchPrefix + 400 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 401 So(err, ShouldBeNil) 402 So(resp, ShouldNotBeNil) 403 So(resp.StatusCode(), ShouldEqual, 200) 404 405 responseStruct := common.BookmarkedReposResponse{} 406 err = json.Unmarshal(resp.Body(), &responseStruct) 407 So(err, ShouldBeNil) 408 So(len(responseStruct.Results), ShouldEqual, 0) 409 410 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(forbiddenRepo)) 411 So(err, ShouldBeNil) 412 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 413 414 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 415 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 416 So(err, ShouldBeNil) 417 So(resp, ShouldNotBeNil) 418 So(resp.StatusCode(), ShouldEqual, 200) 419 420 responseStruct = common.BookmarkedReposResponse{} 421 err = json.Unmarshal(resp.Body(), &responseStruct) 422 So(err, ShouldBeNil) 423 So(len(responseStruct.Results), ShouldEqual, 1) 424 So(responseStruct.Results[0].Name, ShouldEqual, forbiddenRepo) 425 // need to update RepoSummary according to user settings 426 So(responseStruct.Results[0].IsBookmarked, ShouldEqual, true) 427 428 resp, err = clientHTTP.Put(userprefsBaseURL + PutRepoBookmarkURL(forbiddenRepo)) 429 So(err, ShouldBeNil) 430 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 431 432 resp, err = clientHTTP.Get(baseURL + constants.FullSearchPrefix + 433 "?query=" + url.QueryEscape(userBookmarkedReposQuery)) 434 So(err, ShouldBeNil) 435 So(resp, ShouldNotBeNil) 436 So(resp.StatusCode(), ShouldEqual, 200) 437 438 responseStruct = common.BookmarkedReposResponse{} 439 err = json.Unmarshal(resp.Body(), &responseStruct) 440 So(err, ShouldBeNil) 441 So(len(responseStruct.Results), ShouldEqual, 0) 442 }) 443 }) 444 } 445 446 func TestChangingRepoState(t *testing.T) { 447 port := test.GetFreePort() 448 baseURL := test.GetBaseURL(port) 449 defaultVal := true 450 451 simpleUser := "test" 452 simpleUserPassword := "test123" 453 454 forbiddenRepo := "forbidden" 455 accesibleRepo := "accesible" 456 457 htpasswdPath := test.MakeHtpasswdFileFromString(test.GetCredString(simpleUser, simpleUserPassword)) 458 defer os.Remove(htpasswdPath) 459 460 conf := config.New() 461 conf.Storage.RootDirectory = t.TempDir() 462 conf.HTTP.Port = port 463 conf.HTTP.Auth = &config.AuthConfig{ 464 HTPasswd: config.AuthHTPasswd{ 465 Path: htpasswdPath, 466 }, 467 } 468 conf.HTTP.AccessControl = &config.AccessControlConfig{ 469 Repositories: config.Repositories{ 470 "**": config.PolicyGroup{ 471 Policies: []config.Policy{ 472 { 473 Users: []string{simpleUser}, 474 Actions: []string{"read"}, 475 }, 476 }, 477 AnonymousPolicy: []string{"read"}, 478 DefaultPolicy: []string{}, 479 }, 480 forbiddenRepo: config.PolicyGroup{ 481 Policies: []config.Policy{ 482 { 483 Users: []string{}, 484 Actions: []string{}, 485 }, 486 }, 487 DefaultPolicy: []string{}, 488 }, 489 }, 490 } 491 conf.Extensions = &extconf.ExtensionConfig{} 492 conf.Extensions.Search = &extconf.SearchConfig{} 493 conf.Extensions.Search.Enable = &defaultVal 494 conf.Extensions.Search.CVE = nil 495 conf.Extensions.UI = &extconf.UIConfig{} 496 conf.Extensions.UI.Enable = &defaultVal 497 498 gqlStarredRepos := ` 499 { 500 StarredRepos() { 501 Results { 502 Name 503 StarCount 504 IsBookmarked 505 IsStarred 506 } 507 } 508 } 509 ` 510 511 gqlBookmarkedRepos := ` 512 { 513 BookmarkedRepos() { 514 Results { 515 Name 516 StarCount 517 IsBookmarked 518 IsStarred 519 } 520 } 521 } 522 ` 523 524 ctlr := api.NewController(conf) 525 526 img := CreateRandomImage() 527 storeCtlr := GetDefaultStoreController(conf.Storage.RootDirectory, log.NewLogger("debug", "")) 528 529 err := WriteImageToFileSystem(img, accesibleRepo, "tag", storeCtlr) 530 if err != nil { 531 t.FailNow() 532 } 533 534 err = WriteImageToFileSystem(img, forbiddenRepo, "tag", storeCtlr) 535 if err != nil { 536 t.FailNow() 537 } 538 539 ctlrManager := test.NewControllerManager(ctlr) 540 541 ctlrManager.StartAndWait(port) 542 543 defer ctlrManager.StopServer() 544 545 simpleUserClient := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 546 anonynousClient := resty.R() 547 548 userprefsBaseURL := baseURL + constants.FullUserPrefs 549 550 Convey("PutStars", t, func() { 551 resp, err := simpleUserClient.Put(userprefsBaseURL + PutRepoStarURL(accesibleRepo)) 552 So(err, ShouldBeNil) 553 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 554 555 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(gqlStarredRepos)) 556 So(err, ShouldBeNil) 557 So(resp, ShouldNotBeNil) 558 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 559 560 responseStruct := common.StarredReposResponse{} 561 err = json.Unmarshal(resp.Body(), &responseStruct) 562 So(err, ShouldBeNil) 563 So(len(responseStruct.Results), ShouldEqual, 1) 564 So(responseStruct.Results[0].IsStarred, ShouldBeTrue) 565 So(responseStruct.Results[0].Name, ShouldResemble, accesibleRepo) 566 567 resp, err = anonynousClient.Put(userprefsBaseURL + PutRepoStarURL(accesibleRepo)) 568 So(err, ShouldBeNil) 569 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 570 }) 571 // 572 Convey("PutBookmark", t, func() { 573 resp, err := simpleUserClient.Put(userprefsBaseURL + PutRepoBookmarkURL(accesibleRepo)) 574 So(err, ShouldBeNil) 575 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 576 577 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(gqlBookmarkedRepos)) 578 So(err, ShouldBeNil) 579 So(resp, ShouldNotBeNil) 580 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 581 582 responseStruct := common.BookmarkedReposResponse{} 583 err = json.Unmarshal(resp.Body(), &responseStruct) 584 So(err, ShouldBeNil) 585 So(err, ShouldBeNil) 586 So(len(responseStruct.Results), ShouldEqual, 1) 587 So(responseStruct.Results[0].IsBookmarked, ShouldBeTrue) 588 So(responseStruct.Results[0].Name, ShouldResemble, accesibleRepo) 589 590 resp, err = anonynousClient.Put(userprefsBaseURL + PutRepoBookmarkURL(accesibleRepo)) 591 So(err, ShouldBeNil) 592 So(resp.StatusCode(), ShouldEqual, http.StatusForbidden) 593 }) 594 } 595 596 func TestGlobalSearchWithUserPrefFiltering(t *testing.T) { 597 Convey("Bookmarks and Stars filtering", t, func() { 598 dir := t.TempDir() 599 port := test.GetFreePort() 600 baseURL := test.GetBaseURL(port) 601 conf := config.New() 602 conf.HTTP.Port = port 603 conf.Storage.RootDirectory = dir 604 605 simpleUser := "simpleUser" 606 simpleUserPassword := "simpleUserPass" 607 htpasswdPath := test.MakeHtpasswdFileFromString(test.GetCredString(simpleUser, simpleUserPassword)) 608 defer os.Remove(htpasswdPath) 609 610 conf.HTTP.Auth = &config.AuthConfig{ 611 HTPasswd: config.AuthHTPasswd{ 612 Path: htpasswdPath, 613 }, 614 } 615 616 conf.HTTP.AccessControl = &config.AccessControlConfig{ 617 Repositories: config.Repositories{ 618 "**": config.PolicyGroup{ 619 Policies: []config.Policy{ 620 { 621 Users: []string{simpleUser}, 622 Actions: []string{"read", "create"}, 623 }, 624 }, 625 }, 626 }, 627 } 628 629 defaultVal := true 630 conf.Extensions = &extconf.ExtensionConfig{} 631 conf.Extensions.Search = &extconf.SearchConfig{} 632 conf.Extensions.Search.Enable = &defaultVal 633 conf.Extensions.Search.CVE = nil 634 conf.Extensions.UI = &extconf.UIConfig{} 635 conf.Extensions.UI.Enable = &defaultVal 636 637 ctlr := api.NewController(conf) 638 639 ctlrManager := test.NewControllerManager(ctlr) 640 ctlrManager.StartAndWait(port) 641 defer ctlrManager.StopServer() 642 643 preferencesBaseURL := baseURL + constants.FullUserPrefs 644 simpleUserClient := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 645 646 // ------ Add simple repo 647 repo := "repo" 648 img := CreateRandomImage() 649 650 err := UploadImageWithBasicAuth(img, baseURL, repo, "tag", simpleUser, simpleUserPassword) 651 So(err, ShouldBeNil) 652 653 // ------ Add repo and star it 654 sRepo := "starred-repo" 655 img = CreateRandomImage() 656 657 err = UploadImageWithBasicAuth(img, baseURL, sRepo, "tag", simpleUser, simpleUserPassword) 658 So(err, ShouldBeNil) 659 660 resp, err := simpleUserClient.Put(preferencesBaseURL + PutRepoStarURL(sRepo)) 661 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 662 So(err, ShouldBeNil) 663 664 // ------ Add repo and bookmark it 665 bRepo := "bookmarked-repo" 666 img = CreateRandomImage() 667 668 err = UploadImageWithBasicAuth(img, baseURL, bRepo, "tag", simpleUser, simpleUserPassword) 669 So(err, ShouldBeNil) 670 671 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoBookmarkURL(bRepo)) 672 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 673 So(err, ShouldBeNil) 674 675 // ------ Add repo, star and bookmark it 676 sbRepo := "starred-bookmarked-repo" 677 img = CreateRandomImage() 678 679 err = UploadImageWithBasicAuth(img, baseURL, sbRepo, "tag", simpleUser, simpleUserPassword) 680 So(err, ShouldBeNil) 681 682 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoStarURL(sbRepo)) 683 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 684 So(err, ShouldBeNil) 685 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoBookmarkURL(sbRepo)) 686 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 687 So(err, ShouldBeNil) 688 689 // Make global search requests filterin by IsStarred and IsBookmarked 690 691 query := `{ GlobalSearch(query:"repo", ){ Repos { Name } } }` 692 693 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 694 So(resp, ShouldNotBeNil) 695 So(err, ShouldBeNil) 696 So(resp.StatusCode(), ShouldEqual, 200) 697 698 responseStruct := &common.GlobalSearchResultResp{} 699 700 err = json.Unmarshal(resp.Body(), responseStruct) 701 So(err, ShouldBeNil) 702 703 foundRepos := responseStruct.Repos 704 So(len(foundRepos), ShouldEqual, 4) 705 706 // Filter by IsStarred = true 707 query = `{ GlobalSearch(query:"repo", filter:{ IsStarred:true }) { Repos { Name IsStarred IsBookmarked }}}` 708 709 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 710 So(resp, ShouldNotBeNil) 711 So(err, ShouldBeNil) 712 So(resp.StatusCode(), ShouldEqual, 200) 713 714 responseStruct = &common.GlobalSearchResultResp{} 715 716 err = json.Unmarshal(resp.Body(), responseStruct) 717 So(err, ShouldBeNil) 718 719 foundRepos = responseStruct.Repos 720 So(len(foundRepos), ShouldEqual, 2) 721 So(foundRepos, ShouldContain, common.RepoSummary{Name: sRepo, IsStarred: true, IsBookmarked: false}) 722 So(foundRepos, ShouldContain, common.RepoSummary{Name: sbRepo, IsStarred: true, IsBookmarked: true}) 723 724 // Filter by IsStarred = true && IsBookmarked = false 725 query = `{ 726 GlobalSearch(query:"repo", filter:{ IsStarred:true, IsBookmarked:false }) { 727 Repos { Name IsStarred IsBookmarked } 728 } 729 }` 730 731 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 732 So(resp, ShouldNotBeNil) 733 So(err, ShouldBeNil) 734 So(resp.StatusCode(), ShouldEqual, 200) 735 736 responseStruct = &common.GlobalSearchResultResp{} 737 738 err = json.Unmarshal(resp.Body(), responseStruct) 739 So(err, ShouldBeNil) 740 741 foundRepos = responseStruct.Repos 742 So(len(foundRepos), ShouldEqual, 1) 743 So(foundRepos, ShouldContain, common.RepoSummary{Name: sRepo, IsStarred: true, IsBookmarked: false}) 744 745 // Filter by IsBookmarked = true 746 query = `{ 747 GlobalSearch(query:"repo", filter:{ IsBookmarked:true }) { 748 Repos { Name IsStarred IsBookmarked } 749 } 750 }` 751 752 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 753 So(resp, ShouldNotBeNil) 754 So(err, ShouldBeNil) 755 So(resp.StatusCode(), ShouldEqual, 200) 756 757 responseStruct = &common.GlobalSearchResultResp{} 758 759 err = json.Unmarshal(resp.Body(), responseStruct) 760 So(err, ShouldBeNil) 761 762 foundRepos = responseStruct.Repos 763 So(len(foundRepos), ShouldEqual, 2) 764 So(foundRepos, ShouldContain, common.RepoSummary{Name: bRepo, IsStarred: false, IsBookmarked: true}) 765 So(foundRepos, ShouldContain, common.RepoSummary{Name: sbRepo, IsStarred: true, IsBookmarked: true}) 766 767 // Filter by IsBookmarked = true && IsStarred = false 768 query = `{ 769 GlobalSearch(query:"repo", filter:{ IsBookmarked:true, IsStarred:false }) { 770 Repos { Name IsStarred IsBookmarked } 771 } 772 }` 773 774 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 775 So(resp, ShouldNotBeNil) 776 So(err, ShouldBeNil) 777 So(resp.StatusCode(), ShouldEqual, 200) 778 779 responseStruct = &common.GlobalSearchResultResp{} 780 781 err = json.Unmarshal(resp.Body(), responseStruct) 782 So(err, ShouldBeNil) 783 784 foundRepos = responseStruct.Repos 785 So(len(foundRepos), ShouldEqual, 1) 786 So(foundRepos, ShouldContain, common.RepoSummary{Name: bRepo, IsStarred: false, IsBookmarked: true}) 787 }) 788 } 789 790 func TestExpandedRepoInfoWithUserPrefs(t *testing.T) { 791 Convey("ExpandedRepoInfo with User Prefs", t, func() { 792 dir := t.TempDir() 793 port := test.GetFreePort() 794 baseURL := test.GetBaseURL(port) 795 conf := config.New() 796 conf.HTTP.Port = port 797 conf.Storage.RootDirectory = dir 798 799 simpleUser := "simpleUser" 800 simpleUserPassword := "simpleUserPass" 801 htpasswdPath := test.MakeHtpasswdFileFromString(test.GetCredString(simpleUser, simpleUserPassword)) 802 defer os.Remove(htpasswdPath) 803 804 conf.HTTP.Auth = &config.AuthConfig{ 805 HTPasswd: config.AuthHTPasswd{ 806 Path: htpasswdPath, 807 }, 808 } 809 810 conf.HTTP.AccessControl = &config.AccessControlConfig{ 811 Repositories: config.Repositories{ 812 "**": config.PolicyGroup{ 813 Policies: []config.Policy{ 814 { 815 Users: []string{simpleUser}, 816 Actions: []string{"read", "create"}, 817 }, 818 }, 819 }, 820 }, 821 } 822 823 defaultVal := true 824 conf.Extensions = &extconf.ExtensionConfig{} 825 conf.Extensions.Search = &extconf.SearchConfig{} 826 conf.Extensions.Search.Enable = &defaultVal 827 conf.Extensions.Search.CVE = nil 828 conf.Extensions.UI = &extconf.UIConfig{} 829 conf.Extensions.UI.Enable = &defaultVal 830 831 ctlr := api.NewController(conf) 832 833 ctlrManager := test.NewControllerManager(ctlr) 834 ctlrManager.StartAndWait(port) 835 defer ctlrManager.StopServer() 836 837 preferencesBaseURL := baseURL + constants.FullUserPrefs 838 simpleUserClient := resty.R().SetBasicAuth(simpleUser, simpleUserPassword) 839 840 // ------ Add sbrepo and star/bookmark it 841 sbrepo := "sbrepo" 842 img := CreateRandomImage() 843 844 err := UploadImageWithBasicAuth(img, baseURL, sbrepo, "tag", simpleUser, simpleUserPassword) 845 So(err, ShouldBeNil) 846 847 resp, err := simpleUserClient.Put(preferencesBaseURL + PutRepoStarURL(sbrepo)) 848 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 849 So(err, ShouldBeNil) 850 851 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoBookmarkURL(sbrepo)) 852 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 853 So(err, ShouldBeNil) 854 855 // ExpandedRepoinfo 856 857 query := ` 858 { 859 ExpandedRepoInfo(repo:"sbrepo"){ 860 Summary { 861 Name IsStarred IsBookmarked 862 } 863 } 864 }` 865 866 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 867 So(resp, ShouldNotBeNil) 868 So(err, ShouldBeNil) 869 So(resp.StatusCode(), ShouldEqual, 200) 870 871 responseStruct := common.ExpandedRepoInfoResp{} 872 873 err = json.Unmarshal(resp.Body(), &responseStruct) 874 So(err, ShouldBeNil) 875 876 repoInfo := responseStruct.RepoInfo 877 So(repoInfo.Summary.IsBookmarked, ShouldBeTrue) 878 So(repoInfo.Summary.IsStarred, ShouldBeTrue) 879 880 // ------ Add srepo and star it 881 srepo := "srepo" 882 img = CreateRandomImage() 883 884 err = UploadImageWithBasicAuth(img, baseURL, srepo, "tag", simpleUser, simpleUserPassword) 885 So(err, ShouldBeNil) 886 887 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoStarURL(srepo)) 888 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 889 So(err, ShouldBeNil) 890 891 // ExpandedRepoinfo 892 query = ` 893 { 894 ExpandedRepoInfo(repo:"srepo"){ 895 Summary { 896 Name IsStarred IsBookmarked 897 } 898 } 899 }` 900 901 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 902 So(resp, ShouldNotBeNil) 903 So(err, ShouldBeNil) 904 So(resp.StatusCode(), ShouldEqual, 200) 905 906 responseStruct = common.ExpandedRepoInfoResp{} 907 908 err = json.Unmarshal(resp.Body(), &responseStruct) 909 So(err, ShouldBeNil) 910 911 repoInfo = responseStruct.RepoInfo 912 So(repoInfo.Summary.IsBookmarked, ShouldBeFalse) 913 So(repoInfo.Summary.IsStarred, ShouldBeTrue) 914 915 // ------ Add brepo and bookmark it 916 brepo := "brepo" 917 img = CreateRandomImage() 918 919 err = UploadImageWithBasicAuth(img, baseURL, brepo, "tag", simpleUser, simpleUserPassword) 920 So(err, ShouldBeNil) 921 922 resp, err = simpleUserClient.Put(preferencesBaseURL + PutRepoBookmarkURL(brepo)) 923 So(resp.StatusCode(), ShouldEqual, http.StatusOK) 924 So(err, ShouldBeNil) 925 926 // ExpandedRepoinfo 927 query = ` 928 { 929 ExpandedRepoInfo(repo:"brepo"){ 930 Summary { 931 Name IsStarred IsBookmarked 932 } 933 } 934 }` 935 936 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 937 So(resp, ShouldNotBeNil) 938 So(err, ShouldBeNil) 939 So(resp.StatusCode(), ShouldEqual, 200) 940 941 responseStruct = common.ExpandedRepoInfoResp{} 942 943 err = json.Unmarshal(resp.Body(), &responseStruct) 944 So(err, ShouldBeNil) 945 946 repoInfo = responseStruct.RepoInfo 947 So(repoInfo.Summary.IsBookmarked, ShouldBeTrue) 948 So(repoInfo.Summary.IsStarred, ShouldBeFalse) 949 950 // ------ Add repo without star/bookmark 951 repo := "repo" 952 img = CreateRandomImage() 953 954 err = UploadImageWithBasicAuth(img, baseURL, repo, "tag", simpleUser, simpleUserPassword) 955 So(err, ShouldBeNil) 956 957 // ExpandedRepoinfo 958 query = ` 959 { 960 ExpandedRepoInfo(repo:"repo"){ 961 Summary { 962 Name IsStarred IsBookmarked 963 } 964 } 965 }` 966 967 resp, err = simpleUserClient.Get(baseURL + graphqlQueryPrefix + "?query=" + url.QueryEscape(query)) 968 So(resp, ShouldNotBeNil) 969 So(err, ShouldBeNil) 970 So(resp.StatusCode(), ShouldEqual, 200) 971 972 responseStruct = common.ExpandedRepoInfoResp{} 973 974 err = json.Unmarshal(resp.Body(), &responseStruct) 975 So(err, ShouldBeNil) 976 977 repoInfo = responseStruct.RepoInfo 978 So(repoInfo.Summary.IsBookmarked, ShouldBeFalse) 979 So(repoInfo.Summary.IsStarred, ShouldBeFalse) 980 }) 981 } 982 983 func PutRepoStarURL(repo string) string { 984 return fmt.Sprintf("?repo=%s&action=toggleStar", repo) 985 } 986 987 func PutRepoBookmarkURL(repo string) string { 988 return fmt.Sprintf("?repo=%s&action=toggleBookmark", repo) 989 }