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