feat(storage-server): jwt based authentication
All checks were successful
arcad/edge/pipeline/pr-master This commit looks good

This commit is contained in:
2023-09-28 23:41:01 -06:00
parent c63af872ea
commit d2472623f2
25 changed files with 646 additions and 235 deletions

View File

@ -16,6 +16,7 @@ import (
"forge.cadoles.com/arcad/edge/pkg/bus"
"forge.cadoles.com/arcad/edge/pkg/bus/memory"
appHTTP "forge.cadoles.com/arcad/edge/pkg/http"
"forge.cadoles.com/arcad/edge/pkg/jwtutil"
"forge.cadoles.com/arcad/edge/pkg/module"
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
appModuleMemory "forge.cadoles.com/arcad/edge/pkg/module/app/memory"
@ -50,6 +51,8 @@ import (
"forge.cadoles.com/arcad/edge/pkg/storage/share"
)
var dummySecret = []byte("not_so_secret")
func RunCommand() *cli.Command {
return &cli.Command{
Name: "run",
@ -194,13 +197,14 @@ func runApp(ctx context.Context, path, address, documentStoreDSN, blobStoreDSN,
ctx = logger.With(ctx, logger.F("appID", manifest.ID))
// Add auth handler
key, err := dummyKey()
key, err := jwtutil.NewSymmetricKey(dummySecret)
if err != nil {
return errors.WithStack(err)
}
deps := &moduleDeps{}
funcs := []ModuleDepFunc{
initAppID(manifest),
initMemoryBus,
initDatastores(documentStoreDSN, blobStoreDSN, shareStoreDSN, manifest.ID),
initAccounts(accountsFile, manifest.ID),
@ -220,17 +224,18 @@ func runApp(ctx context.Context, path, address, documentStoreDSN, blobStoreDSN,
appModule.Mount(appRepository),
authModule.Mount(
authHTTP.NewLocalHandler(
jwa.HS256, key,
key,
jwa.HS256,
authHTTP.WithRoutePrefix("/auth"),
authHTTP.WithAccounts(deps.Accounts...),
),
authModule.WithJWT(dummyKeySet),
authModule.WithJWT(func() (jwk.Set, error) {
return jwtutil.NewSymmetricKeySet(dummySecret)
}),
),
),
appHTTP.WithHTTPMiddlewares(
authModuleMiddleware.AnonymousUser(
jwa.HS256, key,
),
authModuleMiddleware.AnonymousUser(key, jwa.HS256),
),
)
if err := handler.Load(bundle); err != nil {
@ -276,7 +281,9 @@ func getServerModules(deps *moduleDeps) []app.ServerModuleFactory {
module.StoreModuleFactory(deps.DocumentStore),
blob.ModuleFactory(deps.Bus, deps.BlobStore),
authModule.ModuleFactory(
authModule.WithJWT(dummyKeySet),
authModule.WithJWT(func() (jwk.Set, error) {
return jwtutil.NewSymmetricKeySet(dummySecret)
}),
),
appModule.ModuleFactory(deps.AppRepository),
fetch.ModuleFactory(deps.Bus),
@ -284,36 +291,6 @@ func getServerModules(deps *moduleDeps) []app.ServerModuleFactory {
}
}
var dummySecret = []byte("not_so_secret")
func dummyKey() (jwk.Key, error) {
key, err := jwk.FromRaw(dummySecret)
if err != nil {
return nil, errors.WithStack(err)
}
return key, nil
}
func dummyKeySet() (jwk.Set, error) {
key, err := dummyKey()
if err != nil {
return nil, errors.WithStack(err)
}
if err := key.Set(jwk.AlgorithmKey, jwa.HS256); err != nil {
return nil, errors.WithStack(err)
}
set := jwk.NewSet()
if err := set.AddKey(key); err != nil {
return nil, errors.WithStack(err)
}
return set, nil
}
func ensureDir(path string) error {
if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
return errors.WithStack(err)
@ -435,6 +412,13 @@ func newAppRepository(host string, basePort uint64, manifests ...*app.Manifest)
)
}
func initAppID(manifest *app.Manifest) ModuleDepFunc {
return func(deps *moduleDeps) error {
deps.AppID = manifest.ID
return nil
}
}
func initAppRepository(repo appModule.Repository) ModuleDepFunc {
return func(deps *moduleDeps) error {
deps.AppRepository = repo