feat(controller,app): add app module

This commit is contained in:
2023-03-28 20:43:45 +02:00
parent 3d0b0102c2
commit e832b7dedd
21 changed files with 542 additions and 397 deletions

View File

@ -1,17 +0,0 @@
package app
import (
_ "embed"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
//go:embed schema.json
var schema []byte
func init() {
if err := spec.Register(NameApp, schema); err != nil {
panic(errors.WithStack(err))
}
}

View File

@ -1,87 +0,0 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://app.edge.emissary.cadoles.com/spec.json",
"title": "AppSpec",
"description": "Emissary 'App' specification",
"type": "object",
"properties": {
"apps": {
"type": "object",
"patternProperties": {
".*": {
"type": "object",
"properties": {
"url": {
"type": "string"
},
"sha256sum": {
"type": "string"
},
"address": {
"type": "string"
},
"format": {
"type": "string",
"enum": [
"zip",
"tar.gz"
]
}
},
"required": [
"url",
"sha256sum",
"address",
"format"
],
"additionalProperties": false
}
}
},
"auth": {
"type": "object",
"properties": {
"local": {
"type": "object",
"properties": {
"key": {
"type": ["object", "string"]
},
"accounts": {
"type": "array",
"items": {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"algo": {
"type": "string"
},
"claims": {
"type": "object"
}
},
"required": [
"username",
"password",
"algo"
]
}
}
},
"required": [
"key"
]
}
}
}
},
"required": [
"apps"
],
"additionalProperties": false
}

View File

@ -1,53 +0,0 @@
package app
import (
"forge.cadoles.com/Cadoles/emissary/internal/spec"
edgeAuth "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
)
const NameApp spec.Name = "app.emissary.cadoles.com"
type Spec struct {
Revision int `json:"revision"`
Apps map[string]AppEntry `json:"apps"`
Auth *Auth `json:"auth"`
}
type AppEntry struct {
URL string `json:"url"`
SHA256Sum string `json:"sha256sum"`
Address string `json:"address"`
Format string `json:"format"`
}
type Auth struct {
Local *LocalAuth `json:"local,omitempty"`
}
type LocalAuth struct {
Key any `json:"key"`
Accounts []edgeAuth.LocalAccount `json:"accounts"`
}
func (s *Spec) SpecName() spec.Name {
return NameApp
}
func (s *Spec) SpecRevision() int {
return s.Revision
}
func (s *Spec) SpecData() map[string]any {
return map[string]any{
"apps": s.Apps,
"auth": s.Auth,
}
}
func NewSpec() *Spec {
return &Spec{
Revision: -1,
}
}
var _ spec.Spec = &Spec{}

View File

@ -1,42 +0,0 @@
{
"name": "app.emissary.cadoles.com",
"data": {
"apps": {
"edge.sdk.client.test": {
"url": "http://example.com/edge.sdk.client.test_0.0.0.zip",
"sha256sum": "58019192dacdae17755707719707db007e26dac856102280583fbd18427dd352",
"address": ":8081",
"format": "zip"
}
},
"auth": {
"local": {
"key": {
"d": "YOre0WZefGfUGFvDg42oL5Oad5Zsb1N_hqPyLVM5ajpTZzcHpB3wT6In9tFO_VshB6lxVtPA9ckPkpMTFY7ygt1Yomc1HkoOKRtmIaqdr4VgNQifU-4yiLiJkSbdYSeMV-KkkN8mGR1keJpJeS34W1X0W6CkU2nw7F5VueBCJfWJA0funRfuWdI68MTUgT9kRZFp-SfvptvRL6jVYHV_5hqxzHCvgEdBSF6QKwx4M6P6QBMt7ft6uMLmFx9abKFw2V51hX3PkxiSepVB3w5CYg4HtS3AHX6bILL4m0R2pdTIkap7i3tkH_xAOuKWt8D6JhadI8X1rEAwXmCS5KrRgQ",
"dp": "U0HfvBC6hk-SCpuotGIv3vbHCVt1aF3SHK0y32EYCOe8e_9G6YCEILfcvEJ5fiOCc2kvx6TasHQu4qj1uWRKenZlK1sJ6KDybGCkZL1D3jYnbeLZYBuWBL__YbZiST3ewbxzj_EDMWiZ8sUltahza_1weSgg8auSzTHS2LJBHIE",
"dq": "hVom4ScDxgqhCsQNVpZlN7M3v0tgWjl_gTOHjOyzKCHQJeC0QmJJaMKkQZPWJ8jjLqy7VwVpqC2nZU7QDuX1Cq5eJDQcXi9XtaAfIBico9WcYDre6mDyhL588YHpekyRke8HnZ810iesr0G3gU1h0QvZVVuW-pXTJOXhZTt6nFc",
"e": "AQAB",
"kty": "RSA",
"n": "vPnpkE3-HfNgJSru_K40LstkjiG2Bq_Tt-m0d_yUBBSbirFxF3qH4EXi7WrtZdeDahg2iV2BvpbVVj9GlmGo9OLol6jc7AP2yvZrkbABiiJhCbuPdkYbNpx6B7Itl8RT_bUSYAMZhmux5lpsn4weQ01fzjICi1rA-bIJpOfotdOjP4_lol-LxGZOGJQv9kndP8bgmssJb3Y_2s4gPtkmXySLrhpr5So-_6dVksyuBD9aLcnsMLDbywusjEMCdhqzQbvOjryomnmEXwyz_Ewb5HFK2PfgFtoHkdjqDz-mrEs3tw5g4TdYhCftzJxgbyNAEq4aEiOQrAncYyrXlotP_w",
"p": "8TNMF0WUe7CEeNVUTsuEcBAAXRguNtpvVifIjlwzFRGOYVGIpKuHsqQPKlZL07I9gPr9LifQnyQus3oEmTOrVs6LB9sfbukbg43ZRKoGVM40JYF5Xjs7R3mEZhgU0WaYOVe3iLtBGMfXNWFwlbfQP-zEb-dPCBX1jWT3LdgNBcE",
"q": "yJJLNc9w6O4y2icME8k99FugV9E7ObwUxF3v5JN3y1cmAT0h2njyE3iAGqaDZwcY1_jGCisjwoqX6i5E8xqhxX3Gcy3J7SmUAf8fhY8wU3zv9DK7skg2IdvanDb8Y1OM6GchbYZAOVPEg2IvVio8zI-Ih3DDwDk8Df0ufzoHRb8",
"qi": "zOE-4R3cjPesm3MX-4PdwmsaF9QZLUVRUvvHJ08pKs6kAXP18hzjctAoOjhQDxlTYqNYNePfKzKwost3OJoPgRIc9w9qwUCK1gNOS4Z_xozCIaXgMddNFhkoAfZ4JaKjNCiinzjGfqG99Lf-yzmmREuuhRv7SdS3ST4VQjiJQew"
},
"accounts": [
{
"username": "foo",
"algo": "plain",
"password": "bar",
"claims": {
"arcad_role": "user",
"arcad_tenant": "dev.cli",
"preferred_username": "Foo",
"sub": "foo"
}
}
]
}
}
},
"revision": 0
}

View File

@ -1,65 +0,0 @@
package app
import (
"context"
"encoding/json"
"io/ioutil"
"testing"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/pkg/errors"
)
type validatorTestCase struct {
Name string
Source string
ShouldFail bool
}
var validatorTestCases = []validatorTestCase{
{
Name: "SpecOK",
Source: "testdata/spec-ok.json",
ShouldFail: false,
},
}
func TestValidator(t *testing.T) {
t.Parallel()
validator := spec.NewValidator()
if err := validator.Register(NameApp, schema); err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
for _, tc := range validatorTestCases {
func(tc validatorTestCase) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
rawSpec, err := ioutil.ReadFile(tc.Source)
if err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
var spec spec.RawSpec
if err := json.Unmarshal(rawSpec, &spec); err != nil {
t.Fatalf("+%v", errors.WithStack(err))
}
ctx := context.Background()
err = validator.Validate(ctx, &spec)
if !tc.ShouldFail && err != nil {
t.Errorf("+%v", errors.WithStack(err))
}
if tc.ShouldFail && err == nil {
t.Error("validation should have failed")
}
})
}(tc)
}
}