ci: add dedicated authelia-gen command (#3463)
Adds a dedicated authelia code/doc gen command.pull/3518/head
parent
802b21f3b5
commit
5304178165
|
@ -0,0 +1,34 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newAllCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "all",
|
||||||
|
Short: "Run all generators with default options",
|
||||||
|
RunE: allRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func allRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
for _, subCmd := range cmd.Parent().Commands() {
|
||||||
|
if subCmd == cmd || subCmd.Use == "completion" || subCmd.Use == "help [command]" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case subCmd.RunE != nil:
|
||||||
|
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case subCmd.Run != nil:
|
||||||
|
subCmd.Run(subCmd, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCodeCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "code",
|
||||||
|
Short: "Generate code",
|
||||||
|
RunE: codeRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newCodeKeysCmd())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func codeRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
for _, subCmd := range cmd.Commands() {
|
||||||
|
switch {
|
||||||
|
case subCmd.RunE != nil:
|
||||||
|
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case subCmd.Run != nil:
|
||||||
|
subCmd.Run(subCmd, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -16,92 +16,63 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewRunGenCmd implements the code generation cobra command.
|
func newCodeKeysCmd() *cobra.Command {
|
||||||
func NewRunGenCmd() (cmd *cobra.Command) {
|
cmd := &cobra.Command{
|
||||||
cmd = &cobra.Command{
|
Use: "keys",
|
||||||
Use: "gen",
|
Short: "Generate the list of valid configuration keys",
|
||||||
RunE: runGenE,
|
RunE: codeKeysRunE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringP("file", "f", "./internal/configuration/schema/keys.go", "Sets the path of the keys file")
|
||||||
|
cmd.Flags().String("package", "schema", "Sets the package name of the keys file")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runGenE(cmd *cobra.Command, args []string) (err error) {
|
func codeKeysRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
if err = genConfigurationKeys(); err != nil {
|
var (
|
||||||
|
file string
|
||||||
|
|
||||||
|
f *os.File
|
||||||
|
)
|
||||||
|
|
||||||
|
data := keysTemplateStruct{
|
||||||
|
Timestamp: time.Now(),
|
||||||
|
Keys: readTags("", reflect.TypeOf(schema.Configuration{})),
|
||||||
|
}
|
||||||
|
|
||||||
|
if file, err = cmd.Flags().GetString("file"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
if data.Package, err = cmd.Flags().GetString("package"); err != nil {
|
||||||
}
|
|
||||||
|
|
||||||
func genConfigurationKeys() (err error) {
|
|
||||||
data := loadKeysTemplate()
|
|
||||||
|
|
||||||
f, err := os.Create("./internal/configuration/schema/keys.go")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return keysTemplate.Execute(f, data)
|
if f, err = os.Create(file); err != nil {
|
||||||
|
return fmt.Errorf("failed to create file '%s': %w", file, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
content []byte
|
||||||
|
tmpl *template.Template
|
||||||
|
)
|
||||||
|
|
||||||
|
if content, err = templatesFS.ReadFile("templates/config_keys.go.tmpl"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if tmpl, err = template.New("keys").Parse(string(content)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpl.Execute(f, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
var keysTemplate = template.Must(template.New("keys").Parse(`// Code generated by go generate. DO NOT EDIT.
|
|
||||||
//
|
|
||||||
// Run the following command to generate this file:
|
|
||||||
// go run ./cmd/authelia-scripts gen
|
|
||||||
//
|
|
||||||
|
|
||||||
package schema
|
|
||||||
|
|
||||||
// Keys represents the detected schema keys.
|
|
||||||
var Keys = []string{
|
|
||||||
{{- range .Keys }}
|
|
||||||
{{ printf "%q" . }},
|
|
||||||
{{- end }}
|
|
||||||
}
|
|
||||||
`))
|
|
||||||
|
|
||||||
type keysTemplateStruct struct {
|
type keysTemplateStruct struct {
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
Keys []string
|
Keys []string
|
||||||
}
|
Package string
|
||||||
|
|
||||||
func loadKeysTemplate() keysTemplateStruct {
|
|
||||||
config := schema.Configuration{
|
|
||||||
Storage: schema.StorageConfiguration{
|
|
||||||
Local: &schema.LocalStorageConfiguration{},
|
|
||||||
MySQL: &schema.MySQLStorageConfiguration{},
|
|
||||||
PostgreSQL: &schema.PostgreSQLStorageConfiguration{},
|
|
||||||
},
|
|
||||||
Notifier: schema.NotifierConfiguration{
|
|
||||||
FileSystem: &schema.FileSystemNotifierConfiguration{},
|
|
||||||
SMTP: &schema.SMTPNotifierConfiguration{
|
|
||||||
TLS: &schema.TLSConfig{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
AuthenticationBackend: schema.AuthenticationBackendConfiguration{
|
|
||||||
File: &schema.FileAuthenticationBackendConfiguration{
|
|
||||||
Password: &schema.PasswordConfiguration{},
|
|
||||||
},
|
|
||||||
LDAP: &schema.LDAPAuthenticationBackendConfiguration{
|
|
||||||
TLS: &schema.TLSConfig{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Session: schema.SessionConfiguration{
|
|
||||||
Redis: &schema.RedisSessionConfiguration{
|
|
||||||
TLS: &schema.TLSConfig{},
|
|
||||||
HighAvailability: &schema.RedisHighAvailabilityConfiguration{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
IdentityProviders: schema.IdentityProvidersConfiguration{
|
|
||||||
OIDC: &schema.OpenIDConnectConfiguration{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return keysTemplateStruct{
|
|
||||||
Timestamp: time.Now(),
|
|
||||||
Keys: readTags("", reflect.TypeOf(config)),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var decodedTypes = []reflect.Type{
|
var decodedTypes = []reflect.Type{
|
|
@ -0,0 +1,33 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDocsCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "docs",
|
||||||
|
Short: "Generate docs",
|
||||||
|
RunE: docsRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().StringP("cwd", "C", "", "Sets the CWD for git commands")
|
||||||
|
cmd.AddCommand(newDocsCLICmd(), newDocsDateCmd())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func docsRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
for _, subCmd := range cmd.Commands() {
|
||||||
|
switch {
|
||||||
|
case subCmd.RunE != nil:
|
||||||
|
if err = subCmd.RunE(subCmd, args); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case subCmd.Run != nil:
|
||||||
|
subCmd.Run(subCmd, args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,154 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
|
|
||||||
|
cmdscripts "github.com/authelia/authelia/v4/cmd/authelia-scripts/cmd"
|
||||||
|
"github.com/authelia/authelia/v4/internal/commands"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDocsCLICmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "cli",
|
||||||
|
Short: "Generate CLI docs",
|
||||||
|
RunE: docsCLIRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringP("directory", "d", "./docs/content/en/reference/cli", "The directory to store the markdown in")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func docsCLIRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
var root string
|
||||||
|
|
||||||
|
if root, err = cmd.Flags().GetString("directory"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = os.MkdirAll(root, 0775); err != nil {
|
||||||
|
if !os.IsExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDoc(commands.NewRootCmd(), filepath.Join(root, "authelia")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDocWriteIndex(root, "authelia"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDoc(cmdscripts.NewRootCmd(), filepath.Join(root, "authelia-scripts")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDocWriteIndex(root, "authelia-scripts"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDoc(newRootCmd(), filepath.Join(root, "authelia-gen")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = genCLIDocWriteIndex(root, "authelia-gen"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genCLIDoc(cmd *cobra.Command, path string) (err error) {
|
||||||
|
if err = os.Mkdir(path, 0755); err != nil {
|
||||||
|
if !os.IsExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = doc.GenMarkdownTreeCustom(cmd, path, prepend, linker); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genCLIDocWriteIndex(path, name string) (err error) {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
f, err := os.Create(filepath.Join(path, name, "_index.md"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
weight := 900
|
||||||
|
|
||||||
|
if name == "authelia" {
|
||||||
|
weight = 320
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprintf(f, indexDocs, name, now.Format(dateFmtYAML), "cli-"+name, weight)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepend(input string) string {
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
pathz := strings.Split(strings.Replace(input, ".md", "", 1), "\\")
|
||||||
|
parts := strings.Split(pathz[len(pathz)-1], "_")
|
||||||
|
|
||||||
|
cmd := parts[0]
|
||||||
|
|
||||||
|
args := strings.Join(parts, " ")
|
||||||
|
|
||||||
|
weight := 330
|
||||||
|
if len(parts) == 1 {
|
||||||
|
weight = 320
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf(prefixDocs, args, fmt.Sprintf("Reference for the %s command.", args), "", now.Format(dateFmtYAML), "cli-"+cmd, weight)
|
||||||
|
}
|
||||||
|
|
||||||
|
func linker(input string) string {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
const indexDocs = `---
|
||||||
|
title: "%s"
|
||||||
|
description: ""
|
||||||
|
lead: ""
|
||||||
|
date: %s
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "cli"
|
||||||
|
identifier: "%s"
|
||||||
|
weight: %d
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
`
|
||||||
|
|
||||||
|
const prefixDocs = `---
|
||||||
|
title: "%s"
|
||||||
|
description: "%s"
|
||||||
|
lead: "%s"
|
||||||
|
date: %s
|
||||||
|
draft: false
|
||||||
|
images: []
|
||||||
|
menu:
|
||||||
|
reference:
|
||||||
|
parent: "%s"
|
||||||
|
weight: %d
|
||||||
|
toc: true
|
||||||
|
---
|
||||||
|
|
||||||
|
`
|
|
@ -0,0 +1,220 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newDocsDateCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "date",
|
||||||
|
Short: "Generate doc dates",
|
||||||
|
RunE: docsDateRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringP("directory", "d", "./docs/content", "The directory to modify")
|
||||||
|
cmd.Flags().String("commit-until", "HEAD", "The commit to check the logs until")
|
||||||
|
cmd.Flags().String("commit-since", "", "The commit to check the logs since")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func docsDateRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
|
var (
|
||||||
|
dir, cwd, commitUtil, commitSince, commitFilter string
|
||||||
|
)
|
||||||
|
|
||||||
|
if dir, err = cmd.Flags().GetString("directory"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cwd, err = cmd.Flags().GetString("cwd"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.Flags().Changed("commit-since") {
|
||||||
|
if commitUtil, err = cmd.Flags().GetString("commit-util"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if commitSince, err = cmd.Flags().GetString("commit-since"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
commitFilter = fmt.Sprintf("%s...%s", commitUtil, commitSince)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasSuffix(info.Name(), ".md") {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
abs, err := filepath.Abs(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
frontmatterBytes := getFrontmatter(abs)
|
||||||
|
|
||||||
|
if frontmatterBytes == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
frontmatter := map[string]interface{}{}
|
||||||
|
|
||||||
|
if err = yaml.Unmarshal(frontmatterBytes, frontmatter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
date time.Time
|
||||||
|
)
|
||||||
|
|
||||||
|
if value, ok := frontmatter["date"]; ok {
|
||||||
|
date = value.(time.Time)
|
||||||
|
}
|
||||||
|
|
||||||
|
dateGit := getDateFromGit(cwd, abs, commitFilter)
|
||||||
|
|
||||||
|
replaceDates(abs, date, dateGit)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var newline = []byte("\n")
|
||||||
|
|
||||||
|
func getDateFromGit(cwd, path, commitFilter string) *time.Time {
|
||||||
|
var args []string
|
||||||
|
|
||||||
|
if len(cwd) != 0 {
|
||||||
|
args = append(args, "-C", cwd)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "log")
|
||||||
|
|
||||||
|
if len(commitFilter) != 0 {
|
||||||
|
args = append(args, commitFilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
args = append(args, "-1", "--follow", "--diff-filter=A", "--pretty=format:%cD", "--", path)
|
||||||
|
|
||||||
|
return getTimeFromGitCmd(exec.Command("git", args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTimeFromGitCmd(cmd *exec.Cmd) *time.Time {
|
||||||
|
var (
|
||||||
|
output []byte
|
||||||
|
err error
|
||||||
|
t time.Time
|
||||||
|
)
|
||||||
|
|
||||||
|
if output, err = cmd.Output(); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, err = time.Parse(dateFmtRFC2822, string(output)); err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &t
|
||||||
|
}
|
||||||
|
|
||||||
|
func replaceDates(path string, date time.Time, dateGit *time.Time) {
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
|
||||||
|
var dateGitLine string
|
||||||
|
|
||||||
|
dateLine := fmt.Sprintf("date: %s", date.Format(dateFmtYAML))
|
||||||
|
|
||||||
|
if dateGit != nil {
|
||||||
|
dateGitLine = fmt.Sprintf("date: %s", dateGit.Format(dateFmtYAML))
|
||||||
|
} else {
|
||||||
|
dateGitLine = dateLine
|
||||||
|
}
|
||||||
|
|
||||||
|
found := 0
|
||||||
|
|
||||||
|
frontmatter := 0
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
if found < 2 && frontmatter < 2 {
|
||||||
|
switch {
|
||||||
|
case scanner.Text() == frontmatterDelimiterLine:
|
||||||
|
buf.Write(scanner.Bytes())
|
||||||
|
frontmatter++
|
||||||
|
case frontmatter != 0 && strings.HasPrefix(scanner.Text(), "date: "):
|
||||||
|
buf.WriteString(dateGitLine)
|
||||||
|
found++
|
||||||
|
default:
|
||||||
|
buf.Write(scanner.Bytes())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
buf.Write(scanner.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.Close()
|
||||||
|
|
||||||
|
newF, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = buf.WriteTo(newF)
|
||||||
|
|
||||||
|
newF.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFrontmatter(path string) []byte {
|
||||||
|
f, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(f)
|
||||||
|
|
||||||
|
var start bool
|
||||||
|
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
if start {
|
||||||
|
if scanner.Text() == frontmatterDelimiterLine {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(scanner.Bytes())
|
||||||
|
buf.Write(newline)
|
||||||
|
} else if scanner.Text() == frontmatterDelimiterLine {
|
||||||
|
start = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
const (
|
||||||
|
dateFmtRFC2822 = "Mon, _2 Jan 2006 15:04:05 -0700"
|
||||||
|
dateFmtYAML = "2006-01-02T15:04:05-07:00"
|
||||||
|
frontmatterDelimiterLine = "---"
|
||||||
|
)
|
|
@ -0,0 +1,27 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed templates/*
|
||||||
|
var templatesFS embed.FS
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if err := newRootCmd().Execute(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newRootCmd() *cobra.Command {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "authelia-gen",
|
||||||
|
Short: "Authelia's generator tooling",
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newAllCmd(), newCodeCmd(), newDocsCmd())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
// Code generated by go generate. DO NOT EDIT.
|
||||||
|
//
|
||||||
|
// Run the following command to generate this file:
|
||||||
|
// go run ./cmd/authelia-gen code keys
|
||||||
|
//
|
||||||
|
|
||||||
|
package {{ .Package }}
|
||||||
|
|
||||||
|
// Keys is a list of valid schema keys detected by reflecting over a schema.Configuration struct.
|
||||||
|
var Keys = []string{
|
||||||
|
{{- range .Keys }}
|
||||||
|
{{ printf "%q" . }},
|
||||||
|
{{- end }}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -12,10 +12,53 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// HostEntry represents an entry in /etc/hosts.
|
func newBootstrapCmd() (cmd *cobra.Command) {
|
||||||
type HostEntry struct {
|
cmd = &cobra.Command{
|
||||||
Domain string
|
Use: "bootstrap",
|
||||||
IP string
|
Short: cmdBootstrapShort,
|
||||||
|
Long: cmdBootstrapLong,
|
||||||
|
Example: cmdBootstrapExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdBootstrapRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdBootstrapRun(_ *cobra.Command, _ []string) {
|
||||||
|
bootstrapPrintln("Checking command installation...")
|
||||||
|
checkCommandExist("node", "Follow installation guidelines from https://nodejs.org/en/download/package-manager/ or download installer from https://nodejs.org/en/download/")
|
||||||
|
checkCommandExist("pnpm", "Follow installation guidelines from https://pnpm.io/installation")
|
||||||
|
checkCommandExist("docker", "Follow installation guidelines from https://docs.docker.com/get-docker/")
|
||||||
|
checkCommandExist("docker-compose", "Follow installation guidelines from https://docs.docker.com/compose/install/")
|
||||||
|
|
||||||
|
bootstrapPrintln("Getting versions of tools")
|
||||||
|
readVersions()
|
||||||
|
|
||||||
|
bootstrapPrintln("Checking if GOPATH is set")
|
||||||
|
|
||||||
|
goPathFound := false
|
||||||
|
|
||||||
|
for _, v := range os.Environ() {
|
||||||
|
if strings.HasPrefix(v, "GOPATH=") {
|
||||||
|
goPathFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !goPathFound {
|
||||||
|
log.Fatal("GOPATH is not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
createTemporaryDirectory()
|
||||||
|
createPNPMDirectory()
|
||||||
|
|
||||||
|
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
||||||
|
prepareHostsFile()
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.")
|
||||||
|
bootstrapPrintln("More details at https://github.com/authelia/authelia/blob/master/docs/getting-started.md")
|
||||||
}
|
}
|
||||||
|
|
||||||
var hostEntries = []HostEntry{
|
var hostEntries = []HostEntry{
|
||||||
|
@ -78,9 +121,8 @@ func runCommand(cmd string, args ...string) {
|
||||||
func checkCommandExist(cmd string, resolutionHint string) {
|
func checkCommandExist(cmd string, resolutionHint string) {
|
||||||
fmt.Print("Checking if '" + cmd + "' command is installed...")
|
fmt.Print("Checking if '" + cmd + "' command is installed...")
|
||||||
command := exec.Command("bash", "-c", "command -v "+cmd) //nolint:gosec // Used only in development.
|
command := exec.Command("bash", "-c", "command -v "+cmd) //nolint:gosec // Used only in development.
|
||||||
err := command.Run()
|
|
||||||
|
|
||||||
if err != nil {
|
if command.Run() != nil {
|
||||||
msg := "[ERROR] You must install " + cmd + " on your machine."
|
msg := "[ERROR] You must install " + cmd + " on your machine."
|
||||||
if resolutionHint != "" {
|
if resolutionHint != "" {
|
||||||
msg += fmt.Sprintf(" %s", resolutionHint)
|
msg += fmt.Sprintf(" %s", resolutionHint)
|
||||||
|
@ -214,40 +256,3 @@ func readVersions() {
|
||||||
readVersion("docker", "--version")
|
readVersion("docker", "--version")
|
||||||
readVersion("docker-compose", "version")
|
readVersion("docker-compose", "version")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap bootstrap authelia dev environment.
|
|
||||||
func Bootstrap(cobraCmd *cobra.Command, args []string) {
|
|
||||||
bootstrapPrintln("Checking command installation...")
|
|
||||||
checkCommandExist("node", "Follow installation guidelines from https://nodejs.org/en/download/package-manager/ or download installer from https://nodejs.org/en/download/")
|
|
||||||
checkCommandExist("pnpm", "Follow installation guidelines from https://pnpm.io/installation")
|
|
||||||
checkCommandExist("docker", "Follow installation guidelines from https://docs.docker.com/get-docker/")
|
|
||||||
checkCommandExist("docker-compose", "Follow installation guidelines from https://docs.docker.com/compose/install/")
|
|
||||||
|
|
||||||
bootstrapPrintln("Getting versions of tools")
|
|
||||||
readVersions()
|
|
||||||
|
|
||||||
bootstrapPrintln("Checking if GOPATH is set")
|
|
||||||
|
|
||||||
goPathFound := false
|
|
||||||
|
|
||||||
for _, v := range os.Environ() {
|
|
||||||
if strings.HasPrefix(v, "GOPATH=") {
|
|
||||||
goPathFound = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !goPathFound {
|
|
||||||
log.Fatal("GOPATH is not set")
|
|
||||||
}
|
|
||||||
|
|
||||||
createTemporaryDirectory()
|
|
||||||
createPNPMDirectory()
|
|
||||||
|
|
||||||
bootstrapPrintln("Preparing /etc/hosts to serve subdomains of example.com...")
|
|
||||||
prepareHostsFile()
|
|
||||||
|
|
||||||
fmt.Println()
|
|
||||||
bootstrapPrintln("Run 'authelia-scripts suites setup Standalone' to start Authelia and visit https://home.example.com:8080.")
|
|
||||||
bootstrapPrintln("More details at https://github.com/authelia/authelia/blob/master/docs/getting-started.md")
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -12,8 +12,65 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func buildAutheliaBinary(xflags []string, buildkite bool) {
|
func newBuildCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "build",
|
||||||
|
Short: cmdBuildShort,
|
||||||
|
Long: cmdBuildLong,
|
||||||
|
Example: cmdBuildExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdBuildRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdBuildRun(cobraCmd *cobra.Command, args []string) {
|
||||||
|
branch := os.Getenv("BUILDKITE_BRANCH")
|
||||||
|
|
||||||
|
if strings.HasPrefix(branch, "renovate/") {
|
||||||
|
buildFrontend(branch)
|
||||||
|
log.Info("Skip building Authelia for deps...")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Building Authelia...")
|
||||||
|
|
||||||
|
cmdCleanRun(cobraCmd, args)
|
||||||
|
|
||||||
|
xflags, err := getXFlags(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("Creating `" + OutputDir + "` directory")
|
||||||
|
|
||||||
|
if err = os.MkdirAll(OutputDir, os.ModePerm); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("Building Authelia frontend...")
|
||||||
|
buildFrontend(branch)
|
||||||
|
|
||||||
|
log.Debug("Building swagger-ui frontend...")
|
||||||
|
buildSwagger()
|
||||||
|
|
||||||
|
buildkite, _ := cobraCmd.Flags().GetBool("buildkite")
|
||||||
|
|
||||||
if buildkite {
|
if buildkite {
|
||||||
|
log.Info("Building Authelia Go binaries with gox...")
|
||||||
|
|
||||||
|
buildAutheliaBinaryGOX(xflags)
|
||||||
|
} else {
|
||||||
|
log.Info("Building Authelia Go binary...")
|
||||||
|
|
||||||
|
buildAutheliaBinaryGO(xflags)
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanAssets()
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildAutheliaBinaryGOX(xflags []string) {
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
|
|
||||||
s := time.Now()
|
s := time.Now()
|
||||||
|
@ -52,7 +109,9 @@ func buildAutheliaBinary(xflags []string, buildkite bool) {
|
||||||
e := time.Since(s)
|
e := time.Since(s)
|
||||||
|
|
||||||
log.Debugf("Binary compilation completed in %s.", e)
|
log.Debugf("Binary compilation completed in %s.", e)
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
func buildAutheliaBinaryGO(xflags []string) {
|
||||||
cmd := utils.CommandWithStdout("go", "build", "-buildmode=pie", "-trimpath", "-o", OutputDir+"/authelia", "-ldflags", "-linkmode=external -s -w "+strings.Join(xflags, " "), "./cmd/authelia/")
|
cmd := utils.CommandWithStdout("go", "build", "-buildmode=pie", "-trimpath", "-o", OutputDir+"/authelia", "-ldflags", "-linkmode=external -s -w "+strings.Join(xflags, " "), "./cmd/authelia/")
|
||||||
|
|
||||||
cmd.Env = append(os.Environ(),
|
cmd.Env = append(os.Environ(),
|
||||||
|
@ -62,7 +121,6 @@ func buildAutheliaBinary(xflags []string, buildkite bool) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildFrontend(branch string) {
|
func buildFrontend(branch string) {
|
||||||
|
@ -133,47 +191,3 @@ func cleanAssets() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build build Authelia.
|
|
||||||
func Build(cobraCmd *cobra.Command, args []string) {
|
|
||||||
buildkite, _ := cobraCmd.Flags().GetBool("buildkite")
|
|
||||||
branch := os.Getenv("BUILDKITE_BRANCH")
|
|
||||||
|
|
||||||
if strings.HasPrefix(branch, "renovate/") {
|
|
||||||
buildFrontend(branch)
|
|
||||||
log.Info("Skip building Authelia for deps...")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Building Authelia...")
|
|
||||||
|
|
||||||
Clean(cobraCmd, args)
|
|
||||||
|
|
||||||
xflags, err := getXFlags(branch, os.Getenv("BUILDKITE_BUILD_NUMBER"), "")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Creating `" + OutputDir + "` directory")
|
|
||||||
err = os.MkdirAll(OutputDir, os.ModePerm)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debug("Building Authelia frontend...")
|
|
||||||
buildFrontend(branch)
|
|
||||||
|
|
||||||
log.Debug("Building swagger-ui frontend...")
|
|
||||||
buildSwagger()
|
|
||||||
|
|
||||||
if buildkite {
|
|
||||||
log.Debug("Building Authelia Go binaries with gox...")
|
|
||||||
} else {
|
|
||||||
log.Debug("Building Authelia Go binary...")
|
|
||||||
}
|
|
||||||
|
|
||||||
buildAutheliaBinary(xflags, buildkite)
|
|
||||||
|
|
||||||
cleanAssets()
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
@ -7,12 +7,23 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunCI run the CI scripts.
|
func newCICmd() (cmd *cobra.Command) {
|
||||||
func RunCI(cmd *cobra.Command, args []string) {
|
cmd = &cobra.Command{
|
||||||
|
Use: "ci",
|
||||||
|
Short: cmdCIShort,
|
||||||
|
Long: cmdCILong,
|
||||||
|
Example: cmdCIExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdCIRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdCIRun(cmd *cobra.Command, _ []string) {
|
||||||
log.Info("=====> Build stage <=====")
|
log.Info("=====> Build stage <=====")
|
||||||
|
|
||||||
buildkite, _ := cmd.Flags().GetBool("buildkite")
|
if buildkite, _ := cmd.Flags().GetBool("buildkite"); buildkite {
|
||||||
if buildkite {
|
|
||||||
if err := utils.CommandWithStdout("authelia-scripts", "--log-level", "debug", "--buildkite", "build").Run(); err != nil {
|
if err := utils.CommandWithStdout("authelia-scripts", "--log-level", "debug", "--buildkite", "build").Run(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newCleanCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "clean",
|
||||||
|
Short: cmdCleanShort,
|
||||||
|
Long: cmdCleanLong,
|
||||||
|
Example: cmdCleanExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdCleanRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdCleanRun(_ *cobra.Command, _ []string) {
|
||||||
|
log.Debug("Removing `" + OutputDir + "` directory")
|
||||||
|
err := os.RemoveAll(OutputDir)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
// OutputDir the output directory where the built version of Authelia is located.
|
||||||
|
var OutputDir = "dist"
|
||||||
|
|
||||||
|
// DockerImageName the official name of Authelia docker image.
|
||||||
|
var DockerImageName = "authelia/authelia"
|
||||||
|
|
||||||
|
// IntermediateDockerImageName local name of the docker image.
|
||||||
|
var IntermediateDockerImageName = "authelia:dist"
|
||||||
|
|
||||||
|
const dockerhub = "docker.io"
|
||||||
|
const ghcr = "ghcr.io"
|
||||||
|
|
||||||
|
const masterTag = "master"
|
||||||
|
const stringFalse = "false"
|
||||||
|
const webDirectory = "web"
|
||||||
|
|
||||||
|
const fmtLDFLAGSX = "-X 'github.com/authelia/authelia/v4/internal/utils.%s=%s'"
|
||||||
|
|
||||||
|
const (
|
||||||
|
cmdRootShort = "A utility used in the Authelia development process."
|
||||||
|
|
||||||
|
cmdRootLong = `The authelia-scripts utility is utilized by developers and the CI/CD pipeline for configuring
|
||||||
|
testing suites and various other aspects of the environment.
|
||||||
|
|
||||||
|
It can be used to automate or manually run unit testing, integration testing, etc.`
|
||||||
|
|
||||||
|
cmdRootExample = `authelia-scripts help`
|
||||||
|
|
||||||
|
cmdBootstrapShort = "Prepare environment for development and testing"
|
||||||
|
|
||||||
|
cmdBootstrapLong = `Prepare environment for development and testing.`
|
||||||
|
|
||||||
|
cmdBootstrapExample = `authelia-scripts bootstrap`
|
||||||
|
|
||||||
|
cmdBuildShort = "Build Authelia binary and static assets"
|
||||||
|
|
||||||
|
cmdBuildLong = `Build Authelia binary and static assets.`
|
||||||
|
|
||||||
|
cmdBuildExample = `authelia-scripts build`
|
||||||
|
|
||||||
|
cmdCleanShort = "Clean build artifacts"
|
||||||
|
|
||||||
|
cmdCleanLong = `Clean build artifacts.`
|
||||||
|
|
||||||
|
cmdCleanExample = `authelia-scripts clean`
|
||||||
|
|
||||||
|
cmdCIShort = "Run the continuous integration script"
|
||||||
|
|
||||||
|
cmdCILong = `Run the continuous integration script.`
|
||||||
|
|
||||||
|
cmdCIExample = `authelia-scripts ci`
|
||||||
|
|
||||||
|
cmdDockerShort = "Commands related to building and publishing docker image"
|
||||||
|
|
||||||
|
cmdDockerLong = `Commands related to building and publishing docker image.`
|
||||||
|
|
||||||
|
cmdDockerExample = `authelia-scripts docker`
|
||||||
|
|
||||||
|
cmdDockerBuildShort = "Build the docker image of Authelia"
|
||||||
|
|
||||||
|
cmdDockerBuildLong = `Build the docker image of Authelia.`
|
||||||
|
|
||||||
|
cmdDockerBuildExample = `authelia-scripts docker build`
|
||||||
|
|
||||||
|
cmdDockerPushManifestShort = "Push Authelia docker manifest to the Docker registries"
|
||||||
|
|
||||||
|
cmdDockerPushManifestLong = `Push Authelia docker manifest to the Docker registries.`
|
||||||
|
|
||||||
|
cmdDockerPushManifestExample = `authelia-scripts docker push-manifest`
|
||||||
|
|
||||||
|
cmdServeShort = "Serve compiled version of Authelia"
|
||||||
|
|
||||||
|
cmdServeLong = `Serve compiled version of Authelia.`
|
||||||
|
|
||||||
|
cmdServeExample = `authelia-scripts serve test.yml`
|
||||||
|
|
||||||
|
cmdSuitesShort = "Commands related to suites management"
|
||||||
|
|
||||||
|
cmdSuitesLong = `Commands related to suites management.`
|
||||||
|
|
||||||
|
cmdSuitesExample = `authelia-scripts suites`
|
||||||
|
|
||||||
|
cmdSuitesListShort = "List available suites"
|
||||||
|
|
||||||
|
cmdSuitesListLong = `List available suites.
|
||||||
|
|
||||||
|
Suites can be ran with the authelia-scripts suites test [suite] command.`
|
||||||
|
|
||||||
|
cmdSuitesListExample = `authelia-scripts suites list`
|
||||||
|
|
||||||
|
cmdSuitesTestShort = "Run a test suite"
|
||||||
|
|
||||||
|
cmdSuitesTestLong = `Run a test suite.
|
||||||
|
|
||||||
|
Suites can be listed with the authelia-scripts suites list command.`
|
||||||
|
|
||||||
|
cmdSuitesTestExample = `authelia-scripts suites test Standalone`
|
||||||
|
|
||||||
|
cmdSuitesSetupShort = "Setup a test suite environment"
|
||||||
|
|
||||||
|
cmdSuitesSetupLong = `Setup a test suite environment.
|
||||||
|
|
||||||
|
Suites can be listed with the authelia-scripts suites list command.`
|
||||||
|
|
||||||
|
cmdSuitesSetupExample = `authelia-scripts suites setup Standalone`
|
||||||
|
|
||||||
|
cmdSuitesTeardownShort = "Teardown a test suite environment"
|
||||||
|
|
||||||
|
cmdSuitesTeardownLong = `Teardown a test suite environment.
|
||||||
|
|
||||||
|
Suites can be listed with the authelia-scripts suites list command.`
|
||||||
|
|
||||||
|
cmdSuitesTeardownExample = `authelia-scripts suites setup Standalone`
|
||||||
|
|
||||||
|
cmdUnitTestShort = "Run unit tests"
|
||||||
|
|
||||||
|
cmdUnitTestLong = `Run unit tests.`
|
||||||
|
|
||||||
|
cmdUnitTestExample = `authelia-scripts unittest`
|
||||||
|
|
||||||
|
cmdXFlagsShort = "Generate X LDFlags for building Authelia"
|
||||||
|
|
||||||
|
cmdXFlagsLong = `Generate X LDFlags for building Authelia.`
|
||||||
|
|
||||||
|
cmdXFlagsExample = `authelia-scripts xflags`
|
||||||
|
)
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -23,8 +23,103 @@ var ignoredSuffixes = regexp.MustCompile("alpha|beta")
|
||||||
var publicRepo = regexp.MustCompile(`.*:.*`)
|
var publicRepo = regexp.MustCompile(`.*:.*`)
|
||||||
var tags = dockerTags.FindStringSubmatch(ciTag)
|
var tags = dockerTags.FindStringSubmatch(ciTag)
|
||||||
|
|
||||||
func init() {
|
func newDockerCmd() (cmd *cobra.Command) {
|
||||||
DockerBuildCmd.PersistentFlags().StringVar(&container, "container", defaultContainer, "target container among: "+strings.Join(containers, ", "))
|
cmd = &cobra.Command{
|
||||||
|
Use: "docker",
|
||||||
|
Short: cmdDockerShort,
|
||||||
|
Long: cmdDockerLong,
|
||||||
|
Example: cmdDockerExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdDockerBuildRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(newDockerBuildCmd(), newDockerPushManifestCmd())
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDockerBuildCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "build",
|
||||||
|
Short: cmdDockerBuildShort,
|
||||||
|
Long: cmdDockerBuildLong,
|
||||||
|
Example: cmdDockerBuildExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdDockerBuildRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().StringVar(&container, "container", defaultContainer, "target container among: "+strings.Join(containers, ", "))
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDockerPushManifestCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "push-manifest",
|
||||||
|
Short: cmdDockerPushManifestShort,
|
||||||
|
Long: cmdDockerPushManifestLong,
|
||||||
|
Example: cmdDockerPushManifestExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdDockerPushManifestRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdDockerBuildRun(_ *cobra.Command, _ []string) {
|
||||||
|
log.Infof("Building Docker image %s...", DockerImageName)
|
||||||
|
checkContainerIsSupported(container)
|
||||||
|
err := dockerBuildOfficialImage(container)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
docker := &Docker{}
|
||||||
|
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdDockerPushManifestRun(_ *cobra.Command, _ []string) {
|
||||||
|
docker := &Docker{}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ciTag != "":
|
||||||
|
if len(tags) == 4 {
|
||||||
|
log.Infof("Detected tags: '%s' | '%s' | '%s'", tags[1], tags[2], tags[3])
|
||||||
|
login(docker, dockerhub)
|
||||||
|
login(docker, ghcr)
|
||||||
|
deployManifest(docker, tags[1])
|
||||||
|
publishDockerReadme(docker)
|
||||||
|
|
||||||
|
if !ignoredSuffixes.MatchString(ciTag) {
|
||||||
|
deployManifest(docker, tags[2])
|
||||||
|
deployManifest(docker, tags[3])
|
||||||
|
deployManifest(docker, "latest")
|
||||||
|
publishDockerReadme(docker)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Fatal("Docker manifest will not be published, the specified tag does not conform to the standard")
|
||||||
|
}
|
||||||
|
case ciBranch != masterTag && !publicRepo.MatchString(ciBranch):
|
||||||
|
login(docker, dockerhub)
|
||||||
|
login(docker, ghcr)
|
||||||
|
deployManifest(docker, ciBranch)
|
||||||
|
case ciBranch != masterTag && publicRepo.MatchString(ciBranch):
|
||||||
|
login(docker, dockerhub)
|
||||||
|
login(docker, ghcr)
|
||||||
|
deployManifest(docker, "PR"+ciPullRequest)
|
||||||
|
case ciBranch == masterTag && ciPullRequest == stringFalse:
|
||||||
|
login(docker, dockerhub)
|
||||||
|
login(docker, ghcr)
|
||||||
|
deployManifest(docker, "master")
|
||||||
|
publishDockerReadme(docker)
|
||||||
|
default:
|
||||||
|
log.Info("Docker manifest will not be published")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkContainerIsSupported(container string) {
|
func checkContainerIsSupported(container string) {
|
||||||
|
@ -51,37 +146,6 @@ func dockerBuildOfficialImage(arch string) error {
|
||||||
strings.Join(flags, " "))
|
strings.Join(flags, " "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DockerBuildCmd Command for building docker image of Authelia.
|
|
||||||
var DockerBuildCmd = &cobra.Command{
|
|
||||||
Use: "build",
|
|
||||||
Short: "Build the docker image of Authelia",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
log.Infof("Building Docker image %s...", DockerImageName)
|
|
||||||
checkContainerIsSupported(container)
|
|
||||||
err := dockerBuildOfficialImage(container)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
docker := &Docker{}
|
|
||||||
err = docker.Tag(IntermediateDockerImageName, DockerImageName)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// DockerManifestCmd Command for pushing Authelia docker manifest to DockerHub.
|
|
||||||
var DockerManifestCmd = &cobra.Command{
|
|
||||||
Use: "push-manifest",
|
|
||||||
Short: "Publish Authelia docker manifest to Docker Hub",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
publishDockerManifest()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func login(docker *Docker, registry string) {
|
func login(docker *Docker, registry string) {
|
||||||
username := ""
|
username := ""
|
||||||
password := ""
|
password := ""
|
||||||
|
@ -122,45 +186,6 @@ func deployManifest(docker *Docker, tag string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func publishDockerManifest() {
|
|
||||||
docker := &Docker{}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case ciTag != "":
|
|
||||||
if len(tags) == 4 {
|
|
||||||
log.Infof("Detected tags: '%s' | '%s' | '%s'", tags[1], tags[2], tags[3])
|
|
||||||
login(docker, dockerhub)
|
|
||||||
login(docker, ghcr)
|
|
||||||
deployManifest(docker, tags[1])
|
|
||||||
publishDockerReadme(docker)
|
|
||||||
|
|
||||||
if !ignoredSuffixes.MatchString(ciTag) {
|
|
||||||
deployManifest(docker, tags[2])
|
|
||||||
deployManifest(docker, tags[3])
|
|
||||||
deployManifest(docker, "latest")
|
|
||||||
publishDockerReadme(docker)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Fatal("Docker manifest will not be published, the specified tag does not conform to the standard")
|
|
||||||
}
|
|
||||||
case ciBranch != masterTag && !publicRepo.MatchString(ciBranch):
|
|
||||||
login(docker, dockerhub)
|
|
||||||
login(docker, ghcr)
|
|
||||||
deployManifest(docker, ciBranch)
|
|
||||||
case ciBranch != masterTag && publicRepo.MatchString(ciBranch):
|
|
||||||
login(docker, dockerhub)
|
|
||||||
login(docker, ghcr)
|
|
||||||
deployManifest(docker, "PR"+ciPullRequest)
|
|
||||||
case ciBranch == masterTag && ciPullRequest == stringFalse:
|
|
||||||
login(docker, dockerhub)
|
|
||||||
login(docker, ghcr)
|
|
||||||
deployManifest(docker, "master")
|
|
||||||
publishDockerReadme(docker)
|
|
||||||
default:
|
|
||||||
log.Info("Docker manifest will not be published")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func publishDockerReadme(docker *Docker) {
|
func publishDockerReadme(docker *Docker) {
|
||||||
log.Info("Docker pushing README.md to Docker Hub")
|
log.Info("Docker pushing README.md to Docker Hub")
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ErrNotAvailableSuite error raised when suite is not available.
|
||||||
|
var ErrNotAvailableSuite = errors.New("unavailable suite")
|
||||||
|
|
||||||
|
// ErrNoRunningSuite error raised when no suite is running.
|
||||||
|
var ErrNoRunningSuite = errors.New("no running suite")
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
|
@ -0,0 +1,17 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logLevel string
|
||||||
|
|
||||||
|
func levelStringToLevel(level string) log.Level {
|
||||||
|
if level == "debug" {
|
||||||
|
return log.DebugLevel
|
||||||
|
} else if level == "warning" {
|
||||||
|
return log.WarnLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
return log.InfoLevel
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewRootCmd returns the root authelia-scripts cmd.
|
||||||
|
func NewRootCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "authelia-scripts",
|
||||||
|
Short: cmdRootShort,
|
||||||
|
Long: cmdRootLong,
|
||||||
|
Example: cmdRootExample,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().Bool("buildkite", false, "Set CI flag for Buildkite")
|
||||||
|
cmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
||||||
|
|
||||||
|
cmd.AddCommand(newBootstrapCmd(), newBuildCmd(), newCleanCmd(), newCICmd(), newDockerCmd(), newServeCmd(), newSuitesCmd(), newUnitTestCmd(), newXFlagsCmd())
|
||||||
|
|
||||||
|
cobra.OnInitialize(cmdRootInit)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdRootInit() {
|
||||||
|
log.SetLevel(levelStringToLevel(logLevel))
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newServeCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "serve [config]",
|
||||||
|
Short: cmdServeShort,
|
||||||
|
Long: cmdServeLong,
|
||||||
|
Example: cmdServeExample,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
|
Run: cmdServeRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdServeRun(_ *cobra.Command, args []string) {
|
||||||
|
log.Infof("Running Authelia with config %s...", args[0])
|
||||||
|
execCmd := utils.CommandWithStdout(OutputDir+"/authelia", "--config", args[0])
|
||||||
|
utils.RunCommandUntilCtrlC(execCmd)
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
@ -17,40 +17,88 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotAvailableSuite error raised when suite is not available.
|
var (
|
||||||
var ErrNotAvailableSuite = errors.New("unavailable suite")
|
runningSuiteFile = ".suite"
|
||||||
|
failfast, headless bool
|
||||||
|
testPattern string
|
||||||
|
)
|
||||||
|
|
||||||
// ErrNoRunningSuite error raised when no suite is running.
|
func newSuitesCmd() (cmd *cobra.Command) {
|
||||||
var ErrNoRunningSuite = errors.New("no running suite")
|
cmd = &cobra.Command{
|
||||||
|
Use: "suites",
|
||||||
|
Short: cmdSuitesShort,
|
||||||
|
Long: cmdSuitesLong,
|
||||||
|
Example: cmdSuitesExample,
|
||||||
|
Run: cmdSuitesListRun,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
// runningSuiteFile name of the file containing the currently running suite.
|
cmd.AddCommand(newSuitesListCmd(), newSuitesSetupCmd(), newSuitesTestCmd(), newSuitesTeardownCmd())
|
||||||
var runningSuiteFile = ".suite"
|
|
||||||
|
|
||||||
var failfast bool
|
return cmd
|
||||||
var headless bool
|
|
||||||
var testPattern string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
SuitesTestCmd.Flags().BoolVar(&failfast, "failfast", false, "Stops tests on first failure")
|
|
||||||
SuitesTestCmd.Flags().BoolVar(&headless, "headless", false, "Run tests in headless mode")
|
|
||||||
SuitesTestCmd.Flags().StringVar(&testPattern, "test", "", "The single test to run")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuitesListCmd Command for listing the available suites.
|
func newSuitesListCmd() (cmd *cobra.Command) {
|
||||||
var SuitesListCmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "list",
|
Use: "list",
|
||||||
Short: "List available suites.",
|
Short: cmdSuitesListShort,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Long: cmdSuitesListLong,
|
||||||
fmt.Println(strings.Join(listSuites(), "\n"))
|
Example: cmdSuitesListExample,
|
||||||
},
|
Run: cmdSuitesListRun,
|
||||||
Args: cobra.ExactArgs(0),
|
Args: cobra.NoArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuitesSetupCmd Command to setup a suite environment.
|
func newSuitesSetupCmd() (cmd *cobra.Command) {
|
||||||
var SuitesSetupCmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "setup [suite]",
|
Use: "setup [suite]",
|
||||||
Short: "Setup a Go suite environment. Suites can be listed using the list command.",
|
Short: cmdSuitesSetupShort,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Long: cmdSuitesSetupLong,
|
||||||
|
Example: cmdSuitesSetupExample,
|
||||||
|
Run: cmdSuitesSetupRun,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSuitesTeardownCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "teardown [suite]",
|
||||||
|
Short: cmdSuitesTeardownShort,
|
||||||
|
Long: cmdSuitesTeardownLong,
|
||||||
|
Example: cmdSuitesTeardownExample,
|
||||||
|
Run: cmdSuitesTeardownRun,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSuitesTestCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "test [suite]",
|
||||||
|
Short: cmdSuitesTestShort,
|
||||||
|
Long: cmdSuitesTestLong,
|
||||||
|
Example: cmdSuitesTestExample,
|
||||||
|
Run: cmdSuitesTestRun,
|
||||||
|
Args: cobra.MaximumNArgs(1),
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().BoolVar(&failfast, "failfast", false, "Stops tests on first failure")
|
||||||
|
cmd.Flags().BoolVar(&headless, "headless", false, "Run tests in headless mode")
|
||||||
|
cmd.Flags().StringVar(&testPattern, "test", "", "The single test to run")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdSuitesListRun(_ *cobra.Command, _ []string) {
|
||||||
|
fmt.Println(strings.Join(listSuites(), "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdSuitesSetupRun(_ *cobra.Command, args []string) {
|
||||||
providedSuite := args[0]
|
providedSuite := args[0]
|
||||||
runningSuite, err := getRunningSuite()
|
runningSuite, err := getRunningSuite()
|
||||||
|
|
||||||
|
@ -65,15 +113,9 @@ var SuitesSetupCmd = &cobra.Command{
|
||||||
if err := setupSuite(providedSuite); err != nil {
|
if err := setupSuite(providedSuite); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuitesTeardownCmd Command for tearing down a suite environment.
|
func cmdSuitesTeardownRun(_ *cobra.Command, args []string) {
|
||||||
var SuitesTeardownCmd = &cobra.Command{
|
|
||||||
Use: "teardown [suite]",
|
|
||||||
Short: "Teardown a Go suite environment. Suites can be listed using the list command.",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
var suiteName string
|
var suiteName string
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
suiteName = args[0]
|
suiteName = args[0]
|
||||||
|
@ -93,16 +135,38 @@ var SuitesTeardownCmd = &cobra.Command{
|
||||||
if err := teardownSuite(suiteName); err != nil {
|
if err := teardownSuite(suiteName); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Args: cobra.MaximumNArgs(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuitesTestCmd Command for testing a suite.
|
func cmdSuitesTestRun(_ *cobra.Command, args []string) {
|
||||||
var SuitesTestCmd = &cobra.Command{
|
runningSuite, err := getRunningSuite()
|
||||||
Use: "test [suite]",
|
if err != nil {
|
||||||
Short: "Test a suite. Suites can be listed using the list command.",
|
log.Fatal(err)
|
||||||
Run: testSuite,
|
}
|
||||||
Args: cobra.MaximumNArgs(1),
|
|
||||||
|
// If suite(s) are provided as argument.
|
||||||
|
if len(args) >= 1 {
|
||||||
|
suiteArg := args[0]
|
||||||
|
|
||||||
|
if runningSuite != "" && suiteArg != runningSuite {
|
||||||
|
log.Fatal(errors.New("Running suite (" + runningSuite + ") is different than suite(s) to be tested (" + suiteArg + "). Shutdown running suite and retry"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := runMultipleSuitesTests(strings.Split(suiteArg, ","), runningSuite == ""); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if runningSuite != "" {
|
||||||
|
fmt.Println("Running suite (" + runningSuite + ") detected. Run tests of that suite")
|
||||||
|
if err := runSuiteTests(runningSuite, false); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("No suite provided therefore all suites will be tested")
|
||||||
|
if err := runAllSuites(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listSuites() []string {
|
func listSuites() []string {
|
||||||
|
@ -114,9 +178,9 @@ func listSuites() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkSuiteAvailable(suite string) error {
|
func checkSuiteAvailable(suite string) error {
|
||||||
suites := listSuites()
|
suiteNames := listSuites()
|
||||||
|
|
||||||
for _, s := range suites {
|
for _, s := range suiteNames {
|
||||||
if s == suite {
|
if s == suite {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -218,38 +282,6 @@ func teardownSuite(suiteName string) error {
|
||||||
return runSuiteSetupTeardown("teardown", suiteName)
|
return runSuiteSetupTeardown("teardown", suiteName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testSuite(cmd *cobra.Command, args []string) {
|
|
||||||
runningSuite, err := getRunningSuite()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If suite(s) are provided as argument.
|
|
||||||
if len(args) >= 1 {
|
|
||||||
suiteArg := args[0]
|
|
||||||
|
|
||||||
if runningSuite != "" && suiteArg != runningSuite {
|
|
||||||
log.Fatal(errors.New("Running suite (" + runningSuite + ") is different than suite(s) to be tested (" + suiteArg + "). Shutdown running suite and retry"))
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := runMultipleSuitesTests(strings.Split(suiteArg, ","), runningSuite == ""); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if runningSuite != "" {
|
|
||||||
fmt.Println("Running suite (" + runningSuite + ") detected. Run tests of that suite")
|
|
||||||
if err := runSuiteTests(runningSuite, false); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fmt.Println("No suite provided therefore all suites will be tested")
|
|
||||||
if err := runAllSuites(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getRunningSuite() (string, error) {
|
func getRunningSuite() (string, error) {
|
||||||
exist, err := utils.FileExists(runningSuiteFile)
|
exist, err := utils.FileExists(runningSuiteFile)
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
// HostEntry represents an entry in /etc/hosts.
|
||||||
|
type HostEntry struct {
|
||||||
|
Domain string
|
||||||
|
IP string
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -9,8 +9,20 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RunUnitTest run the unit tests.
|
func newUnitTestCmd() (cmd *cobra.Command) {
|
||||||
func RunUnitTest(cobraCmd *cobra.Command, args []string) {
|
cmd = &cobra.Command{
|
||||||
|
Use: "unittest",
|
||||||
|
Short: cmdUnitTestShort,
|
||||||
|
Long: cmdUnitTestLong,
|
||||||
|
Example: cmdUnitTestExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdUnitTestRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdUnitTestRun(_ *cobra.Command, _ []string) {
|
||||||
log.SetLevel(log.TraceLevel)
|
log.SetLevel(log.TraceLevel)
|
||||||
|
|
||||||
if err := utils.Shell("go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v suites)").Run(); err != nil {
|
if err := utils.Shell("go test -coverprofile=coverage.txt -covermode=atomic $(go list ./... | grep -v suites)").Run(); err != nil {
|
|
@ -0,0 +1,44 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newXFlagsCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "xflags",
|
||||||
|
Short: cmdXFlagsShort,
|
||||||
|
Long: cmdXFlagsLong,
|
||||||
|
Example: cmdXFlagsExample,
|
||||||
|
Args: cobra.NoArgs,
|
||||||
|
Run: cmdXFlagsRun,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().StringP("build", "b", "0", "Sets the BuildNumber flag value")
|
||||||
|
cmd.Flags().StringP("extra", "e", "", "Sets the BuildExtra flag value")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func cmdXFlagsRun(cobraCmd *cobra.Command, _ []string) {
|
||||||
|
build, err := cobraCmd.Flags().GetString("build")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
extra, err := cobraCmd.Flags().GetString("extra")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
flags, err := getXFlags("", build, extra)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(strings.Join(flags, " "))
|
||||||
|
}
|
|
@ -1,18 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Clean artifacts built and installed by authelia-scripts.
|
|
||||||
func Clean(cobraCmd *cobra.Command, args []string) {
|
|
||||||
log.Debug("Removing `" + OutputDir + "` directory")
|
|
||||||
err := os.RemoveAll(OutputDir)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ServeCmd serve Authelia with the provided configuration.
|
|
||||||
func ServeCmd(cmd *cobra.Command, args []string) {
|
|
||||||
log.Infof("Running Authelia with config %s...", args[0])
|
|
||||||
execCmd := utils.CommandWithStdout(OutputDir+"/authelia", "--config", args[0])
|
|
||||||
utils.RunCommandUntilCtrlC(execCmd)
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
xflagsCmd.Flags().StringP("build", "b", "0", "Sets the BuildNumber flag value")
|
|
||||||
xflagsCmd.Flags().StringP("extra", "e", "", "Sets the BuildExtra flag value")
|
|
||||||
}
|
|
||||||
|
|
||||||
var xflagsCmd = &cobra.Command{
|
|
||||||
Use: "xflags",
|
|
||||||
Run: runXFlags,
|
|
||||||
Short: "Generate X LDFlags for building Authelia",
|
|
||||||
}
|
|
||||||
|
|
||||||
func runXFlags(cobraCmd *cobra.Command, _ []string) {
|
|
||||||
build, err := cobraCmd.Flags().GetString("build")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
extra, err := cobraCmd.Flags().GetString("extra")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
flags, err := getXFlags("", build, extra)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(strings.Join(flags, " "))
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// OutputDir the output directory where the built version of Authelia is located.
|
|
||||||
var OutputDir = "dist"
|
|
||||||
|
|
||||||
// DockerImageName the official name of Authelia docker image.
|
|
||||||
var DockerImageName = "authelia/authelia"
|
|
||||||
|
|
||||||
// IntermediateDockerImageName local name of the docker image.
|
|
||||||
var IntermediateDockerImageName = "authelia:dist"
|
|
||||||
|
|
||||||
const dockerhub = "docker.io"
|
|
||||||
const ghcr = "ghcr.io"
|
|
||||||
|
|
||||||
const masterTag = "master"
|
|
||||||
const stringFalse = "false"
|
|
||||||
const webDirectory = "web"
|
|
||||||
|
|
||||||
const fmtLDFLAGSX = "-X 'github.com/authelia/authelia/v4/internal/utils.%s=%s'"
|
|
|
@ -5,151 +5,12 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/commands"
|
"github.com/authelia/authelia/v4/cmd/authelia-scripts/cmd"
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var buildkite bool
|
|
||||||
var logLevel string
|
|
||||||
|
|
||||||
// AutheliaCommandDefinition is the definition of one authelia-scripts command.
|
|
||||||
type AutheliaCommandDefinition struct {
|
|
||||||
Name string
|
|
||||||
Short string
|
|
||||||
Long string
|
|
||||||
CommandLine string
|
|
||||||
Args cobra.PositionalArgs
|
|
||||||
Func func(cmd *cobra.Command, args []string)
|
|
||||||
SubCommands []*cobra.Command
|
|
||||||
}
|
|
||||||
|
|
||||||
// CobraCommands list of cobra commands.
|
|
||||||
type CobraCommands = []*cobra.Command
|
|
||||||
|
|
||||||
// Commands is the list of commands of authelia-scripts.
|
|
||||||
var Commands = []AutheliaCommandDefinition{
|
|
||||||
{
|
|
||||||
Name: "bootstrap",
|
|
||||||
Short: "Prepare environment for development and testing.",
|
|
||||||
Long: `Prepare environment for development and testing. This command prepares docker
|
|
||||||
images and download tools like Kind for Kubernetes testing.`,
|
|
||||||
Func: Bootstrap,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "build",
|
|
||||||
Short: "Build Authelia binary and static assets",
|
|
||||||
Func: Build,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "clean",
|
|
||||||
Short: "Clean build artifacts",
|
|
||||||
Func: Clean,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "docker",
|
|
||||||
Short: "Commands related to building and publishing docker image",
|
|
||||||
SubCommands: CobraCommands{DockerBuildCmd, DockerManifestCmd},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "serve [config]",
|
|
||||||
Short: "Serve compiled version of Authelia",
|
|
||||||
Func: ServeCmd,
|
|
||||||
Args: cobra.MinimumNArgs(1),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "suites",
|
|
||||||
Short: "Commands related to suites management",
|
|
||||||
SubCommands: CobraCommands{
|
|
||||||
SuitesTestCmd,
|
|
||||||
SuitesListCmd,
|
|
||||||
SuitesSetupCmd,
|
|
||||||
SuitesTeardownCmd,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "ci",
|
|
||||||
Short: "Run continuous integration script",
|
|
||||||
Func: RunCI,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "unittest",
|
|
||||||
Short: "Run unit tests",
|
|
||||||
Func: RunUnitTest,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func levelStringToLevel(level string) log.Level {
|
|
||||||
if level == "debug" {
|
|
||||||
return log.DebugLevel
|
|
||||||
} else if level == "warning" {
|
|
||||||
return log.WarnLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
return log.InfoLevel
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var rootCmd = &cobra.Command{Use: "authelia-scripts"}
|
if err := cmd.NewRootCmd().Execute(); err != nil {
|
||||||
|
|
||||||
cobraCommands := make([]*cobra.Command, 0)
|
|
||||||
|
|
||||||
for _, autheliaCommand := range Commands {
|
|
||||||
var fn func(cobraCmd *cobra.Command, args []string)
|
|
||||||
|
|
||||||
if autheliaCommand.CommandLine != "" {
|
|
||||||
cmdline := autheliaCommand.CommandLine
|
|
||||||
fn = func(cobraCmd *cobra.Command, args []string) {
|
|
||||||
cmd := utils.CommandWithStdout(cmdline, args...)
|
|
||||||
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if autheliaCommand.Func != nil {
|
|
||||||
fn = autheliaCommand.Func
|
|
||||||
}
|
|
||||||
|
|
||||||
command := &cobra.Command{
|
|
||||||
Use: autheliaCommand.Name,
|
|
||||||
Short: autheliaCommand.Short,
|
|
||||||
}
|
|
||||||
|
|
||||||
if autheliaCommand.Long != "" {
|
|
||||||
command.Long = autheliaCommand.Long
|
|
||||||
}
|
|
||||||
|
|
||||||
if fn != nil {
|
|
||||||
command.Run = fn
|
|
||||||
}
|
|
||||||
|
|
||||||
if autheliaCommand.Args != nil {
|
|
||||||
command.Args = autheliaCommand.Args
|
|
||||||
}
|
|
||||||
|
|
||||||
if autheliaCommand.SubCommands != nil {
|
|
||||||
command.AddCommand(autheliaCommand.SubCommands...)
|
|
||||||
}
|
|
||||||
|
|
||||||
cobraCommands = append(cobraCommands, command)
|
|
||||||
}
|
|
||||||
|
|
||||||
cobraCommands = append(cobraCommands, commands.NewHashPasswordCmd(), commands.NewCertificatesCmd(), commands.NewRSACmd(), NewRunGenCmd(), xflagsCmd)
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVar(&buildkite, "buildkite", false, "Set CI flag for Buildkite")
|
|
||||||
rootCmd.PersistentFlags().StringVar(&logLevel, "log-level", "info", "Set the log level for the command")
|
|
||||||
rootCmd.AddCommand(cobraCommands...)
|
|
||||||
cobra.OnInitialize(initConfig)
|
|
||||||
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
|
||||||
log.SetLevel(levelStringToLevel(logLevel))
|
|
||||||
}
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -46,6 +46,7 @@ require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dgraph-io/ristretto v0.1.0 // indirect
|
github.com/dgraph-io/ristretto v0.1.0 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
|
@ -87,6 +88,7 @@ require (
|
||||||
github.com/prometheus/client_model v0.2.0 // indirect
|
github.com/prometheus/client_model v0.2.0 // indirect
|
||||||
github.com/prometheus/common v0.32.1 // indirect
|
github.com/prometheus/common v0.32.1 // indirect
|
||||||
github.com/prometheus/procfs v0.7.3 // indirect
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/savsgio/dictpool v0.0.0-20220406081701-03de5edb2e6d // indirect
|
github.com/savsgio/dictpool v0.0.0-20220406081701-03de5edb2e6d // indirect
|
||||||
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
|
github.com/savsgio/gotils v0.0.0-20220530130905-52f3993e8d6d // indirect
|
||||||
github.com/spf13/afero v1.6.0 // indirect
|
github.com/spf13/afero v1.6.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -158,9 +158,11 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
||||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||||
|
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
@ -1185,8 +1187,10 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
|
github.com/rubenv/sql-migrate v0.0.0-20190212093014-1007f53448d7/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY=
|
||||||
|
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||||
|
|
|
@ -18,7 +18,9 @@ import (
|
||||||
func newAccessControlCommand() (cmd *cobra.Command) {
|
func newAccessControlCommand() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "access-control",
|
Use: "access-control",
|
||||||
Short: "Helpers for the access control system",
|
Short: cmdAutheliaAccessControlShort,
|
||||||
|
Long: cmdAutheliaAccessControlLong,
|
||||||
|
Example: cmdAutheliaAccessControlExample,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
|
@ -31,12 +33,13 @@ func newAccessControlCommand() (cmd *cobra.Command) {
|
||||||
func newAccessControlCheckCommand() (cmd *cobra.Command) {
|
func newAccessControlCheckCommand() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "check-policy",
|
Use: "check-policy",
|
||||||
Short: "Checks a request against the access control rules to determine what policy would be applied",
|
Short: cmdAutheliaAccessControlCheckPolicyShort,
|
||||||
Long: accessControlPolicyCheckLong,
|
Long: cmdAutheliaAccessControlCheckPolicyLong,
|
||||||
|
Example: cmdAutheliaAccessControlCheckPolicyExample,
|
||||||
RunE: accessControlCheckRunE,
|
RunE: accessControlCheckRunE,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdWithConfigFlags(cmd, false, []string{"config.yml"})
|
cmdWithConfigFlags(cmd, false, []string{"configuration.yml"})
|
||||||
|
|
||||||
cmd.Flags().String("url", "", "the url of the object")
|
cmd.Flags().String("url", "", "the url of the object")
|
||||||
cmd.Flags().String("method", "GET", "the HTTP method of the object")
|
cmd.Flags().String("method", "GET", "the HTTP method of the object")
|
||||||
|
|
|
@ -12,8 +12,9 @@ import (
|
||||||
func newBuildInfoCmd() (cmd *cobra.Command) {
|
func newBuildInfoCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "build-info",
|
Use: "build-info",
|
||||||
Short: "Show the build information of Authelia",
|
Short: cmdAutheliaBuildInfoShort,
|
||||||
Long: buildLong,
|
Long: cmdAutheliaBuildInfoLong,
|
||||||
|
Example: cmdAutheliaBuildInfoExample,
|
||||||
RunE: cmdBuildInfoRunE,
|
RunE: cmdBuildInfoRunE,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,12 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/utils"
|
"github.com/authelia/authelia/v4/internal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCertificatesCmd returns a new Certificates Cmd.
|
func newCertificatesCmd() (cmd *cobra.Command) {
|
||||||
func NewCertificatesCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "certificates",
|
Use: "certificates",
|
||||||
Short: "Commands related to certificate generation",
|
Short: cmdAutheliaCertificatesShort,
|
||||||
|
Long: cmdAutheliaCertificatesLong,
|
||||||
|
Example: cmdAutheliaCertificatesExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +37,9 @@ func NewCertificatesCmd() (cmd *cobra.Command) {
|
||||||
func newCertificatesGenerateCmd() (cmd *cobra.Command) {
|
func newCertificatesGenerateCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "generate",
|
Use: "generate",
|
||||||
Short: "Generate a self-signed certificate",
|
Short: cmdAutheliaCertificatesGenerateShort,
|
||||||
|
Long: cmdAutheliaCertificatesGenerateLong,
|
||||||
|
Example: cmdAutheliaCertificatesGenerateExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: cmdCertificatesGenerateRun,
|
Run: cmdCertificatesGenerateRun,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
package commands
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newCompletionCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "completion [bash|zsh|fish|powershell]",
|
|
||||||
Short: "Generate completion script",
|
|
||||||
Long: completionLong,
|
|
||||||
Args: cobra.ExactValidArgs(1),
|
|
||||||
ValidArgs: []string{"bash", "zsh", "fish", "powershell"},
|
|
||||||
DisableFlagsInUseLine: true,
|
|
||||||
Run: cmdCompletionRun,
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func cmdCompletionRun(cmd *cobra.Command, args []string) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
switch args[0] {
|
|
||||||
case "bash":
|
|
||||||
err = cmd.Root().GenBashCompletion(os.Stdout)
|
|
||||||
case "zsh":
|
|
||||||
err = cmd.Root().GenZshCompletion(os.Stdout)
|
|
||||||
case "fish":
|
|
||||||
err = cmd.Root().GenFishCompletion(os.Stdout, true)
|
|
||||||
case "powershell":
|
|
||||||
err = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout)
|
|
||||||
default:
|
|
||||||
fmt.Printf("Invalid shell provided for completion command: %s\n", args[0])
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("Error generating completion: %v\n", err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,21 +4,22 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const cmdAutheliaExample = `authelia --config /etc/authelia/config.yml --config /etc/authelia/access-control.yml
|
const (
|
||||||
authelia --config /etc/authelia/config.yml,/etc/authelia/access-control.yml
|
fmtCmdAutheliaShort = "authelia %s"
|
||||||
authelia --config /etc/authelia/config/
|
|
||||||
`
|
|
||||||
|
|
||||||
const fmtAutheliaLong = `authelia %s
|
fmtCmdAutheliaLong = `authelia %s
|
||||||
|
|
||||||
An open-source authentication and authorization server providing
|
An open-source authentication and authorization server providing
|
||||||
two-factor authentication and single sign-on (SSO) for your
|
two-factor authentication and single sign-on (SSO) for your
|
||||||
applications via a web portal.
|
applications via a web portal.
|
||||||
|
|
||||||
Documentation is available at: https://www.authelia.com/docs
|
Documentation is available at: https://www.authelia.com/docs`
|
||||||
`
|
|
||||||
|
|
||||||
const fmtAutheliaBuild = `Last Tag: %s
|
cmdAutheliaExample = `authelia --config /etc/authelia/config.yml --config /etc/authelia/access-control.yml
|
||||||
|
authelia --config /etc/authelia/config.yml,/etc/authelia/access-control.yml
|
||||||
|
authelia --config /etc/authelia/config/`
|
||||||
|
|
||||||
|
fmtAutheliaBuild = `Last Tag: %s
|
||||||
State: %s
|
State: %s
|
||||||
Branch: %s
|
Branch: %s
|
||||||
Commit: %s
|
Commit: %s
|
||||||
|
@ -29,7 +30,9 @@ Build Date: %s
|
||||||
Extra: %s
|
Extra: %s
|
||||||
`
|
`
|
||||||
|
|
||||||
const buildLong = `Show the build information of Authelia
|
cmdAutheliaBuildInfoShort = "Show the build information of Authelia"
|
||||||
|
|
||||||
|
cmdAutheliaBuildInfoLong = `Show the build information of Authelia.
|
||||||
|
|
||||||
This outputs detailed version information about the specific version
|
This outputs detailed version information about the specific version
|
||||||
of the Authelia binary. This information is embedded into Authelia
|
of the Authelia binary. This information is embedded into Authelia
|
||||||
|
@ -39,48 +42,17 @@ This could be vital in debugging if you're not using a particular
|
||||||
tagged build of Authelia. It's suggested to provide it along with
|
tagged build of Authelia. It's suggested to provide it along with
|
||||||
your issue.
|
your issue.
|
||||||
`
|
`
|
||||||
|
cmdAutheliaBuildInfoExample = `authelia build-info`
|
||||||
|
|
||||||
const completionLong = `To load completions:
|
cmdAutheliaAccessControlShort = "Helpers for the access control system"
|
||||||
|
|
||||||
Bash:
|
cmdAutheliaAccessControlLong = `Helpers for the access control system.`
|
||||||
|
|
||||||
$ source <(authelia completion bash)
|
cmdAutheliaAccessControlExample = `authelia access-control --help`
|
||||||
|
|
||||||
# To load completions for each session, execute once:
|
cmdAutheliaAccessControlCheckPolicyShort = "Checks a request against the access control rules to determine what policy would be applied"
|
||||||
# Linux:
|
|
||||||
$ authelia completion bash > /etc/bash_completion.d/authelia
|
|
||||||
# macOS:
|
|
||||||
$ authelia completion bash > /usr/local/etc/bash_completion.d/authelia
|
|
||||||
|
|
||||||
Zsh:
|
cmdAutheliaAccessControlCheckPolicyLong = `
|
||||||
|
|
||||||
# If shell completion is not already enabled in your environment,
|
|
||||||
# you will need to enable it. You can execute the following once:
|
|
||||||
|
|
||||||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
|
|
||||||
|
|
||||||
# To load completions for each session, execute once:
|
|
||||||
$ authelia completion zsh > "${fpath[1]}/_authelia"
|
|
||||||
|
|
||||||
# You will need to start a new shell for this setup to take effect.
|
|
||||||
|
|
||||||
fish:
|
|
||||||
|
|
||||||
$ authelia completion fish | source
|
|
||||||
|
|
||||||
# To load completions for each session, execute once:
|
|
||||||
$ authelia completion fish > ~/.config/fish/completions/authelia.fish
|
|
||||||
|
|
||||||
PowerShell:
|
|
||||||
|
|
||||||
PS> authelia completion powershell | Out-String | Invoke-Expression
|
|
||||||
|
|
||||||
# To load completions for every new session, run:
|
|
||||||
PS> authelia completion powershell > authelia.ps1
|
|
||||||
# and source this file from your PowerShell profile.
|
|
||||||
`
|
|
||||||
|
|
||||||
const accessControlPolicyCheckLong = `
|
|
||||||
Checks a request against the access control rules to determine what policy would be applied.
|
Checks a request against the access control rules to determine what policy would be applied.
|
||||||
|
|
||||||
Legend:
|
Legend:
|
||||||
|
@ -97,15 +69,299 @@ Notes:
|
||||||
A rule that potentially matches a request will cause a redirection to occur in order to perform one-factor
|
A rule that potentially matches a request will cause a redirection to occur in order to perform one-factor
|
||||||
authentication. This is so Authelia can adequately determine if the rule actually matches.
|
authentication. This is so Authelia can adequately determine if the rule actually matches.
|
||||||
`
|
`
|
||||||
|
cmdAutheliaAccessControlCheckPolicyExample = `authelia access-control check-policy --config config.yml --url https://example.com
|
||||||
|
authelia access-control check-policy --config config.yml --url https://example.com --username john
|
||||||
|
authelia access-control check-policy --config config.yml --url https://example.com --groups admin,public
|
||||||
|
authelia access-control check-policy --config config.yml --url https://example.com --username john --method GET
|
||||||
|
authelia access-control check-policy --config config.yml --url https://example.com --username john --method GET --verbose`
|
||||||
|
|
||||||
|
cmdAutheliaStorageShort = "Manage the Authelia storage"
|
||||||
|
|
||||||
|
cmdAutheliaStorageLong = `Manage the Authelia storage.
|
||||||
|
|
||||||
|
This subcommand has several methods to interact with the Authelia SQL Database. This allows doing several advanced
|
||||||
|
operations which would be much harder to do manually.
|
||||||
|
`
|
||||||
|
|
||||||
|
cmdAutheliaStorageExample = `authelia storage --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionShort = "Manage storage encryption"
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionLong = `Manage storage encryption.
|
||||||
|
|
||||||
|
This subcommand allows management of the storage encryption.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionExample = `authelia storage encryption --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionCheckShort = "Checks the encryption key against the database data"
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionCheckLong = `Checks the encryption key against the database data.
|
||||||
|
|
||||||
|
This is useful for validating all data that can be encrypted is intact.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionCheckExample = `authelia storage encryption check
|
||||||
|
authelia storage encryption check --verbose
|
||||||
|
authelia storage encryption check --verbose --config config.yml
|
||||||
|
authelia storage encryption check --verbose --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionChangeKeyShort = "Changes the encryption key"
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionChangeKeyLong = `Changes the encryption key.
|
||||||
|
|
||||||
|
This subcommand allows you to change the encryption key of an Authelia SQL database.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageEncryptionChangeKeyExample = `authelia storage encryption change-key --config config.yml --new-encryption-key 0e95cb49-5804-4ad9-be82-bb04a9ddecd8
|
||||||
|
authelia storage encryption change-key --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --new-encryption-key 0e95cb49-5804-4ad9-be82-bb04a9ddecd8 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserShort = "Manages user settings"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserLong = `Manages user settings.
|
||||||
|
|
||||||
|
This subcommand allows modifying and exporting user settings.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserExample = `authelia storage user --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersShort = "Manage user opaque identifiers"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersLong = `Manage user opaque identifiers.
|
||||||
|
|
||||||
|
This subcommand allows performing various tasks related to the opaque identifiers for users.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersExample = `authelia storage user identifiers --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersExportShort = "Export the identifiers to a YAML file"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersExportLong = `Export the identifiers to a YAML file.
|
||||||
|
|
||||||
|
This subcommand allows exporting the opaque identifiers for users in order to back them up.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersExportExample = `authelia storage user identifiers export
|
||||||
|
authelia storage user identifiers export --file export.yaml
|
||||||
|
authelia storage user identifiers export --file export.yaml --config config.yml
|
||||||
|
authelia storage user identifiers export --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersImportShort = "Import the identifiers from a YAML file"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersImportLong = `Import the identifiers from a YAML file.
|
||||||
|
|
||||||
|
This subcommand allows you to import the opaque identifiers for users from a YAML file.
|
||||||
|
|
||||||
|
The YAML file can either be automatically generated using the authelia storage user identifiers export command, or
|
||||||
|
manually provided the file is in the same format.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersImportExample = `authelia storage user identifiers import
|
||||||
|
authelia storage user identifiers import --file export.yaml
|
||||||
|
authelia storage user identifiers import --file export.yaml --config config.yml
|
||||||
|
authelia storage user identifiers import --file export.yaml --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersGenerateShort = "Generate opaque identifiers in bulk"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersGenerateLong = `Generate opaque identifiers in bulk.
|
||||||
|
|
||||||
|
This subcommand allows various options for generating the opaque identifies for users in bulk.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersGenerateExample = `authelia storage user identifiers generate --users john,mary
|
||||||
|
authelia storage user identifiers generate --users john,mary --services openid
|
||||||
|
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com"
|
||||||
|
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com" --config config.yml
|
||||||
|
authelia storage user identifiers generate --users john,mary --services openid --sectors=",example.com,test.com" --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersAddShort = "Add an opaque identifier for a user to the database"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersAddLong = `Add an opaque identifier for a user to the database.
|
||||||
|
|
||||||
|
This subcommand allows manually adding an opaque identifier for a user to the database provided it's in the correct format.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserIdentifiersAddExample = `authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073
|
||||||
|
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --config config.yml
|
||||||
|
authelia storage user identifiers add john --identifier f0919359-9d15-4e15-bcba-83b41620a073 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPShort = "Manage TOTP configurations"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPLong = `Manage TOTP configurations.
|
||||||
|
|
||||||
|
This subcommand allows deleting, exporting, and creating user TOTP configurations.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPExample = `authelia storage user totp --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPGenerateShort = "Generate a TOTP configuration for a user"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPGenerateLong = `Generate a TOTP configuration for a user.
|
||||||
|
|
||||||
|
This subcommand allows generating a new TOTP configuration for a user,
|
||||||
|
and overwriting the existing configuration if applicable.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPGenerateExample = `authelia storage user totp generate john
|
||||||
|
authelia storage user totp generate john --period 90
|
||||||
|
authelia storage user totp generate john --digits 8
|
||||||
|
authelia storage user totp generate john --algorithm SHA512
|
||||||
|
authelia storage user totp generate john --algorithm SHA512 --config config.yml
|
||||||
|
authelia storage user totp generate john --algorithm SHA512 --config config.yml --path john.png`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPDeleteShort = "Delete a TOTP configuration for a user"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPDeleteLong = `Delete a TOTP configuration for a user.
|
||||||
|
|
||||||
|
This subcommand allows deleting a TOTP configuration directly from the database for a given user.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPDeleteExample = `authelia storage user totp delete john
|
||||||
|
authelia storage user totp delete john --config config.yml
|
||||||
|
authelia storage user totp delete john --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPExportShort = "Perform exports of the TOTP configurations"
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPExportLong = `Perform exports of the TOTP configurations.
|
||||||
|
|
||||||
|
This subcommand allows exporting TOTP configurations to various formats.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageUserTOTPExportExample = `authelia storage user totp export --format csv
|
||||||
|
authelia storage user totp export --format png --dir ./totp-qr
|
||||||
|
authelia storage user totp export --format png --dir ./totp-qr --config config.yml
|
||||||
|
authelia storage user totp export --format png --dir ./totp-qr --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageSchemaInfoShort = "Show the storage information"
|
||||||
|
|
||||||
|
cmdAutheliaStorageSchemaInfoLong = `Show the storage information.
|
||||||
|
|
||||||
|
This subcommand shows advanced information about the storage schema useful in some diagnostic tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageSchemaInfoExample = `authelia storage schema-info
|
||||||
|
authelia storage schema-info --config config.yml
|
||||||
|
authelia storage schema-info --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateShort = "Perform or list migrations"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateLong = `Perform or list migrations.
|
||||||
|
|
||||||
|
This subcommand handles schema migration tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateExample = `authelia storage migrate --help`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateHistoryShort = "Show migration history"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateHistoryLong = `Show migration history.
|
||||||
|
|
||||||
|
This subcommand allows users to list previous migrations.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateHistoryExample = `authelia storage migrate history
|
||||||
|
authelia storage migrate history --config config.yml
|
||||||
|
authelia storage migrate history --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListUpShort = "List the up migrations available"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListUpLong = `List the up migrations available.
|
||||||
|
|
||||||
|
This subcommand lists the schema migrations available in this version of Authelia which are greater than the current
|
||||||
|
schema version of the database.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListUpExample = `authelia storage migrate list-up
|
||||||
|
authelia storage migrate list-up --config config.yml
|
||||||
|
authelia storage migrate list-up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListDownShort = "List the down migrations available"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListDownLong = `List the down migrations available.
|
||||||
|
|
||||||
|
This subcommand lists the schema migrations available in this version of Authelia which are less than the current
|
||||||
|
schema version of the database.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateListDownExample = `authelia storage migrate list-down
|
||||||
|
authelia storage migrate list-down --config config.yml
|
||||||
|
authelia storage migrate list-down --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateUpShort = "Perform a migration up"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateUpLong = `Perform a migration up.
|
||||||
|
|
||||||
|
This subcommand performs the schema migrations available in this version of Authelia which are greater than the current
|
||||||
|
schema version of the database. By default this will migrate up to the latest available, but you can customize this.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateUpExample = `authelia storage migrate up
|
||||||
|
authelia storage migrate up --config config.yml
|
||||||
|
authelia storage migrate up --target 20 --config config.yml
|
||||||
|
authelia storage migrate up --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateDownShort = "Perform a migration down"
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateDownLong = `Perform a migration down.
|
||||||
|
|
||||||
|
This subcommand performs the schema migrations available in this version of Authelia which are less than the current
|
||||||
|
schema version of the database.`
|
||||||
|
|
||||||
|
cmdAutheliaStorageMigrateDownExample = `authelia storage migrate down --target 20
|
||||||
|
authelia storage migrate down --target 20 --config config.yml
|
||||||
|
authelia storage migrate down --target 20 --encryption-key b3453fde-ecc2-4a1f-9422-2707ddbed495 --postgres.host postgres --postgres.password autheliapw`
|
||||||
|
|
||||||
|
cmdAutheliaValidateConfigShort = "Check a configuration against the internal configuration validation mechanisms"
|
||||||
|
|
||||||
|
cmdAutheliaValidateConfigLong = `Check a configuration against the internal configuration validation mechanisms.
|
||||||
|
|
||||||
|
This subcommand allows validation of the YAML and Environment configurations so that a configuration can be checked
|
||||||
|
prior to deploying it.`
|
||||||
|
|
||||||
|
cmdAutheliaValidateConfigExample = `authelia validate-config
|
||||||
|
authelia validate-config --config config.yml`
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesShort = "Commands related to certificate generation"
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesLong = `Commands related to certificate generation.
|
||||||
|
|
||||||
|
This subcommand allows preforming X509 certificate tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesExample = `authelia certificates --help`
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesGenerateShort = "Generate a self-signed certificate"
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesGenerateLong = `Generate a self-signed certificate.
|
||||||
|
|
||||||
|
This subcommand allows generating self-signed certificates.`
|
||||||
|
|
||||||
|
cmdAutheliaCertificatesGenerateExample = `authelia certificates generate
|
||||||
|
authelia certificates generate --dir ./out`
|
||||||
|
|
||||||
|
cmdAutheliaRSAShort = "Commands related to rsa keypair generation"
|
||||||
|
|
||||||
|
cmdAutheliaRSALong = `Commands related to rsa keypair generation.
|
||||||
|
|
||||||
|
This subcommand allows performing RSA keypair tasks.`
|
||||||
|
|
||||||
|
cmdAutheliaRSAExample = `authelia rsa --help`
|
||||||
|
|
||||||
|
cmdAutheliaRSAGenerateShort = "Generate a RSA keypair"
|
||||||
|
|
||||||
|
cmdAutheliaRSAGenerateLong = `Generate a RSA keypair.
|
||||||
|
|
||||||
|
This subcommand allows generating an RSA keypair.`
|
||||||
|
|
||||||
|
cmdAutheliaRSAGenerateExample = `authelia rsa generate
|
||||||
|
authelia rsa generate --dir ./out`
|
||||||
|
|
||||||
|
cmdAutheliaHashPasswordShort = "Hash a password to be used in file-based users database."
|
||||||
|
|
||||||
|
cmdAutheliaHashPasswordLong = `Hash a password to be used in file-based users database.`
|
||||||
|
|
||||||
|
//nolint:gosec // This is an example.
|
||||||
|
cmdAutheliaHashPasswordExample = `authelia hash-password -- 'mypass'
|
||||||
|
authelia hash-password --sha512 -- 'mypass'
|
||||||
|
authelia hash-password --iterations=4 -- 'mypass'
|
||||||
|
authelia hash-password --memory=128 -- 'mypass'
|
||||||
|
authelia hash-password --parallelism=1 -- 'mypass'
|
||||||
|
authelia hash-password --key-length=64 -- 'mypass'`
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
storageMigrateDirectionUp = "up"
|
storageMigrateDirectionUp = "up"
|
||||||
storageMigrateDirectionDown = "down"
|
storageMigrateDirectionDown = "down"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
storageExportFormatCSV = "csv"
|
storageTOTPExportFormatCSV = "csv"
|
||||||
storageExportFormatURI = "uri"
|
storageTOTPExportFormatURI = "uri"
|
||||||
storageExportFormatPNG = "png"
|
storageTOTPExportFormatPNG = "png"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
validStorageTOTPExportFormats = []string{storageTOTPExportFormatCSV, storageTOTPExportFormatURI, storageTOTPExportFormatPNG}
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -12,11 +12,12 @@ import (
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
"github.com/authelia/authelia/v4/internal/configuration/validator"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewHashPasswordCmd returns a new Hash Password Cmd.
|
func newHashPasswordCmd() (cmd *cobra.Command) {
|
||||||
func NewHashPasswordCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "hash-password [flags] -- <password>",
|
Use: "hash-password [flags] -- <password>",
|
||||||
Short: "Hash a password to be used in file-based users database. Default algorithm is argon2id.",
|
Short: cmdAutheliaHashPasswordShort,
|
||||||
|
Long: cmdAutheliaHashPasswordLong,
|
||||||
|
Example: cmdAutheliaHashPasswordExample,
|
||||||
Args: cobra.MinimumNArgs(1),
|
Args: cobra.MinimumNArgs(1),
|
||||||
RunE: cmdHashPasswordRunE,
|
RunE: cmdHashPasswordRunE,
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,9 @@ func NewRootCmd() (cmd *cobra.Command) {
|
||||||
|
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "authelia",
|
Use: "authelia",
|
||||||
|
Short: fmt.Sprintf(fmtCmdAutheliaShort, version),
|
||||||
|
Long: fmt.Sprintf(fmtCmdAutheliaLong, version),
|
||||||
Example: cmdAutheliaExample,
|
Example: cmdAutheliaExample,
|
||||||
Short: fmt.Sprintf("authelia %s", version),
|
|
||||||
Long: fmt.Sprintf(fmtAutheliaLong, version),
|
|
||||||
Version: version,
|
Version: version,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
PreRun: newCmdWithConfigPreRun(true, true, true),
|
PreRun: newCmdWithConfigPreRun(true, true, true),
|
||||||
|
@ -36,11 +36,10 @@ func NewRootCmd() (cmd *cobra.Command) {
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
newBuildInfoCmd(),
|
newBuildInfoCmd(),
|
||||||
NewCertificatesCmd(),
|
newCertificatesCmd(),
|
||||||
newCompletionCmd(),
|
newHashPasswordCmd(),
|
||||||
NewHashPasswordCmd(),
|
|
||||||
NewRSACmd(),
|
NewRSACmd(),
|
||||||
NewStorageCmd(),
|
newStorageCmd(),
|
||||||
newValidateConfigCmd(),
|
newValidateConfigCmd(),
|
||||||
newAccessControlCommand(),
|
newAccessControlCommand(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,7 +14,9 @@ import (
|
||||||
func NewRSACmd() (cmd *cobra.Command) {
|
func NewRSACmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "rsa",
|
Use: "rsa",
|
||||||
Short: "Commands related to rsa keypair generation",
|
Short: cmdAutheliaRSAShort,
|
||||||
|
Long: cmdAutheliaRSALong,
|
||||||
|
Example: cmdAutheliaRSAExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +28,9 @@ func NewRSACmd() (cmd *cobra.Command) {
|
||||||
func newRSAGenerateCmd() (cmd *cobra.Command) {
|
func newRSAGenerateCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "generate",
|
Use: "generate",
|
||||||
Short: "Generate a RSA keypair",
|
Short: cmdAutheliaRSAGenerateShort,
|
||||||
|
Long: cmdAutheliaRSAGenerateLong,
|
||||||
|
Example: cmdAutheliaRSAGenerateExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
Run: cmdRSAGenerateRun,
|
Run: cmdRSAGenerateRun,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
"github.com/authelia/authelia/v4/internal/configuration/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewStorageCmd returns a new storage *cobra.Command.
|
func newStorageCmd() (cmd *cobra.Command) {
|
||||||
func NewStorageCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "storage",
|
Use: "storage",
|
||||||
Short: "Manage the Authelia storage",
|
Short: cmdAutheliaStorageShort,
|
||||||
|
Long: cmdAutheliaStorageLong,
|
||||||
|
Example: cmdAutheliaStorageExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
PersistentPreRunE: storagePersistentPreRunE,
|
PersistentPreRunE: storagePersistentPreRunE,
|
||||||
}
|
}
|
||||||
|
@ -48,15 +52,61 @@ func NewStorageCmd() (cmd *cobra.Command) {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newStorageEncryptionCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "encryption",
|
||||||
|
Short: cmdAutheliaStorageEncryptionShort,
|
||||||
|
Long: cmdAutheliaStorageEncryptionLong,
|
||||||
|
Example: cmdAutheliaStorageEncryptionExample,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.AddCommand(
|
||||||
|
newStorageEncryptionChangeKeyCmd(),
|
||||||
|
newStorageEncryptionCheckCmd(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStorageEncryptionCheckCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "check",
|
||||||
|
Short: cmdAutheliaStorageEncryptionCheckShort,
|
||||||
|
Long: cmdAutheliaStorageEncryptionCheckLong,
|
||||||
|
Example: cmdAutheliaStorageEncryptionCheckExample,
|
||||||
|
RunE: storageSchemaEncryptionCheckRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().Bool("verbose", false, "enables verbose checking of every row of encrypted data")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStorageEncryptionChangeKeyCmd() (cmd *cobra.Command) {
|
||||||
|
cmd = &cobra.Command{
|
||||||
|
Use: "change-key",
|
||||||
|
Short: cmdAutheliaStorageEncryptionChangeKeyShort,
|
||||||
|
Long: cmdAutheliaStorageEncryptionChangeKeyLong,
|
||||||
|
Example: cmdAutheliaStorageEncryptionChangeKeyExample,
|
||||||
|
RunE: storageSchemaEncryptionChangeKeyRunE,
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Flags().String("new-encryption-key", "", "the new key to encrypt the data with")
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
func newStorageUserCmd() (cmd *cobra.Command) {
|
func newStorageUserCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "user",
|
Use: "user",
|
||||||
Short: "Manages user settings",
|
Short: cmdAutheliaStorageUserShort,
|
||||||
|
Long: cmdAutheliaStorageUserLong,
|
||||||
|
Example: cmdAutheliaStorageUserExample,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
newStorageUserIdentifiersCmd(),
|
newStorageUserIdentifiersCmd(),
|
||||||
newStorageTOTPCmd(),
|
newStorageUserTOTPCmd(),
|
||||||
)
|
)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -65,7 +115,9 @@ func newStorageUserCmd() (cmd *cobra.Command) {
|
||||||
func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "identifiers",
|
Use: "identifiers",
|
||||||
Short: "Manages user opaque identifiers",
|
Short: cmdAutheliaStorageUserIdentifiersShort,
|
||||||
|
Long: cmdAutheliaStorageUserIdentifiersLong,
|
||||||
|
Example: cmdAutheliaStorageUserIdentifiersExample,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
|
@ -81,7 +133,9 @@ func newStorageUserIdentifiersCmd() (cmd *cobra.Command) {
|
||||||
func newStorageUserIdentifiersExportCmd() (cmd *cobra.Command) {
|
func newStorageUserIdentifiersExportCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "export",
|
Use: "export",
|
||||||
Short: "Export the identifiers to a YAML file",
|
Short: cmdAutheliaStorageUserIdentifiersExportShort,
|
||||||
|
Long: cmdAutheliaStorageUserIdentifiersExportLong,
|
||||||
|
Example: cmdAutheliaStorageUserIdentifiersExportExample,
|
||||||
RunE: storageUserIdentifiersExport,
|
RunE: storageUserIdentifiersExport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +147,9 @@ func newStorageUserIdentifiersExportCmd() (cmd *cobra.Command) {
|
||||||
func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "import",
|
Use: "import",
|
||||||
Short: "Import the identifiers from a YAML file",
|
Short: cmdAutheliaStorageUserIdentifiersImportShort,
|
||||||
|
Long: cmdAutheliaStorageUserIdentifiersImportLong,
|
||||||
|
Example: cmdAutheliaStorageUserIdentifiersImportExample,
|
||||||
RunE: storageUserIdentifiersImport,
|
RunE: storageUserIdentifiersImport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,12 +161,14 @@ func newStorageUserIdentifiersImportCmd() (cmd *cobra.Command) {
|
||||||
func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "generate",
|
Use: "generate",
|
||||||
Short: "Generate opaque identifiers in bulk",
|
Short: cmdAutheliaStorageUserIdentifiersGenerateShort,
|
||||||
|
Long: cmdAutheliaStorageUserIdentifiersGenerateLong,
|
||||||
|
Example: cmdAutheliaStorageUserIdentifiersGenerateExample,
|
||||||
RunE: storageUserIdentifiersGenerate,
|
RunE: storageUserIdentifiersGenerate,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().StringSlice("users", nil, "The list of users to generate the opaque identifiers for")
|
cmd.Flags().StringSlice("users", nil, "The list of users to generate the opaque identifiers for")
|
||||||
cmd.Flags().StringSlice("services", []string{identifierServiceOpenIDConnect}, "The list of services to generate the opaque identifiers for, valid values are: openid")
|
cmd.Flags().StringSlice("services", []string{identifierServiceOpenIDConnect}, fmt.Sprintf("The list of services to generate the opaque identifiers for, valid values are: %s", strings.Join(validIdentifierServices, ", ")))
|
||||||
cmd.Flags().StringSlice("sectors", []string{""}, "The list of sectors to generate identifiers for")
|
cmd.Flags().StringSlice("sectors", []string{""}, "The list of sectors to generate identifiers for")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -118,76 +176,44 @@ func newStorageUserIdentifiersGenerateCmd() (cmd *cobra.Command) {
|
||||||
|
|
||||||
func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
func newStorageUserIdentifiersAddCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "add [username]",
|
Use: "add <username>",
|
||||||
Short: "Add an identifiers to the database",
|
Short: cmdAutheliaStorageUserIdentifiersAddShort,
|
||||||
|
Long: cmdAutheliaStorageUserIdentifiersAddLong,
|
||||||
|
Example: cmdAutheliaStorageUserIdentifiersAddExample,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: storageUserIdentifiersAdd,
|
RunE: storageUserIdentifiersAdd,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().String("identifier", "", "The optional version 4 UUID to use, if not set a random one will be used")
|
cmd.Flags().String("identifier", "", "The optional version 4 UUID to use, if not set a random one will be used")
|
||||||
cmd.Flags().String("service", identifierServiceOpenIDConnect, "The service to add the identifier for, valid values are: openid")
|
cmd.Flags().String("service", identifierServiceOpenIDConnect, fmt.Sprintf("The service to add the identifier for, valid values are: %s", strings.Join(validIdentifierServices, ", ")))
|
||||||
cmd.Flags().String("sector", "", "The sector identifier to use (should usually be blank)")
|
cmd.Flags().String("sector", "", "The sector identifier to use (should usually be blank)")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStorageEncryptionCmd() (cmd *cobra.Command) {
|
func newStorageUserTOTPCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "encryption",
|
|
||||||
Short: "Manages encryption",
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.AddCommand(
|
|
||||||
newStorageEncryptionChangeKeyCmd(),
|
|
||||||
newStorageEncryptionCheckCmd(),
|
|
||||||
)
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStorageEncryptionCheckCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "check",
|
|
||||||
Short: "Checks the encryption key against the database data",
|
|
||||||
RunE: storageSchemaEncryptionCheckRunE,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().Bool("verbose", false, "enables verbose checking of every row of encrypted data")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStorageEncryptionChangeKeyCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "change-key",
|
|
||||||
Short: "Changes the encryption key",
|
|
||||||
RunE: storageSchemaEncryptionChangeKeyRunE,
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd.Flags().String("new-encryption-key", "", "the new key to encrypt the data with")
|
|
||||||
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func newStorageTOTPCmd() (cmd *cobra.Command) {
|
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "totp",
|
Use: "totp",
|
||||||
Short: "Manage TOTP configurations",
|
Short: cmdAutheliaStorageUserTOTPShort,
|
||||||
|
Long: cmdAutheliaStorageUserTOTPLong,
|
||||||
|
Example: cmdAutheliaStorageUserTOTPExample,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.AddCommand(
|
cmd.AddCommand(
|
||||||
newStorageTOTPGenerateCmd(),
|
newStorageUserTOTPGenerateCmd(),
|
||||||
newStorageTOTPDeleteCmd(),
|
newStorageUserTOTPDeleteCmd(),
|
||||||
newStorageTOTPExportCmd(),
|
newStorageUserTOTPExportCmd(),
|
||||||
)
|
)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStorageTOTPGenerateCmd() (cmd *cobra.Command) {
|
func newStorageUserTOTPGenerateCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "generate [username]",
|
Use: "generate <username>",
|
||||||
Short: "Generate a TOTP configuration for a user",
|
Short: cmdAutheliaStorageUserTOTPGenerateShort,
|
||||||
|
Long: cmdAutheliaStorageUserTOTPGenerateLong,
|
||||||
|
Example: cmdAutheliaStorageUserTOTPGenerateExample,
|
||||||
RunE: storageTOTPGenerateRunE,
|
RunE: storageTOTPGenerateRunE,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
|
@ -204,10 +230,12 @@ func newStorageTOTPGenerateCmd() (cmd *cobra.Command) {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStorageTOTPDeleteCmd() (cmd *cobra.Command) {
|
func newStorageUserTOTPDeleteCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "delete username",
|
Use: "delete <username>",
|
||||||
Short: "Delete a TOTP configuration for a user",
|
Short: cmdAutheliaStorageUserTOTPDeleteShort,
|
||||||
|
Long: cmdAutheliaStorageUserTOTPDeleteLong,
|
||||||
|
Example: cmdAutheliaStorageUserTOTPDeleteExample,
|
||||||
RunE: storageTOTPDeleteRunE,
|
RunE: storageTOTPDeleteRunE,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
}
|
}
|
||||||
|
@ -215,14 +243,16 @@ func newStorageTOTPDeleteCmd() (cmd *cobra.Command) {
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStorageTOTPExportCmd() (cmd *cobra.Command) {
|
func newStorageUserTOTPExportCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "export",
|
Use: "export",
|
||||||
Short: "Performs exports of the TOTP configurations",
|
Short: cmdAutheliaStorageUserTOTPExportShort,
|
||||||
|
Long: cmdAutheliaStorageUserTOTPExportLong,
|
||||||
|
Example: cmdAutheliaStorageUserTOTPExportExample,
|
||||||
RunE: storageTOTPExportRunE,
|
RunE: storageTOTPExportRunE,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Flags().String("format", storageExportFormatURI, "sets the output format")
|
cmd.Flags().String("format", storageTOTPExportFormatURI, fmt.Sprintf("sets the output format, valid values are: %s", strings.Join(validStorageTOTPExportFormats, ", ")))
|
||||||
cmd.Flags().String("dir", "", "used with the png output format to specify which new directory to save the files in")
|
cmd.Flags().String("dir", "", "used with the png output format to specify which new directory to save the files in")
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -231,7 +261,9 @@ func newStorageTOTPExportCmd() (cmd *cobra.Command) {
|
||||||
func newStorageSchemaInfoCmd() (cmd *cobra.Command) {
|
func newStorageSchemaInfoCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "schema-info",
|
Use: "schema-info",
|
||||||
Short: "Show the storage information",
|
Short: cmdAutheliaStorageSchemaInfoShort,
|
||||||
|
Long: cmdAutheliaStorageSchemaInfoLong,
|
||||||
|
Example: cmdAutheliaStorageSchemaInfoExample,
|
||||||
RunE: storageSchemaInfoRunE,
|
RunE: storageSchemaInfoRunE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +274,9 @@ func newStorageSchemaInfoCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateCmd() (cmd *cobra.Command) {
|
func newStorageMigrateCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "migrate",
|
Use: "migrate",
|
||||||
Short: "Perform or list migrations",
|
Short: cmdAutheliaStorageMigrateShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +292,9 @@ func newStorageMigrateCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateHistoryCmd() (cmd *cobra.Command) {
|
func newStorageMigrateHistoryCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "history",
|
Use: "history",
|
||||||
Short: "Show migration history",
|
Short: cmdAutheliaStorageMigrateHistoryShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateHistoryLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateHistoryExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: storageMigrateHistoryRunE,
|
RunE: storageMigrateHistoryRunE,
|
||||||
}
|
}
|
||||||
|
@ -269,7 +305,9 @@ func newStorageMigrateHistoryCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateListUpCmd() (cmd *cobra.Command) {
|
func newStorageMigrateListUpCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "list-up",
|
Use: "list-up",
|
||||||
Short: "List the up migrations available",
|
Short: cmdAutheliaStorageMigrateListUpShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateListUpLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateListUpExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: newStorageMigrateListRunE(true),
|
RunE: newStorageMigrateListRunE(true),
|
||||||
}
|
}
|
||||||
|
@ -280,7 +318,9 @@ func newStorageMigrateListUpCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateListDownCmd() (cmd *cobra.Command) {
|
func newStorageMigrateListDownCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "list-down",
|
Use: "list-down",
|
||||||
Short: "List the down migrations available",
|
Short: cmdAutheliaStorageMigrateListDownShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateListDownLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateListDownExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: newStorageMigrateListRunE(false),
|
RunE: newStorageMigrateListRunE(false),
|
||||||
}
|
}
|
||||||
|
@ -291,7 +331,9 @@ func newStorageMigrateListDownCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateUpCmd() (cmd *cobra.Command) {
|
func newStorageMigrateUpCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: storageMigrateDirectionUp,
|
Use: storageMigrateDirectionUp,
|
||||||
Short: "Perform a migration up",
|
Short: cmdAutheliaStorageMigrateUpShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateUpLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateUpExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: newStorageMigrationRunE(true),
|
RunE: newStorageMigrationRunE(true),
|
||||||
}
|
}
|
||||||
|
@ -304,7 +346,9 @@ func newStorageMigrateUpCmd() (cmd *cobra.Command) {
|
||||||
func newStorageMigrateDownCmd() (cmd *cobra.Command) {
|
func newStorageMigrateDownCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: storageMigrateDirectionDown,
|
Use: storageMigrateDirectionDown,
|
||||||
Short: "Perform a migration down",
|
Short: cmdAutheliaStorageMigrateDownShort,
|
||||||
|
Long: cmdAutheliaStorageMigrateDownLong,
|
||||||
|
Example: cmdAutheliaStorageMigrateDownExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: newStorageMigrationRunE(false),
|
RunE: newStorageMigrationRunE(false),
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,17 +351,17 @@ func storageTOTPExportRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if page == 0 && format == storageExportFormatCSV {
|
if page == 0 && format == storageTOTPExportFormatCSV {
|
||||||
fmt.Printf("issuer,username,algorithm,digits,period,secret\n")
|
fmt.Printf("issuer,username,algorithm,digits,period,secret\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range configurations {
|
for _, c := range configurations {
|
||||||
switch format {
|
switch format {
|
||||||
case storageExportFormatCSV:
|
case storageTOTPExportFormatCSV:
|
||||||
fmt.Printf("%s,%s,%s,%d,%d,%s\n", c.Issuer, c.Username, c.Algorithm, c.Digits, c.Period, string(c.Secret))
|
fmt.Printf("%s,%s,%s,%d,%d,%s\n", c.Issuer, c.Username, c.Algorithm, c.Digits, c.Period, string(c.Secret))
|
||||||
case storageExportFormatURI:
|
case storageTOTPExportFormatURI:
|
||||||
fmt.Println(c.URI())
|
fmt.Println(c.URI())
|
||||||
case storageExportFormatPNG:
|
case storageTOTPExportFormatPNG:
|
||||||
file, _ := os.Create(filepath.Join(dir, fmt.Sprintf("%s.png", c.Username)))
|
file, _ := os.Create(filepath.Join(dir, fmt.Sprintf("%s.png", c.Username)))
|
||||||
|
|
||||||
if img, err = c.Image(256, 256); err != nil {
|
if img, err = c.Image(256, 256); err != nil {
|
||||||
|
@ -385,7 +385,7 @@ func storageTOTPExportRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if format == storageExportFormatPNG {
|
if format == storageTOTPExportFormatPNG {
|
||||||
fmt.Printf("Exported TOTP QR codes in PNG format in the '%s' directory\n", dir)
|
fmt.Printf("Exported TOTP QR codes in PNG format in the '%s' directory\n", dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,9 +402,9 @@ func storageTOTPExportGetConfigFromFlags(cmd *cobra.Command) (format, dir string
|
||||||
}
|
}
|
||||||
|
|
||||||
switch format {
|
switch format {
|
||||||
case storageExportFormatCSV, storageExportFormatURI:
|
case storageTOTPExportFormatCSV, storageTOTPExportFormatURI:
|
||||||
break
|
break
|
||||||
case storageExportFormatPNG:
|
case storageTOTPExportFormatPNG:
|
||||||
if dir == "" {
|
if dir == "" {
|
||||||
dir = utils.RandomString(8, utils.AlphaNumericCharacters, false)
|
dir = utils.RandomString(8, utils.AlphaNumericCharacters, false)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@ import (
|
||||||
func newValidateConfigCmd() (cmd *cobra.Command) {
|
func newValidateConfigCmd() (cmd *cobra.Command) {
|
||||||
cmd = &cobra.Command{
|
cmd = &cobra.Command{
|
||||||
Use: "validate-config",
|
Use: "validate-config",
|
||||||
Short: "Check a configuration against the internal configuration validation mechanisms",
|
Short: cmdAutheliaValidateConfigShort,
|
||||||
|
Long: cmdAutheliaValidateConfigLong,
|
||||||
|
Example: cmdAutheliaValidateConfigExample,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: cmdValidateConfigRunE,
|
RunE: cmdValidateConfigRunE,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// Code generated by go generate. DO NOT EDIT.
|
// Code generated by go generate. DO NOT EDIT.
|
||||||
//
|
//
|
||||||
// Run the following command to generate this file:
|
// Run the following command to generate this file:
|
||||||
// go run ./cmd/authelia-scripts gen
|
// go run ./cmd/authelia-gen code keys
|
||||||
//
|
//
|
||||||
|
|
||||||
package schema
|
package schema
|
||||||
|
|
||||||
// Keys represents the detected schema keys.
|
// Keys is a list of valid schema keys detected by reflecting over a schema.Configuration struct.
|
||||||
var Keys = []string{
|
var Keys = []string{
|
||||||
"theme",
|
"theme",
|
||||||
"certificates_directory",
|
"certificates_directory",
|
||||||
|
|
Loading…
Reference in New Issue