mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-25 14:35:40 +00:00
320ab7ed7f
This commit allows the `forgejo-cli actions register` command to change an existing runner's secret, as discussed in #4610. It refactors `RegisterRunner` to extract the code that hashes the token, moving this code to a method called `UpdateSecret` on `ActionRunner`. A test for the method has been added. The `RegisterRunner` function is updated so that: - it relies on `ActionRunner.UpdateSecret` when creating new runners, - it checks whether an existing runner's secret still matches the one passed on the command line, - it updates the runner's secret if it wasn't created and it no longer matches. A test has been added for the new behaviour.
85 lines
2 KiB
Go
85 lines
2 KiB
Go
// SPDX-License-Identifier: MIT
|
|
|
|
package actions
|
|
|
|
import (
|
|
"context"
|
|
"crypto/subtle"
|
|
"fmt"
|
|
|
|
auth_model "code.gitea.io/gitea/models/auth"
|
|
"code.gitea.io/gitea/models/db"
|
|
"code.gitea.io/gitea/modules/util"
|
|
|
|
gouuid "github.com/google/uuid"
|
|
)
|
|
|
|
func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, labels *[]string, name, version string) (*ActionRunner, error) {
|
|
uuid, err := gouuid.FromBytes([]byte(token[:16]))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("gouuid.FromBytes %v", err)
|
|
}
|
|
uuidString := uuid.String()
|
|
|
|
var runner ActionRunner
|
|
|
|
has, err := db.GetEngine(ctx).Where("uuid=?", uuidString).Get(&runner)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("GetRunner %v", err)
|
|
}
|
|
|
|
var mustUpdateSecret bool
|
|
if has {
|
|
//
|
|
// The runner exists, check if the rest of the token has changed.
|
|
//
|
|
mustUpdateSecret = subtle.ConstantTimeCompare(
|
|
[]byte(runner.TokenHash),
|
|
[]byte(auth_model.HashToken(token, runner.TokenSalt)),
|
|
) != 1
|
|
} else {
|
|
//
|
|
// The runner does not exist yet, create it
|
|
//
|
|
runner = ActionRunner{
|
|
UUID: uuidString,
|
|
AgentLabels: []string{},
|
|
}
|
|
|
|
if err := runner.UpdateSecret(token); err != nil {
|
|
return &runner, fmt.Errorf("can't set new runner's secret: %w", err)
|
|
}
|
|
|
|
if err := CreateRunner(ctx, &runner); err != nil {
|
|
return &runner, fmt.Errorf("can't create new runner %w", err)
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update the existing runner
|
|
//
|
|
name, _ = util.SplitStringAtByteN(name, 255)
|
|
|
|
cols := []string{"name", "owner_id", "repo_id", "version"}
|
|
runner.Name = name
|
|
runner.OwnerID = ownerID
|
|
runner.RepoID = repoID
|
|
runner.Version = version
|
|
if labels != nil {
|
|
runner.AgentLabels = *labels
|
|
cols = append(cols, "agent_labels")
|
|
}
|
|
if mustUpdateSecret {
|
|
if err := runner.UpdateSecret(token); err != nil {
|
|
return &runner, fmt.Errorf("can't change runner's secret: %w", err)
|
|
}
|
|
cols = append(cols, "token_hash", "token_salt")
|
|
}
|
|
|
|
if err := UpdateRunner(ctx, &runner, cols...); err != nil {
|
|
return &runner, fmt.Errorf("can't update the runner %+v %w", runner, err)
|
|
}
|
|
|
|
return &runner, nil
|
|
}
|