[v15.0/forgejo] fix: store pull mirror creds encrypted with keying (#11984)

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

Fixes #9629.

New pull mirrors have credentials stored encrypted in the database, the same as push mirrors, rather than in the repository's `config` file.  `git fetch` on the pull mirror is updated to use the credential store.  Pull mirrors will have their credentials migrated to the encrypted storage in the database as they're synced or otherwise accessed via the web UI.

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

- [x] 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.
- [ ] 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: Mathieu Fenniak <mathieu@fenniak.net>
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11984
Reviewed-by: Mathieu Fenniak <mfenniak@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 2026-04-04 14:47:05 +02:00 committed by Mathieu Fenniak
parent 6d67717a21
commit 06888ca34a
12 changed files with 774 additions and 182 deletions

View file

@ -462,12 +462,12 @@ func SettingsPost(ctx *context.Context) {
return
}
u, err := git.GetRemoteURL(ctx, ctx.Repo.Repository.RepoPath(), pullMirror.GetRemoteName())
u, err := mirror_service.DecryptOrRecoverRemoteAddress(ctx, pullMirror)
if err != nil {
ctx.Data["Err_MirrorAddress"] = true
handleSettingRemoteAddrError(ctx, err, form)
ctx.ServerError("DecryptOrRecoverRemoteAddress", err)
return
}
if u.User != nil && form.MirrorPassword == "" && form.MirrorUsername == u.User.Username() {
form.MirrorPassword, _ = u.User.Password()
}
@ -482,17 +482,25 @@ func SettingsPost(ctx *context.Context) {
return
}
if err := mirror_service.UpdateAddress(ctx, pullMirror, address); err != nil {
ctx.ServerError("UpdateAddress", err)
return
}
remoteAddress, err := util.SanitizeURL(address)
if err != nil {
if err := pullMirror.UpdateRemoteAddress(ctx, address); err != nil {
ctx.Data["Err_MirrorAddress"] = true
handleSettingRemoteAddrError(ctx, err, form)
return
}
pullMirror.RemoteAddress = remoteAddress
// Update the unencrypted address stored in the git config, so that future `git fetch` will access the right
// address. pullMirror.RemoteAddress is the sanitized no-creds version from UpdateRemoteAddress.
if maybeSanitizedURL, err := pullMirror.SanitizedRemoteAddress(); err != nil {
ctx.ServerError("SanitizedRemoteAddress", err)
return
} else if has, sanitizedURL := maybeSanitizedURL.Get(); !has {
// SanitizedRemoteAddress must be present after we just stored it
ctx.ServerError("SanitizedRemoteAddress", err)
return
} else if err := mirror_service.UpdateAddress(ctx, pullMirror, sanitizedURL); err != nil {
ctx.ServerError("UpdateAddress", err)
return
}
form.LFS = form.LFS && setting.LFS.StartServer