summaryrefslogtreecommitdiff
path: root/player-server
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-19 19:32:30 +0300
committerPaul Buetow <paul@buetow.org>2026-05-19 19:32:30 +0300
commit965b36f3e09a0d4cdbb69cb3f423ab01fecf2419 (patch)
treec7271588848864b88c67e82818153d08c91dae64 /player-server
parent3779053951f338076fcc448daf9bee9ada18cf54 (diff)
Inject narrow api.Authenticator into NewMiddleware
The middleware previously took the full service.AuthService, but only called three methods on it. Define a narrow api.Authenticator interface (AuthenticateBearer, CountUsers, GetUserByID) and inject that instead, fixing the ISP violation. service.AuthService satisfies the new interface structurally, so callers and tests need no changes. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'player-server')
-rw-r--r--player-server/internal/api/middleware.go29
1 files changed, 26 insertions, 3 deletions
diff --git a/player-server/internal/api/middleware.go b/player-server/internal/api/middleware.go
index ec7c1a7..5566e42 100644
--- a/player-server/internal/api/middleware.go
+++ b/player-server/internal/api/middleware.go
@@ -8,7 +8,6 @@ import (
"codeberg.org/snonux/player/internal/auth"
"codeberg.org/snonux/player/internal/model"
- "codeberg.org/snonux/player/internal/service"
)
type ctxKey int
@@ -20,6 +19,24 @@ const (
userCtxKey
)
+// Authenticator is the narrow auth interface needed by middleware.
+//
+// It exposes only the methods middleware actually calls, satisfying the
+// Interface Segregation Principle: callers (and test doubles) need not
+// implement the full service.AuthService surface (bootstrap, login, API
+// token CRUD, etc.) just to wire up request authentication.
+//
+// service.AuthService satisfies this interface structurally, so the live
+// server simply passes its concrete service in.
+type Authenticator interface {
+ // AuthenticateBearer validates a Bearer token and returns a synthetic session.
+ AuthenticateBearer(ctx context.Context, plaintext string) (*model.Session, error)
+ // CountUsers reports the number of registered users (used by BootstrapRedirect).
+ CountUsers(ctx context.Context) (int, error)
+ // GetUserByID returns a user by database ID (used by RequireAdmin).
+ GetUserByID(ctx context.Context, id int64) (*model.User, error)
+}
+
// Middleware holds dependencies for middleware constructors.
//
// publicPaths and publicPrefixes form a route registry used by
@@ -29,16 +46,22 @@ const (
// the bypass set — no hidden hardcoded whitelist that silently 401s/redirects
// new routes the developer forgot to add.
type Middleware struct {
- authSvc service.AuthService
+ authSvc Authenticator
sm auth.SessionManager
publicPaths map[string]bool
publicPrefixes []string
}
// NewMiddleware creates middleware handlers.
+//
+// The auth dependency is the narrow Authenticator interface rather than the
+// full service.AuthService — middleware only needs three methods, and the
+// smaller surface keeps tests cheap and prevents accidental coupling to
+// unrelated auth-service operations.
+//
// The public route registry starts empty; callers register public paths
// via RegisterPublic / RegisterPublicPrefix as routes are wired up.
-func NewMiddleware(authSvc service.AuthService, sm auth.SessionManager) *Middleware {
+func NewMiddleware(authSvc Authenticator, sm auth.SessionManager) *Middleware {
return &Middleware{
authSvc: authSvc,
sm: sm,