gitforge/modules/test/utils.go
Mathieu Fenniak a9a598d4b8 fix: ensure migrations allow/deny host lists are applied to onedev, pagure, and codebase migrators (#13184)
Similar to #13129, fixing a few places where `[migrations].ALLOWED_DOMAINS`, `...BLOCKED_DOMAINS`, and `...ALLOW_LOCALNETWORKS` are not implemented in external migrations, creating SSRF risks.

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

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

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13184
Reviewed-by: Andreas Ahlenstorf <aahlenst@noreply.codeberg.org>
2026-06-25 14:11:36 +02:00

74 lines
1.7 KiB
Go

// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package test
import (
"net/http"
"net/http/httptest"
"strings"
"time"
"forgejo.org/modules/json"
)
// RedirectURL returns the redirect URL of a http response.
// It also works for JSONRedirect: `{"redirect": "..."}`
func RedirectURL(resp http.ResponseWriter) string {
loc := resp.Header().Get("Location")
if loc != "" {
return loc
}
if r, ok := resp.(*httptest.ResponseRecorder); ok {
m := map[string]any{}
err := json.Unmarshal(r.Body.Bytes(), &m)
if err == nil {
if loc, ok := m["redirect"].(string); ok {
return loc
}
}
}
return ""
}
func IsNormalPageCompleted(s string) bool {
return strings.Contains(s, `<footer class="page-footer"`) && strings.Contains(s, `</html>`)
}
// use for global variables only
func MockVariableValue[T any](p *T, v T) (reset func()) {
old := *p
*p = v
return func() {
*p = old
}
}
// Set the value *p to v, and return a closure that resets it when invoked. On
// set and reset the `afterChange` closure will be invoked.
func MockVariableValueWithReset[T any](p *T, v T, afterChange func()) (reset func()) {
old := *p
*p = v
afterChange()
return func() {
*p = old
afterChange()
}
}
// use for global variables only
func MockProtect[T any](p *T) (reset func()) {
old := *p
return func() { *p = old }
}
// When this is called, sleep until the unix time was increased by one.
func SleepTillNextSecond() {
time.Sleep(time.Second - time.Since(time.Now().Truncate(time.Second)))
}
// When this is called, sleep until the truncated unix time to a minute was
// increased by one.
func SleepTillNextMinute() {
time.Sleep(time.Minute - time.Since(time.Now().Truncate(time.Minute)))
}