gitea源码

auth.go 2.3KB

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