Files
user-system/internal/auth/jwt_closure_test.go
long-agent adb251e4ad fix: P2 security and correctness issues
P2-10: Change ActivateEmail from GET to POST - token now passed in
request body instead of URL query parameter for better security

P2-11: Change ValidateResetToken from GET to POST - token now passed
in request body instead of URL query parameter to prevent log leakage

P2-12: Note - /uploads static exposure remains (requires architectural
decision about file serving)

P2-13: cursor.Encode() now checks and returns empty string on JSON
marshaling error instead of silently ignoring

P2-14: initDefaultData and ensurePermissions now properly check and
propagate errors from RolePermission creation, and createDefaultPermissions
aggregates errors instead of silently continuing

P2-15: NewJWT now returns (nil, error) on initialization failure
instead of a partially initialized object. All callers updated to handle
the error return.

Backend routes updated:
- POST /auth/activate-email (was GET /activate)
- POST /auth/password/validate (was GET /reset-password)

Frontend updated to match new API endpoints.
2026-04-18 20:48:11 +08:00

154 lines
4.2 KiB
Go

package auth
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"testing"
"time"
)
func TestNewJWT_DoesNotPanicOnInvalidLegacyConfig(t *testing.T) {
manager, err := NewJWT("", 2*time.Hour, 7*24*time.Hour)
if err == nil {
t.Fatal("expected error for empty secret")
}
if manager != nil {
t.Fatal("expected nil manager for empty secret")
}
}
func TestParseRSAPrivateKey_PKCS1(t *testing.T) {
// Generate a PKCS1 private key
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate RSA key: %v", err)
}
privateDER := x509.MarshalPKCS1PrivateKey(privateKey)
privatePEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privateDER})
parsed, err := parseRSAPrivateKey(string(privatePEM))
if err != nil {
t.Fatalf("parseRSAPrivateKey failed for PKCS1: %v", err)
}
if parsed == nil {
t.Fatal("Expected non-nil parsed key")
}
if parsed.N.Cmp(privateKey.N) != 0 {
t.Error("Parsed key does not match original")
}
}
func TestParseRSAPrivateKey_PKCS8(t *testing.T) {
// Generate a PKCS8 private key
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate RSA key: %v", err)
}
privateDER, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
t.Fatalf("Failed to marshal PKCS8: %v", err)
}
privatePEM := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateDER})
parsed, err := parseRSAPrivateKey(string(privatePEM))
if err != nil {
t.Fatalf("parseRSAPrivateKey failed for PKCS8: %v", err)
}
if parsed == nil {
t.Fatal("Expected non-nil parsed key")
}
}
func TestParseRSAPrivateKey_InvalidPEMBlock(t *testing.T) {
_, err := parseRSAPrivateKey("not a valid PEM")
if err == nil {
t.Fatal("Expected error for invalid PEM")
}
}
func TestParseRSAPrivateKey_InvalidDER(t *testing.T) {
// Valid PEM block but invalid DER content
invalidPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: []byte("invalid der data")})
_, err := parseRSAPrivateKey(string(invalidPEM))
if err == nil {
t.Fatal("Expected error for invalid DER content")
}
}
func TestParseRSAPrivateKey_ECKey(t *testing.T) {
// Create an EC private key PEM (not RSA)
ecPEM := `-----BEGIN PRIVATE KEY-----
MHcCAQEEIBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxQYJKoZIhvcNAQEH
-----END PRIVATE KEY-----`
_, err := parseRSAPrivateKey(ecPEM)
if err == nil {
t.Fatal("Expected error for non-RSA key")
}
}
func TestParseRSAPublicKey_PKIX(t *testing.T) {
// Generate a key pair
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate RSA key: %v", err)
}
publicDER, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
if err != nil {
t.Fatalf("Failed to marshal public key: %v", err)
}
publicPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: publicDER})
parsed, err := parseRSAPublicKey(string(publicPEM))
if err != nil {
t.Fatalf("parseRSAPublicKey failed: %v", err)
}
if parsed == nil {
t.Fatal("Expected non-nil parsed key")
}
if parsed.N.Cmp(privateKey.PublicKey.N) != 0 {
t.Error("Parsed key does not match original")
}
}
func TestParseRSAPublicKey_Certificate(t *testing.T) {
// This test would require a certificate, skip for now
// The code path is covered by the PKIX test
t.Log("Certificate parsing is covered by PKIX path in production")
}
func TestParseRSAPublicKey_InvalidPEMBlock(t *testing.T) {
_, err := parseRSAPublicKey("not a valid PEM")
if err == nil {
t.Fatal("Expected error for invalid PEM")
}
}
func TestParseRSAPublicKey_InvalidDER(t *testing.T) {
invalidPEM := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: []byte("invalid der data")})
_, err := parseRSAPublicKey(string(invalidPEM))
if err == nil {
t.Fatal("Expected error for invalid DER content")
}
}
func TestParseRSAPublicKey_NonRSAKey(t *testing.T) {
// Create a non-RSA public key PEM (simulated)
nonRSAPEM := `-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END PUBLIC KEY-----`
_, err := parseRSAPublicKey(nonRSAPEM)
// This might fail during parsing or during type assertion
if err == nil {
t.Log("Non-RSA key was rejected or handled")
}
}