feat(controller,app): validate app manifests on app load
This commit is contained in:
parent
8fb86c600f
commit
280b0fbd50
|
@ -17,14 +17,12 @@ import (
|
||||||
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
|
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module"
|
"forge.cadoles.com/arcad/edge/pkg/module"
|
||||||
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
|
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module/auth"
|
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module/blob"
|
"forge.cadoles.com/arcad/edge/pkg/module/blob"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module/cast"
|
"forge.cadoles.com/arcad/edge/pkg/module/cast"
|
||||||
fetchModule "forge.cadoles.com/arcad/edge/pkg/module/fetch"
|
fetchModule "forge.cadoles.com/arcad/edge/pkg/module/fetch"
|
||||||
netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
|
netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/storage/sqlite"
|
"forge.cadoles.com/arcad/edge/pkg/storage/sqlite"
|
||||||
"github.com/Masterminds/sprig/v3"
|
"github.com/Masterminds/sprig/v3"
|
||||||
"github.com/dop251/goja"
|
|
||||||
"github.com/lestrrat-go/jwx/v2/jwa"
|
"github.com/lestrrat-go/jwx/v2/jwa"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gitlab.com/wpetit/goweb/logger"
|
"gitlab.com/wpetit/goweb/logger"
|
||||||
|
@ -49,12 +47,6 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
|
||||||
return nil, errors.Wrap(err, "could not retrieve auth key set")
|
return nil, errors.Wrap(err, "could not retrieve auth key set")
|
||||||
}
|
}
|
||||||
|
|
||||||
bundles := make([]string, 0, len(specs.Apps))
|
|
||||||
for appKey, app := range specs.Apps {
|
|
||||||
path := c.getAppBundlePath(appKey, app.Format)
|
|
||||||
bundles = append(bundles, path)
|
|
||||||
}
|
|
||||||
|
|
||||||
bus := memory.NewBus()
|
bus := memory.NewBus()
|
||||||
modules := c.getAppModules(bus, db, specs, keySet)
|
modules := c.getAppModules(bus, db, specs, keySet)
|
||||||
|
|
||||||
|
@ -252,30 +244,7 @@ func (c *Controller) getAppModules(bus bus.Bus, db *sql.DB, spec *appSpec.Spec,
|
||||||
module.RPCModuleFactory(bus),
|
module.RPCModuleFactory(bus),
|
||||||
module.StoreModuleFactory(ds),
|
module.StoreModuleFactory(ds),
|
||||||
blob.ModuleFactory(bus, bs),
|
blob.ModuleFactory(bus, bs),
|
||||||
module.Extends(
|
authModule(keySet),
|
||||||
auth.ModuleFactory(
|
|
||||||
auth.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"))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
appModule.ModuleFactory(c.appRepository),
|
appModule.ModuleFactory(c.appRepository),
|
||||||
fetchModule.ModuleFactory(bus),
|
fetchModule.ModuleFactory(bus),
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"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"
|
||||||
|
"github.com/dop251/goja"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RoleVisitor string = "visitor"
|
||||||
|
RoleUser string = "user"
|
||||||
|
RoleSuperuser string = "superuser"
|
||||||
|
RoleAdmin string = "admin"
|
||||||
|
RoleSuperadmin string = "superadmin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func authModule(keySet jwk.Set) app.ServerModuleFactory {
|
||||||
|
return module.Extends(
|
||||||
|
auth.ModuleFactory(
|
||||||
|
auth.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"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Set("ROLE_USER", RoleUser); err != nil {
|
||||||
|
panic(errors.New("could not set 'ROLE_USER' property"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Set("ROLE_SUPERUSER", RoleSuperuser); err != nil {
|
||||||
|
panic(errors.New("could not set 'ROLE_SUPERUSER' property"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Set("ROLE_ADMIN", RoleAdmin); err != nil {
|
||||||
|
panic(errors.New("could not set 'ROLE_ADMIN' property"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := o.Set("ROLE_SUPERADMIN", RoleSuperadmin); err != nil {
|
||||||
|
panic(errors.New("could not set 'ROLE_SUPERADMIN' property"))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/agent"
|
"forge.cadoles.com/Cadoles/emissary/internal/agent"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
||||||
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/bundle"
|
"forge.cadoles.com/arcad/edge/pkg/bundle"
|
||||||
"github.com/mitchellh/hashstructure/v2"
|
"github.com/mitchellh/hashstructure/v2"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -276,7 +277,21 @@ func (c *Controller) ensureAppBundle(ctx context.Context, appID string, spec spe
|
||||||
return nil, "", errors.WithStack(err)
|
return nil, "", errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bdle, "", nil
|
manifest, err := app.LoadManifest(bdle)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, err := validateManifest(manifest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !valid {
|
||||||
|
return nil, "", errors.New("bundle's manifest is invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
return bdle, spec.SHA256Sum, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Controller) downloadFile(url string, sha256sum string, dest string) error {
|
func (c *Controller) downloadFile(url string, sha256sum string, dest string) error {
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
||||||
|
"forge.cadoles.com/arcad/edge/pkg/app/metadata"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func validateManifest(manifest *app.Manifest) (bool, error) {
|
||||||
|
valid, err := manifest.Validate(
|
||||||
|
metadata.WithMinimumRoleValidator(RoleVisitor, RoleUser, RoleSuperuser, RoleAdmin, RoleSuperadmin),
|
||||||
|
metadata.WithNamedPathsValidator(metadata.NamedPathAdmin, metadata.NamedPathIcon),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return valid, nil
|
||||||
|
}
|
Loading…
Reference in New Issue