api

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 19, 2026 License: GPL-3.0 Imports: 34 Imported by: 0

Documentation

Overview

Package api provides the REST API handlers and server for Healarr. It includes endpoints for managing scans, corruptions, configurations, notifications, and real-time updates via WebSocket.

Index

Constants

View Source
const (
	ErrMsgDatabaseError       = "Database error"
	ErrMsgAuthenticationError = "Authentication error"
	ErrMsgInvalidRequest      = "Invalid request"
	ErrMsgNotFound            = "Not found"
	ErrMsgServiceUnavailable  = "Service unavailable"
	ErrMsgInternalError       = "Internal server error"
	ErrMsgScanNotFound        = "Scan not found"
	ErrMsgNoIDsProvided       = "No IDs provided"
	ErrMsgInvalidID           = "Invalid ID"
)

Standard error messages (don't leak internal details)

View Source
const RequestIDKey contextKey = "request_id"

RequestIDKey is the context key for storing the request ID.

Variables

View Source
var (
	// LoginLimiter: 5 attempts per minute, burst of 5
	// Protects against brute force login attempts
	LoginLimiter = NewRateLimiter(5, time.Minute, 5)

	// SetupLimiter: 3 attempts per minute, burst of 3
	// Setup should only happen once, strict limiting
	SetupLimiter = NewRateLimiter(3, time.Minute, 3)

	// WebhookLimiter: 60 requests per minute, burst of 30
	// Webhooks can be frequent but need some protection
	WebhookLimiter = NewRateLimiter(60, time.Minute, 30)

	// APILimiter: 120 requests per minute per IP, burst of 60
	// General API protection against abuse
	APILimiter = NewRateLimiter(120, time.Minute, 60)
)

Global rate limiters for different endpoints

Functions

func GetRequestID added in v1.2.0

func GetRequestID(ctx context.Context) string

GetRequestID extracts the request ID from a context. Returns an empty string if no request ID is set.

func SafeOrderByClause added in v1.1.18

func SafeOrderByClause(sortBy, sortOrder string, allowedColumns map[string]string, defaultColumn, defaultOrder string) string

SafeOrderByClause returns a SQL ORDER BY clause with validated column and direction. This function enforces validation at the point of use, making it clear to static analysis tools that the returned string is safe for SQL interpolation. The allowedColumns map contains the ONLY columns that can be used in the ORDER BY. If sortBy is not in allowedColumns, defaultColumn is used. If sortOrder is not "asc" or "desc", defaultOrder is used.

Types

type GitHubRelease added in v1.1.7

type GitHubRelease struct {
	TagName     string    `json:"tag_name"`
	Name        string    `json:"name"`
	Body        string    `json:"body"`
	HTMLURL     string    `json:"html_url"`
	PublishedAt time.Time `json:"published_at"`
	Assets      []struct {
		Name               string `json:"name"`
		BrowserDownloadURL string `json:"browser_download_url"`
	} `json:"assets"`
}

GitHubRelease represents the response from GitHub's releases API

type HealthNotifier added in v1.1.23

type HealthNotifier interface {
	SendSystemHealthDegraded(data map[string]interface{})
}

HealthNotifier defines the interface for health-related notifications. This allows for easier testing by enabling mock implementations.

type MountInfo added in v1.1.9

type MountInfo struct {
	Source      string `json:"source"`
	Destination string `json:"destination"`
	Type        string `json:"type,omitempty"`
	ReadOnly    bool   `json:"read_only"`
}

MountInfo contains information about a mounted volume

type PaginationConfig added in v1.1.0

type PaginationConfig struct {
	DefaultLimit     int
	MaxLimit         int
	DefaultSortBy    string
	DefaultSortOrder string
	AllowedSortBy    map[string]bool
}

PaginationConfig configures pagination parsing behavior

func DefaultPaginationConfig added in v1.1.0

func DefaultPaginationConfig() PaginationConfig

DefaultPaginationConfig returns a standard config for most endpoints. SECURITY NOTE: AllowedSortBy is nil, meaning no sort column validation is performed. This is ONLY safe when the query uses a FIXED ORDER BY clause (not p.SortBy). For dynamic sorting, always specify AllowedSortBy to prevent SQL injection.

type PaginationParams added in v1.1.0

type PaginationParams struct {
	Page      int
	Limit     int
	Offset    int
	SortBy    string
	SortOrder string
}

PaginationParams holds parsed pagination parameters

func ParsePagination added in v1.1.0

func ParsePagination(c *gin.Context, cfg PaginationConfig) PaginationParams

ParsePagination extracts and validates pagination parameters from a Gin context

type PaginationResponse added in v1.1.0

type PaginationResponse struct {
	Page       int `json:"page"`
	Limit      int `json:"limit"`
	Total      int `json:"total"`
	TotalPages int `json:"total_pages"`
}

PaginationResponse is the JSON response structure for paginated endpoints

func NewPaginationResponse added in v1.1.0

func NewPaginationResponse(p PaginationParams, total int) PaginationResponse

NewPaginationResponse creates a pagination response from params and total count

type PathHealth added in v1.1.30

type PathHealth struct {
	PathID            int     `json:"path_id"`
	LocalPath         string  `json:"local_path"`
	Enabled           bool    `json:"enabled"`
	LastScanTime      *string `json:"last_scan_time,omitempty"`
	LastScanID        *int    `json:"last_scan_id,omitempty"`
	ActiveCorruptions int     `json:"active_corruptions"` // Pending + in-progress + failed + manual
	TotalCorruptions  int     `json:"total_corruptions"`  // All-time for this path
	ResolvedCount     int     `json:"resolved_count"`
	Status            string  `json:"status"` // "healthy", "warning", "critical", "unknown"
}

PathHealth represents the health status of a configured scan path.

type RESTServer

type RESTServer struct {
	// contains filtered or unexported fields
}

RESTServer provides the HTTP REST API for Healarr.

func NewRESTServer

func NewRESTServer(deps ServerDeps) *RESTServer

NewRESTServer creates a new REST server with the provided dependencies.

func (*RESTServer) Shutdown

func (s *RESTServer) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the HTTP server and WebSocket hub

func (*RESTServer) Start

func (s *RESTServer) Start(addr string) error

Start begins listening for HTTP requests on the specified address.

type RateLimiter

type RateLimiter struct {
	// contains filtered or unexported fields
}

RateLimiter implements a token bucket rate limiter per IP address

func NewRateLimiter

func NewRateLimiter(rate int, interval time.Duration, burst int) *RateLimiter

NewRateLimiter creates a rate limiter with specified rate (requests per interval) and burst size

func (*RateLimiter) Allow

func (rl *RateLimiter) Allow(ip string) bool

Allow checks if a request from the given IP should be allowed

func (*RateLimiter) Middleware

func (rl *RateLimiter) Middleware() gin.HandlerFunc

Middleware returns a Gin middleware that rate limits requests

func (*RateLimiter) Shutdown added in v1.1.0

func (rl *RateLimiter) Shutdown()

Shutdown stops the rate limiter's cleanup goroutine

type ServerDeps added in v1.1.20

type ServerDeps struct {
	DB         *sql.DB
	EventBus   *eventbus.EventBus
	Scanner    services.Scanner
	PathMapper integration.PathMapper
	ArrClient  integration.ArrClient
	Scheduler  services.Scheduler
	Notifier   *notifier.Notifier
	Metrics    *metrics.MetricsService
}

ServerDeps contains all dependencies required for the REST server

type SetupStatus added in v1.1.20

type SetupStatus struct {
	NeedsSetup          bool `json:"needs_setup"`
	HasPassword         bool `json:"has_password"`
	HasAPIKey           bool `json:"has_api_key"`
	HasInstances        bool `json:"has_instances"`
	HasScanPaths        bool `json:"has_scan_paths"`
	OnboardingDismissed bool `json:"onboarding_dismissed"`
}

SetupStatus represents the current setup state of the application

type SystemConfigInfo added in v1.1.9

type SystemConfigInfo struct {
	Port                 string  `json:"port"`
	BasePath             string  `json:"base_path"`
	BasePathSource       string  `json:"base_path_source"`
	LogLevel             string  `json:"log_level"`
	DataDir              string  `json:"data_dir"`
	DatabasePath         string  `json:"database_path"`
	LogDir               string  `json:"log_dir"`
	DryRunMode           bool    `json:"dry_run_mode"`
	RetentionDays        int     `json:"retention_days"`
	DefaultMaxRetries    int     `json:"default_max_retries"`
	VerificationTimeout  string  `json:"verification_timeout"`
	VerificationInterval string  `json:"verification_interval"`
	ArrRateLimitRPS      float64 `json:"arr_rate_limit_rps"`
	ArrRateLimitBurst    int     `json:"arr_rate_limit_burst"`
}

SystemConfigInfo contains configuration details

type SystemInfo added in v1.1.9

type SystemInfo struct {
	Version     string                             `json:"version"`
	Environment string                             `json:"environment"` // "docker" or "native"
	OS          string                             `json:"os"`
	Arch        string                             `json:"arch"`
	GoVersion   string                             `json:"go_version"`
	Uptime      string                             `json:"uptime"`
	UptimeSecs  int64                              `json:"uptime_seconds"`
	StartedAt   time.Time                          `json:"started_at"`
	Config      SystemConfigInfo                   `json:"config"`
	Mounts      []MountInfo                        `json:"mounts,omitempty"`
	Tools       map[string]*integration.ToolStatus `json:"tools"`
	Links       SystemLinks                        `json:"links"`
}

SystemInfo contains runtime environment information

type SystemLinks struct {
	GitHub      string `json:"github"`
	Issues      string `json:"issues"`
	Releases    string `json:"releases"`
	Wiki        string `json:"wiki"`
	Discussions string `json:"discussions"`
}

SystemLinks contains useful links

type UpdateCheckResponse added in v1.1.7

type UpdateCheckResponse struct {
	CurrentVersion     string             `json:"current_version"`
	LatestVersion      string             `json:"latest_version"`
	UpdateAvailable    bool               `json:"update_available"`
	ReleaseURL         string             `json:"release_url"`
	Changelog          string             `json:"changelog"`
	PublishedAt        string             `json:"published_at"`
	DownloadURLs       map[string]string  `json:"download_urls"`
	DockerPullCmd      string             `json:"docker_pull_cmd"`
	UpdateInstructions UpdateInstructions `json:"update_instructions"`
}

UpdateCheckResponse is the response returned to the frontend

type UpdateInstructions added in v1.1.7

type UpdateInstructions struct {
	Docker  string `json:"docker"`
	Linux   string `json:"linux"`
	MacOS   string `json:"macos"`
	Windows string `json:"windows"`
}

UpdateInstructions provides platform-specific upgrade guidance

type WebSocketHub

type WebSocketHub struct {
	// contains filtered or unexported fields
}

WebSocketHub manages WebSocket connections and broadcasts events to connected clients.

func NewWebSocketHub

func NewWebSocketHub(eventBus *eventbus.EventBus, metricsService ...*metrics.MetricsService) *WebSocketHub

NewWebSocketHub creates a new WebSocketHub and subscribes to relevant events. The metrics service is optional and enables connection tracking metrics.

func (*WebSocketHub) ClientCount

func (h *WebSocketHub) ClientCount() int

ClientCount returns the number of connected WebSocket clients

func (*WebSocketHub) HandleConnection

func (h *WebSocketHub) HandleConnection(c *gin.Context)

HandleConnection upgrades an HTTP connection to WebSocket and manages its lifecycle.

func (*WebSocketHub) Shutdown added in v1.1.0

func (h *WebSocketHub) Shutdown()

Shutdown stops the WebSocket hub and closes all client connections

type WebhookRequest

type WebhookRequest struct {
	EventType string `json:"eventType"` // Download, Upgrade, etc.
	Series    struct {
		Path string `json:"path"`
	} `json:"series"`
	Movie struct {
		Path string `json:"path"`
	} `json:"movie"`
	EpisodeFile struct {
		Path string `json:"path"`
	} `json:"episodeFile"`
	MovieFile struct {
		Path string `json:"path"`
	} `json:"movieFile"`
}

WebhookRequest represents the payload from Sonarr/Radarr

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL