mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-08-19 11:26:25 +00:00
80 lines
2.3 KiB
Go
80 lines
2.3 KiB
Go
package apikey
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/italypaleale/francis/host/local"
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/pocket-id/pocket-id/backend/internal/appconfig"
|
|
"github.com/pocket-id/pocket-id/backend/internal/httpserver"
|
|
"github.com/pocket-id/pocket-id/backend/internal/model"
|
|
)
|
|
|
|
type Dependencies struct {
|
|
DB *gorm.DB
|
|
Actors *local.Host
|
|
StaticApiKey string
|
|
AppConfig appconfig.AppConfigResolver
|
|
EmailSender APIKeyExpiryEmailSender
|
|
CleanupDisabled bool
|
|
}
|
|
|
|
type Module struct {
|
|
service *Service
|
|
handler *handler
|
|
}
|
|
|
|
func New(ctx context.Context, deps Dependencies) (*Module, error) {
|
|
service, err := newService(ctx, deps.DB, deps.StaticApiKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
module := &Module{
|
|
service: service,
|
|
handler: newHandler(service),
|
|
}
|
|
|
|
// Register the cleanup job for expired API keys
|
|
if !deps.CleanupDisabled {
|
|
if deps.Actors == nil {
|
|
return nil, errors.New("actor host is required for the API key expiration cron job")
|
|
}
|
|
if deps.AppConfig == nil || deps.EmailSender == nil {
|
|
return nil, errors.New("notification dependencies are required for the API key expiration cron job")
|
|
}
|
|
|
|
expiryJob, err := newExpiryJob(service, deps.AppConfig, deps.EmailSender)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = deps.Actors.RegisterBuiltInActor(expiryJob)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error registering API key expiration cron actor: %w", err)
|
|
}
|
|
}
|
|
|
|
return module, nil
|
|
}
|
|
|
|
// RegisterRoutes mounts the API key management endpoints
|
|
// authWithoutApiKey disables API key authentication so an API key cannot be used to mint or renew further API keys
|
|
func (m *Module) RegisterRoutes(apiGroup *gin.RouterGroup, auth, authWithoutApiKey gin.HandlerFunc) {
|
|
group := apiGroup.Group("/api-keys")
|
|
group.GET("", auth, httpserver.Handle(m.handler.list))
|
|
group.POST("", authWithoutApiKey, httpserver.Handle(m.handler.create))
|
|
group.POST("/:id/renew", authWithoutApiKey, httpserver.Handle(m.handler.renew))
|
|
group.DELETE("/:id", auth, httpserver.Handle(m.handler.revoke))
|
|
}
|
|
|
|
// ValidateApiKey resolves the user that owns the given raw API key
|
|
// It is used by the authentication middleware
|
|
func (m *Module) ValidateApiKey(ctx context.Context, apiKey string) (model.User, error) {
|
|
return m.service.ValidateApiKey(ctx, apiKey)
|
|
}
|