edge/pkg/module/auth/module.go

100 lines
2.5 KiB
Go

package auth
import (
"forge.cadoles.com/arcad/edge/pkg/app"
edgehttp "forge.cadoles.com/arcad/edge/pkg/http"
"forge.cadoles.com/arcad/edge/pkg/jwtutil"
"forge.cadoles.com/arcad/edge/pkg/module/util"
"github.com/dop251/goja"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
const (
CookieName string = "edge-auth"
)
const (
ClaimSubject = "sub"
ClaimIssuer = "iss"
ClaimPreferredUsername = "preferred_username"
ClaimEdgeRole = "edge_role"
ClaimEdgeTenant = "edge_tenant"
ClaimEdgeEntrypoint = "edge_entrypoint"
)
type Module struct {
server *app.Server
getClaimFn GetClaimFunc
}
func (m *Module) Name() string {
return "auth"
}
func (m *Module) Export(export *goja.Object) {
if err := export.Set("getClaim", m.getClaim); err != nil {
panic(errors.Wrap(err, "could not set 'getClaim' function"))
}
if err := export.Set("CLAIM_SUBJECT", ClaimSubject); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_SUBJECT' property"))
}
if err := export.Set("CLAIM_TENANT", ClaimEdgeTenant); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_TENANT' property"))
}
if err := export.Set("CLAIM_ENTRYPOINT", ClaimEdgeEntrypoint); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_ENTRYPOINT' property"))
}
if err := export.Set("CLAIM_ROLE", ClaimEdgeRole); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_ROLE' property"))
}
if err := export.Set("CLAIM_PREFERRED_USERNAME", ClaimPreferredUsername); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_PREFERRED_USERNAME' property"))
}
if err := export.Set("CLAIM_ISSUER", ClaimIssuer); err != nil {
panic(errors.Wrap(err, "could not set 'CLAIM_ISSUER' property"))
}
}
func (m *Module) getClaim(call goja.FunctionCall, rt *goja.Runtime) goja.Value {
ctx := util.AssertContext(call.Argument(0), rt)
claimName := util.AssertString(call.Argument(1), rt)
req, ok := edgehttp.ContextHTTPRequest(ctx)
if !ok {
panic(rt.ToValue(errors.New("could not find http request in context")))
}
claim, err := m.getClaimFn(ctx, req, claimName)
if err != nil {
if errors.Is(err, jwtutil.ErrUnauthenticated) {
return nil
}
logger.Error(ctx, "could not retrieve claim", logger.CapturedE(errors.WithStack(err)))
return nil
}
return rt.ToValue(claim)
}
func ModuleFactory(funcs ...OptionFunc) app.ServerModuleFactory {
opt := defaultOptions()
for _, fn := range funcs {
fn(opt)
}
return func(server *app.Server) app.ServerModule {
return &Module{
server: server,
getClaimFn: opt.GetClaim,
}
}
}