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
This commit is contained in:
parent
0188d82e49
commit
6106a61eff
@ -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…
Reference in New Issue
Block a user