feat: initial commit
All checks were successful
Cadoles/bouncer/pipeline/head This commit looks good

This commit is contained in:
2023-04-24 20:52:12 +02:00
commit ac21629d28
90 changed files with 5730 additions and 0 deletions

View File

@ -0,0 +1,91 @@
package apierr
import (
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
)
func Wrap(err error) error {
apiErr := &api.Error{}
if !errors.As(err, &apiErr) {
return err
}
switch apiErr.Code {
case api.ErrCodeInvalidFieldValue:
return wrapInvalidFieldValueErr(apiErr)
default:
return wrapApiErrorWithMessage(apiErr)
}
}
func wrapApiErrorWithMessage(err *api.Error) error {
data, ok := err.Data.(map[string]any)
if !ok {
return err
}
rawMessage, exists := data["message"]
if !exists {
return err
}
message, ok := rawMessage.(string)
if !ok {
return err
}
return errors.Wrapf(err, message)
}
func wrapInvalidFieldValueErr(err *api.Error) error {
data, ok := err.Data.(map[string]any)
if !ok {
return err
}
rawFields, exists := data["Fields"]
if !exists {
return err
}
fields, ok := rawFields.([]any)
if !ok {
return err
}
var (
field string
rule string
)
if len(fields) == 0 {
return err
}
firstField, ok := fields[0].(map[string]any)
if !ok {
return err
}
param, ok := firstField["Param"].(string)
if !ok {
return err
}
tag, ok := firstField["Tag"].(string)
if !ok {
return err
}
fieldName, ok := firstField["Field"].(string)
if !ok {
return err
}
field = fieldName
rule = tag + "=" + param
return errors.Wrapf(err, "server expected field '%s' to match rule '%s'", field, rule)
}

View File

@ -0,0 +1,96 @@
package flag
import (
"fmt"
"io/ioutil"
"os"
"strings"
"forge.cadoles.com/cadoles/bouncer/internal/format"
"forge.cadoles.com/cadoles/bouncer/internal/format/table"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
)
func ComposeFlags(flags ...cli.Flag) []cli.Flag {
baseFlags := []cli.Flag{
&cli.StringFlag{
Name: "server",
Aliases: []string{"s"},
Usage: "use `SERVER` as server url",
Value: "http://127.0.0.1:3000",
},
&cli.StringFlag{
Name: "format",
Aliases: []string{"f"},
Usage: fmt.Sprintf("use `FORMAT` as output format (available: %s)", format.Available()),
Value: string(table.Format),
},
&cli.StringFlag{
Name: "output-mode",
Aliases: []string{"m"},
Usage: fmt.Sprintf("use `MODE` as output mode (available: %s)", []format.OutputMode{format.OutputModeCompact, format.OutputModeWide}),
Value: string(format.OutputModeCompact),
},
&cli.StringFlag{
Name: "token",
Aliases: []string{"t"},
Usage: "use `TOKEN` as authentication token",
},
&cli.StringFlag{
Name: "token-file",
Usage: "use `TOKEN_FILE` as file containing the authentication token",
Value: ".emissary-token",
TakesFile: true,
},
}
flags = append(flags, baseFlags...)
return flags
}
type BaseFlags struct {
ServerURL string
Format format.Format
OutputMode format.OutputMode
Token string
TokenFile string
}
func GetBaseFlags(ctx *cli.Context) *BaseFlags {
serverURL := ctx.String("server")
rawFormat := ctx.String("format")
rawOutputMode := ctx.String("output-mode")
tokenFile := ctx.String("token-file")
token := ctx.String("token")
return &BaseFlags{
ServerURL: serverURL,
Format: format.Format(rawFormat),
OutputMode: format.OutputMode(rawOutputMode),
Token: token,
TokenFile: tokenFile,
}
}
func GetToken(flags *BaseFlags) (string, error) {
if flags.Token != "" {
return flags.Token, nil
}
if flags.TokenFile == "" {
return "", nil
}
rawToken, err := ioutil.ReadFile(flags.TokenFile)
if err != nil && !errors.Is(err, os.ErrNotExist) {
return "", errors.WithStack(err)
}
if rawToken == nil {
return "", nil
}
return strings.TrimSpace(string(rawToken)), nil
}

View File

@ -0,0 +1,11 @@
package flag
func AsAnySlice[T any](src []T) []any {
dst := make([]any, len(src))
for i, s := range src {
dst[i] = s
}
return dst
}

View File

@ -0,0 +1,34 @@
package flag
import (
"errors"
clientFlag "forge.cadoles.com/cadoles/bouncer/internal/command/api/flag"
"forge.cadoles.com/cadoles/bouncer/internal/datastore"
"github.com/urfave/cli/v2"
)
func WithInboundFlags(flags ...cli.Flag) []cli.Flag {
baseFlags := clientFlag.ComposeFlags(
&cli.StringFlag{
Name: "inbound-id",
Aliases: []string{"in"},
Usage: "use `INBOUND_ID` as selected inbound",
Value: "",
},
)
flags = append(flags, baseFlags...)
return flags
}
func AssertInboundID(ctx *cli.Context) (datastore.InboundID, error) {
rawInboundID := ctx.String("inbound-id")
if rawInboundID == "" {
return "", errors.New("flag 'inbound-id' is required")
}
return datastore.InboundID(rawInboundID), nil
}

View File

@ -0,0 +1,13 @@
package inbound
import (
"github.com/urfave/cli/v2"
)
func Root() *cli.Command {
return &cli.Command{
Name: "agent",
Usage: "Inbounds related commands",
Subcommands: []*cli.Command{},
}
}

View File

@ -0,0 +1,17 @@
package inbound
import "forge.cadoles.com/cadoles/bouncer/internal/format"
func agentHints(outputMode format.OutputMode) format.Hints {
return format.Hints{
OutputMode: outputMode,
Props: []format.Prop{
format.NewProp("ID", "ID"),
format.NewProp("Label", "Label"),
format.NewProp("Thumbprint", "Thumbprint"),
format.NewProp("Status", "Status"),
format.NewProp("ContactedAt", "ContactedAt"),
format.NewProp("UpdatedAt", "UpdatedAt"),
},
}
}

View File

@ -0,0 +1,16 @@
package api
import (
"forge.cadoles.com/cadoles/bouncer/internal/command/api/inbound"
"github.com/urfave/cli/v2"
)
func Root() *cli.Command {
return &cli.Command{
Name: "api",
Usage: "API related commands",
Subcommands: []*cli.Command{
inbound.Root(),
},
}
}