2024-02-18 21:37:17 +00:00
|
|
|
package jwt
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/rsa"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"code.tjo.space/mentos1386/zdravko/internal/config"
|
|
|
|
"github.com/golang-jwt/jwt/v5"
|
2024-02-18 22:11:42 +00:00
|
|
|
"github.com/pkg/errors"
|
2024-02-18 21:37:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func JwtPublicKeyID(key *rsa.PublicKey) string {
|
|
|
|
hash := sha256.Sum256(key.N.Bytes())
|
|
|
|
return hex.EncodeToString(hash[:])
|
|
|
|
}
|
|
|
|
|
|
|
|
func JwtPrivateKey(c *config.Config) (*rsa.PrivateKey, error) {
|
2024-02-18 22:11:42 +00:00
|
|
|
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(c.Jwt.PrivateKey))
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "failed to parse private key")
|
|
|
|
}
|
|
|
|
return key, nil
|
2024-02-18 21:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func JwtPublicKey(c *config.Config) (*rsa.PublicKey, error) {
|
2024-02-18 22:11:42 +00:00
|
|
|
key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(c.Jwt.PublicKey))
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "failed to parse public key")
|
|
|
|
}
|
|
|
|
return key, nil
|
2024-02-18 21:37:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ref: https://docs.temporal.io/self-hosted-guide/security#authorization
|
|
|
|
func NewToken(config *config.Config, permissions []string, subject string) (string, error) {
|
|
|
|
privateKey, err := JwtPrivateKey(config)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
publicKey, err := JwtPublicKey(config)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
type WorkerClaims struct {
|
|
|
|
jwt.RegisteredClaims
|
|
|
|
Permissions []string `json:"permissions"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create claims with multiple fields populated
|
|
|
|
claims := WorkerClaims{
|
|
|
|
jwt.RegisteredClaims{
|
|
|
|
ExpiresAt: jwt.NewNumericDate(time.Now().Add(12 * 30 * 24 * time.Hour)),
|
|
|
|
IssuedAt: jwt.NewNumericDate(time.Now()),
|
|
|
|
NotBefore: jwt.NewNumericDate(time.Now()),
|
|
|
|
Issuer: "zdravko",
|
|
|
|
Subject: subject,
|
|
|
|
},
|
|
|
|
permissions,
|
|
|
|
}
|
|
|
|
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
|
|
|
|
token.Header["kid"] = JwtPublicKeyID(publicKey)
|
|
|
|
|
|
|
|
signedToken, err := token.SignedString(privateKey)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return signedToken, nil
|
|
|
|
}
|