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:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 == "" {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user