<commit_before>package jwthelper_test

import (
	"encoding/json"
	"log"

	"github.com/dgrijalva/jwt-go"
	"github.com/northbright/jwthelper"
)

func ExampleMultipleKeysSigner_SignedString() {
	// Example to show sign / parse JWT with multiple keys.

	// New a signer with RSA SHA-256 alg by given RSA private PEM key.
	s1 := jwthelper.NewRSASHASigner([]byte(rsaPrivPEM1))

	// New a signer with RSA SHA-512 alg by given RSA private PEM key.
	s2 := jwthelper.NewRSASHASigner([]byte(rsaPrivPEM1), jwthelper.SigningMethod(jwt.SigningMethodRS512))

	signer := jwthelper.NewMultipleKeysSigner()
	signer.Set("kid-for-api-1", s1)
	signer.Set("kid-for-vendor", s2)

	str, err := signer.SignedString(
		"kid-for-api-1",
		jwthelper.NewClaim("uid", "1"),
		jwthelper.NewClaim("count", 100),
	)

	if err != nil {
		log.Printf("SignedString() error: %v", err)
		return
	}
	log.Printf("SignedString() OK. str: %v", str)

	// New a parser.
	p1 := jwthelper.NewRSASHAParser([]byte(rsaPubPEM1))
	p2 := jwthelper.NewRSASHAParser([]byte(rsaPubPEM1))

	parser := jwthelper.NewMultipleKeysParser()
	parser.Set("kid-for-api-1", p1)
	parser.Set("kid-for-vendor", p2)

	mapClaims, err := parser.Parse(str)
	if err != nil {
		log.Printf("Parse() error: %v", err)
		return
	}

	uid, ok := mapClaims["uid"]
	if !ok {
		log.Printf("uid not found")
		return
	}

	if _, ok = uid.(string); !ok {
		log.Printf("uid is not string type")
		return
	}

	count, ok := mapClaims["count"]
	if !ok {
		log.Printf("count not found")
		return
	}

	// It'll parse number as json.Number type by default.
	// Call Number.Int64(), Number.Float64(), Number.String() according to your need.
	// See https://godoc.org/encoding/json#Number
	num, ok := count.(json.Number)
	if !ok {
		log.Printf("count is not json.Number type: %T", count)
		return
	}

	n, err := num.Int64()
	if err != nil {
		log.Printf("convert json.Number to int64 error: %v", err)
		return
	}

	log.Printf("Parse() OK. uid: %v, count: %v, mapClaims: %v", uid, n, mapClaims)

	// Output:
}

var rsaPrivPEM1 string = `
-----<KEY>

`

var rsaPubPEM1 string = `
-----<KEY>
-----END PUBLIC KEY-----
`<commit_msg>Implemented multiple keys signer / parser test case<commit_after>package jwthelper_test

import (
	"encoding/json"
	"log"

	"github.com/dgrijalva/jwt-go"
	"github.com/northbright/jwthelper"
)

func ExampleMultipleKeysSigner_SignedString() {
	// Example to show sign / parse JWT with multiple keys.

	// New a signer with RSA SHA-512 alg by given RSA private PEM key.
	s1 := jwthelper.NewRSASHASignerFromPEMFile("keys/rsa-priv-vendor.pem", jwthelper.SigningMethod(jwt.SigningMethodRS512))
	// New a signer with RSA SHA-256 alg by given RSA private PEM key.
	s2 := jwthelper.NewRSASHASignerFromPEMFile("keys/rsa-priv-api.pem")

	// New a multiple keys signer and set signers with "kid"(key id) which will be added to claims automatically.
	signer := jwthelper.NewMultipleKeysSigner()
	signer.Set("kid-vendor", s1)
	signer.Set("kid-api", s2)

	str, err := signer.SignedString(
		"kid-api",
		jwthelper.NewClaim("uid", "2"),
		jwthelper.NewClaim("count", 200),
	)

	if err != nil {
		log.Printf("SignedString() error: %v", err)
		return
	}
	log.Printf("SignedString() OK. str: %v", str)

	// New parsers from public PEM file.
	p1 := jwthelper.NewRSASHAParserFromPEMFile("keys/rsa-pub-vendor.pem")
	p2 := jwthelper.NewRSASHAParserFromPEMFile("keys/rsa-pub-api.pem")

	// New a multiple keys parser and set parsers with "kid".
	parser := jwthelper.NewMultipleKeysParser()
	parser.Set("kid-vendor", p1)
	parser.Set("kid-api", p2)

	tokenStrs := []string{str, tokenStrSignedByVendor}

	for _, tokenStr := range tokenStrs {
		mapClaims, err := parser.Parse(tokenStr)
		if err != nil {
			log.Printf("Parse() error: %v", err)
			return
		}

		uid, ok := mapClaims["uid"]
		if !ok {
			log.Printf("uid not found")
			return
		}

		if _, ok = uid.(string); !ok {
			log.Printf("uid is not string type")
			return
		}

		count, ok := mapClaims["count"]
		if !ok {
			log.Printf("count not found")
			return
		}

		// It'll parse number as json.Number type by default.
		// Call Number.Int64(), Number.Float64(), Number.String() according to your need.
		// See https://godoc.org/encoding/json#Number
		num, ok := count.(json.Number)
		if !ok {
			log.Printf("count is not json.Number type: %T", count)
			return
		}

		n, err := num.Int64()
		if err != nil {
			log.Printf("convert json.Number to int64 error: %v", err)
			return
		}

		log.Printf("Parse() OK. uid: %v, count: %v, mapClaims: %v", uid, n, mapClaims)
	}
	// Output:
}

var tokenStrSignedByVendor string = `<KEY>`
{'fraction_non_alphanumeric': 0.156794425087108, 'fraction_numerical': 0.014590592334494773, 'mean_word_length': 3.6915219611848826, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2824651', 'n_tokens_mistral': 1927, 'n_tokens_neox': 1756, 'n_words': 429}