37 lines
971 B
Go
37 lines
971 B
Go
package runnerfacade
|
|
|
|
import (
|
|
"crypto/hmac"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"errors"
|
|
)
|
|
|
|
// Capabilities are deterministic per assignment so controller restarts do not
|
|
// require a per-task token database.
|
|
type Capabilities struct{ key []byte }
|
|
|
|
func NewCapabilities(key []byte) (Capabilities, error) {
|
|
if len(key) < 32 {
|
|
return Capabilities{}, errors.New("runner facade capability key must be at least 32 bytes")
|
|
}
|
|
return Capabilities{key: append([]byte(nil), key...)}, nil
|
|
}
|
|
|
|
func (c Capabilities) Issue(assignmentID string) string {
|
|
if len(c.key) < 32 || assignmentID == "" {
|
|
return ""
|
|
}
|
|
mac := hmac.New(sha256.New, c.key)
|
|
_, _ = mac.Write([]byte("gitea-runner-assignment\x00" + assignmentID))
|
|
return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
|
|
}
|
|
|
|
func (c Capabilities) Verify(assignmentID, token string) bool {
|
|
want := c.Issue(assignmentID)
|
|
if want == "" || token == "" {
|
|
return false
|
|
}
|
|
return hmac.Equal([]byte(want), []byte(token))
|
|
}
|