fix(auth): stop duplicating the domain in the auth redirect parameter
Why
#1178, reported from
ZD#673388 against 18.4.3 and reproduced on
18.5.3. With gitlab_pages['namespace_in_path'] = true, the authorization redirect carries the
FQDN twice:
domain=https://pages.acceptance.example.com/pages.acceptance.example.comso authorization is requested for a host that does not exist, and the browser ends on a 404.
Root cause
getRequestDomain rewrites the wildcard layout — where the namespace is a subdomain — into a
path form:
ns.pages.example.com -> pages.example.com/nsif len(namespace) > 0 && strings.HasPrefix(r.Host, namespace) {
requestDomain = strings.TrimPrefix(r.Host, namespace+".") + "/" + namespace
}The guard tests namespace. The rewrite removes namespace+".". Those are not the same
string. When namespace+"." is not actually a prefix, TrimPrefix returns r.Host
untouched — but "/" + namespace is appended regardless, giving r.Host + "/" + namespace.
With namespace_in_path the namespace held in the session is the host itself, so that is
r.Host + "/" + r.Host — exactly the duplication reported.
The same mismatch fires more generally, for any namespace that is a prefix without being a subdomain.
Reproduced first
getRequestDomain had no test coverage. I wrote the table against the unfixed code and
confirmed it reproduces the customer's string before changing anything:
--- FAIL: TestGetRequestDomain/namespace_equals_the_host
expected: "https://pages.acceptance.example.com"
actual : "https://pages.acceptance.example.com/pages.acceptance.example.com"
--- FAIL: TestGetRequestDomain/namespace_is_a_prefix_but_not_a_subdomain
expected: "https://foobar.example.com"
actual : "https://foobar.example.com/foo"The other two rows — the wildcard rewrite and the no-namespace case — passed before and after, which is the point: the fix narrows the rewrite rather than removing it.
What
The guard now tests namespace+".", the string the rewrite actually removes, so the condition
and the operation cannot disagree.
| host | namespace | before | after |
|---|---|---|---|
ns.pages.example.com |
ns |
pages.example.com/ns |
pages.example.com/ns |
pages.example.com |
(none) | pages.example.com |
pages.example.com |
pages.acceptance.example.com |
(same as host) | …example.com/pages.acceptance.example.com |
pages.acceptance.example.com |
foobar.example.com |
foo |
foobar.example.com/foo |
foobar.example.com |
Verification
| check | result |
|---|---|
go test -race ./internal/auth/... |
ok |
go build ./..., go vet ./internal/auth/..., gofmt -l |
clean |
Closes #1178