diff --git a/server/server.go b/server/server.go
index 65415d0e9fe4..5222244378c5 100644
--- a/server/server.go
+++ b/server/server.go
@@ -132,7 +132,7 @@ var backoff = wait.Backoff{
var (
clientConstraint = fmt.Sprintf(">= %s", common.MinClientVersion)
- baseHRefRegex = regexp.MustCompile(``)
+ baseHRefRegex = regexp.MustCompile(``)
// limits number of concurrent login requests to prevent password brute forcing. If set to 0 then no limit is enforced.
maxConcurrentLoginRequestsCount = 50
replicasCount = 1
@@ -893,7 +893,7 @@ func (s *ArgoCDServer) getIndexData() ([]byte, error) {
if s.BaseHRef == "/" || s.BaseHRef == "" {
s.indexData = data
} else {
- s.indexData = []byte(baseHRefRegex.ReplaceAllString(string(data), fmt.Sprintf(``, strings.Trim(s.BaseHRef, "/"))))
+ s.indexData = []byte(replaceBaseHRef(string(data), fmt.Sprintf(``, strings.Trim(s.BaseHRef, "/"))))
}
})
@@ -978,6 +978,10 @@ func mustRegisterGWHandler(register registerFunc, ctx context.Context, mux *runt
}
}
+func replaceBaseHRef(data string, replaceWith string) string {
+ return baseHRefRegex.ReplaceAllString(data, replaceWith)
+}
+
// Authenticate checks for the presence of a valid token when accessing server-side resources.
func (a *ArgoCDServer) Authenticate(ctx context.Context) (context.Context, error) {
if a.DisableAuth {
diff --git a/server/server_test.go b/server/server_test.go
index 9ebd53723624..063e0835bc47 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -583,7 +583,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) {
anonymousEnabled: false,
claims: jwt.RegisteredClaims{Audience: jwt.ClaimStrings{"test-client"}, Subject: "admin", ExpiresAt: jwt.NewNumericDate(time.Now())},
expectedErrorContains: "token is expired",
- expectedClaims: jwt.RegisteredClaims{Issuer:"sso"},
+ expectedClaims: jwt.RegisteredClaims{Issuer: "sso"},
},
{
test: "anonymous enabled, expired token, admin claim",
@@ -601,7 +601,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) {
t.Parallel()
// Must be declared here to avoid race.
- ctx := context.Background() //nolint:ineffassign,staticcheck
+ ctx := context.Background() //nolint:ineffassign,staticcheck
argocd, dexURL := getTestServer(t, testDataCopy.anonymousEnabled, true)
testDataCopy.claims.Issuer = fmt.Sprintf("%s/api/dex", dexURL)
@@ -698,7 +698,7 @@ func TestAuthenticate_no_SSO(t *testing.T) {
t.Parallel()
// Must be declared here to avoid race.
- ctx := context.Background() //nolint:ineffassign,staticcheck
+ ctx := context.Background() //nolint:ineffassign,staticcheck
argocd, dexURL := getTestServer(t, testDataCopy.anonymousEnabled, false)
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{Issuer: fmt.Sprintf("%s/api/dex", dexURL)})
@@ -806,7 +806,7 @@ func TestAuthenticate_bad_request_metadata(t *testing.T) {
t.Parallel()
// Must be declared here to avoid race.
- ctx := context.Background() //nolint:ineffassign,staticcheck
+ ctx := context.Background() //nolint:ineffassign,staticcheck
argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true)
ctx = metadata.NewIncomingContext(context.Background(), testDataCopy.metadata)
@@ -1065,39 +1065,39 @@ func TestOIDCConfigChangeDetection_NoChange(t *testing.T) {
}
func TestIsMainJsBundle(t *testing.T) {
- testCases := []struct{
+ testCases := []struct {
name string
url string
isMainJsBundle bool
}{
{
- name: "localhost with valid main bundle",
- url: "https://localhost:8080/main.e4188e5adc97bbfc00c3.js",
+ name: "localhost with valid main bundle",
+ url: "https://localhost:8080/main.e4188e5adc97bbfc00c3.js",
isMainJsBundle: true,
},
{
- name: "localhost and deep path with valid main bundle",
- url: "https://localhost:8080/some/argo-cd-instance/main.e4188e5adc97bbfc00c3.js",
+ name: "localhost and deep path with valid main bundle",
+ url: "https://localhost:8080/some/argo-cd-instance/main.e4188e5adc97bbfc00c3.js",
isMainJsBundle: true,
},
{
- name: "font file",
- url: "https://localhost:8080/assets/fonts/google-fonts/Heebo-Bols.woff2",
+ name: "font file",
+ url: "https://localhost:8080/assets/fonts/google-fonts/Heebo-Bols.woff2",
isMainJsBundle: false,
},
{
- name: "no dot after main",
- url: "https://localhost:8080/main/e4188e5adc97bbfc00c3.js",
+ name: "no dot after main",
+ url: "https://localhost:8080/main/e4188e5adc97bbfc00c3.js",
isMainJsBundle: false,
},
{
- name: "wrong extension character",
- url: "https://localhost:8080/main.e4188e5adc97bbfc00c3/js",
+ name: "wrong extension character",
+ url: "https://localhost:8080/main.e4188e5adc97bbfc00c3/js",
isMainJsBundle: false,
},
{
- name: "wrong hash length",
- url: "https://localhost:8080/main.e4188e5adc97bbfc00c3abcdefg.js",
+ name: "wrong hash length",
+ url: "https://localhost:8080/main.e4188e5adc97bbfc00c3abcdefg.js",
isMainJsBundle: false,
},
}
@@ -1111,3 +1111,123 @@ func TestIsMainJsBundle(t *testing.T) {
})
}
}
+
+func TestReplaceBaseHRef(t *testing.T) {
+ testCases := []struct {
+ name string
+ data string
+ expected string
+ replaceWith string
+ }{
+ {
+ name: "non-root basepath",
+ data: `
+
+
+
+
+ Argo CD
+
+
+
+
+
+
+
+
+
+
+
+
+`,
+ expected: `
+
+
+
+
+ Argo CD
+
+
+
+
+
+
+
+
+
+
+
+
+`,
+ replaceWith: ``,
+ },
+ {
+ name: "root basepath",
+ data: `
+
+
+
+
+ Argo CD
+
+
+
+
+
+
+
+
+
+
+
+
+`,
+ expected: `
+
+
+
+
+ Argo CD
+
+
+
+
+
+
+
+
+
+
+
+
+`,
+ replaceWith: ``,
+ },
+ }
+ for _, testCase := range testCases {
+ t.Run(testCase.name, func(t *testing.T) {
+ result := replaceBaseHRef(testCase.data, testCase.replaceWith)
+ assert.Equal(t, testCase.expected, result)
+ })
+ }
+}