Commit graph

173 commits

Author SHA1 Message Date
Mathieu Fenniak
7b5d623737 fix: introduce lint-single-response to prevent control flow continuing past a ctx.Error(...)-style method (#13087)
This PR adds a new linter to the codebase and addresses all the problems that it identified (including a small number of false positives).  The lint-single-response Go analyzer attempts to prevent a common problem in Forgejo where it is possible for a web handler to provide a response to a request, and then continue code execution unintentionally.  For example:

```go
err := json.Unmarshal(data, &claims)
if err != nil {
    ctx.Error(http.StatusInternalServerError, "Error in unmarshal", err)
    // Oops, I forgot to `return` here...
}
// ... more work occurs ...
ctx.JSON(http.StatusOK, resp)
```

In order to detect these cases, lint-single-response contains a list of functions that deliver a web response.  When any of those functions are used within a function, the control flow must not perform any work after the function is invoked -- it can only return and exit the function.

### Tests for Go changes

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
  - [x] `make pr-go` before pushing

### Documentation

- [x] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
    - Documentation on the new linter is included inline, in `build/lint-single-response/README.md`.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13087
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
2026-06-14 17:06:03 +02:00
hwipl
1ea5605eae feat: add dynamic group mappings for OIDC (#11656)
Currently, Forgejo supports configuring static group team mappings for
an OIDC authentication source that map OIDC groups to Forgejo
organizations and teams. For example, the following mapping

```json
{"Developer": {"MyForgejoOrganization": ["MyForgejoTeam1", "MyForgejoTeam2"]}}
```

automatically adds a user in the OIDC group `Developer` to the teams
`MyForgejoTeam1` and `MyForgejoTeam2` in organization
`MyForgejoOrganization`.

In order to support more dynamic mappings and to avoid having to update
the mappings for new organizations and teams, add an additional
configuration option that supports mappings with placeholders like in
the following example:

```json
["group-{org}-{team}", "other:{org}/{team}"]
```

In this example, the mappings add a user in OIDC groups
`group-org1-team1`, `group-org2-team2`, and `other:org3/team3` to team
`team1` in organization `org1`, team `team2` in organization `org2`, and
to team `team3` in organization `org3`.

Additionally, this adds a configuration option to dynamically remove
users from organization teams. If enabled, a user is removed from all
teams that are not added via a static or dynamic mapping. Thus, users
are only in teams that are added via such a mapping and no other teams.

Docs: forgejo/docs!1950

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11656
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2026-05-22 12:38:20 +02:00
IRONM00N
d130e1ee94 feat: add option to use preferred_username claim when registering users via oauth2 (#12504)
This is a continuation of #3346 based on the advise of https://codeberg.org/forgejo/forgejo/issues/1452#issuecomment-14591307.

fixes: #1452
docs: https://codeberg.org/forgejo/docs/pulls/1938

Extends the `oauth2_client` `USERNAME` setting to be able to use the `preferred_username` claim.

Co-authored-by: thepaperpilot <thepaperpilot@gmail.com>
Co-authored-by: Anthony Lawn <thepaperpilot@gmail.com>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12504
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2026-05-18 00:14:46 +02:00
Erwan Leboucher
0211c1eace feat: persist OAuth2/OIDC sign-in via IdP re-validation (#12321)
The session cookie has no Max-Age, so it is lost when the browser closes. The password flow compensates via a "Remember me" checkbox issuing an LTA cookie; OAuth2/OIDC sign-in had no such UI.

Issuing a regular LTA cookie after an OAuth callback would skip the IdP for LOGIN_REMEMBER_DAYS. Instead, this introduces a separate LongTermAuthorizationSSO purpose: the cookie is opt-in via the existing "Remember me" checkbox, and when presented without a session, autoSignIn redirects through the IdP with OIDC prompt=none for silent re-auth. On login_required / interaction_required / consent_required / account_selection_required
we transparently fall back to interactive sign-in.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12321
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2026-05-15 02:31:20 +02:00
Mathieu Fenniak
32b8d732b8 2026-05-12 security patches (#12493)
- fix: prevent git write to wiki repo from unauthorized user via git HTTP
- fix: prevent LFS authorization token from being used for read/write access after user's access is restricted from Forgejo
- fix: prevent scoped API access (OAuth tokens, Access tokens) from accessing resources beyond their permitted scope via non-API endpoints (e.g. /user/repo/raw/...)
- fix: implementing missing OAuth validation checks, improve protections against race conditions
- fix: prevent OAuth redirect URI spoofing via non-ascii case collision
- fix: strengthen Actions Artifact V4 signature algorithm against spoofing attacks

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

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Security bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/12493): <!--number 12493 --><!--line 0 --><!--description MjAyNi0wNS0xMiBzZWN1cml0eSBwYXRjaGVz-->2026-05-12 security patches<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: Derzsi Dániel <daniel@tohka.us>
Co-authored-by: jvoisin <julien.voisin@dustri.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12493
2026-05-12 04:54:25 +02:00
jvoisin
cc60e3d693 fix(oauth): only accept refresh tokens as refresh tokens (#12291)
`handleRefreshToken` never checked `token.Type == TypeRefreshToken`. When
`InvalidateRefreshTokens` is disabled, an access token could be submitted as a
`refresh_token` and exchanged for a new token pair.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). 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 for Go changes

(can be removed for JavaScript changes)

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I ran...
  - [x] `make pr-go` before pushing

### Documentation

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

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Co-authored-by: jvoisin <julien.voisin@dustri.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12291
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
2026-04-30 19:24:13 +02:00
Mathieu Fenniak
ef5479af71 refactor: split "basic" and "oauth2" authentication impl into smaller single-purpose components (#12236)
Forgejo's `basic` and `oauth2` authentication methods perform five distinct types of authentication:
- Username and password authentication
- Personal access tokens
- OAuth2 access tokens
- Forgejo Action's `${{ forgejo.token }}` -- task-based static tokens
- Forgejo Action's `${{ env.ACTIONS_RUNTIME_TOKEN }}` JWT, which is the authentication method used for `upload-artifact` (mirroring GitHub's implementation)

`basic` and `oauth2` both supported almost all of these methods, resulting in quite a bit of code duplication between them.  This PR splits personal access tokens into `access_token.go`, Action's task-based tokens into `action_task_token.go`, and Action's JWT tokens into `action_runtime_token.go`.

**Note:** There is one peculiar side-effect that is worth discussing.  Previously, `Authorization: Basic ...` was handled by one complex code path in basic.go, and `Authorization: Bearer ...` was handled by another in oauth2.go, and if authorization failed and a 401 was returned, a single error message would be returned to the user.  Now, as multiple authorization methods may look at `Authorization: Basic ...` and provide their own reason why authorization didn't work, a 401 response has multiple reasons for a lack of authorization listed:

```
401 Unauthorized
...

failure to authenticate with oauth2 access token: not a JWT
Basic authorization is not allowed while having security keys enrolled
access token does not exist [sha: notpassword]
task with token "notpassword": resource does not exist
```

A couple tests have been adapted to check that the result contains their expected response, rather than is equal-to or prefixed-with their expected result.  This is caused by the "auth group" joining together any "invalid credentials" errors, and, to a certain extent it is useful to understand why the authorization request failed.  But it's a bit obscure as well.

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). 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 for Go changes

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
  - Relying on integration testing for regression checks.
- I ran...
  - [x] `make pr-go` before pushing

### Documentation

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

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12236
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
2026-04-24 18:19:58 +02:00
Mathieu Fenniak
1ddd5faa5c refactor: change authentication to return structured data (#12202)
Currently authentication methods return information in two forms: they return who was authenticated as a `*user_model.User`, and then they insert key-values into `ctx.Data` which has critical impact on how the authenticated request is treated.  This PR changes the authentication methods to return structured data in the form of an `AuthenticationResult`, with all the key-value information in `ctx.Data` being moved into methods on the `AuthenticationResult` interface.

Authentication workflows in Forgejo are a real mess.  This is the first step in trying to clean it up and make the code predictable and reasonable, and is both follow-up work that was identified from the repo-specific access tokens (where the `"ApiTokenReducer"` key-value was added), and is pre-requisite work to future JWT enhancements that are [being discussed](https://codeberg.org/forgejo/forgejo/issues/3571#issuecomment-13268004).

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. All work and communication must conform to Forgejo's [AI Agreement](https://codeberg.org/forgejo/governance/src/branch/main/AIAgreement.md). 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 for Go changes

- I added test coverage for Go changes...
  - [ ] in their respective `*_test.go` for unit tests.
  - [ ] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
  - All changes, at least in theory, are refactors of existing logic and are not expected to have functional deviations -- existing regression tests are the only planned testing.
- I ran...
  - [x] `make pr-go` before pushing

### Documentation

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

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12202
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
2026-04-22 21:00:26 +02:00
Gusted
77dbc35138 chore: add modernizer linter (#11936)
- Go has a suite of small linters that helps with modernizing Go code by using newer functions and catching small mistakes, https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize.
- Enable this linter in golangci-lint.
- There's also [`go fix`](https://go.dev/blog/gofix), which is not yet released as a linter in golangci-lint: https://github.com/golangci/golangci-lint/pull/6385

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11936
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2026-04-02 03:29:37 +02:00
Gusted
1c64bad453 fix: improve OAuth2 experience (#11715)
- fix: show oauth2 retrieve error
  - `true` indicates it only should be shown when the page is rendered
directly via `ctx.HTML` and not propagated if it redirects. As you can
see this always redirects and means the error is not shown.
  - Has the funny behavior that you get redirected to `/user/login`
without any indication what went wrong, no errors in the logs either.
- fix: pre-process OAuth2 client ID and secret
  - Spaces should are not appropriate for these input, remove them.
  - Manually copying and pasting client ID and secret from Github OAuth2
applications seems prone to introduce whitespaces.
  - The error of having a incorrect client ID is more noticeable (404 page
for the user).
  - The error of having a incorrect client secret is not noticeable (404
page for the goth library but no mention it's the wrong secret).

Reported-by: marijnh
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11715
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2026-03-17 18:44:23 +01:00
Mathieu Fenniak
f93d2cb261 ci: detect and prevent empty case statements in Go code (#11593)
One of the security patches released 2026-03-09 [fixed a vulnerability](!11513 (commit d1c7b04d09)) caused by a misapplication of Go `case` statements, where the implementation would have been correct if Go `case` statements automatically fall through to the next case block, but they do not.  This PR adds a semgrep rule which detects any empty `case` statement and raises an error, in order to prevent this coding mistake in the future.

For example, code like this will now trigger a build error:
```go
	switch setting.Protocol {
	case setting.HTTPUnix:
	case setting.FCGI:
	case setting.FCGIUnix:
	default:
		defaultLocalURL := string(setting.Protocol) + "://"
	}
```

Example error:
```
    cmd/web.go
   ❯❯❱ semgrep.config.forgejo-switch-empty-case
          switch has a case block with no content. This is treated as "break" by Go, but developers may
          confuse it for "fallthrough".  To fix this error, disambiguate by using "break" or
          "fallthrough".

          279┆ switch setting.Protocol {
          280┆ case setting.HTTPUnix:
          281┆ case setting.FCGI:
          282┆ case setting.FCGIUnix:
          283┆ default:
          284┆   defaultLocalURL := string(setting.Protocol) + "://"
          285┆   if setting.HTTPAddr == "0.0.0.0" {
          286┆           defaultLocalURL += "localhost"
          287┆   } else {
          288┆           defaultLocalURL += setting.HTTPAddr
```

As described in the error output, this error can be fixed by explicitly listing `break` (the real Go behaviour, to do nothing in the block), or by listing `fallthrough` (if the intent was to fall through).

All existing code triggering this detection has been changed to `break` (or, rarely, irrelevant cases have been removed), which should maintain the same code functionality.  While performing this fixup, a light analysis was performed on each case and they *appeared* correct, but with ~65 cases I haven't gone into extreme depth.

Tests are present for the semgrep rule in `.semgrep/tests/go.go`.

## 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).

### Documentation

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

### Release notes

- [ ] This change will be noticed by a Forgejo user or admin (feature, bug fix, performance, etc.). I suggest to include a release note for this change.
- [x] This change is not visible to a Forgejo user or admin (refactor, dependency upgrade, etc.). I think there is no need to add a release note for this change.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11593
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net>
Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
2026-03-10 02:50:28 +01:00
Oliver Eikemeier
d499c3b132 chore: rename AccessTokenError to AccessTokenErrorResponse (#11595)
AccessTokenError is never used as a Go error. In fact, it is returned
as a *AccessTokenError (which would result in a `nil` error when cast).

Rename the struct to a more accurate name and remove the unused
`Error() string` method to prevent future confusion.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11595
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Oliver Eikemeier <eikemeier@fillmore-labs.com>
Co-committed-by: Oliver Eikemeier <eikemeier@fillmore-labs.com>
2026-03-09 23:36:47 +01:00
Gusted
d1c7b04d09 fix: verify code challenge of S256
We do not know for sure, but it is quite likely someone assumed implicit
fallthrough. This meant that if someone used S256 for PKCE, it simply
did not verify the code challenge and always accepted it.

PKCE only started working recently as it was broken for a long time
already, forgejo/forgejo!8678
2026-03-06 11:21:07 -07:00
AngryDove
44501c80eb feat: add trace logging for oauth2 callback (#11175)
This change is to enable some additional trace logging for oauth2.

Initial setups can be a real pain to debug, and getting JWT back for debug purpose helps a lot i.e. checking claims, roles, groups.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11175
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: AngryDove <angrydove@noreply.codeberg.org>
Co-committed-by: AngryDove <angrydove@noreply.codeberg.org>
2026-03-02 02:08:21 +01:00
Nils Goroll
d934e0c9fb chore: refactor signup logic (#10915)
This PR is in preparation of, but independent of, an upcoming suggestion for a feature addition:

* The first commit moves a tiny bit of logic into a separate function to prepare for extension of that logic, avoiding duplication
* The second commit moves checking for disabled registrations earlier, which, I think, has merits in terms of performance and resilience (hopefully not significant, but who knows?)
* The third commit adds simple unit tests for SignUp() and SignUpPost() to avoid the long-ish roundtrip over integration tests
*  The forth commit introduces `ctx.Data["DisableRegistrationReason"]` for the signup template to use as the reason printed if `.DisableRegistration` to prepare for other reasons to be added

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10915
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Nils Goroll <nils.goroll@uplex.de>
Co-committed-by: Nils Goroll <nils.goroll@uplex.de>
2026-01-26 22:55:30 +01:00
Nils Goroll
b4412c2206 chore: do not pass the full signing key to template (#10967)
A template should not get (easy) access to a full signing key to prevent accidents.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10967
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Nils Goroll <nils.goroll@uplex.de>
Co-committed-by: Nils Goroll <nils.goroll@uplex.de>
2026-01-26 14:47:48 +01:00
Mario Minardi
c84cbd56a1 feat: add OIDC workload identity federation support (#10481)
Add support for OIDC workload identity federation.

Add ID_TOKEN_SIGNING_ALGORITHM, ID_TOKEN_SIGNING_PRIVATE_KEY_FILE, and
ID_TOKEN_EXPIRATION_TIME settings to settings.actions to allow for admin
configuration of this functionality.

Add OIDC endpoints (/.well-known/openid-configuration and /.well-known/keys)
underneath the "/api/actions" route.

Add a token generation endpoint (/_apis/pipelines/workflows/{run_id}/idtoken)
underneath the "/api/actions" route.

Depends on: https://code.forgejo.org/forgejo/runner/pulls/1232
Docs PR: https://codeberg.org/forgejo/docs/pulls/1667

Signed-off-by: Mario Minardi <mminardi@shaw.ca>

## 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...
  - [x] 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

- [x] 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.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10481
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Mario Minardi <mminardi@shaw.ca>
Co-committed-by: Mario Minardi <mminardi@shaw.ca>
2026-01-15 03:39:00 +01:00
thezzisu
e31d67e0aa feat: allow sync quota groups with oauth2 auth source (#8554)
Implements synchronizing an external user's quota group with provided OAuth2 claim.

This functionality will allow system administrators to manage user's quota groups automatically.

Documentation is at forgejo/docs#1337

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8554
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: thezzisu <thezzisu@gmail.com>
Co-committed-by: thezzisu <thezzisu@gmail.com>
2025-12-01 14:12:00 +01:00
RaymondKroon
81f20a69b6 fix: do casefolding in OAuth2 account autolinking (#10072)
Resolves #9992.

Creating new users will make sure to avoid creating duplicate users where the only difference is a casing. Error handling did not handle this correctly, resulting in 500. This is fixed by searching for LowerName in the error handling.

Co-authored-by: Raymond Kroon <raymond.kroon@kadaster.nl>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10072
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: RaymondKroon <raymondkroon@noreply.codeberg.org>
Co-committed-by: RaymondKroon <raymondkroon@noreply.codeberg.org>
2025-11-16 16:39:06 +01:00
Gusted
691dd023ff chore: unify the usage of CryptoRandomString (#10110)
- Similair spirit of forgejo/forgejo!7453.
- Refactor the code in such a way that it always succeeds.
- To avoid doing mathematics if you use this function, define three security level (64, 128 and 256 bits) that correspond to a specific length which has that a security guarantee. I picked them as they fit the need for the existing usages of the code.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10110
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Lucas <sclu1034@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-11-15 13:24:53 +01:00
Gusted
a4642af51a feat: replace cross origin protection (#9830)
Replace the anti-CSRF token with a [cross origin protection by Go](https://go.dev/doc/go1.25#nethttppkgnethttp) that uses a stateless way of verifying if a request was cross origin or not. This allows is to remove al lot of code and replace it with a few lines of code and we no longer have to hand roll this protection. The new protection uses indicators by the browser itself that indicate if the request is cross-origin, thus we no longer have to take care of ensuring the generated CSRF token is passed back to the server any request by the the browser will have send this indicator.

Resolves forgejo/forgejo#3538

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9830
Reviewed-by: oliverpool <oliverpool@noreply.codeberg.org>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-10-29 22:43:22 +01:00
Gusted
8bd5169c5f fix: allow unactivated users to send recovery mails (#9504)
With forgejo/forgejo#9075 the `GetUserByEmail` now actually only used activated emails. This however broke sending recovery mails to unactivated users, as their email are not yet activated.

Use the newly introduced function `GetUserByEmailSimple` to not care about this activated email requirement and also avoid the no-reply address being a valid email address for this functionality.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9504
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-10-03 07:16:24 +02:00
BtbN
fd849bb9f2 Reject password reset attempts for OAuth2 users without a current password (#9060)
Currently, if a user signed up via OAuth2 and then somehow gets their E-Mail account compromised, their Forgejo account can be taken over by requesting a password reset for their Forgejo account.
This PR changes the logic so that a password reset request is denied for a user using OAuth2 if they do not already have a password set.
Which should be the case for all users who only ever log in via their Auth-Provider.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9060
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: BtbN <btbn@btbn.de>
Co-committed-by: BtbN <btbn@btbn.de>
2025-09-12 00:08:29 +02:00
Earl Warren
1b13fda06b fix: email comments are removed from email addresses (#9074)
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9074
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
2025-08-30 13:15:30 +02:00
famfo
a511e37572
chore: add email blocklist unit test 2025-08-30 09:45:19 +02:00
Gusted
90e974cd24
fix: do 2FA on OpenID connect 2025-08-30 09:41:20 +02:00
Leni Kadali
0606f05707 chore: Use common SetCaptchaData in link account (#8592)
Fixes [#7990](https://codeberg.org/forgejo/forgejo/issues/7990)

This PR upstreams commit [2bf3621c99](2bf3621c99) which fixes `SetCaptcha` not being called when it is typically used in other places.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8592
Reviewed-by: Beowulf <beowulf@beocode.eu>
Co-authored-by: Leni Kadali <lenikadali@noreply.codeberg.org>
Co-committed-by: Leni Kadali <lenikadali@noreply.codeberg.org>
2025-08-26 20:30:18 +02:00
zokki
d6838462b8 feat: Global 2FA enforcement (#8753)
resolves #8549

This PR add a config to enforce 2FA for the whole Forgejo instance. It can be configured to `none`, `admin` or `all`.
A user who is required to enable 2FA is like a disabled user. He can only see the `/user/settings/security`-Page to enable 2FA, this should be similar to a user which needs to change his password. Also api and git-commands are not allowed.

## 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...
  - [x] 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.

I will do it, if the general idea of this PR is a good feature.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [x] 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-->
- Security features
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/8753): <!--number 8753 --><!--line 0 --><!--description R2xvYmFsIDJGQSBlbmZvcmNlbWVudA==-->Global 2FA enforcement<!--description-->
<!--end release-notes-assistant-->

Co-authored-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8753
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Ellen Εμιλία Άννα Zscheile <fogti@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: zokki <zokki.softwareschmiede@gmail.com>
Co-committed-by: zokki <zokki.softwareschmiede@gmail.com>
2025-08-15 10:56:45 +02:00
Gusted
24014c349e fix: store code challenge correctly in session (#8678)
- Even though the test file contains some good extensive testing, it didn't bother to actually call `/login/oauth/access_token` to see if the received code actually resulted into a access token.
- The fix itself is... well yeah self-explanatory.
- Resolves forgejo/forgejo#8669

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8678
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-07-26 05:16:55 +02:00
Gusted
288c56f5d3 feat: if OAuth2 is disabled return 'Not found' for openid configuration (#8426)
- If a Forgejo has disabled being a OAuth2 provider via `[oauth2].ENABLED = false` then return 'Not found' when clients requests `.well-known/openid-configuration` to reflect that OAuth2 is not supported.
- This allows clients to query if Forgejo has OAuth2 enabled.
- Resolves forgejo/forgejo#6978

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8426
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-07-06 07:19:23 +02:00
jmaasing
5391f43888 fix: remove trailing slash from the issuer in oauth claims (#8028)
- Trim the ending slash '/' from the URL used in the OpenID Connect "well_known" endpoint and in the JWT tokens issued by Forgejo.
- This makes it compliant with the OpenID specification. https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
- Resolves #7941

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8028
Reviewed-by: Lucas <sclu1034@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: jmaasing <jmaasing@noreply.codeberg.org>
Co-committed-by: jmaasing <jmaasing@noreply.codeberg.org>
2025-06-10 20:46:17 +02:00
chavacava
99d697263f chore(cleanup): replaces unnecessary calls to formatting functions by non-formatting equivalents (#7994)
This PR replaces unnecessary calls to formatting functions (`fmt.Printf`, `fmt.Errorf`, ...) by non-formatting equivalents.
Resolves #7967

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7994
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: chavacava <chavacava@noreply.codeberg.org>
Co-committed-by: chavacava <chavacava@noreply.codeberg.org>
2025-05-29 17:34:29 +02:00
Gusted
7d2a7b8559 feat: add validating user password as trace region (#7981)
- Password hashing can take a measurable amount of time, make this more visible in the trace by capturing the computations done in the password hash in their own region.
- Ref: forgejo/forgejo#6470

## Screenshot

![image](/attachments/9834b094-a78f-4ac2-847e-91f221a84833)

The upper part are where the tasks are shown (and nothing else). The bottom part is where the interesting execution tracing happens and the part where the user password hashing happens is now properly indicated/highlighted and does not need to be inferred by looking at the stack traces.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7981
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-05-28 14:46:23 +02:00
famfo
dda37e86bd feat: relax email requirements (#7829)
The current email restrictions were put in place because of a security issue with sendmail (https://github.com/go-gitea/gitea/pull/17688). Remove this restriction and instead ensure that this security issue cannot happen with sendmail.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7829
Reviewed-by: Ellen Εμιλία Άννα Zscheile <fogti@noreply.codeberg.org>
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: famfo <famfo@famfo.xyz>
Co-committed-by: famfo <famfo@famfo.xyz>
2025-05-22 12:20:25 +02:00
Gusted
df5d656827 feat: consider WebAuthn & SSH for instance signing (#7693)
- Currently the options `pubkey` and `twofa` only consider TOTP and GPG keys respectively. Adjust the code to also consider WebAuthn credentials and SSH keys.
- While adding the new unified functions I noticed that certain places also benefited from using these unified functions and took the liberty (where it was either a trivial translation or it was covered under testing) to use the new unified functions.
- Resolves forgejo/forgejo#7658
- Adds unit and integration tests.

Documentation PR: https://codeberg.org/forgejo/docs/pulls/1166

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7693
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-04-29 10:34:07 +00:00
Gusted
2ce7affc9a fix: set default restricted for OAuth2 user (#7683)
- The OAuthCallback code that is responsible for creating a new user, if one does not exist yet, did not use `[service].ALLOW_ONLY_EXTERNAL_REGISTRATION` as default value for the restricted field of a user.
- Resolves forgejo/forgejo#7681
- Add integration test.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7683
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-04-27 19:51:09 +00:00
Gusted
53df0bf9a4 chore(sec): unify usage of crypto/rand.Read (#7453)
- Unify the usage of [`crypto/rand.Read`](https://pkg.go.dev/crypto/rand#Read) to `util.CryptoRandomBytes`.
- Refactor `util.CryptoRandomBytes` to never return an error. It is documented by Go, https://go.dev/issue/66821, to always succeed. So if we still receive a error or if the returned bytes read is not equal to the expected bytes to be read we panic (just to be on the safe side).
- This simplifies a lot of code to no longer care about error handling.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7453
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-04-04 03:31:37 +00:00
Renovate Bot
fed2d81c44 Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367)
Co-authored-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
Co-committed-by: Renovate Bot <forgejo-renovate-action@forgejo.org>
2025-03-28 22:22:21 +00:00
Gusted
2457f5ff22 chore: branding import path (#7337)
- Massive replacement of changing `code.gitea.io/gitea` to `forgejo.org`.
- Resolves forgejo/discussions#258

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7337
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
Reviewed-by: Beowulf <beowulf@beocode.eu>
Reviewed-by: Panagiotis "Ivory" Vasilopoulos <git@n0toose.net>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-03-27 19:40:14 +00:00
Otto Richter
9dea54a9d6 Drop SSPI auth support and more Windows files (#7148)
## Dropping SSPI auth support

SSPI authentication relied on Microsoft Windows support, removal started in https://codeberg.org/forgejo/forgejo/pulls/5353, because it was broken anyway. We have no knowledge of any users using SSPI authentication. However, if you somehow managed to run Forgejo on Windows, or want to upgrade from a Gitea version which does, please ensure that you do not use SSPI as an authentication mechanism for user accounts. Feel free to reach out if you need assistance.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/7148
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Co-authored-by: Otto Richter <otto@codeberg.org>
Co-committed-by: Otto Richter <otto@codeberg.org>
2025-03-08 00:43:41 +00:00
Gusted
06556abb6d fix: delay deleting authorization token (#6937)
- 1ce33aa38d extended the LTA table with a purpose column so it could be extended to other tokens. However some are single-use tokens and should be deleted after use.
- This did not result in a good UX for activating user as they needed to also fill in their passwords and in the case that the password was incorrect the token would no longer be usable.
- This patch modifies the code to allow for a little delay before deleting authorization tokens to do additional verification such as the password check. This cannot be done before the authorization token check as that the authorization token determines who the user is.
- Resolves forgejo/forgejo#6912
- Adjusted existing unit test.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6937
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-02-17 11:09:33 +00:00
davrot
ef2fbc6093 fix: disable forgotten password for external signin only (#6680)
- Make it such that `[service].ENABLE_INTERNAL_SIGNIN = false` disables the forgotten password prompt on the login page.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6680
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: davrot <davrot@noreply.codeberg.org>
Co-committed-by: davrot <davrot@noreply.codeberg.org>
2025-02-14 12:54:18 +00:00
Matthias Riße
b1a7db7e28 fix: show internal login prompt for account linking (#6920)
Fixes #6878.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6920
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Co-authored-by: Matthias Riße <m.risse@fz-juelich.de>
Co-committed-by: Matthias Riße <m.risse@fz-juelich.de>
2025-02-14 12:45:15 +00:00
Gusted
801c392e0c
chore: remove deadcode in models/user
- Remove `ErrUserInactive` introduced in
f5fa22a499 and removed in
ef2a343e27
- Remove `GetUserEmailsByNames` introduced in
a4cbe79567 and removed in
08ae6bb7ed
- Remove `GetUserNamesByIDs` introduced in
9ff4e1d2d9 and removed in
b3a6596b54
2025-01-29 18:37:14 +01:00
Gusted
a9c97110f9 feat: add configurable cooldown to claim usernames (#6422)
Add a new option that allows instances to set a cooldown period to claim
old usernames. In the context of public instances this can be used to
prevent old usernames to be claimed after they are free and allow
graceful migration (by making use of the redirect feature) to a new
username. The granularity of this cooldown is a day. By default this
feature is disabled and thus no cooldown period.

The `CreatedUnix` column is added the `user_redirect` table, for
existing redirects the timestamp is simply zero as we simply do not know
when they were created and are likely already over the cooldown period
if the instance configures one.

Users can always reclaim their 'old' user name again within the cooldown
period. Users can also always reclaim 'old' names of organization they
currently own within the cooldown period.

Creating and renaming users as an admin user are not affected by the
cooldown period for moderation and user support reasons.

To avoid abuse of the cooldown feature, such that a user holds a lot of
usernames, a new option is added `MAX_USER_REDIRECTS` which sets a limit
to the amount of user redirects a user may have, by default this is
disabled. If a cooldown period is set then the default is 5. This
feature operates independently of the cooldown period feature.

Added integration and unit testing.

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6422
Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org>
Reviewed-by: 0ko <0ko@noreply.codeberg.org>
Reviewed-by: Otto <otto@codeberg.org>
Co-authored-by: Gusted <postmaster@gusted.xyz>
Co-committed-by: Gusted <postmaster@gusted.xyz>
2025-01-24 04:16:56 +00:00
Maxim Slipenko
666654a5ef fix: return empty slice if AttributeSSHPublicKey is missing in RawData 2024-12-27 11:17:27 +03:00
Maxim Slipenko
515eec3d1a remove len(sshKeys) == 0 check 2024-12-21 21:25:38 +00:00
Maxim Slipenko
32de0745e4 style: fix fmt and lint 2024-12-19 11:17:28 +00:00
Maxim Slipenko
8bd1c7ff31 feat: add synchronization for SSH keys in handleOAuth2SignIn 2024-12-19 10:47:47 +00:00
Gusted
7f8f9b878f
fix: Revert "allow synchronizing user status from OAuth2 login providers (#31572)"
This commit has a fundamental flaw, in order to syncronize if external
users are still active the commit checks if the refresh token is
accepted by the OAuth provider, if that is not the case it sees that as
the user is disabled and sets the is active field to `false` to signal
that. Because it might be possible (this commit makes this a highly
likelyhood) that the OAuth provider still recognizes this user the
commit introduces code to allow users to re-active themselves via the
oauth flow if they were disabled because of this. However this code
makes no distinction in why the user was disabled and always re-actives
the user.

Thus the reactivation via the OAuth flow allows users to bypass the
manually activation setting (`[service].REGISTER_MANUAL_CONFIRM`) or if
the admin for other reasons disabled the user.

This reverts commit 21fdd28f08.
2024-12-12 05:59:06 +01:00