From 56a7a4132d5f24cb171a9422ab99ba8bf8a884ad Mon Sep 17 00:00:00 2001 From: zeroZshadow Date: Thu, 15 Jul 2021 21:23:59 +0100 Subject: [PATCH] Move interactive setup to own package Remove reflex installation for windows --- Taskfile.yml | 2 +- cli/main.go | 86 +++---------- cli/setup/setup.go | 210 ++++++++++++++++++++++++++++++++ go.mod | 6 +- go.sum | 1 + util/config.go | 266 ++++------------------------------------- web2/package-lock.json | 234 +++++++++++++++++++++--------------- 7 files changed, 397 insertions(+), 408 deletions(-) create mode 100644 cli/setup/setup.go diff --git a/Taskfile.yml b/Taskfile.yml index 4116a285..571e96e8 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -53,7 +53,7 @@ tasks: GORELEASER_VERSION: "0.159.0" GOLINTER_VERSION: "1.31.0" cmds: - - go install github.com/cespare/reflex + - '{{ if ne OS "windows" }} go install github.com/cespare/reflex {{ else }} {{ end }}' - go install github.com/gobuffalo/packr/... - go install github.com/haya14busa/goverage - go install github.com/snikch/goodman/cmd/goodman diff --git a/cli/main.go b/cli/main.go index f9e0e1a5..6814d770 100644 --- a/cli/main.go +++ b/cli/main.go @@ -2,17 +2,16 @@ package main import ( "bufio" - "encoding/json" "fmt" + "net/http" + "os" + "strings" + "time" + + "github.com/ansible-semaphore/semaphore/cli/setup" "github.com/ansible-semaphore/semaphore/db" "github.com/ansible-semaphore/semaphore/db/factory" "github.com/gorilla/context" - "io/ioutil" - "net/http" - "os" - "path" - "strings" - "time" log "github.com/Sirupsen/logrus" "github.com/ansible-semaphore/semaphore/api" @@ -31,7 +30,6 @@ func cropTrailingSlashMiddleware(next http.Handler) http.Handler { }) } - func main() { util.ConfigInit() @@ -78,7 +76,7 @@ func main() { route := api.Route() - route.Use(func (next http.Handler) http.Handler { + route.Use(func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { context.Set(r, "store", store) next.ServeHTTP(w, r) @@ -100,79 +98,33 @@ func main() { //nolint: gocyclo func doSetup() int { - - fmt.Print(` - Hello! You will now be guided through a setup to: - - 1. Set up configuration for a MySQL/MariaDB database - 2. Set up a path for your playbooks (auto-created) - 3. Run database Migrations - 4. Set up initial semaphore user & password - -`) - - var b []byte - setup := util.NewConfig() + var config *util.ConfigType for { - setup.Scan() - setup.GenerateCookieSecrets() + config = &util.ConfigType{} + config.GenerateCookieSecrets() + setup.InteractiveSetup(config) - var err error - b, err = json.MarshalIndent(&setup, " ", "\t") - if err != nil { - panic(err) - } - - fmt.Printf("\n Generated configuration:\n %v\n\n", string(b)) - fmt.Print(" > Is this correct? (yes/no): ") - - var answer string - util.ScanErrorChecker(fmt.Scanln(&answer)) - if answer == "yes" || answer == "y" { + if setup.VerifyConfig(config) { break } fmt.Println() - setup = util.NewConfig() } - confDir, err := os.Getwd() - if err != nil { - confDir = "/etc/semaphore" - } - fmt.Print(" > Config output directory (default " + confDir + "): ") - - var answer string - util.ScanErrorChecker(fmt.Scanln(&answer)) - if len(answer) > 0 { - confDir = answer - } - - fmt.Printf(" Running: mkdir -p %v..\n", confDir) - err = os.MkdirAll(confDir, 0755) //nolint: gas - if err != nil { - log.Panic("Could not create config directory: " + err.Error()) - } - - configPath := path.Join(confDir, "/config.json") - if err = ioutil.WriteFile(configPath, b, 0644); err != nil { - panic(err) - } - fmt.Printf(" Configuration written to %v..\n", configPath) + configPath := setup.ScanConfigPathAndSave(config) + util.Config = config fmt.Println(" Pinging db..") - util.Config = setup store := factory.CreateStore() - - if err = store.Connect(); err != nil { - fmt.Printf("\n Cannot connect to database!\n %v\n", err.Error()) + if err := store.Connect(); err != nil { + fmt.Printf("Cannot connect to database!\n %v\n", err.Error()) os.Exit(1) } - fmt.Println("\n Running DB Migrations..") - if err = store.Migrate(); err != nil { - fmt.Printf("\n Database migrations failed!\n %v\n", err.Error()) + fmt.Println("Running DB Migrations..") + if err := store.Migrate(); err != nil { + fmt.Printf("Database migrations failed!\n %v\n", err.Error()) os.Exit(1) } diff --git a/cli/setup/setup.go b/cli/setup/setup.go new file mode 100644 index 00000000..c2450149 --- /dev/null +++ b/cli/setup/setup.go @@ -0,0 +1,210 @@ +package setup + +import ( + "bufio" + "fmt" + "io" + "io/ioutil" + "os" + "path/filepath" + "strings" + + log "github.com/Sirupsen/logrus" + + "github.com/ansible-semaphore/semaphore/util" +) + +const yesLong = "yes" +const yesShort = "y" + +const interactiveSetupBlurb = ` +Hello! You will now be guided through a setup to: + +1. Set up configuration for a MySQL/MariaDB database +2. Set up a path for your playbooks (auto-created) +3. Run database Migrations +4. Set up initial semaphore user & password + +` + +func InteractiveSetup(conf *util.ConfigType) { + stdin := bufio.NewReader(os.Stdin) + + fmt.Print(interactiveSetupBlurb) + + dbPrompt := `What database to use: + 1 - MySQL + 2 - BoltDB +` + + var db int + promptValue(stdin, dbPrompt, "1", &db) + + switch db { + case 1: + scanMySQL(conf, stdin) + case 2: + scanBoltDb(conf, stdin) + } + + defaultPlaybookPath := filepath.Join(os.TempDir(), "semaphore") + promptValue(stdin, "Playbook path", defaultPlaybookPath, &conf.TmpPath) + conf.TmpPath = filepath.Clean(conf.TmpPath) + + promptValue(stdin, "Web root URL (optional, see https://github.com/ansible-semaphore/semaphore/wiki/Web-root-URL)", "", &conf.WebHost) + + promptConfirmation(stdin, "Enable email alerts?", false, &conf.EmailAlert) + if conf.EmailAlert { + promptValue(stdin, "Mail server host", "localhost", &conf.EmailHost) + promptValue(stdin, "Mail server port", "25", &conf.EmailPort) + promptValue(stdin, "Mail sender address", "semaphore@localhost", &conf.EmailSender) + } + + promptConfirmation(stdin, "Enable telegram alerts?", false, &conf.TelegramAlert) + if conf.TelegramAlert { + promptValue(stdin, "Telegram bot token (you can get it from @BotFather)", "", &conf.TelegramToken) + promptValue(stdin, "Telegram chat ID", "", &conf.TelegramChat) + } + + promptConfirmation(stdin, "Enable LDAP authentication?", false, &conf.LdapEnable) + if conf.LdapEnable { + promptValue(stdin, "LDAP server host", "localhost:389", &conf.LdapServer) + promptConfirmation(stdin, "Enable LDAP TLS connection", false, &conf.LdapNeedTLS) + promptValue(stdin, "LDAP DN for bind", "cn=user,ou=users,dc=example", &conf.LdapBindDN) + promptValue(stdin, "Password for LDAP bind user", "pa55w0rd", &conf.LdapBindPassword) + promptValue(stdin, "LDAP DN for user search", "ou=users,dc=example", &conf.LdapSearchDN) + promptValue(stdin, "LDAP search filter", `(uid=%s)`, &conf.LdapSearchFilter) + promptValue(stdin, "LDAP mapping for DN field", "dn", &conf.LdapMappings.DN) + promptValue(stdin, "LDAP mapping for username field", "uid", &conf.LdapMappings.UID) + promptValue(stdin, "LDAP mapping for full name field", "cn", &conf.LdapMappings.CN) + promptValue(stdin, "LDAP mapping for email field", "mail", &conf.LdapMappings.Mail) + } +} + +func scanBoltDb(conf *util.ConfigType, stdin *bufio.Reader) { + workingDirectory, err := os.Getwd() + if err != nil { + workingDirectory = os.TempDir() + } + defaultBoltDBPath := filepath.Join(workingDirectory, "database.boltdb") + promptValue(stdin, "DB filename", defaultBoltDBPath, &conf.BoltDb.Hostname) +} + +func scanMySQL(conf *util.ConfigType, stdin *bufio.Reader) { + promptValue(stdin, "DB Hostname", "127.0.0.1:3306", &conf.MySQL.Hostname) + promptValue(stdin, "DB User", "root", &conf.MySQL.Username) + promptValue(stdin, "DB Password", "", &conf.MySQL.Password) + promptValue(stdin, "DB Name", "semaphore", &conf.MySQL.DbName) +} + +func ScanConfigPathAndSave(config *util.ConfigType) string { + stdin := bufio.NewReader(os.Stdin) + + configDirectory, err := os.Getwd() + if err != nil { + configDirectory, err = os.UserConfigDir() + if err != nil { + // Final fallback + configDirectory = "/etc/semaphore" + } + configDirectory = filepath.Join(configDirectory, "semaphore") + } + promptValue(stdin, "Config output directory", configDirectory, &configDirectory) + + fmt.Printf("Running: mkdir -p %v..\n", configDirectory) + err = os.MkdirAll(configDirectory, 0755) + if err != nil { + log.Panic("Could not create config directory: " + err.Error()) + } + + // Marshal config to json + bytes, err := config.ToJSON() + if err != nil { + panic(err) + } + + configPath := filepath.Join(configDirectory, "config.json") + if err = ioutil.WriteFile(configPath, bytes, 0644); err != nil { + panic(err) + } + + fmt.Printf("Configuration written to %v..\n", configPath) + return configPath +} + +func VerifyConfig(config *util.ConfigType) bool { + stdin := bufio.NewReader(os.Stdin) + + bytes, err := config.ToJSON() + if err != nil { + panic(err) + } + + fmt.Printf("\nGenerated configuration:\n %v\n\n", string(bytes)) + + var correct bool + promptConfirmation(stdin, "Is this correct?", true, &correct) + return correct +} + +func promptValue(stdin *bufio.Reader, prompt string, def string, item interface{}) { + // Print prompt with optional default value + fmt.Print(prompt) + if len(def) != 0 { + fmt.Print(" (default " + def + ")") + } + fmt.Print("\n> ") + + str, err := stdin.ReadString('\n') + if err != nil { + log.WithFields(log.Fields{"level": "Warn"}).Warn(err.Error()) + } + + // Remove newlines + str = strings.TrimSuffix(str, "\n") + str = strings.TrimSuffix(str, "\r") + + // If default, print default on input line + if len(str) == 0 { + str = def + fmt.Print("\033[1A") + fmt.Println("> " + def) + } + + //Parse + if _, err := fmt.Sscanln(str, item); err != nil && err != io.EOF { + log.WithFields(log.Fields{"level": "Warn"}).Warn(err.Error()) + } + + // Empty line after prompt + fmt.Println("") +} + +func promptConfirmation(stdin *bufio.Reader, prompt string, def bool, item *bool) { + defString := "yes" + if !def { + defString = "no" + } + + fmt.Print(prompt + " (yes/no) (default " + defString + ")") + fmt.Print("\n> ") + + str, err := stdin.ReadString('\n') + if err != nil { + log.WithFields(log.Fields{"level": "Warn"}).Warn(err.Error()) + } + + switch strings.ToLower(str) { + case "y", "yes": + *item = true + case "n", "no": + *item = false + default: + *item = def + fmt.Print("\033[1A") + fmt.Println("> " + defString) + } + + // Empty line after prompt + fmt.Println("") +} diff --git a/go.mod b/go.mod index 609c2280..eb0c91b9 100644 --- a/go.mod +++ b/go.mod @@ -9,8 +9,8 @@ require ( github.com/Sirupsen/logrus v1.0.4 github.com/cespare/reflex v0.3.0 // indirect github.com/go-gorp/gorp/v3 v3.0.2 - github.com/go-openapi/loads v0.19.4 - github.com/go-openapi/spec v0.19.6 + github.com/go-openapi/loads v0.19.4 // indirect + github.com/go-openapi/spec v0.19.6 // indirect github.com/go-sql-driver/mysql v1.4.1 github.com/go-swagger/go-swagger v0.22.0 // indirect github.com/go-task/task v2.2.0+incompatible // indirect @@ -39,7 +39,7 @@ require ( github.com/radovskyb/watcher v1.0.7 // indirect github.com/russross/blackfriday v1.5.2 github.com/sirupsen/logrus v1.4.2 // indirect - github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa + github.com/snikch/goodman v0.0.0-20171125024755-10e37e294daa // indirect github.com/spf13/cobra v0.0.5 // indirect github.com/ziutek/mymysql v1.5.4 // indirect go.etcd.io/bbolt v1.3.2 diff --git a/go.sum b/go.sum index c9dbc759..72658787 100644 --- a/go.sum +++ b/go.sum @@ -165,6 +165,7 @@ github.com/haya14busa/goverage v0.0.0-20180129164344-eec3514a20b5/go.mod h1:0YZ2 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= diff --git a/util/config.go b/util/config.go index 32bf1f3f..609cd939 100644 --- a/util/config.go +++ b/util/config.go @@ -6,10 +6,8 @@ import ( "errors" "flag" "fmt" - log "github.com/Sirupsen/logrus" "os" "path" - "path/filepath" "net/url" @@ -35,11 +33,6 @@ var Upgrade bool // WebHostURL is the public route to the semaphore server var WebHostURL *url.URL -const ( - longPos = "yes" - shortPos = "y" -) - type DbDriver int const ( @@ -64,8 +57,8 @@ type ldapMappings struct { //ConfigType mapping between Config and the json file that sets it type ConfigType struct { - MySQL DbConfig `json:"mysql"` - BoltDb DbConfig `json:"bolt"` + MySQL DbConfig `json:"mysql"` + BoltDb DbConfig `json:"bolt"` // Format `:port_num` eg, :3000 // if : is missing it will be corrected @@ -119,21 +112,9 @@ type ConfigType struct { //Config exposes the application configuration storage for use in the application var Config *ConfigType -var confPath *string - -// NewConfig returns a reference to a new blank configType -// nolint: golint -func NewConfig() *ConfigType { - return &ConfigType{} -} - -// ScanErrorChecker deals with errors encountered while scanning lines -// since we do not fail on these errors currently we can simply note them -// and move on -func ScanErrorChecker(n int, err error) { - if err != nil { - log.Warn("An input error occurred:" + err.Error()) - } +// ToJSON returns a JSON string of the config +func (config *ConfigType) ToJSON() ([]byte, error) { + return json.MarshalIndent(&config, " ", "\t") } // ConfigInit reads in cli flags, and switches actions appropriately on them @@ -141,7 +122,7 @@ func ConfigInit() { flag.BoolVar(&InteractiveSetup, "setup", false, "perform interactive setup") flag.BoolVar(&Migration, "migrate", false, "execute migrations") flag.BoolVar(&Upgrade, "upgrade", false, "upgrade semaphore") - confPath = flag.String("config", "", "config path") + configPath := flag.String("config", "", "config path") var unhashedPwd string flag.StringVar(&unhashedPwd, "hash", "", "generate hash of given password") @@ -164,7 +145,7 @@ func ConfigInit() { } if printConfig { - cfg := &ConfigType{ + config := &ConfigType{ MySQL: DbConfig{ Hostname: "127.0.0.1:3306", Username: "root", @@ -173,10 +154,10 @@ func ConfigInit() { Port: ":3000", TmpPath: "/tmp/semaphore", } - cfg.GenerateCookieSecrets() + config.GenerateCookieSecrets() - b, _ := json.MarshalIndent(cfg, "", "\t") - fmt.Println(string(b)) + bytes, _ := config.ToJSON() + fmt.Println(string(bytes)) os.Exit(0) } @@ -188,7 +169,7 @@ func ConfigInit() { os.Exit(0) } - loadConfig() + loadConfig(configPath) validateConfig() var encryption []byte @@ -205,24 +186,27 @@ func ConfigInit() { } } -func loadConfig() { - - //If the confPath option has been set try to load and decode it - if confPath != nil && len(*confPath) > 0 { - file, err := os.Open(*confPath) +func loadConfig(configPath *string) { + //If the configPath option has been set try to load and decode it + var usedPath string + if configPath != nil && len(*configPath) > 0 { + path := *configPath + file, err := os.Open(path) exitOnConfigError(err) decodeConfig(file) + usedPath = path } else { - // if no confPath look in the cwd + // if no configPath look in the cwd cwd, err := os.Getwd() exitOnConfigError(err) - cwd = cwd + "/config.json" - confPath = &cwd - file, err := os.Open(*confPath) + defaultPath := path.Join(cwd, "config.json") + file, err := os.Open(defaultPath) exitOnConfigError(err) decodeConfig(file) + usedPath = defaultPath } - fmt.Println("Using config file: " + *confPath) + + fmt.Println("Using config file: " + usedPath) } func validateConfig() { @@ -325,205 +309,3 @@ func (conf *ConfigType) GenerateCookieSecrets() { conf.CookieHash = base64.StdEncoding.EncodeToString(hash) conf.CookieEncryption = base64.StdEncoding.EncodeToString(encryption) } - -func (conf *ConfigType) ScanBoltDb() { - filename, err := os.Getwd() // os.UserHomeDir() - exitOnConfigError(err) - filename = filepath.Join(filename, "database.bolt") - fmt.Print(" > DB filename (default " + filename + "): ") - ScanErrorChecker(fmt.Scanln(&conf.BoltDb.Hostname)) - if len(conf.BoltDb.Hostname) == 0 { - conf.BoltDb.Hostname = filename - } -} - -func (conf *ConfigType) ScanMySQL() { - - fmt.Print(" > DB Hostname (default 127.0.0.1:3306): ") - ScanErrorChecker(fmt.Scanln(&conf.MySQL.Hostname)) - if len(conf.MySQL.Hostname) == 0 { - conf.MySQL.Hostname = "127.0.0.1:3306" - } - - fmt.Print(" > DB User (default root): ") - ScanErrorChecker(fmt.Scanln(&conf.MySQL.Username)) - if len(conf.MySQL.Username) == 0 { - conf.MySQL.Username = "root" - } - - fmt.Print(" > DB Password: ") - ScanErrorChecker(fmt.Scanln(&conf.MySQL.Password)) - - fmt.Print(" > DB Name (default semaphore): ") - ScanErrorChecker(fmt.Scanln(&conf.MySQL.DbName)) - if len(conf.MySQL.DbName) == 0 { - conf.MySQL.DbName = "semaphore" - } -} - -//nolint: gocyclo -func (conf *ConfigType) Scan() { - db := 1 - fmt.Println(" > DB") - fmt.Println(" 1 - MySQL") - fmt.Println(" 2 - bbolt") - fmt.Print(" (default 1): ") - ScanErrorChecker(fmt.Scanln(&db)) - - switch db { - case 1: - conf.ScanMySQL() - case 2: - conf.ScanBoltDb() - } - - fmt.Print(" > Playbook path (default /tmp/semaphore): ") - ScanErrorChecker(fmt.Scanln(&conf.TmpPath)) - - if len(conf.TmpPath) == 0 { - conf.TmpPath = "/tmp/semaphore" - } - conf.TmpPath = path.Clean(conf.TmpPath) - - fmt.Print(" > Web root URL (optional, see https://github.com/ansible-semaphore/semaphore/wiki/Web-root-URL): ") - ScanErrorChecker(fmt.Scanln(&conf.WebHost)) - - var EmailAlertAnswer string - fmt.Print(" > Enable email alerts (y/n, default n): ") - ScanErrorChecker(fmt.Scanln(&EmailAlertAnswer)) - if EmailAlertAnswer == longPos || EmailAlertAnswer == shortPos { - - conf.EmailAlert = true - - fmt.Print(" > Mail server host (default localhost): ") - ScanErrorChecker(fmt.Scanln(&conf.EmailHost)) - - if len(conf.EmailHost) == 0 { - conf.EmailHost = "localhost" - } - - fmt.Print(" > Mail server port (default 25): ") - ScanErrorChecker(fmt.Scanln(&conf.EmailPort)) - - if len(conf.EmailPort) == 0 { - conf.EmailPort = "25" - } - - fmt.Print(" > Mail sender address (default semaphore@localhost): ") - ScanErrorChecker(fmt.Scanln(&conf.EmailSender)) - - if len(conf.EmailSender) == 0 { - conf.EmailSender = "semaphore@localhost" - } - - } else { - conf.EmailAlert = false - } - - var TelegramAlertAnswer string - fmt.Print(" > Enable telegram alerts (y/n, default n): ") - ScanErrorChecker(fmt.Scanln(&TelegramAlertAnswer)) - if TelegramAlertAnswer == longPos || TelegramAlertAnswer == shortPos { - - conf.TelegramAlert = true - - fmt.Print(" > Telegram bot token (you can get it from @BotFather) (default ''): ") - ScanErrorChecker(fmt.Scanln(&conf.TelegramToken)) - - if len(conf.TelegramToken) == 0 { - conf.TelegramToken = "" - } - - fmt.Print(" > Telegram chat ID (default ''): ") - ScanErrorChecker(fmt.Scanln(&conf.TelegramChat)) - - if len(conf.TelegramChat) == 0 { - conf.TelegramChat = "" - } - - } else { - conf.TelegramAlert = false - } - - var LdapAnswer string - fmt.Print(" > Enable LDAP authentication (y/n, default n): ") - ScanErrorChecker(fmt.Scanln(&LdapAnswer)) - if LdapAnswer == longPos || LdapAnswer == shortPos { - - conf.LdapEnable = true - - fmt.Print(" > LDAP server host (default localhost:389): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapServer)) - - if len(conf.LdapServer) == 0 { - conf.LdapServer = "localhost:389" - } - - var LdapTLSAnswer string - fmt.Print(" > Enable LDAP TLS connection (y/n, default n): ") - ScanErrorChecker(fmt.Scanln(&LdapTLSAnswer)) - if LdapTLSAnswer == longPos || LdapTLSAnswer == shortPos { - conf.LdapNeedTLS = true - } else { - conf.LdapNeedTLS = false - } - - fmt.Print(" > LDAP DN for bind (default cn=user,ou=users,dc=example): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapBindDN)) - - if len(conf.LdapBindDN) == 0 { - conf.LdapBindDN = "cn=user,ou=users,dc=example" - } - - fmt.Print(" > Password for LDAP bind user (default pa55w0rd): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapBindPassword)) - - if len(conf.LdapBindPassword) == 0 { - conf.LdapBindPassword = "pa55w0rd" - } - - fmt.Print(" > LDAP DN for user search (default ou=users,dc=example): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapSearchDN)) - - if len(conf.LdapSearchDN) == 0 { - conf.LdapSearchDN = "ou=users,dc=example" - } - - fmt.Print(" > LDAP search filter (default (uid=" + "%" + "s)): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapSearchFilter)) - - if len(conf.LdapSearchFilter) == 0 { - conf.LdapSearchFilter = "(uid=%s)" - } - - fmt.Print(" > LDAP mapping for DN field (default dn): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapMappings.DN)) - - if len(conf.LdapMappings.DN) == 0 { - conf.LdapMappings.DN = "dn" - } - - fmt.Print(" > LDAP mapping for username field (default uid): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapMappings.UID)) - - if len(conf.LdapMappings.UID) == 0 { - conf.LdapMappings.UID = "uid" - } - - fmt.Print(" > LDAP mapping for full name field (default cn): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapMappings.CN)) - - if len(conf.LdapMappings.CN) == 0 { - conf.LdapMappings.CN = "cn" - } - - fmt.Print(" > LDAP mapping for email field (default mail): ") - ScanErrorChecker(fmt.Scanln(&conf.LdapMappings.Mail)) - - if len(conf.LdapMappings.Mail) == 0 { - conf.LdapMappings.Mail = "mail" - } - } else { - conf.LdapEnable = false - } -} diff --git a/web2/package-lock.json b/web2/package-lock.json index 93b67d05..41f7c4fe 100644 --- a/web2/package-lock.json +++ b/web2/package-lock.json @@ -1913,17 +1913,6 @@ "unique-filename": "^1.1.1" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -1971,25 +1960,6 @@ "path-exists": "^4.0.0" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "optional": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "optional": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2045,25 +2015,15 @@ "dev": true }, "ssri": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", - "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.1.tgz", + "integrity": "sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==", "dev": true, "requires": { "figgy-pudding": "^3.5.1", "minipass": "^3.1.1" } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "optional": true, - "requires": { - "has-flag": "^4.0.0" - } - }, "terser-webpack-plugin": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", @@ -2081,18 +2041,6 @@ "webpack-sources": "^1.4.3" } }, - "vue-loader-v16": { - "version": "npm:vue-loader@16.0.0-beta.10", - "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.0.0-beta.10.tgz", - "integrity": "sha512-PflGsj4RHW3tuYFmSPhcozAkds8ELXf8d19twWorQTjcuWxl/Xqb9W1NgfsY7AAkCkkRRYy2FwIX4tSnskfKig==", - "dev": true, - "optional": true, - "requires": { - "chalk": "^4.1.0", - "hash-sum": "^2.0.0", - "loader-utils": "^2.0.0" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -3291,15 +3239,30 @@ } }, "browserslist": { - "version": "4.14.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.5.tgz", - "integrity": "sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001135", - "electron-to-chromium": "^1.3.571", - "escalade": "^3.1.0", - "node-releases": "^1.1.61" + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "dependencies": { + "caniuse-lite": { + "version": "1.0.30001245", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", + "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + } } }, "buffer": { @@ -5228,9 +5191,9 @@ "dev": true }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "requires": { "ip": "^1.1.0", @@ -5427,9 +5390,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.572", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.572.tgz", - "integrity": "sha512-TKqdEukCCl7JC20SwEoWTbtnGt4YjfHWAv4tcNky0a9qGo0WdM+Lrd60tps+nkaJCmktKBJjr99fLtEBU1ipWQ==", + "version": "1.3.776", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.776.tgz", + "integrity": "sha512-V0w7eFSBoFPpdw4xexjVPZ770UDZIevSwkkj4W97XbE3IsCsTRFpa7/yXGZ88EOQAUEA09JMMsWK0xsw0kRAYw==", "dev": true }, "elliptic": { @@ -5576,9 +5539,9 @@ "dev": true }, "escalade": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.0.tgz", - "integrity": "sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true }, "escape-html": { @@ -6918,9 +6881,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -7191,9 +7154,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "hpack.js": { @@ -8679,9 +8642,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.clonedeep": { @@ -9845,9 +9808,9 @@ } }, "node-releases": { - "version": "1.1.61", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.61.tgz", - "integrity": "sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "node-sass": { @@ -10951,9 +10914,9 @@ "dev": true }, "postcss": { - "version": "7.0.34", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.34.tgz", - "integrity": "sha512-H/7V2VeNScX9KE83GDrDZNiGT1m2H+UTnlinIzhjlLX9hfMUn1mHNnGeX81a1c8JSBdBvqk7c2ZOG6ZPn5itGw==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -14122,9 +14085,9 @@ } }, "url-parse": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", - "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", "dev": true, "requires": { "querystringify": "^2.1.1", @@ -14333,6 +14296,87 @@ } } }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.3.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.3.0.tgz", + "integrity": "sha512-UDgni/tUVSdwHuQo+vuBmEgamWx88SuSlEb5fgdvHrlJSPB9qMBRF6W7bfPWSqDns425Gt1wxAUif+f+h/rWjg==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "optional": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "optional": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "optional": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "optional": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "optional": true + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "optional": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "vue-router": { "version": "3.4.4", "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.4.tgz", @@ -15100,9 +15144,9 @@ } }, "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", "dev": true }, "xml-name-validator": { @@ -15124,9 +15168,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": {