feat(auth): automatically create session for anonymous users
All checks were successful
arcad/emissary/pipeline/head This commit looks good

ref arcad/edge-menu#86
This commit is contained in:
2023-09-20 10:02:59 -06:00
parent 3d7a094cb8
commit 6318a8b497
5 changed files with 85 additions and 5 deletions

View File

@ -90,10 +90,18 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
modules := c.getAppModules(deps)
anonymousUserMiddleware, err := getAnonymousUserMiddleware(specs.Config.Auth)
if err != nil {
return nil, errors.Wrap(err, "could not get anonymous user middleware")
}
options := []edgeHTTP.HandlerOptionFunc{
edgeHTTP.WithBus(deps.Bus),
edgeHTTP.WithServerModules(modules...),
edgeHTTP.WithHTTPMounts(mounts...),
edgeHTTP.WithHTTPMiddlewares(
anonymousUserMiddleware,
),
}
return options, nil

View File

@ -1,15 +1,19 @@
package app
import (
"net/http"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/module"
"forge.cadoles.com/arcad/edge/pkg/module/auth"
authModule "forge.cadoles.com/arcad/edge/pkg/module/auth"
authHTTP "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
authModuleMiddleware "forge.cadoles.com/arcad/edge/pkg/module/auth/middleware"
"github.com/dop251/goja"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
@ -91,3 +95,72 @@ func getAuthMount(auth *spec.Auth, keySet jwk.Set) (auth.MountFunc, error) {
return nil, nil
}
}
func getAnonymousUserMiddleware(auth *appSpec.Auth) (func(http.Handler) http.Handler, error) {
anonymousUserSigningKey, err := getAnonymousUserSigningKey(auth)
if err != nil {
return nil, errors.Wrap(err, "could not get anonymous user signing key")
}
cookieDuration := defaultCookieDuration
if auth.Local.CookieDuration != "" {
cookieDuration, err = time.ParseDuration(auth.Local.CookieDuration)
if err != nil {
return nil, errors.WithStack(err)
}
}
middleware := authModuleMiddleware.AnonymousUser(
anonymousUserSigningKey.Algorithm(),
anonymousUserSigningKey,
authModuleMiddleware.WithCookieOptions(getCookieDomain, cookieDuration),
)
return middleware, nil
}
func getAnonymousUserSigningKey(auth *appSpec.Auth) (jwk.Key, error) {
var (
key jwk.Key
err error
)
generateNewKey := func() (jwk.Key, error) {
key, err := jwk.Generate(2048)
if err != nil {
return nil, errors.WithStack(err)
}
return key, nil
}
switch {
default:
fallthrough
case auth == nil:
key, err = generateNewKey()
if err != nil {
return nil, errors.Wrap(err, "could not generate anonymous user signing key")
}
return key, nil
case auth.Local != nil:
switch typedKey := auth.Local.Key.(type) {
case string:
key, err = jwk.FromRaw([]byte(typedKey))
if err != nil {
return nil, errors.Wrap(err, "could not parse local auth key")
}
if err := key.Set(jwk.AlgorithmKey, jwa.HS256); err != nil {
return nil, errors.WithStack(err)
}
default:
return nil, errors.Errorf("unexpected key type '%T'", auth.Local.Key)
}
}
return key, nil
}

View File

@ -8,7 +8,6 @@ import (
"sync"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/Cadoles/emissary/internal/proxy/wildcard"
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
@ -128,7 +127,7 @@ func (s *Server) Stop() error {
return nil
}
func NewServer(bundle bundle.Bundle, config *spec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
func NewServer(bundle bundle.Bundle, config *appSpec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
return &Server{
bundle: bundle,
config: config,