[v12.0/forgejo] fix: trim trailing slash in WebFinger OIDC issuer link (#8800)

**Backport:** https://codeberg.org/forgejo/forgejo/pulls/8794

As stated in a comment: https://codeberg.org/forgejo/forgejo/issues/8634#issuecomment-6136933

> `routers/web/webfinger.go` was left unchanged, so it still includes the trailing slash, no longer matching the issuer specified in other endpoints.
>
> ...
>
> From the [OpenID Connect Discovery specification](https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery):
>
> > The Issuer location MUST be returned in the WebFinger response as the value of the href member of a links array element with rel member value http://openid.net/specs/connect/1.0/issuer.
>
> This sounds to me like the `href` should be the issuer location exactly.
>
> Using Forgejo for OIDC for auth with Tailscale is one instance of this change breaking something - signing up to Tailscale with OIDC now gives an error. Unsure what happens for existing accounts.

In summary, since !8028, trailing slashes have been removed from the OIDC issuer locations specified by Forgejo everywhere except in WebFinger responses at `/.well-known/webfinger`, which still includes a trailing slash and so no longer matches the issuer as specified elsewhere (such as at `/.well-known/openid-configuration`).

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/8794): <!--number 8794 --><!--line 0 --><!--description dHJpbSB0cmFpbGluZyBzbGFzaCBpbiBXZWJGaW5nZXIgT0lEQyBpc3N1ZXIgbGluaw==-->trim trailing slash in WebFinger OIDC issuer link<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: hazycora <git@hazy.gay>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8800
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
Co-committed-by: forgejo-backport-action <forgejo-backport-action@noreply.codeberg.org>
This commit is contained in:
forgejo-backport-action 2025-08-06 16:17:03 +02:00 committed by Earl Warren
commit 514229544f
2 changed files with 24 additions and 1 deletions

View file

@ -153,7 +153,7 @@ func WebfingerQuery(ctx *context.Context) {
}, },
{ {
Rel: "http://openid.net/specs/connect/1.0/issuer", Rel: "http://openid.net/specs/connect/1.0/issuer",
Href: appURL.String(), Href: strings.TrimSuffix(appURL.String(), "/"),
}, },
} }

View file

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"net/url" "net/url"
"strings"
"testing" "testing"
"forgejo.org/models/unittest" "forgejo.org/models/unittest"
@ -43,6 +44,8 @@ func TestWebfinger(t *testing.T) {
session := loginUser(t, "user1") session := loginUser(t, "user1")
ctx := t.Context()
req := NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, appURL.Host)) req := NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, appURL.Host))
resp := MakeRequest(t, req, http.StatusOK) resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "application/jrd+json", resp.Header().Get("Content-Type")) assert.Equal(t, "application/jrd+json", resp.Header().Get("Content-Type"))
@ -50,6 +53,26 @@ func TestWebfinger(t *testing.T) {
var jrd webfingerJRD var jrd webfingerJRD
DecodeJSON(t, resp, &jrd) DecodeJSON(t, resp, &jrd)
assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject) assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject)
assert.ElementsMatch(t, []*webfingerLink{
{
Rel: "http://webfinger.net/rel/profile-page",
Type: "text/html",
Href: user.HTMLURL(),
},
{
Rel: "http://webfinger.net/rel/avatar",
Href: user.AvatarLink(ctx),
},
{
Rel: "self",
Type: "application/activity+json",
Href: appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID),
},
{
Rel: "http://openid.net/specs/connect/1.0/issuer",
Href: strings.TrimSuffix(appURL.String(), "/"),
},
}, jrd.Links)
assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID)}, jrd.Aliases) assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID)}, jrd.Aliases)
req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host")) req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host"))