p2p-llm / auth /service.go
arpinfidel's picture
temp
48511d8
package auth
import (
"crypto/rsa"
"errors"
"time"
"github.com/arpinfidel/p2p-llm/db"
"github.com/golang-jwt/jwt"
"golang.org/x/crypto/bcrypt"
)
type AuthService struct {
keys *rsa.PrivateKey
authRepo db.APIKeyRepository
}
func NewAuthService(privateKey *rsa.PrivateKey, authRepo db.APIKeyRepository) *AuthService {
return &AuthService{
keys: privateKey,
authRepo: authRepo,
}
}
func (s *AuthService) HashAPIKey(apiKey string) (string, error) {
hash, err := bcrypt.GenerateFromPassword([]byte(apiKey), bcrypt.DefaultCost)
if err != nil {
return "", err
}
return string(hash), nil
}
func (s *AuthService) VerifyAPIKey(apiKey, hash string) bool {
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(apiKey))
return err == nil
}
func (s *AuthService) GenerateJWT() (string, error) {
token := jwt.New(jwt.SigningMethodRS256)
claims := token.Claims.(jwt.MapClaims)
claims["exp"] = time.Now().Add(time.Hour * 24).Unix() // Token expires in 24 hours
claims["iat"] = time.Now().Unix()
tokenString, err := token.SignedString(s.keys)
if err != nil {
return "", err
}
return tokenString, nil
}
func (s *AuthService) Authenticate(apiKey string) (string, error) {
hash, err := s.authRepo.GetActiveKeyHash()
if err != nil {
return "", err
}
if !s.VerifyAPIKey(apiKey, hash) {
return "", ErrInvalidAPIKey
}
return s.GenerateJWT()
}
var (
ErrInvalidAPIKey = errors.New("invalid API key")
)