diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index 0726302d41f..3fdd62298ea 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -27,6 +27,7 @@ import ( container_module "code.gitea.io/gitea/modules/packages/container" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/storage" + "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/api/packages/helper" auth_service "code.gitea.io/gitea/services/auth" @@ -125,8 +126,15 @@ func APIUnauthorizedError(ctx *context.Context) { // container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed realmURL := httplib.GuessCurrentHostURL(ctx) + "/v2/token" ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`) - // support apple container like: container registry login -u - ctx.Resp.Header().Add("WWW-Authenticate", `Basic realm="Gitea Container Registry"`) + + ownerName := ctx.PathParam("username") + owner, _ := user_model.GetUserByName(ctx, ownerName) + requireSignIn := owner != nil && owner.Visibility != structs.VisibleTypePublic + requireSignIn = requireSignIn || setting.Service.RequireSignInViewStrict + if requireSignIn { + // support apple container like: container registry login -u + ctx.Resp.Header().Add("WWW-Authenticate", `Basic realm="Gitea Container Registry"`) + } apiErrorDefined(ctx, errUnauthorized) } diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index d5d243f9ab3..59888692082 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -88,37 +88,34 @@ func TestPackageContainer(t *testing.T) { Token string `json:"token"` } - defaultAuthenticateValues := []string{ + wwwAuthenticateForPublic := []string{ + `Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`, + } + wwwAuthenticateForRequiredSignIn := []string{ `Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`, `Basic realm="Gitea Container Registry"`, } - t.Run("Anonymous", func(t *testing.T) { defer tests.PrintCurrentTest(t)() req := NewRequest(t, "GET", setting.AppURL+"v2") resp := MakeRequest(t, req, http.StatusUnauthorized) - - assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate")) + assert.ElementsMatch(t, wwwAuthenticateForPublic, resp.Header().Values("WWW-Authenticate")) req = NewRequest(t, "GET", setting.AppURL+"v2/token") resp = MakeRequest(t, req, http.StatusOK) - - tokenResponse := &TokenResponse{} - DecodeJSON(t, resp, &tokenResponse) - - assert.NotEmpty(t, tokenResponse.Token) - + tokenResponse := DecodeJSON(t, resp, &TokenResponse{}) + require.NotEmpty(t, tokenResponse.Token) anonymousToken = "Bearer " + tokenResponse.Token - req = NewRequest(t, "GET", setting.AppURL+"v2"). - AddTokenAuth(anonymousToken) + req = NewRequest(t, "GET", setting.AppURL+"v2").AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusOK) defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() req = NewRequest(t, "GET", setting.AppURL+"v2") - MakeRequest(t, req, http.StatusUnauthorized) + resp = MakeRequest(t, req, http.StatusUnauthorized) + assert.ElementsMatch(t, wwwAuthenticateForRequiredSignIn, resp.Header().Values("WWW-Authenticate")) req = NewRequest(t, "GET", setting.AppURL+"v2/token") MakeRequest(t, req, http.StatusUnauthorized) @@ -135,17 +132,13 @@ func TestPackageContainer(t *testing.T) { req := NewRequest(t, "GET", setting.AppURL+"v2") resp := MakeRequest(t, req, http.StatusUnauthorized) + assert.ElementsMatch(t, wwwAuthenticateForPublic, resp.Header().Values("WWW-Authenticate")) - assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate")) - - req = NewRequest(t, "GET", setting.AppURL+"v2/token"). - AddBasicAuth(user.Name) + req = NewRequest(t, "GET", setting.AppURL+"v2/token").AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) - - tokenResponse := &TokenResponse{} - DecodeJSON(t, resp, &tokenResponse) - + tokenResponse := DecodeJSON(t, resp, &TokenResponse{}) assert.NotEmpty(t, tokenResponse.Token) + pkgMeta, err := package_service.ParseAuthorizationToken(tokenResponse.Token) assert.NoError(t, err) assert.Equal(t, user.ID, pkgMeta.UserID)