feat(auth): store and retrieve auth token from home directory by default (#2)
arcad/emissary/pipeline/head This commit looks good Details

This commit is contained in:
wpetit 2023-08-25 12:02:02 -06:00
parent 077964c7b9
commit 3d7a094cb8
4 changed files with 56 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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 := ioutil.ReadFile(flags.TokenFile) rawToken, err := os.ReadFile(tokenFile)
if err != nil && !errors.Is(err, os.ErrNotExist) { if err != nil && !errors.Is(err, os.ErrNotExist) {
return "", errors.WithStack(err) return "", errors.WithStack(err)
} }
if rawToken == nil { if rawToken == nil {
return "", nil continue
} }
return strings.TrimSpace(string(rawToken)), nil return strings.TrimSpace(string(rawToken)), nil
} }
return "", nil
}

View File

@ -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)
} }
output = os.ExpandEnv(output)
if output == "-" {
fmt.Println(token) 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
}, },