Compare commits
4 Commits
2023.8.25-
...
2023.9.20-
Author | SHA1 | Date | |
---|---|---|---|
6318a8b497 | |||
3d7a094cb8 | |||
077964c7b9 | |||
3af6324121 |
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -65,6 +65,8 @@ pipeline {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String currentVersion = sh(script: "MKT_PROJECT_VERSION_BRANCH_NAME=${env.BRANCH_NAME} make version", returnStdout: true).trim()
|
||||||
|
|
||||||
build(
|
build(
|
||||||
job: "../emissary-firmware/${env.GIT_BRANCH}",
|
job: "../emissary-firmware/${env.GIT_BRANCH}",
|
||||||
parameters: [
|
parameters: [
|
||||||
|
4
Makefile
4
Makefile
@ -118,7 +118,7 @@ gitea-release: .mktools tools/gitea-release/bin/gitea-release.sh goreleaser chan
|
|||||||
tools/gitea-release/bin/gitea-release.sh
|
tools/gitea-release/bin/gitea-release.sh
|
||||||
|
|
||||||
.emissary-token:
|
.emissary-token:
|
||||||
$(MAKE) run-emissary-server EMISSARY_CMD="--debug --config tmp/server.yml server auth create-token --role writer > .emissary-token"
|
$(MAKE) run-emissary-server EMISSARY_CMD="--debug --config tmp/server.yml server auth create-token --role writer --output .emissary-token"
|
||||||
|
|
||||||
AGENT_ID ?= 1
|
AGENT_ID ?= 1
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ update-edge-lib:
|
|||||||
|
|
||||||
.PHONY: changelog
|
.PHONY: changelog
|
||||||
changelog: .mktools
|
changelog: .mktools
|
||||||
$(MAKE) MKT_GIT_CHGLOG_ARGS='--tag-filter-pattern $(MKT_PROJECT_VERSION_CHANNEL) --output CHANGELOG.md' mkt-changelog
|
$(MAKE) MKT_GIT_CHGLOG_ARGS='--next-tag $(MKT_PROJECT_VERSION) --tag-filter-pattern $(MKT_PROJECT_VERSION_CHANNEL) --output CHANGELOG.md' mkt-changelog
|
||||||
|
|
||||||
.PHONY: mktools
|
.PHONY: mktools
|
||||||
mktools:
|
mktools:
|
||||||
|
@ -80,9 +80,11 @@
|
|||||||
5. Créer un jeton d'administration:
|
5. Créer un jeton d'administration:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
sudo emissary --workdir /usr/share/emissary --config /etc/emissary/server.yml server auth create-token --role writer --subject $(whoami) > .emissary-token
|
sudo emissary --workdir /usr/share/emissary --config /etc/emissary/server.yml server auth create-token --role writer --subject $(whoami)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> **Note** Le jeton sera stocké dans le répertoire `$HOME/.config/emissary`.
|
||||||
|
|
||||||
6. Vérifier l'authentification sur l'API:
|
6. Vérifier l'authentification sur l'API:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module forge.cadoles.com/Cadoles/emissary
|
|||||||
go 1.19
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978
|
forge.cadoles.com/arcad/edge v0.0.0-20230920152353-c3535a4a9b7f
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3
|
github.com/Masterminds/sprig/v3 v3.2.3
|
||||||
github.com/alecthomas/participle/v2 v2.0.0-beta.5
|
github.com/alecthomas/participle/v2 v2.0.0-beta.5
|
||||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
|
||||||
|
4
go.sum
4
go.sum
@ -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.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
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=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978 h1:fekSRSb8gYcVx8C0B9K6B7+KiFHVixIwvPUkxcnRFp4=
|
forge.cadoles.com/arcad/edge v0.0.0-20230920152353-c3535a4a9b7f h1:3DcH1hDBRjTaBJTlxzSJ0zf9G5/y0AUtyU11DiDhCwI=
|
||||||
forge.cadoles.com/arcad/edge v0.0.0-20230426135323-17808d14c978/go.mod h1:uv3wBa+UbcEUb7IiJCj1T96Xo3cmx1BwNxbBYRZhln8=
|
forge.cadoles.com/arcad/edge v0.0.0-20230920152353-c3535a4a9b7f/go.mod h1:uv3wBa+UbcEUb7IiJCj1T96Xo3cmx1BwNxbBYRZhln8=
|
||||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
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/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=
|
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
|
||||||
|
@ -90,10 +90,18 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
|
|||||||
|
|
||||||
modules := c.getAppModules(deps)
|
modules := c.getAppModules(deps)
|
||||||
|
|
||||||
|
anonymousUserMiddleware, err := getAnonymousUserMiddleware(specs.Config.Auth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not get anonymous user middleware")
|
||||||
|
}
|
||||||
|
|
||||||
options := []edgeHTTP.HandlerOptionFunc{
|
options := []edgeHTTP.HandlerOptionFunc{
|
||||||
edgeHTTP.WithBus(deps.Bus),
|
edgeHTTP.WithBus(deps.Bus),
|
||||||
edgeHTTP.WithServerModules(modules...),
|
edgeHTTP.WithServerModules(modules...),
|
||||||
edgeHTTP.WithHTTPMounts(mounts...),
|
edgeHTTP.WithHTTPMounts(mounts...),
|
||||||
|
edgeHTTP.WithHTTPMiddlewares(
|
||||||
|
anonymousUserMiddleware,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
return options, nil
|
return options, nil
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package app
|
package app
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
||||||
|
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/app"
|
"forge.cadoles.com/arcad/edge/pkg/app"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module"
|
"forge.cadoles.com/arcad/edge/pkg/module"
|
||||||
"forge.cadoles.com/arcad/edge/pkg/module/auth"
|
"forge.cadoles.com/arcad/edge/pkg/module/auth"
|
||||||
authModule "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"
|
authHTTP "forge.cadoles.com/arcad/edge/pkg/module/auth/http"
|
||||||
|
authModuleMiddleware "forge.cadoles.com/arcad/edge/pkg/module/auth/middleware"
|
||||||
|
|
||||||
"github.com/dop251/goja"
|
"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"
|
||||||
@ -91,3 +95,72 @@ func getAuthMount(auth *spec.Auth, keySet jwk.Set) (auth.MountFunc, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAnonymousUserMiddleware(auth *appSpec.Auth) (func(http.Handler) http.Handler, error) {
|
||||||
|
anonymousUserSigningKey, err := getAnonymousUserSigningKey(auth)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not get anonymous user signing key")
|
||||||
|
}
|
||||||
|
|
||||||
|
cookieDuration := defaultCookieDuration
|
||||||
|
if auth.Local.CookieDuration != "" {
|
||||||
|
cookieDuration, err = time.ParseDuration(auth.Local.CookieDuration)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
middleware := authModuleMiddleware.AnonymousUser(
|
||||||
|
anonymousUserSigningKey.Algorithm(),
|
||||||
|
anonymousUserSigningKey,
|
||||||
|
authModuleMiddleware.WithCookieOptions(getCookieDomain, cookieDuration),
|
||||||
|
)
|
||||||
|
|
||||||
|
return middleware, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getAnonymousUserSigningKey(auth *appSpec.Auth) (jwk.Key, error) {
|
||||||
|
var (
|
||||||
|
key jwk.Key
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
generateNewKey := func() (jwk.Key, error) {
|
||||||
|
key, err := jwk.Generate(2048)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
default:
|
||||||
|
fallthrough
|
||||||
|
case auth == nil:
|
||||||
|
key, err = generateNewKey()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not generate anonymous user signing key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, nil
|
||||||
|
|
||||||
|
case auth.Local != nil:
|
||||||
|
switch typedKey := auth.Local.Key.(type) {
|
||||||
|
case string:
|
||||||
|
key, err = jwk.FromRaw([]byte(typedKey))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not parse local auth key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := key.Set(jwk.AlgorithmKey, jwa.HS256); err != nil {
|
||||||
|
return nil, errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, errors.Errorf("unexpected key type '%T'", auth.Local.Key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return key, nil
|
||||||
|
}
|
||||||
|
@ -8,7 +8,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
|
||||||
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
appSpec "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/proxy/wildcard"
|
"forge.cadoles.com/Cadoles/emissary/internal/proxy/wildcard"
|
||||||
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
|
edgeHTTP "forge.cadoles.com/arcad/edge/pkg/http"
|
||||||
@ -128,7 +127,7 @@ func (s *Server) Stop() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(bundle bundle.Bundle, config *spec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
|
func NewServer(bundle bundle.Bundle, config *appSpec.Config, handlerOptions ...edgeHTTP.HandlerOptionFunc) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
bundle: bundle,
|
bundle: bundle,
|
||||||
config: config,
|
config: config,
|
||||||
|
@ -2,7 +2,6 @@ package flag
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -12,6 +11,11 @@ import (
|
|||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
AuthTokenDefaultHomePath = "$HOME/.config/emissary/auth-token"
|
||||||
|
AuthTokenDefaultLocalPath = ".emissary-token"
|
||||||
|
)
|
||||||
|
|
||||||
func ComposeFlags(flags ...cli.Flag) []cli.Flag {
|
func ComposeFlags(flags ...cli.Flag) []cli.Flag {
|
||||||
baseFlags := []cli.Flag{
|
baseFlags := []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -37,10 +41,10 @@ func ComposeFlags(flags ...cli.Flag) []cli.Flag {
|
|||||||
Aliases: []string{"t"},
|
Aliases: []string{"t"},
|
||||||
Usage: "use `TOKEN` as authentication token",
|
Usage: "use `TOKEN` as authentication token",
|
||||||
},
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "token-file",
|
Name: "token-file",
|
||||||
Usage: "use `TOKEN_FILE` as file containing the authentication token",
|
Usage: "use `TOKEN_FILE` as file containing the authentication token",
|
||||||
Value: ".emissary-token",
|
Value: cli.NewStringSlice(AuthTokenDefaultLocalPath, AuthTokenDefaultHomePath),
|
||||||
TakesFile: true,
|
TakesFile: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -55,14 +59,14 @@ type BaseFlags struct {
|
|||||||
Format format.Format
|
Format format.Format
|
||||||
OutputMode format.OutputMode
|
OutputMode format.OutputMode
|
||||||
Token string
|
Token string
|
||||||
TokenFile string
|
TokenFiles []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetBaseFlags(ctx *cli.Context) *BaseFlags {
|
func GetBaseFlags(ctx *cli.Context) *BaseFlags {
|
||||||
serverURL := ctx.String("server")
|
serverURL := ctx.String("server")
|
||||||
rawFormat := ctx.String("format")
|
rawFormat := ctx.String("format")
|
||||||
rawOutputMode := ctx.String("output-mode")
|
rawOutputMode := ctx.String("output-mode")
|
||||||
tokenFile := ctx.String("token-file")
|
tokenFiles := ctx.StringSlice("token-file")
|
||||||
token := ctx.String("token")
|
token := ctx.String("token")
|
||||||
|
|
||||||
return &BaseFlags{
|
return &BaseFlags{
|
||||||
@ -70,7 +74,7 @@ func GetBaseFlags(ctx *cli.Context) *BaseFlags {
|
|||||||
Format: format.Format(rawFormat),
|
Format: format.Format(rawFormat),
|
||||||
OutputMode: format.OutputMode(rawOutputMode),
|
OutputMode: format.OutputMode(rawOutputMode),
|
||||||
Token: token,
|
Token: token,
|
||||||
TokenFile: tokenFile,
|
TokenFiles: tokenFiles,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,18 +83,20 @@ func GetToken(flags *BaseFlags) (string, error) {
|
|||||||
return flags.Token, nil
|
return flags.Token, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if flags.TokenFile == "" {
|
for _, tokenFile := range flags.TokenFiles {
|
||||||
return "", nil
|
tokenFile = os.ExpandEnv(tokenFile)
|
||||||
|
|
||||||
|
rawToken, err := os.ReadFile(tokenFile)
|
||||||
|
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||||
|
return "", errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rawToken == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimSpace(string(rawToken)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
rawToken, err := ioutil.ReadFile(flags.TokenFile)
|
return "", nil
|
||||||
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
||||||
return "", errors.WithStack(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rawToken == nil {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return strings.TrimSpace(string(rawToken)), nil
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,11 @@ package auth
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/auth/thirdparty"
|
"forge.cadoles.com/Cadoles/emissary/internal/auth/thirdparty"
|
||||||
|
"forge.cadoles.com/Cadoles/emissary/internal/command/api/flag"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/command/common"
|
"forge.cadoles.com/Cadoles/emissary/internal/command/common"
|
||||||
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
|
||||||
"github.com/lithammer/shortuuid/v4"
|
"github.com/lithammer/shortuuid/v4"
|
||||||
@ -26,6 +29,13 @@ func CreateTokenCommand() *cli.Command {
|
|||||||
Usage: "associate `SUBJECT` to the token",
|
Usage: "associate `SUBJECT` to the token",
|
||||||
Value: fmt.Sprintf("user-%s", shortuuid.New()),
|
Value: fmt.Sprintf("user-%s", shortuuid.New()),
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "output",
|
||||||
|
Aliases: []string{"o"},
|
||||||
|
TakesFile: true,
|
||||||
|
Usage: "output token to `OUTPUT` (or '-' to print to stdout)",
|
||||||
|
Value: flag.AuthTokenDefaultHomePath,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(ctx *cli.Context) error {
|
Action: func(ctx *cli.Context) error {
|
||||||
conf, err := common.LoadConfig(ctx)
|
conf, err := common.LoadConfig(ctx)
|
||||||
@ -35,6 +45,7 @@ func CreateTokenCommand() *cli.Command {
|
|||||||
|
|
||||||
subject := ctx.String("subject")
|
subject := ctx.String("subject")
|
||||||
role := ctx.String("role")
|
role := ctx.String("role")
|
||||||
|
output := ctx.String("output")
|
||||||
|
|
||||||
localAuth := conf.Server.Auth.Local
|
localAuth := conf.Server.Auth.Local
|
||||||
if localAuth == nil {
|
if localAuth == nil {
|
||||||
@ -51,7 +62,23 @@ func CreateTokenCommand() *cli.Command {
|
|||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(token)
|
output = os.ExpandEnv(output)
|
||||||
|
|
||||||
|
if output == "-" {
|
||||||
|
fmt.Println(token)
|
||||||
|
} else {
|
||||||
|
outputDirectory := filepath.Dir(output)
|
||||||
|
|
||||||
|
if err := os.MkdirAll(outputDirectory, os.FileMode(0o700)); err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(output, []byte(token), os.FileMode(0o600)); err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Token written to '%s'.\n", output)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user