gitea源码

token.go 3.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package oauth2_provider
  4. import (
  5. "errors"
  6. "fmt"
  7. "time"
  8. "code.gitea.io/gitea/modules/timeutil"
  9. "github.com/golang-jwt/jwt/v5"
  10. )
  11. // Token represents an Oauth grant
  12. // TokenKind represents the type of token for an oauth application
  13. type TokenKind int
  14. const (
  15. // KindAccessToken is a token with short lifetime to access the api
  16. KindAccessToken TokenKind = 0
  17. // KindRefreshToken is token with long lifetime to refresh access tokens obtained by the client
  18. KindRefreshToken = iota
  19. )
  20. // Token represents a JWT token used to authenticate a client
  21. type Token struct {
  22. GrantID int64 `json:"gnt"`
  23. Kind TokenKind `json:"tt"`
  24. Counter int64 `json:"cnt,omitempty"`
  25. jwt.RegisteredClaims
  26. }
  27. // ParseToken parses a signed jwt string
  28. func ParseToken(jwtToken string, signingKey JWTSigningKey) (*Token, error) {
  29. parsedToken, err := jwt.ParseWithClaims(jwtToken, &Token{}, func(token *jwt.Token) (any, error) {
  30. if token.Method == nil || token.Method.Alg() != signingKey.SigningMethod().Alg() {
  31. return nil, fmt.Errorf("unexpected signing algo: %v", token.Header["alg"])
  32. }
  33. return signingKey.VerifyKey(), nil
  34. })
  35. if err != nil {
  36. return nil, err
  37. }
  38. if !parsedToken.Valid {
  39. return nil, errors.New("invalid token")
  40. }
  41. var token *Token
  42. var ok bool
  43. if token, ok = parsedToken.Claims.(*Token); !ok || !parsedToken.Valid {
  44. return nil, errors.New("invalid token")
  45. }
  46. return token, nil
  47. }
  48. // SignToken signs the token with the JWT secret
  49. func (token *Token) SignToken(signingKey JWTSigningKey) (string, error) {
  50. token.IssuedAt = jwt.NewNumericDate(time.Now())
  51. jwtToken := jwt.NewWithClaims(signingKey.SigningMethod(), token)
  52. signingKey.PreProcessToken(jwtToken)
  53. return jwtToken.SignedString(signingKey.SignKey())
  54. }
  55. // OIDCToken represents an OpenID Connect id_token
  56. type OIDCToken struct {
  57. jwt.RegisteredClaims
  58. Nonce string `json:"nonce,omitempty"`
  59. // Scope profile
  60. Name string `json:"name,omitempty"`
  61. PreferredUsername string `json:"preferred_username,omitempty"`
  62. Profile string `json:"profile,omitempty"`
  63. Picture string `json:"picture,omitempty"`
  64. Website string `json:"website,omitempty"`
  65. Locale string `json:"locale,omitempty"`
  66. UpdatedAt timeutil.TimeStamp `json:"updated_at,omitempty"`
  67. // Scope email
  68. Email string `json:"email,omitempty"`
  69. EmailVerified bool `json:"email_verified,omitempty"`
  70. // Groups are generated by organization and team names
  71. Groups []string `json:"groups,omitempty"`
  72. }
  73. // SignToken signs an id_token with the (symmetric) client secret key
  74. func (token *OIDCToken) SignToken(signingKey JWTSigningKey) (string, error) {
  75. token.IssuedAt = jwt.NewNumericDate(time.Now())
  76. jwtToken := jwt.NewWithClaims(signingKey.SigningMethod(), token)
  77. signingKey.PreProcessToken(jwtToken)
  78. return jwtToken.SignedString(signingKey.SignKey())
  79. }