package auth import ( "net/http" "forge.cadoles.com/arcad/edge/pkg/app" edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http" "forge.cadoles.com/arcad/edge/pkg/module/util" "github.com/dop251/goja" "github.com/pkg/errors" "gitlab.com/wpetit/goweb/logger" ) const ( ClaimSubject = "sub" ClaimIssuer = "iss" ClaimPreferredUsername = "preferred_username" ClaimEdgeRole = "edge_role" ClaimEdgeTenant = "edge_tenant" ClaimEdgeEntrypoint = "edge_entrypoint" ) type Module struct { server *app.Server getClaims GetClaimsFunc } 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")) } } 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 := ctx.Value(edgeHTTP.ContextKeyOriginRequest).(*http.Request) if !ok { panic(rt.ToValue(errors.New("could not find http request in context"))) } claim, err := m.getClaims(ctx, req, claimName) if err != nil { if errors.Is(err, ErrUnauthenticated) { return nil } logger.Error(ctx, "could not retrieve claim", logger.E(errors.WithStack(err))) return nil } if len(claim) == 0 || claim[0] == "" { return nil } return rt.ToValue(claim[0]) } 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, getClaims: opt.GetClaims, } } }