github.com/nektos/act@v0.2.63/pkg/common/auth.go (about) 1 // Copyright 2024 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package common 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net/http" 10 "strings" 11 "time" 12 13 "github.com/golang-jwt/jwt/v5" 14 log "github.com/sirupsen/logrus" 15 ) 16 17 type actionsClaims struct { 18 jwt.RegisteredClaims 19 Scp string `json:"scp"` 20 TaskID int64 21 RunID int64 22 JobID int64 23 Ac string `json:"ac"` 24 } 25 26 type actionsCacheScope struct { 27 Scope string 28 Permission actionsCachePermission 29 } 30 31 type actionsCachePermission int 32 33 const ( 34 actionsCachePermissionRead = 1 << iota 35 actionsCachePermissionWrite 36 ) 37 38 func CreateAuthorizationToken(taskID, runID, jobID int64) (string, error) { 39 now := time.Now() 40 41 ac, err := json.Marshal(&[]actionsCacheScope{ 42 { 43 Scope: "", 44 Permission: actionsCachePermissionWrite, 45 }, 46 }) 47 if err != nil { 48 return "", err 49 } 50 51 claims := actionsClaims{ 52 RegisteredClaims: jwt.RegisteredClaims{ 53 ExpiresAt: jwt.NewNumericDate(now.Add(24 * time.Hour)), 54 NotBefore: jwt.NewNumericDate(now), 55 }, 56 Scp: fmt.Sprintf("Actions.Results:%d:%d", runID, jobID), 57 TaskID: taskID, 58 RunID: runID, 59 JobID: jobID, 60 Ac: string(ac), 61 } 62 token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) 63 64 tokenString, err := token.SignedString([]byte{}) 65 if err != nil { 66 return "", err 67 } 68 69 return tokenString, nil 70 } 71 72 func ParseAuthorizationToken(req *http.Request) (int64, error) { 73 h := req.Header.Get("Authorization") 74 if h == "" { 75 return 0, nil 76 } 77 78 parts := strings.SplitN(h, " ", 2) 79 if len(parts) != 2 { 80 log.Errorf("split token failed: %s", h) 81 return 0, fmt.Errorf("split token failed") 82 } 83 84 token, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) { 85 if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok { 86 return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"]) 87 } 88 return []byte{}, nil 89 }) 90 if err != nil { 91 return 0, err 92 } 93 94 c, ok := token.Claims.(*actionsClaims) 95 if !token.Valid || !ok { 96 return 0, fmt.Errorf("invalid token claim") 97 } 98 99 return c.TaskID, nil 100 }