Remove sub-path from container registry realm (#31293)

Container registry requires that the "/v2" must be in the root, so the
sub-path in AppURL should be removed
pull/31306/head
wxiaoguang 6 months ago committed by GitHub
parent 0188d82e49
commit 6106a61eff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 5
      modules/setting/packages.go
  2. 6
      modules/test/utils.go
  3. 6
      routers/api/packages/container/container.go
  4. 8
      routers/web/user/package.go
  5. 12
      tests/integration/api_packages_container_test.go

@ -6,7 +6,6 @@ package setting
import ( import (
"fmt" "fmt"
"math" "math"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
@ -19,7 +18,6 @@ var (
Storage *Storage Storage *Storage
Enabled bool Enabled bool
ChunkedUploadPath string ChunkedUploadPath string
RegistryHost string
LimitTotalOwnerCount int64 LimitTotalOwnerCount int64
LimitTotalOwnerSize int64 LimitTotalOwnerSize int64
@ -66,9 +64,6 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
return err return err
} }
appURL, _ := url.Parse(AppURL)
Packages.RegistryHost = appURL.Host
Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload")) Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload"))
if !filepath.IsAbs(Packages.ChunkedUploadPath) { if !filepath.IsAbs(Packages.ChunkedUploadPath) {
Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath)) Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))

@ -34,8 +34,10 @@ func IsNormalPageCompleted(s string) bool {
return strings.Contains(s, `<footer class="page-footer"`) && strings.Contains(s, `</html>`) return strings.Contains(s, `<footer class="page-footer"`) && strings.Contains(s, `</html>`)
} }
func MockVariableValue[T any](p *T, v T) (reset func()) { func MockVariableValue[T any](p *T, v ...T) (reset func()) {
old := *p old := *p
*p = v if len(v) > 0 {
*p = v[0]
}
return func() { *p = old } return func() { *p = old }
} }

@ -116,9 +116,9 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
} }
func apiUnauthorizedError(ctx *context.Context) { func apiUnauthorizedError(ctx *context.Context) {
// TODO: it doesn't seem quite right but it doesn't really cause problem at the moment. // container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed
// container registry requires that the "/v2" must be in the root, so the sub-path in AppURL should be removed, ideally. realmURL := strings.TrimSuffix(httplib.GuessCurrentAppURL(ctx), setting.AppSubURL+"/") + "/v2/token"
ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+httplib.GuessCurrentAppURL(ctx)+`v2/token",service="container_registry",scope="*"`) ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+realmURL+`",service="container_registry",scope="*"`)
apiErrorDefined(ctx, errUnauthorized) apiErrorDefined(ctx, errUnauthorized)
} }

@ -5,6 +5,7 @@ package user
import ( import (
"net/http" "net/http"
"net/url"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
org_model "code.gitea.io/gitea/models/organization" org_model "code.gitea.io/gitea/models/organization"
@ -15,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional" "code.gitea.io/gitea/modules/optional"
alpine_module "code.gitea.io/gitea/modules/packages/alpine" alpine_module "code.gitea.io/gitea/modules/packages/alpine"
@ -178,7 +180,11 @@ func ViewPackageVersion(ctx *context.Context) {
switch pd.Package.Type { switch pd.Package.Type {
case packages_model.TypeContainer: case packages_model.TypeContainer:
ctx.Data["RegistryHost"] = setting.Packages.RegistryHost registryAppURL, err := url.Parse(httplib.GuessCurrentAppURL(ctx))
if err != nil {
registryAppURL, _ = url.Parse(setting.AppURL)
}
ctx.Data["RegistryHost"] = registryAppURL.Host
case packages_model.TypeAlpine: case packages_model.TypeAlpine:
branches := make(container.Set[string]) branches := make(container.Set[string])
repositories := make(container.Set[string]) repositories := make(container.Set[string])

@ -84,7 +84,7 @@ func TestPackageContainer(t *testing.T) {
Token string `json:"token"` Token string `json:"token"`
} }
authenticate := []string{`Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`} defaultAuthenticateValues := []string{`Bearer realm="` + setting.AppURL + `v2/token",service="container_registry",scope="*"`}
t.Run("Anonymous", func(t *testing.T) { t.Run("Anonymous", func(t *testing.T) {
defer tests.PrintCurrentTest(t)() defer tests.PrintCurrentTest(t)()
@ -92,7 +92,7 @@ func TestPackageContainer(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL))
resp := MakeRequest(t, req, http.StatusUnauthorized) resp := MakeRequest(t, req, http.StatusUnauthorized)
assert.ElementsMatch(t, authenticate, resp.Header().Values("WWW-Authenticate")) assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate"))
req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL))
resp = MakeRequest(t, req, http.StatusOK) resp = MakeRequest(t, req, http.StatusOK)
@ -115,6 +115,12 @@ func TestPackageContainer(t *testing.T) {
req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL))
MakeRequest(t, req, http.StatusUnauthorized) MakeRequest(t, req, http.StatusUnauthorized)
defer test.MockVariableValue(&setting.AppURL, "https://domain:8443/sub-path/")()
defer test.MockVariableValue(&setting.AppSubURL, "/sub-path")()
req = NewRequest(t, "GET", "/v2")
resp = MakeRequest(t, req, http.StatusUnauthorized)
assert.Equal(t, `Bearer realm="https://domain:8443/v2/token",service="container_registry",scope="*"`, resp.Header().Get("WWW-Authenticate"))
}) })
t.Run("User", func(t *testing.T) { t.Run("User", func(t *testing.T) {
@ -123,7 +129,7 @@ func TestPackageContainer(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL))
resp := MakeRequest(t, req, http.StatusUnauthorized) resp := MakeRequest(t, req, http.StatusUnauthorized)
assert.ElementsMatch(t, authenticate, resp.Header().Values("WWW-Authenticate")) assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate"))
req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)). req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)).
AddBasicAuth(user.Name) AddBasicAuth(user.Name)

Loading…
Cancel
Save