feat: integration v2 and API key PART 1/3

This commit is contained in:
fsylvain committed 2026-10-04 21:56:14 +02:00
1 parent 7e9bd9ba30
commit 844842fdae
40 files changed
+3782 -64

No files matched your search

@@ -0,0 +1,34 @@
package mappers
import (
"RenewCMS/internal/domain/apikey"
"RenewCMS/internal/infrastructure/persistence/models"
)
func APIKeyToDomain(m models.APIKey) apikey.APIKey {
return apikey.APIKey{
ID: m.ID,
UserID: m.UserID,
Name: m.Name,
Prefix: m.Prefix,
HashedKey: m.HashedKey,
ExpiresAt: m.ExpiresAt,
RevokedAt: m.RevokedAt,
LastUsedAt: m.LastUsedAt,
CreatedAt: m.CreatedAt,
}
}
func APIKeyToModel(k apikey.APIKey) models.APIKey {
return models.APIKey{
ID: k.ID,
UserID: k.UserID,
Name: k.Name,
Prefix: k.Prefix,
HashedKey: k.HashedKey,
ExpiresAt: k.ExpiresAt,
RevokedAt: k.RevokedAt,
LastUsedAt: k.LastUsedAt,
CreatedAt: k.CreatedAt,
}
}
@@ -0,0 +1,15 @@
package models
import "time"
type APIKey struct {
ID uint32 `gorm:"primaryKey;autoIncrement"`
UserID uint32 `gorm:"index;not null"`
Name string `gorm:"not null"`
Prefix string `gorm:"not null"`
HashedKey string `gorm:"uniqueIndex;not null"`
ExpiresAt *time.Time
RevokedAt *time.Time
LastUsedAt *time.Time
CreatedAt time.Time `gorm:"autoCreateTime"`
}
@@ -0,0 +1,85 @@
package persistence
import (
domainAPIKey "RenewCMS/internal/domain/apikey"
"RenewCMS/internal/infrastructure/persistence/mappers"
entity "RenewCMS/internal/infrastructure/persistence/models"
"time"
"gorm.io/gorm"
)
type APIKeyRepository struct {
db *gorm.DB
}
func NewAPIKeyRepository(db *gorm.DB) *APIKeyRepository {
return &APIKeyRepository{db}
}
func (a *APIKeyRepository) Create(key domainAPIKey.APIKey) (domainAPIKey.APIKey, error) {
model := mappers.APIKeyToModel(key)
model.ID = 0
if err := a.db.Create(&model).Error; err != nil {
return domainAPIKey.APIKey{}, err
}
return mappers.APIKeyToDomain(model), nil
}
func (a *APIKeyRepository) Get(id uint32) (domainAPIKey.APIKey, error) {
var model entity.APIKey
if err := a.db.First(&model, id).Error; err != nil {
return domainAPIKey.APIKey{}, mapNotFoundErr(err, domainAPIKey.ErrAPIKeyNotFound)
}
return mappers.APIKeyToDomain(model), nil
}
func (a *APIKeyRepository) GetByHashedKey(hashedKey string) (domainAPIKey.APIKey, error) {
var model entity.APIKey
if err := a.db.Where("hashed_key = ?", hashedKey).First(&model).Error; err != nil {
return domainAPIKey.APIKey{}, mapNotFoundErr(err, domainAPIKey.ErrAPIKeyNotFound)
}
return mappers.APIKeyToDomain(model), nil
}
func (a *APIKeyRepository) ListByUser(userId uint32) ([]domainAPIKey.APIKey, error) {
return a.list(a.db.Where("user_id = ?", userId))
}
func (a *APIKeyRepository) ListAll() ([]domainAPIKey.APIKey, error) {
return a.list(a.db)
}
func (a *APIKeyRepository) list(query *gorm.DB) ([]domainAPIKey.APIKey, error) {
var found []entity.APIKey
if err := query.Order("created_at DESC, id DESC").Find(&found).Error; err != nil {
return nil, err
}
keys := make([]domainAPIKey.APIKey, 0, len(found))
for _, model := range found {
keys = append(keys, mappers.APIKeyToDomain(model))
}
return keys, nil
}
func (a *APIKeyRepository) Revoke(id uint32, at time.Time) error {
result := a.db.Model(&entity.APIKey{}).
Where("id = ? AND revoked_at IS NULL", id).
Update("revoked_at", at)
return result.Error
}
func (a *APIKeyRepository) RevokeAllByUser(userId uint32, at time.Time) error {
return a.db.Model(&entity.APIKey{}).
Where("user_id = ? AND revoked_at IS NULL", userId).
Update("revoked_at", at).Error
}
func (a *APIKeyRepository) TouchLastUsed(id uint32, at time.Time) error {
return a.db.Model(&entity.APIKey{}).
Where("id = ?", id).
Update("last_used_at", at).Error
}
var _ domainAPIKey.Repository = &APIKeyRepository{}