77 "context"
88 "crypto/tls"
99 "encoding/json"
10+ "errors"
1011 "fmt"
1112 "io"
1213 "net"
@@ -22,9 +23,8 @@ import (
2223
2324 "github.com/go-logr/logr"
2425 "github.com/golang-jwt/jwt/v5"
25- "github.com/gorilla/handlers"
2626 "github.com/gorilla/mux"
27- "github.com/pkg/errors"
27+ pkgerrors "github.com/pkg/errors"
2828 capsulev1beta2 "github.com/projectcapsule/capsule/api/v1beta2"
2929 capsulerbac "github.com/projectcapsule/capsule/pkg/api/rbac"
3030 "golang.org/x/net/http/httpguts"
@@ -82,7 +82,7 @@ func NewKubeFilter(
8282
8383 reverseProxyTransport , err := opts .ReverseProxyTransport ()
8484 if err != nil {
85- return nil , errors .Wrap (err , "cannot create transport for reverse proxy" )
85+ return nil , pkgerrors .Wrap (err , "cannot create transport for reverse proxy" )
8686 }
8787
8888 reverseProxy .Transport = reverseProxyTransport
@@ -92,12 +92,12 @@ func NewKubeFilter(
9292
9393 err = corev1 .AddToScheme (scheme )
9494 if err != nil {
95- return nil , errors .Wrap (err , "cannot add corev1 to scheme" )
95+ return nil , pkgerrors .Wrap (err , "cannot add corev1 to scheme" )
9696 }
9797
9898 err = authorizationv1 .AddToScheme (scheme )
9999 if err != nil {
100- return nil , errors .Wrap (err , "cannot add authorizationv1 to scheme" )
100+ return nil , pkgerrors .Wrap (err , "cannot add authorizationv1 to scheme" )
101101 }
102102
103103 codecFactory := serializer .NewCodecFactory (scheme )
@@ -167,7 +167,7 @@ func (n *kubeFilter) NeedLeaderElection() bool {
167167//nolint:funlen
168168func (n * kubeFilter ) Start (ctx context.Context ) error {
169169 r := mux .NewRouter ()
170- r .Use (handlers . RecoveryHandler () )
170+ r .Use (n . recoveryMiddleware )
171171
172172 r .Path ("/_healthz" ).Subrouter ().HandleFunc ("" , func (writer http.ResponseWriter , _ * http.Request ) {
173173 writer .WriteHeader (http .StatusOK )
@@ -283,13 +283,13 @@ func (n *kubeFilter) ReadinessProbe(req *http.Request) (err error) {
283283 var r * http.Request
284284
285285 if r , err = http .NewRequestWithContext (req .Context (), http .MethodGet , url , nil ); err != nil {
286- return errors .Wrap (err , "cannot create request" )
286+ return pkgerrors .Wrap (err , "cannot create request" )
287287 }
288288
289289 var resp * http.Response
290290
291291 if resp , err = clt .Do (r ); err != nil {
292- return errors .Wrap (err , "cannot make local _healthz request" )
292+ return pkgerrors .Wrap (err , "cannot make local _healthz request" )
293293 }
294294
295295 defer func () {
@@ -349,13 +349,17 @@ func (n *kubeFilter) authorizationMiddleware(next http.Handler) http.Handler {
349349
350350 request , username , groups , err := req .ResolveUserAndGroups (request , n .authTypes , n .usernameClaimField , n .writer , n .ignoredImpersonationGroups , n .impersonationGroupsRegexp , n .skipImpersonationReview , n .xfcc_header )
351351 if err != nil {
352- server .HandleError (writer , err , "cannot retrieve user and group from the request" )
352+ n .handleResolveUserAndGroupsError (writer , err )
353+
354+ return
353355 }
354356
355357 //nolint:contextcheck
356358 proxyTenants , err := n .getTenantsForOwner (request .Context (), username , groups )
357359 if err != nil {
358360 server .HandleError (writer , err , "cannot list Tenant resources" )
361+
362+ return
359363 }
360364
361365 obj , gvk , err := n .universalDecoder .Decode (body , nil , nil )
@@ -547,12 +551,16 @@ func (n *kubeFilter) registerModules(ctx context.Context, root *mux.Router) {
547551 sr .HandleFunc ("" , func (writer http.ResponseWriter , request * http.Request ) {
548552 request , username , groups , err := req .ResolveUserAndGroups (request , n .authTypes , n .usernameClaimField , n .writer , n .ignoredImpersonationGroups , n .impersonationGroupsRegexp , n .skipImpersonationReview , n .xfcc_header )
549553 if err != nil {
550- server .HandleError (writer , err , "cannot retrieve user and group from the request" )
554+ n .handleResolveUserAndGroupsError (writer , err )
555+
556+ return
551557 }
552558
553559 proxyTenants , err := n .getTenantsForOwner (ctx , username , groups )
554560 if err != nil {
555561 server .HandleError (writer , err , "cannot list Tenant resources" )
562+
563+ return
556564 }
557565
558566 var selector labels.Selector
@@ -574,19 +582,23 @@ func (n *kubeFilter) registerModules(ctx context.Context, root *mux.Router) {
574582 case err != nil :
575583 var t moderrors.Error
576584 if errors .As (err , & t ) {
585+ writer .Header ().Set ("Content-Type" , "application/json" )
586+
577587 if t .Status ().Code > 0 {
578588 writer .WriteHeader (int (t .Status ().Code ))
589+ } else {
590+ writer .WriteHeader (http .StatusInternalServerError )
579591 }
580592
581- writer .Header ().Set ("Content-Type" , "application/json" )
582-
583593 b , _ := json .Marshal (t .Status ())
584594 _ , _ = writer .Write (b )
585595
586- panic ( err . Error ())
596+ return
587597 }
588598
589599 server .HandleError (writer , err , err .Error ())
600+
601+ return
590602 case selector == nil :
591603 // if there's no selector, let it pass to the
592604 n .impersonateHandler (writer , request )
@@ -597,6 +609,37 @@ func (n *kubeFilter) registerModules(ctx context.Context, root *mux.Router) {
597609 }
598610}
599611
612+ func (n * kubeFilter ) recoveryMiddleware (next http.Handler ) http.Handler {
613+ return http .HandlerFunc (func (writer http.ResponseWriter , request * http.Request ) {
614+ defer func () {
615+ recovered := recover ()
616+ if recovered == nil {
617+ return
618+ }
619+
620+ if err , ok := recovered .(error ); ok && errors .Is (err , http .ErrAbortHandler ) {
621+ panic (err )
622+ }
623+
624+ n .log .Error (fmt .Errorf ("%v" , recovered ), "panic while handling request" )
625+ server .HandleError (writer , fmt .Errorf ("internal server error" ), "panic while handling request" )
626+ }()
627+
628+ next .ServeHTTP (writer , request )
629+ })
630+ }
631+
632+ func (n * kubeFilter ) handleResolveUserAndGroupsError (writer http.ResponseWriter , err error ) {
633+ var unauthorizedErr * req.ErrUnauthorized
634+ if errors .As (err , & unauthorizedErr ) {
635+ server .HandleUnauthorized (writer , err , "cannot retrieve user and group from the request" )
636+
637+ return
638+ }
639+
640+ server .HandleError (writer , err , "cannot retrieve user and group from the request" )
641+ }
642+
600643func (n * kubeFilter ) getTenantsForOwner (ctx context.Context , username string , groups []string ) (proxyTenants []* tenant.ProxyTenant , err error ) {
601644 if strings .HasPrefix (username , serviceaccount .ServiceAccountUsernamePrefix ) {
602645 proxyTenants , err = n .getProxyTenantsForOwnerKind (ctx , capsulerbac .ServiceAccountOwner , username )
0 commit comments