Compare commits

...

8 Commits

Author SHA1 Message Date
ef3048b005 feat(controller,app): use new edge new mountpoints api
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-20 12:23:17 +02:00
51e1dc3b2d fix(server,api): return 'not found' errors 2023-04-20 12:22:30 +02:00
3d01cf0f93 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-20 11:01:04 +02:00
bb03b3a54a feat(controller,app): compress http responses
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-04-20 10:59:27 +02:00
813f837291 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-14 16:29:09 +02:00
ed35ee5002 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 13:48:33 +02:00
4b5bc0bc82 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 12:08:13 +02:00
dee62184b9 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-04-13 11:35:51 +02:00
7 changed files with 121 additions and 85 deletions

4
go.mod
View File

@ -3,7 +3,7 @@ module forge.cadoles.com/Cadoles/emissary
go 1.19
require (
forge.cadoles.com/arcad/edge v0.0.0-20230413092334-310dac296fcd
forge.cadoles.com/arcad/edge v0.0.0-20230420084103-20c4189599c5
github.com/Masterminds/sprig/v3 v3.2.3
github.com/alecthomas/participle/v2 v2.0.0-beta.5
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
@ -25,7 +25,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/qri-io/jsonschema v0.2.1
github.com/urfave/cli/v2 v2.24.4
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.21.0
)

8
go.sum
View File

@ -54,8 +54,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
forge.cadoles.com/arcad/edge v0.0.0-20230413092334-310dac296fcd h1:yRMIeeyRXdu/YMdqRT11vozrppJ4LjiOravtTTd8f2M=
forge.cadoles.com/arcad/edge v0.0.0-20230413092334-310dac296fcd/go.mod h1:Vx4iq/oewXUOkGyi8QKc14clTLNO1sWpb0SjBYELlAs=
forge.cadoles.com/arcad/edge v0.0.0-20230420084103-20c4189599c5 h1:YDMFsNnEQC5ixv4swcwInMda2se4oo6Iok8B+13nsCU=
forge.cadoles.com/arcad/edge v0.0.0-20230420084103-20c4189599c5/go.mod h1:VShMOiyzb5sE6f8KwfZNhcK8UiAhU36cfEvRFiowoNY=
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
@ -1310,8 +1310,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3 h1:ddXRTeqEr7LcHQEtkd6gogZOh9tI1Y6Gappr0a1oa2I=
gitlab.com/wpetit/goweb v0.0.0-20230227162855-a1f09bafccb3/go.mod h1:3sus4zjoUv1GB7eDLL60QaPkUnXJCWBpjvbe0jWifeY=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b h1:nkvOl8TCj/mErADnwFFynjxBtC+hHsrESw6rw56JGmg=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b/go.mod h1:3sus4zjoUv1GB7eDLL60QaPkUnXJCWBpjvbe0jWifeY=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=

View File

@ -23,6 +23,7 @@ import (
netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
"forge.cadoles.com/arcad/edge/pkg/storage/sqlite"
"github.com/Masterminds/sprig/v3"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
@ -47,12 +48,26 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
return nil, errors.Wrap(err, "could not retrieve auth key set")
}
mounts := make([]func(r chi.Router), 0)
authMount, err := getAuthMount(specs.Config.Auth, keySet)
if err != nil {
return nil, errors.WithStack(err)
}
if authMount != nil {
mounts = append(mounts, authMount)
}
mounts = append(mounts, appModule.Mount(c.appRepository))
bus := memory.NewBus()
modules := c.getAppModules(bus, db, specs, keySet)
options := []edgeHTTP.HandlerOptionFunc{
edgeHTTP.WithBus(bus),
edgeHTTP.WithServerModules(modules...),
edgeHTTP.WithHTTPMounts(mounts...),
}
return options, nil
@ -244,7 +259,7 @@ func (c *Controller) getAppModules(bus bus.Bus, db *sql.DB, spec *appSpec.Spec,
module.RPCModuleFactory(bus),
module.StoreModuleFactory(ds),
blob.ModuleFactory(bus, bs),
authModule(keySet),
authModuleFactory(keySet),
appModule.ModuleFactory(c.appRepository),
fetchModule.ModuleFactory(bus),
}

View File

@ -1,11 +1,17 @@
package app
import (
"time"
"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"
"github.com/dop251/goja"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
)
@ -17,30 +23,14 @@ const (
RoleSuperadmin string = "superadmin"
)
func authModule(keySet jwk.Set) app.ServerModuleFactory {
func authModuleFactory(keySet jwk.Set) app.ServerModuleFactory {
return module.Extends(
auth.ModuleFactory(
auth.WithJWT(func() (jwk.Set, error) {
authModule.ModuleFactory(
authModule.WithJWT(func() (jwk.Set, error) {
return keySet, nil
}),
),
func(o *goja.Object) {
if err := o.Set("CLAIM_TENANT", "arcad_tenant"); err != nil {
panic(errors.New("could not set 'CLAIM_TENANT' property"))
}
if err := o.Set("CLAIM_ENTRYPOINT", "arcad_entrypoint"); err != nil {
panic(errors.New("could not set 'CLAIM_ENTRYPOINT' property"))
}
if err := o.Set("CLAIM_ROLE", "arcad_role"); err != nil {
panic(errors.New("could not set 'CLAIM_ROLE' property"))
}
if err := o.Set("CLAIM_PREFERRED_USERNAME", "preferred_username"); err != nil {
panic(errors.New("could not set 'CLAIM_PREFERRED_USERNAME' property"))
}
if err := o.Set("ROLE_VISITOR", RoleVisitor); err != nil {
panic(errors.New("could not set 'ROLE_VISITOR' property"))
}
@ -63,3 +53,41 @@ func authModule(keySet jwk.Set) app.ServerModuleFactory {
},
)
}
func getAuthMount(auth *spec.Auth, keySet jwk.Set) (auth.MountFunc, error) {
switch {
case auth.Local != nil:
var rawKey any = auth.Local.Key
if strKey, ok := rawKey.(string); ok {
rawKey = []byte(strKey)
}
key, err := jwk.FromRaw(rawKey)
if err != nil {
return nil, errors.WithStack(err)
}
cookieDuration := defaultCookieDuration
if auth.Local.CookieDuration != "" {
cookieDuration, err = time.ParseDuration(auth.Local.CookieDuration)
if err != nil {
return nil, errors.WithStack(err)
}
}
return authModule.Mount(
authHTTP.NewLocalHandler(
jwa.HS256, key,
authHTTP.WithRoutePrefix("/auth"),
authHTTP.WithAccounts(auth.Local.Accounts...),
authHTTP.WithCookieOptions(getCookieDomain, cookieDuration),
),
authModule.WithJWT(func() (jwk.Set, error) {
return keySet, nil
}),
), nil
default:
return nil, nil
}
}

View File

@ -12,14 +12,11 @@ import (
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"
authHTTP "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
"gitlab.com/wpetit/goweb/logger"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/pkg/errors"
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/passwd"
@ -48,6 +45,7 @@ func (s *Server) Start(ctx context.Context, addr string) (err error) {
router := chi.NewRouter()
router.Use(middleware.Logger)
router.Use(middleware.Compress(5))
handler := edgeHTTP.NewHandler(s.handlerOptions...)
if err := handler.Load(s.bundle); err != nil {
@ -61,12 +59,6 @@ func (s *Server) Start(ctx context.Context, addr string) (err error) {
s.config.UnexpectedHostRedirect.AcceptedHostPatterns...,
))
}
if s.config.Auth != nil {
if err := s.configureAuth(router, s.config.Auth); err != nil {
return errors.WithStack(err)
}
}
}
router.Handle("/*", handler)
@ -135,38 +127,6 @@ func (s *Server) Stop() error {
return nil
}
func (s *Server) configureAuth(router chi.Router, auth *spec.Auth) error {
switch {
case auth.Local != nil:
var rawKey any = auth.Local.Key
if strKey, ok := rawKey.(string); ok {
rawKey = []byte(strKey)
}
key, err := jwk.FromRaw(rawKey)
if err != nil {
return errors.WithStack(err)
}
cookieDuration := defaultCookieDuration
if auth.Local.CookieDuration != "" {
cookieDuration, err = time.ParseDuration(auth.Local.CookieDuration)
if err != nil {
return errors.WithStack(err)
}
}
router.Handle("/auth/*", authHTTP.NewLocalHandler(
jwa.HS256, key,
authHTTP.WithRoutePrefix("/auth"),
authHTTP.WithAccounts(auth.Local.Accounts...),
authHTTP.WithCookieOptions(getCookieDomain, cookieDuration),
))
}
return nil
}
func NewServer(bundle bundle.Bundle, config *spec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
return &Server{
bundle: bundle,

View File

@ -58,6 +58,12 @@ func (s *Server) updateSpec(w http.ResponseWriter, r *http.Request) {
updateSpecReq.SpecData(),
)
if err != nil {
if errors.Is(err, datastore.ErrNotFound) {
api.ErrorResponse(w, http.StatusNotFound, ErrCodeNotFound, nil)
return
}
if errors.Is(err, datastore.ErrUnexpectedRevision) {
api.ErrorResponse(w, http.StatusConflict, ErrCodeUnexpectedRevision, nil)
@ -87,6 +93,12 @@ func (s *Server) getAgentSpecs(w http.ResponseWriter, r *http.Request) {
specs, err := s.agentRepo.GetSpecs(ctx, agentID)
if err != nil {
if errors.Is(err, datastore.ErrNotFound) {
api.ErrorResponse(w, http.StatusNotFound, ErrCodeNotFound, nil)
return
}
logger.Error(ctx, "could not list specs", logger.E(errors.WithStack(err)))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)

View File

@ -1,28 +1,16 @@
{
"apps": {
"edge.portal": {
"url": "https://emissary.cadol.es/files/apps/edge.portal_v2023.4.9-41c100d.zip",
"sha256sum": "b73a6741654f3e24281e354b3b506b109dac6ada8a9698452f52b03a53299a7d",
"address": ":8082",
"format": "zip"
},
"app.arcad.edge.hextris": {
"url": "https://emissary.cadol.es/files/apps/app.arcad.edge.hextris_v2023.4.11-81fb4c4.zip",
"sha256sum": "6d70f65971b3dd288da32d8d004ab8fbca030398b5c12e3c052ef98c53a6b81a",
"url": "https://emissary.cadol.es/files/apps/app.arcad.edge.hextris_v2023.4.20-2bbbe94.zip",
"sha256sum": "67942ef4b623c46308c3f640b534bd4cb6b1d6021a422e40b62ab97658ba4586",
"address": ":8083",
"format": "zip"
},
"edge.sdk.client.test": {
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_v2023.4.11-f5283b8.zip",
"sha256sum": "785d9f8d427900e1bb27ab85a33e8b1cbd1b6a1f8b2eab6366dc215a69655ade",
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_v2023.4.20-20c4189.zip",
"sha256sum": "1edeb4aa75c1675db49cf27367b1537234a04526848ea6657931ca63f26e5dae",
"address": ":8084",
"format": "zip"
},
"arcad.diffusion": {
"url": "https://emissary.cadol.es/files/apps/arcad.diffusion_v2023.4.9-81046a2.zip",
"sha256sum": "b8770adfaaf60e6d3e7776e0a090e6e7a0b31f3f9425b91168b42144d0346513",
"address": ":8085",
"format": "zip"
}
},
"config": {
@ -48,11 +36,44 @@
"algo": "plain",
"password": "admin",
"claims": {
"arcad_role": "admin",
"arcad_tenant": "x86",
"edge_role": "admin",
"edge_tenant": "emissary-dev",
"preferred_username": "Admin",
"sub": "admin"
}
},
{
"username": "superadmin",
"algo": "plain",
"password": "superadmin",
"claims": {
"edge_role": "superadmin",
"edge_tenant": "emissary-dev",
"preferred_username": "SuperAdmin",
"sub": "superadmin"
}
},
{
"username": "user",
"algo": "plain",
"password": "user",
"claims": {
"edge_role": "user",
"edge_tenant": "emissary-dev",
"preferred_username": "User",
"sub": "user"
}
},
{
"username": "superuser",
"algo": "plain",
"password": "superuser",
"claims": {
"edge_role": "superuser",
"edge_tenant": "emissary-dev",
"preferred_username": "SuperUser",
"sub": "superuser"
}
}
]
}