Files
autoglue/internal/auth/validate_keys.go
2025-11-02 13:19:30 +00:00

89 lines
2.2 KiB
Go

package auth
import (
"time"
"github.com/glueops/autoglue/internal/models"
"gorm.io/gorm"
)
// ValidateAPIKey validates a single-token user API key sent via X-API-KEY.
func ValidateAPIKey(rawKey string, db *gorm.DB) *models.User {
if rawKey == "" {
return nil
}
digest := SHA256Hex(rawKey)
var k models.APIKey
if err := db.
Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "user", time.Now()).
First(&k).Error; err != nil {
return nil
}
if k.UserID == nil {
return nil
}
var u models.User
if err := db.First(&u, "id = ? AND is_disabled = false", *k.UserID).Error; err != nil {
return nil
}
// Optional: touch last_used_at here if you've added it on the model.
return &u
}
// ValidateAppKeyPair validates a user key/secret pair via X-APP-KEY / X-APP-SECRET.
func ValidateAppKeyPair(appKey, secret string, db *gorm.DB) *models.User {
if appKey == "" || secret == "" {
return nil
}
digest := SHA256Hex(appKey)
var k models.APIKey
if err := db.
Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "user", time.Now()).
First(&k).Error; err != nil {
return nil
}
ok, _ := VerifySecretArgon2id(zeroIfNil(k.SecretHash), secret)
if !ok || k.UserID == nil {
return nil
}
var u models.User
if err := db.First(&u, "id = ? AND is_disabled = false", *k.UserID).Error; err != nil {
return nil
}
return &u
}
// ValidateOrgKeyPair validates an org key/secret via X-ORG-KEY / X-ORG-SECRET.
func ValidateOrgKeyPair(orgKey, secret string, db *gorm.DB) *models.Organization {
if orgKey == "" || secret == "" {
return nil
}
digest := SHA256Hex(orgKey)
var k models.APIKey
if err := db.
Where("key_hash = ? AND scope = ? AND (expires_at IS NULL OR expires_at > ?)", digest, "org", time.Now()).
First(&k).Error; err != nil {
return nil
}
ok, _ := VerifySecretArgon2id(zeroIfNil(k.SecretHash), secret)
if !ok || k.OrgID == nil {
return nil
}
var o models.Organization
if err := db.First(&o, "id = ?", *k.OrgID).Error; err != nil {
return nil
}
return &o
}
// local helper; avoids nil-deref when comparing secrets
func zeroIfNil(s *string) string {
if s == nil {
return ""
}
return *s
}