providers/proxy: fix panic, keep session storages open (#11439)
* fix panic when redis connection fails Signed-off-by: Jens Langhammer <jens@goauthentik.io> * re-use session when refreshing apps Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
		| @ -65,8 +65,11 @@ type Server interface { | ||||
| 	CryptoStore() *ak.CryptoStore | ||||
| } | ||||
|  | ||||
| func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server) (*Application, error) { | ||||
| func init() { | ||||
| 	gob.Register(Claims{}) | ||||
| } | ||||
|  | ||||
| func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server, oldApp *Application) (*Application, error) { | ||||
| 	muxLogger := log.WithField("logger", "authentik.outpost.proxyv2.application").WithField("name", p.Name) | ||||
|  | ||||
| 	externalHost, err := url.Parse(p.ExternalHost) | ||||
| @ -137,7 +140,15 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server) (*A | ||||
| 		isEmbedded:           isEmbedded, | ||||
| 	} | ||||
| 	go a.authHeaderCache.Start() | ||||
| 	a.sessions = a.getStore(p, externalHost) | ||||
| 	if oldApp != nil && oldApp.sessions != nil { | ||||
| 		a.sessions = oldApp.sessions | ||||
| 	} else { | ||||
| 		sess, err := a.getStore(p, externalHost) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		a.sessions = sess | ||||
| 	} | ||||
| 	mux.Use(web.NewLoggingHandler(muxLogger, func(l *log.Entry, r *http.Request) *log.Entry { | ||||
| 		c := a.getClaimsFromSession(r) | ||||
| 		if c == nil { | ||||
| @ -235,9 +246,8 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, server Server) (*A | ||||
| 				// TODO: maybe create event for this? | ||||
| 				a.log.WithError(err).Warning("failed to compile SkipPathRegex") | ||||
| 				continue | ||||
| 			} else { | ||||
| 				a.UnauthenticatedRegex = append(a.UnauthenticatedRegex, re) | ||||
| 			} | ||||
| 			a.UnauthenticatedRegex = append(a.UnauthenticatedRegex, re) | ||||
| 		} | ||||
| 	} | ||||
| 	return a, nil | ||||
|  | ||||
| @ -26,7 +26,7 @@ import ( | ||||
|  | ||||
| const RedisKeyPrefix = "authentik_proxy_session_" | ||||
|  | ||||
| func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL) sessions.Store { | ||||
| func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL) (sessions.Store, error) { | ||||
| 	maxAge := 0 | ||||
| 	if p.AccessTokenValidity.IsSet() { | ||||
| 		t := p.AccessTokenValidity.Get() | ||||
| @ -73,7 +73,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL) | ||||
| 		// New default RedisStore | ||||
| 		rs, err := redisstore.NewRedisStore(context.Background(), client) | ||||
| 		if err != nil { | ||||
| 			a.log.WithError(err).Panic("failed to connect to redis") | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		rs.KeyPrefix(RedisKeyPrefix) | ||||
| @ -87,7 +87,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL) | ||||
| 		}) | ||||
|  | ||||
| 		a.log.Trace("using redis session backend") | ||||
| 		return rs | ||||
| 		return rs, nil | ||||
| 	} | ||||
| 	dir := os.TempDir() | ||||
| 	cs := sessions.NewFilesystemStore(dir) | ||||
| @ -106,7 +106,7 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL) | ||||
| 	cs.Options.MaxAge = maxAge | ||||
| 	cs.Options.Path = "/" | ||||
| 	a.log.WithField("dir", dir).Trace("using filesystem session backend") | ||||
| 	return cs | ||||
| 	return cs, nil | ||||
| } | ||||
|  | ||||
| func (a *Application) SessionName() string { | ||||
|  | ||||
| @ -66,6 +66,7 @@ func newTestApplication() *Application { | ||||
| 		}, | ||||
| 		http.DefaultClient, | ||||
| 		ts, | ||||
| 		nil, | ||||
| 	) | ||||
| 	ts.apps = append(ts.apps, a) | ||||
| 	return a | ||||
|  | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/getsentry/sentry-go" | ||||
| 	"goauthentik.io/internal/constants" | ||||
| @ -37,16 +38,21 @@ func (ps *ProxyServer) Refresh() error { | ||||
| 				), | ||||
| 			), | ||||
| 		} | ||||
| 		a, err := application.NewApplication(provider, hc, ps) | ||||
| 		existing, ok := ps.apps[a.Host] | ||||
| 		externalHost, err := url.Parse(provider.ExternalHost) | ||||
| 		if err != nil { | ||||
| 			ps.log.WithError(err).Warning("failed to parse URL, skipping provider") | ||||
| 			continue | ||||
| 		} | ||||
| 		existing, ok := ps.apps[externalHost.Host] | ||||
| 		a, err := application.NewApplication(provider, hc, ps, existing) | ||||
| 		if ok { | ||||
| 			existing.Stop() | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			ps.log.WithError(err).Warning("failed to setup application") | ||||
| 		} else { | ||||
| 			apps[a.Host] = a | ||||
| 			continue | ||||
| 		} | ||||
| 		apps[externalHost.Host] = a | ||||
| 	} | ||||
| 	ps.apps = apps | ||||
| 	ps.log.Debug("Swapped maps") | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens L.
					Jens L.