snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
This commit is contained in:
95
internal/cli/checksubtoken.go
Normal file
95
internal/cli/checksubtoken.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package cli
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/centrifugal/centrifugo/v6/internal/config"
|
||||
"github.com/centrifugal/centrifugo/v6/internal/confighelpers"
|
||||
"github.com/centrifugal/centrifugo/v6/internal/jwtverify"
|
||||
|
||||
"github.com/cristalhq/jwt/v5"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func CheckSubToken() *cobra.Command {
|
||||
var checkSubTokenConfigFile string
|
||||
var checkSubTokenCmd = &cobra.Command{
|
||||
Use: "checksubtoken [TOKEN]",
|
||||
Short: "Check subscription JWT",
|
||||
Long: `Check subscription JWT`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
checkSubToken(cmd, checkSubTokenConfigFile, args)
|
||||
},
|
||||
}
|
||||
checkSubTokenCmd.Flags().StringVarP(&checkSubTokenConfigFile, "config", "c", "config.json", "path to config file")
|
||||
return checkSubTokenCmd
|
||||
}
|
||||
|
||||
func checkSubToken(cmd *cobra.Command, checkSubTokenConfigFile string, args []string) {
|
||||
cfg, _, err := config.GetConfig(cmd, checkSubTokenConfigFile)
|
||||
if err != nil {
|
||||
fmt.Printf("error getting config: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
verifierConfig, err := confighelpers.MakeVerifierConfig(cfg.Client.Token)
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if cfg.Client.SubscriptionToken.Enabled {
|
||||
verifierConfig, err = confighelpers.MakeVerifierConfig(cfg.Client.SubscriptionToken.Token)
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
if len(args) != 1 {
|
||||
fmt.Printf("error: provide token to check [centrifugo checksubtoken <TOKEN>]\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
subject, channel, claims, err := parseAndVerifySubToken(verifierConfig, cfg, args[0])
|
||||
if err != nil {
|
||||
fmt.Printf("error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
var user = fmt.Sprintf("user \"%s\"", subject)
|
||||
if subject == "" {
|
||||
user = "anonymous user"
|
||||
}
|
||||
fmt.Printf("valid subscription token for %s and channel \"%s\"\npayload: %s\n", user, channel, string(claims))
|
||||
}
|
||||
|
||||
// parseAndVerifySubToken checks subscription JWT for user.
|
||||
func parseAndVerifySubToken(config jwtverify.VerifierConfig, cfg config.Config, t string) (string, string, []byte, error) {
|
||||
token, err := jwt.ParseNoVerify([]byte(t)) // Will be verified later.
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
var claims jwtverify.SubscribeTokenClaims
|
||||
err = json.Unmarshal(token.Claims(), &claims)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
|
||||
ct, err := verifySub(config, cfg, t)
|
||||
if err != nil {
|
||||
return "", "", nil, fmt.Errorf("token with algorithm %s and claims %s has error: %v", token.Header().Algorithm, string(token.Claims()), err)
|
||||
}
|
||||
|
||||
return ct.UserID, ct.Channel, token.Claims(), nil
|
||||
}
|
||||
|
||||
func verifySub(verifierConf jwtverify.VerifierConfig, cfg config.Config, token string) (jwtverify.SubscribeToken, error) {
|
||||
cfgContainer, err := config.NewContainer(cfg)
|
||||
if err != nil {
|
||||
return jwtverify.SubscribeToken{}, err
|
||||
}
|
||||
verifier, err := jwtverify.NewTokenVerifierJWT(verifierConf, cfgContainer)
|
||||
if err != nil {
|
||||
return jwtverify.SubscribeToken{}, err
|
||||
}
|
||||
return verifier.VerifySubscribeToken(token, false)
|
||||
}
|
||||
Reference in New Issue
Block a user