Initial commit
This commit is contained in:
83
pkg/auth/validator.go
Normal file
83
pkg/auth/validator.go
Normal file
@@ -0,0 +1,83 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
pkgjwt "github.com/openware/pkg/jwt"
|
||||
)
|
||||
|
||||
const (
|
||||
ValidatorRSA = "rsa"
|
||||
ValidatorEdDSA = "eddsa"
|
||||
)
|
||||
|
||||
// Validator verifies Barong JWT tokens using RS256 or EdDSA depending on configured key material.
|
||||
type Validator struct {
|
||||
Mode string
|
||||
RSA *rsa.PublicKey
|
||||
EdDSA ed25519.PublicKey
|
||||
}
|
||||
|
||||
type Claims struct {
|
||||
UID string
|
||||
Role string
|
||||
}
|
||||
|
||||
// LoadValidator reads JWT_PUBLIC_KEY (base64 PEM) or -pubKey file path.
|
||||
// OpenDAX / Barong 2.6 uses RS256; upstream Rango 3.1.2+ defaults to EdDSA.
|
||||
func LoadValidator(pubKeyPath string) (Validator, error) {
|
||||
if encPem := os.Getenv("JWT_PUBLIC_KEY"); encPem != "" {
|
||||
rsaStore := KeyStore{}
|
||||
if err := rsaStore.LoadPublicKeyFromString(encPem); err == nil && rsaStore.PublicKey != nil {
|
||||
return Validator{Mode: ValidatorRSA, RSA: rsaStore.PublicKey}, nil
|
||||
}
|
||||
|
||||
edStore := pkgjwt.KeyStoreEdDSA{}
|
||||
if err := edStore.LoadPublicKeyFromString(encPem); err == nil && edStore.PublicKey != nil {
|
||||
return Validator{Mode: ValidatorEdDSA, EdDSA: edStore.PublicKey}, nil
|
||||
}
|
||||
|
||||
return Validator{}, fmt.Errorf("JWT_PUBLIC_KEY is neither a valid RSA nor EdDSA public key")
|
||||
}
|
||||
|
||||
rsaStore := KeyStore{}
|
||||
if err := rsaStore.LoadPublicKeyFromFile("config/rsa-key.pub"); err == nil && rsaStore.PublicKey != nil {
|
||||
return Validator{Mode: ValidatorRSA, RSA: rsaStore.PublicKey}, nil
|
||||
}
|
||||
|
||||
edStore := pkgjwt.KeyStoreEdDSA{}
|
||||
if err := edStore.LoadPublicKeyFromFile(pubKeyPath); err != nil {
|
||||
return Validator{}, fmt.Errorf("load public key from %q: %w", pubKeyPath, err)
|
||||
}
|
||||
if edStore.PublicKey == nil {
|
||||
return Validator{}, fmt.Errorf("public key not loaded from %q", pubKeyPath)
|
||||
}
|
||||
|
||||
return Validator{Mode: ValidatorEdDSA, EdDSA: edStore.PublicKey}, nil
|
||||
}
|
||||
|
||||
func (v Validator) ParseAndValidate(token string) (Claims, error) {
|
||||
if token == "" {
|
||||
return Claims{}, fmt.Errorf("missing token")
|
||||
}
|
||||
|
||||
switch v.Mode {
|
||||
case ValidatorRSA:
|
||||
auth, err := ParseAndValidate(token, v.RSA)
|
||||
if err != nil {
|
||||
return Claims{}, err
|
||||
}
|
||||
return Claims{UID: auth.UID, Role: auth.Role}, nil
|
||||
case ValidatorEdDSA:
|
||||
auth, err := pkgjwt.ParseAndValidateEdDSA(token, v.EdDSA)
|
||||
if err != nil {
|
||||
return Claims{}, err
|
||||
}
|
||||
return Claims{UID: auth.UID, Role: auth.Role}, nil
|
||||
default:
|
||||
return Claims{}, fmt.Errorf("unknown validator mode %q", v.Mode)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user