Remove runtime nil checks for always-initialized components

Since signing_key is now required at config load time, sessMgr, encGen,
and signer are always initialized. Remove unnecessary nil checks that
were runtime failure paths that can no longer be reached.

- handlers.go: Remove conditional init, always create sessMgr/encGen
- auth.go: Remove nil checks for sessMgr
- imageenc.go: Remove nil check for encGen
- service.go: Require signing_key in NewService, remove signer nil checks
- Update tests to provide signing_key
This commit is contained in:
2026-01-08 15:58:44 -08:00
parent 02dedd433b
commit 3849128c45
6 changed files with 27 additions and 51 deletions

View File

@@ -15,13 +15,6 @@ import (
// HandleRoot serves the login page or generator page based on authentication state. // HandleRoot serves the login page or generator page based on authentication state.
func (s *Handlers) HandleRoot() http.HandlerFunc { func (s *Handlers) HandleRoot() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// Check if signing key is configured
if s.sessMgr == nil {
s.respondError(w, "signing key not configured", http.StatusServiceUnavailable)
return
}
if r.Method == http.MethodPost { if r.Method == http.MethodPost {
s.handleLoginPost(w, r) s.handleLoginPost(w, r)
@@ -75,10 +68,7 @@ func (s *Handlers) handleLoginPost(w http.ResponseWriter, r *http.Request) {
// HandleLogout clears the session and redirects to login. // HandleLogout clears the session and redirects to login.
func (s *Handlers) HandleLogout() http.HandlerFunc { func (s *Handlers) HandleLogout() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
if s.sessMgr != nil {
s.sessMgr.ClearSession(w) s.sessMgr.ClearSession(w)
}
http.Redirect(w, r, "/", http.StatusSeeOther) http.Redirect(w, r, "/", http.StatusSeeOther)
} }
} }
@@ -87,7 +77,7 @@ func (s *Handlers) HandleLogout() http.HandlerFunc {
func (s *Handlers) HandleGenerateURL() http.HandlerFunc { func (s *Handlers) HandleGenerateURL() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// Check authentication // Check authentication
if s.sessMgr == nil || !s.sessMgr.IsAuthenticated(r) { if !s.sessMgr.IsAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther) http.Redirect(w, r, "/", http.StatusSeeOther)
return return

View File

@@ -95,14 +95,14 @@ func (s *Handlers) initImageService() error {
s.imgSvc = svc s.imgSvc = svc
s.log.Info("image service initialized") s.log.Info("image service initialized")
// Initialize session manager and URL generator if signing key is configured // Initialize session manager (signing key is validated at config load time)
if s.config.SigningKey != "" {
sessMgr, err := session.NewManager(s.config.SigningKey, !s.config.Debug) sessMgr, err := session.NewManager(s.config.SigningKey, !s.config.Debug)
if err != nil { if err != nil {
return err return err
} }
s.sessMgr = sessMgr s.sessMgr = sessMgr
// Initialize encrypted URL generator
encGen, err := encurl.NewGenerator(s.config.SigningKey) encGen, err := encurl.NewGenerator(s.config.SigningKey)
if err != nil { if err != nil {
return err return err
@@ -110,7 +110,6 @@ func (s *Handlers) initImageService() error {
s.encGen = encGen s.encGen = encGen
s.log.Info("session manager and URL generator initialized") s.log.Info("session manager and URL generator initialized")
}
return nil return nil
} }

View File

@@ -57,6 +57,7 @@ func setupTestHandler(t *testing.T) *testFixtures {
svc, err := imgcache.NewService(&imgcache.ServiceConfig{ svc, err := imgcache.NewService(&imgcache.ServiceConfig{
Cache: cache, Cache: cache,
Fetcher: newMockFetcher(mockFS), Fetcher: newMockFetcher(mockFS),
SigningKey: "test-signing-key-must-be-32-chars",
Whitelist: []string{goodHost}, Whitelist: []string{goodHost},
}) })
if err != nil { if err != nil {

View File

@@ -20,13 +20,6 @@ func (s *Handlers) HandleImageEnc() http.HandlerFunc {
ctx := r.Context() ctx := r.Context()
start := time.Now() start := time.Now()
// Check if encryption is configured
if s.encGen == nil {
s.respondError(w, "encrypted URLs not configured", http.StatusServiceUnavailable)
return
}
// Extract token from URL // Extract token from URL
token := chi.URLParam(r, "token") token := chi.URLParam(r, "token")
if token == "" { if token == "" {

View File

@@ -45,6 +45,10 @@ func NewService(cfg *ServiceConfig) (*Service, error) {
return nil, errors.New("cache is required") return nil, errors.New("cache is required")
} }
if cfg.SigningKey == "" {
return nil, errors.New("signing key is required")
}
// Use custom fetcher if provided, otherwise create HTTP fetcher // Use custom fetcher if provided, otherwise create HTTP fetcher
var fetcher Fetcher var fetcher Fetcher
if cfg.Fetcher != nil { if cfg.Fetcher != nil {
@@ -57,10 +61,7 @@ func NewService(cfg *ServiceConfig) (*Service, error) {
fetcher = NewHTTPFetcher(fetcherCfg) fetcher = NewHTTPFetcher(fetcherCfg)
} }
var signer *Signer signer := NewSigner(cfg.SigningKey)
if cfg.SigningKey != "" {
signer = NewSigner(cfg.SigningKey)
}
log := cfg.Logger log := cfg.Logger
if log == nil { if log == nil {
@@ -269,11 +270,7 @@ func (s *Service) ValidateRequest(req *ImageRequest) error {
return nil return nil
} }
// Signature required // Signature required for non-whitelisted hosts
if s.signer == nil {
return errors.New("signing key not configured but host not whitelisted")
}
return s.signer.Verify(req) return s.signer.Verify(req)
} }
@@ -283,10 +280,6 @@ func (s *Service) GenerateSignedURL(
req *ImageRequest, req *ImageRequest,
ttl time.Duration, ttl time.Duration,
) (string, error) { ) (string, error) {
if s.signer == nil {
return "", errors.New("signing key not configured")
}
path, sig, exp := s.signer.GenerateSignedURL(req, ttl) path, sig, exp := s.signer.GenerateSignedURL(req, ttl)
return fmt.Sprintf("%s%s?sig=%s&exp=%d", baseURL, path, sig, exp), nil return fmt.Sprintf("%s%s?sig=%s&exp=%d", baseURL, path, sig, exp), nil

View File

@@ -147,7 +147,7 @@ func SetupTestService(t *testing.T, opts ...TestServiceOption) (*Service, *TestF
cfg := &testServiceConfig{ cfg := &testServiceConfig{
whitelist: []string{fixtures.GoodHost}, whitelist: []string{fixtures.GoodHost},
signingKey: "", signingKey: "test-signing-key-must-be-32-chars",
} }
for _, opt := range opts { for _, opt := range opts {