@@ -100,45 +100,67 @@ func (h *Handler) authenticatePrincipal(ctx context.Context, req *events.LambdaF
100100 return nil , NewClientError (401 , "authentication required" )
101101 }
102102
103- if apiKey != "" {
104- _ , userRaw , err := h .auth .ValidateUserAPIKeyAPI (ctx , apiKey )
105- if err == nil && userRaw != nil {
106- p := & Principal {Kind : PrincipalUserAPIKey , Role : "user" }
107- // userRaw is returned as any from the interface. Extract fields
108- // via a locally-scoped interface to avoid an import cycle.
109- if uf , ok := userRaw .(interface {
110- GetID () string
111- GetEmail () string
112- GetRole () string
113- }); ok {
114- p .UserID = uf .GetID ()
115- p .Email = uf .GetEmail ()
116- p .Role = uf .GetRole ()
117- }
118- return p , nil
119- }
120- if err != nil {
121- logging .Debugf ("User API key validation failed: %v" , err )
122- }
103+ if p := h .principalFromUserAPIKey (ctx , apiKey ); p != nil {
104+ return p , nil
123105 }
124106
125- token := h .extractBearerToken (req )
126- if token != "" {
127- session , err := h .auth .ValidateSession (ctx , token )
128- if err == nil && session != nil {
129- return & Principal {
130- Kind : PrincipalSession ,
131- UserID : session .UserID ,
132- Email : session .Email ,
133- Role : session .Role ,
134- Session : session ,
135- }, nil
136- }
107+ if p := h .principalFromBearerToken (ctx , req ); p != nil {
108+ return p , nil
137109 }
138110
139111 return nil , NewClientError (401 , "authentication required" )
140112}
141113
114+ // principalFromUserAPIKey resolves a Principal from a user API key.
115+ // Returns nil when the key is empty, validation fails, or the user record
116+ // cannot be retrieved.
117+ func (h * Handler ) principalFromUserAPIKey (ctx context.Context , apiKey string ) * Principal {
118+ if apiKey == "" {
119+ return nil
120+ }
121+ _ , userRaw , err := h .auth .ValidateUserAPIKeyAPI (ctx , apiKey )
122+ if err != nil {
123+ logging .Debugf ("User API key validation failed: %v" , err )
124+ return nil
125+ }
126+ if userRaw == nil {
127+ return nil
128+ }
129+ p := & Principal {Kind : PrincipalUserAPIKey , Role : "user" }
130+ // userRaw is returned as any from the interface. Extract fields
131+ // via a locally-scoped interface to avoid an import cycle.
132+ if uf , ok := userRaw .(interface {
133+ GetID () string
134+ GetEmail () string
135+ GetRole () string
136+ }); ok {
137+ p .UserID = uf .GetID ()
138+ p .Email = uf .GetEmail ()
139+ p .Role = uf .GetRole ()
140+ }
141+ return p
142+ }
143+
144+ // principalFromBearerToken resolves a Principal from a session bearer token.
145+ // Returns nil when no token is present or the session is invalid.
146+ func (h * Handler ) principalFromBearerToken (ctx context.Context , req * events.LambdaFunctionURLRequest ) * Principal {
147+ token := h .extractBearerToken (req )
148+ if token == "" {
149+ return nil
150+ }
151+ session , err := h .auth .ValidateSession (ctx , token )
152+ if err != nil || session == nil {
153+ return nil
154+ }
155+ return & Principal {
156+ Kind : PrincipalSession ,
157+ UserID : session .UserID ,
158+ Email : session .Email ,
159+ Role : session .Role ,
160+ Session : session ,
161+ }
162+ }
163+
142164func extractAPIKey (req * events.LambdaFunctionURLRequest ) string {
143165 apiKey := req .Headers ["x-api-key" ]
144166 if apiKey == "" {
0 commit comments