mirror of
https://code.forgejo.org/forgejo/runner.git
synced 2025-09-15 18:57:01 +00:00
refactor: remove duplicate computeMac function (#936)
It was raised during embargo review of #925 that there are two implementations of `computeMac`; this PR fixes that. As all the tests for `computeMac` were in the `artifactcache` package, it made more sense to keep the method there. That required reversing the dependency `artifactcache->cacheproxy` package dependency -- it makes more sense to me for the proxy to depend on the cache, rather than vice-versa. <!--start release-notes-assistant--> <!--URL:https://code.forgejo.org/forgejo/runner--> - other - [PR](https://code.forgejo.org/forgejo/runner/pulls/936): <!--number 936 --><!--line 0 --><!--description cmVmYWN0b3I6IHJlbW92ZSBkdXBsaWNhdGUgY29tcHV0ZU1hYyBmdW5jdGlvbg==-->refactor: remove duplicate computeMac function<!--description--> <!--end release-notes-assistant--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/936 Reviewed-by: Michael Kriese <michael.kriese@gmx.de> Co-authored-by: Mathieu Fenniak <mathieu@fenniak.net> Co-committed-by: Mathieu Fenniak <mathieu@fenniak.net>
This commit is contained in:
parent
35f93b6b11
commit
a3aedba3f1
5 changed files with 29 additions and 47 deletions
|
@ -20,7 +20,6 @@ import (
|
||||||
"github.com/timshannon/bolthold"
|
"github.com/timshannon/bolthold"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
|
||||||
"code.forgejo.org/forgejo/runner/v9/act/cacheproxy"
|
|
||||||
"code.forgejo.org/forgejo/runner/v9/act/common"
|
"code.forgejo.org/forgejo/runner/v9/act/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -689,8 +688,16 @@ func parseContentRange(s string) (uint64, uint64, error) {
|
||||||
return start, stop, nil
|
return start, stop, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDataFromHeaders(r *http.Request) cacheproxy.RunData {
|
type RunData struct {
|
||||||
return cacheproxy.RunData{
|
RepositoryFullName string
|
||||||
|
RunNumber string
|
||||||
|
Timestamp string
|
||||||
|
RepositoryMAC string
|
||||||
|
WriteIsolationKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func runDataFromHeaders(r *http.Request) RunData {
|
||||||
|
return RunData{
|
||||||
RepositoryFullName: r.Header.Get("Forgejo-Cache-Repo"),
|
RepositoryFullName: r.Header.Get("Forgejo-Cache-Repo"),
|
||||||
RunNumber: r.Header.Get("Forgejo-Cache-RunNumber"),
|
RunNumber: r.Header.Get("Forgejo-Cache-RunNumber"),
|
||||||
Timestamp: r.Header.Get("Forgejo-Cache-Timestamp"),
|
Timestamp: r.Header.Get("Forgejo-Cache-Timestamp"),
|
||||||
|
|
|
@ -821,7 +821,7 @@ func overrideWriteIsolationKey(writeIsolationKey string) func() {
|
||||||
originalMac := httpClientTransport.OverrideDefaultMac
|
originalMac := httpClientTransport.OverrideDefaultMac
|
||||||
|
|
||||||
httpClientTransport.WriteIsolationKey = writeIsolationKey
|
httpClientTransport.WriteIsolationKey = writeIsolationKey
|
||||||
httpClientTransport.OverrideDefaultMac = computeMac("secret", cacheRepo, cacheRunnum, cacheTimestamp, httpClientTransport.WriteIsolationKey)
|
httpClientTransport.OverrideDefaultMac = ComputeMac("secret", cacheRepo, cacheRunnum, cacheTimestamp, httpClientTransport.WriteIsolationKey)
|
||||||
|
|
||||||
return func() {
|
return func() {
|
||||||
httpClientTransport.WriteIsolationKey = originalWriteIsolationKey
|
httpClientTransport.WriteIsolationKey = originalWriteIsolationKey
|
||||||
|
|
|
@ -10,19 +10,17 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.forgejo.org/forgejo/runner/v9/act/cacheproxy"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrValidation = errors.New("validation error")
|
var ErrValidation = errors.New("validation error")
|
||||||
|
|
||||||
func (h *handler) validateMac(rundata cacheproxy.RunData) (string, error) {
|
func (h *handler) validateMac(rundata RunData) (string, error) {
|
||||||
// TODO: allow configurable max age
|
// TODO: allow configurable max age
|
||||||
if !validateAge(rundata.Timestamp) {
|
if !validateAge(rundata.Timestamp) {
|
||||||
return "", ErrValidation
|
return "", ErrValidation
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedMAC := computeMac(h.secret, rundata.RepositoryFullName, rundata.RunNumber, rundata.Timestamp, rundata.WriteIsolationKey)
|
expectedMAC := ComputeMac(h.secret, rundata.RepositoryFullName, rundata.RunNumber, rundata.Timestamp, rundata.WriteIsolationKey)
|
||||||
if hmac.Equal([]byte(expectedMAC), []byte(rundata.RepositoryMAC)) {
|
if hmac.Equal([]byte(expectedMAC), []byte(rundata.RepositoryMAC)) {
|
||||||
return rundata.RepositoryFullName, nil
|
return rundata.RepositoryFullName, nil
|
||||||
}
|
}
|
||||||
|
@ -40,7 +38,7 @@ func validateAge(ts string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeMac(secret, repo, run, ts, writeIsolationKey string) string {
|
func ComputeMac(secret, repo, run, ts, writeIsolationKey string) string {
|
||||||
mac := hmac.New(sha256.New, []byte(secret))
|
mac := hmac.New(sha256.New, []byte(secret))
|
||||||
mac.Write([]byte(repo))
|
mac.Write([]byte(repo))
|
||||||
mac.Write([]byte(">"))
|
mac.Write([]byte(">"))
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"code.forgejo.org/forgejo/runner/v9/act/cacheproxy"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,8 +18,8 @@ func TestMac(t *testing.T) {
|
||||||
run := "1"
|
run := "1"
|
||||||
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
mac := computeMac(handler.secret, name, run, ts, "")
|
mac := ComputeMac(handler.secret, name, run, ts, "")
|
||||||
rundata := cacheproxy.RunData{
|
rundata := RunData{
|
||||||
RepositoryFullName: name,
|
RepositoryFullName: name,
|
||||||
RunNumber: run,
|
RunNumber: run,
|
||||||
Timestamp: ts,
|
Timestamp: ts,
|
||||||
|
@ -37,8 +36,8 @@ func TestMac(t *testing.T) {
|
||||||
run := "1"
|
run := "1"
|
||||||
ts := "9223372036854775807" // This should last us for a while...
|
ts := "9223372036854775807" // This should last us for a while...
|
||||||
|
|
||||||
mac := computeMac(handler.secret, name, run, ts, "")
|
mac := ComputeMac(handler.secret, name, run, ts, "")
|
||||||
rundata := cacheproxy.RunData{
|
rundata := RunData{
|
||||||
RepositoryFullName: name,
|
RepositoryFullName: name,
|
||||||
RunNumber: run,
|
RunNumber: run,
|
||||||
Timestamp: ts,
|
Timestamp: ts,
|
||||||
|
@ -54,7 +53,7 @@ func TestMac(t *testing.T) {
|
||||||
run := "1"
|
run := "1"
|
||||||
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
ts := strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
rundata := cacheproxy.RunData{
|
rundata := RunData{
|
||||||
RepositoryFullName: name,
|
RepositoryFullName: name,
|
||||||
RunNumber: run,
|
RunNumber: run,
|
||||||
Timestamp: ts,
|
Timestamp: ts,
|
||||||
|
@ -72,12 +71,12 @@ func TestMac(t *testing.T) {
|
||||||
run := "42"
|
run := "42"
|
||||||
ts := "1337"
|
ts := "1337"
|
||||||
|
|
||||||
mac := computeMac(secret, name, run, ts, "")
|
mac := ComputeMac(secret, name, run, ts, "")
|
||||||
expectedMac := "4754474b21329e8beadd2b4054aa4be803965d66e710fa1fee091334ed804f29" // * Precomputed, anytime the computeMac function changes this needs to be recalculated
|
expectedMac := "4754474b21329e8beadd2b4054aa4be803965d66e710fa1fee091334ed804f29" // * Precomputed, anytime the ComputeMac function changes this needs to be recalculated
|
||||||
require.Equal(t, expectedMac, mac)
|
require.Equal(t, expectedMac, mac)
|
||||||
|
|
||||||
mac = computeMac(secret, name, run, ts, "refs/pull/12/head")
|
mac = ComputeMac(secret, name, run, ts, "refs/pull/12/head")
|
||||||
expectedMac = "9ca8f4cb5e1b083ee8cd215215bc00f379b28511d3ef7930bf054767de34766d" // * Precomputed, anytime the computeMac function changes this needs to be recalculated
|
expectedMac = "9ca8f4cb5e1b083ee8cd215215bc00f379b28511d3ef7930bf054767de34766d" // * Precomputed, anytime the ComputeMac function changes this needs to be recalculated
|
||||||
require.Equal(t, expectedMac, mac)
|
require.Equal(t, expectedMac, mac)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,6 @@
|
||||||
package cacheproxy
|
package cacheproxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -22,6 +19,7 @@ import (
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"code.forgejo.org/forgejo/runner/v9/act/artifactcache"
|
||||||
"code.forgejo.org/forgejo/runner/v9/act/common"
|
"code.forgejo.org/forgejo/runner/v9/act/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -46,17 +44,9 @@ type Handler struct {
|
||||||
runs sync.Map
|
runs sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
type RunData struct {
|
func (h *Handler) CreateRunData(fullName, runNumber, timestamp, writeIsolationKey string) artifactcache.RunData {
|
||||||
RepositoryFullName string
|
mac := artifactcache.ComputeMac(h.cacheSecret, fullName, runNumber, timestamp, writeIsolationKey)
|
||||||
RunNumber string
|
return artifactcache.RunData{
|
||||||
Timestamp string
|
|
||||||
RepositoryMAC string
|
|
||||||
WriteIsolationKey string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) CreateRunData(fullName, runNumber, timestamp, writeIsolationKey string) RunData {
|
|
||||||
mac := computeMac(h.cacheSecret, fullName, runNumber, timestamp, writeIsolationKey)
|
|
||||||
return RunData{
|
|
||||||
RepositoryFullName: fullName,
|
RepositoryFullName: fullName,
|
||||||
RunNumber: runNumber,
|
RunNumber: runNumber,
|
||||||
Timestamp: timestamp,
|
Timestamp: timestamp,
|
||||||
|
@ -142,7 +132,7 @@ func (h *Handler) newReverseProxy(targetHost string) (*httputil.ReverseProxy, er
|
||||||
h.logger.Warn(fmt.Sprintf("Tried starting a cache proxy with id %s, which does not exist.", id))
|
h.logger.Warn(fmt.Sprintf("Tried starting a cache proxy with id %s, which does not exist.", id))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
runData := data.(RunData)
|
runData := data.(artifactcache.RunData)
|
||||||
uri := matches[2]
|
uri := matches[2]
|
||||||
|
|
||||||
r.SetURL(targetURL)
|
r.SetURL(targetURL)
|
||||||
|
@ -170,7 +160,7 @@ func (h *Handler) ExternalURL() string {
|
||||||
// Informs the proxy of a workflow run that can make cache requests.
|
// Informs the proxy of a workflow run that can make cache requests.
|
||||||
// The RunData contains the information about the repository.
|
// The RunData contains the information about the repository.
|
||||||
// The function returns the 32-bit random key which the run will use to identify itself.
|
// The function returns the 32-bit random key which the run will use to identify itself.
|
||||||
func (h *Handler) AddRun(data RunData) (string, error) {
|
func (h *Handler) AddRun(data artifactcache.RunData) (string, error) {
|
||||||
for range 3 {
|
for range 3 {
|
||||||
key := common.MustRandName(4)
|
key := common.MustRandName(4)
|
||||||
_, loaded := h.runs.LoadOrStore(key, data)
|
_, loaded := h.runs.LoadOrStore(key, data)
|
||||||
|
@ -211,15 +201,3 @@ func (h *Handler) Close() error {
|
||||||
}
|
}
|
||||||
return retErr
|
return retErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func computeMac(secret, repo, run, ts, writeIsolationKey string) string {
|
|
||||||
mac := hmac.New(sha256.New, []byte(secret))
|
|
||||||
mac.Write([]byte(repo))
|
|
||||||
mac.Write([]byte(">"))
|
|
||||||
mac.Write([]byte(run))
|
|
||||||
mac.Write([]byte(">"))
|
|
||||||
mac.Write([]byte(ts))
|
|
||||||
mac.Write([]byte(">"))
|
|
||||||
mac.Write([]byte(writeIsolationKey))
|
|
||||||
return hex.EncodeToString(mac.Sum(nil))
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue