summaryrefslogtreecommitdiffstats
path: root/services/actions/auth.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--services/actions/auth.go102
1 files changed, 102 insertions, 0 deletions
diff --git a/services/actions/auth.go b/services/actions/auth.go
new file mode 100644
index 0000000..8e934d8
--- /dev/null
+++ b/services/actions/auth.go
@@ -0,0 +1,102 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/setting"
+
+ "github.com/golang-jwt/jwt/v5"
+)
+
+type actionsClaims struct {
+ jwt.RegisteredClaims
+ Scp string `json:"scp"`
+ TaskID int64
+ RunID int64
+ JobID int64
+ Ac string `json:"ac"`
+}
+
+type actionsCacheScope struct {
+ Scope string
+ Permission actionsCachePermission
+}
+
+type actionsCachePermission int
+
+const (
+ actionsCachePermissionRead = 1 << iota
+ actionsCachePermissionWrite
+)
+
+func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) {
+ now := time.Now()
+
+ ac, err := json.Marshal(&[]actionsCacheScope{
+ {
+ Scope: "",
+ Permission: actionsCachePermissionWrite,
+ },
+ })
+ if err != nil {
+ return "", err
+ }
+
+ claims := actionsClaims{
+ RegisteredClaims: jwt.RegisteredClaims{
+ ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)),
+ NotBefore: jwt.NewNumericDate(now),
+ },
+ Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID),
+ Ac: string(ac),
+ TaskID: taskID,
+ RunID: runID,
+ JobID: jobID,
+ }
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+
+ tokenString, err := token.SignedString(setting.GetGeneralTokenSigningSecret())
+ if err != nil {
+ return "", err
+ }
+
+ return tokenString, nil
+}
+
+func ParseAuthorizationToken(req *http.Request) (int64, error) {
+ h := req.Header.Get("Authorization")
+ if h == "" {
+ return 0, nil
+ }
+
+ parts := strings.SplitN(h, " ", 2)
+ if len(parts) != 2 {
+ log.Error("split token failed: %s", h)
+ return 0, fmt.Errorf("split token failed")
+ }
+
+ token, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) {
+ if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
+ return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
+ }
+ return setting.GetGeneralTokenSigningSecret(), nil
+ })
+ if err != nil {
+ return 0, err
+ }
+
+ c, ok := token.Claims.(*actionsClaims)
+ if !token.Valid || !ok {
+ return 0, fmt.Errorf("invalid token claim")
+ }
+
+ return c.TaskID, nil
+}