feat(commands): random character generator (#4213)

This improves all random character generator command usages to be nearly identical and reuse a large block of code. It also improves several functions to give more options when randomly generating outputs.
pull/4219/head
James Elliott 2022-10-21 07:41:46 +11:00 committed by GitHub
parent 3f8958d1b1
commit 3113ec2b80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 186 additions and 136 deletions

View File

@ -2,7 +2,7 @@
title: "Specific Information"
description: "Specific information regarding integrating the Authelia OpenID Connect Provider with an OpenID Connect relying party"
lead: "Specific information regarding integrating the Authelia OpenID Connect Provider with an OpenID Connect relying party."
date: 2022-06-15T17:51:47+10:00
date: 2022-10-20T15:27:09+11:00
draft: false
images: []
menu:

View File

@ -37,10 +37,14 @@ authelia crypto hash generate --help
### Options
```
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for generate
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for generate
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -35,19 +35,26 @@ authelia crypto hash generate argon2 --help
### Options
```
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for argon2
-i, --iterations int number of iterations (default 3)
-k, --key-size int key size in bytes (default 32)
-m, --memory int memory in kibibytes (default 65536)
--no-confirm skip the password confirmation prompt
-p, --parallelism int parallelism or threads (default 4)
--password string manually supply the password rather than using the terminal prompt
--profile string profile to use, options are low-memory and recommended
--random uses a randomly generated password
--random.length int when using a randomly generated password it configures the length (default 72)
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are 'argon2id', 'argon2i', and 'argon2d' (default "argon2id")
-h, --help help for argon2
-i, --iterations int number of iterations (default 3)
-k, --key-size int key size in bytes (default 32)
-m, --memory int memory in kibibytes (default 65536)
-p, --parallelism int parallelism or threads (default 4)
--profile string profile to use, options are low-memory and recommended
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are 'argon2id', 'argon2i', and 'argon2d' (default "argon2id")
```
### Options inherited from parent commands
```
-c, --config strings configuration files to load (default [configuration.yml])
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -35,14 +35,21 @@ authelia crypto hash generate bcrypt --help
### Options
```
-c, --config strings configuration files to load (default [configuration.yml])
-i, --cost int hashing cost (default 12)
-h, --help help for bcrypt
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.length int when using a randomly generated password it configures the length (default 72)
-v, --variant string variant, options are 'standard' and 'sha256' (default "standard")
-i, --cost int hashing cost (default 12)
-h, --help help for bcrypt
-v, --variant string variant, options are 'standard' and 'sha256' (default "standard")
```
### Options inherited from parent commands
```
-c, --config strings configuration files to load (default [configuration.yml])
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -35,15 +35,22 @@ authelia crypto hash generate pbkdf2 --help
### Options
```
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for pbkdf2
-i, --iterations int number of iterations (default 310000)
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.length int when using a randomly generated password it configures the length (default 72)
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are 'sha1', 'sha224', 'sha256', 'sha384', and 'sha512' (default "sha512")
-h, --help help for pbkdf2
-i, --iterations int number of iterations (default 310000)
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are 'sha1', 'sha224', 'sha256', 'sha384', and 'sha512' (default "sha512")
```
### Options inherited from parent commands
```
-c, --config strings configuration files to load (default [configuration.yml])
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -35,17 +35,24 @@ authelia crypto hash generate scrypt --help
### Options
```
-r, --block-size int block size (default 8)
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for scrypt
-i, --iterations int number of iterations (default 16)
-k, --key-size int key size in bytes (default 32)
--no-confirm skip the password confirmation prompt
-p, --parallelism int parallelism or threads (default 1)
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.length int when using a randomly generated password it configures the length (default 72)
-s, --salt-size int salt size in bytes (default 16)
-r, --block-size int block size (default 8)
-h, --help help for scrypt
-i, --iterations int number of iterations (default 16)
-k, --key-size int key size in bytes (default 32)
-p, --parallelism int parallelism or threads (default 1)
-s, --salt-size int salt size in bytes (default 16)
```
### Options inherited from parent commands
```
-c, --config strings configuration files to load (default [configuration.yml])
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -35,15 +35,22 @@ authelia crypto hash generate sha2crypt --help
### Options
```
-c, --config strings configuration files to load (default [configuration.yml])
-h, --help help for sha2crypt
-i, --iterations int number of iterations (default 50000)
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.length int when using a randomly generated password it configures the length (default 72)
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are sha256 and sha512 (default "sha512")
-h, --help help for sha2crypt
-i, --iterations int number of iterations (default 50000)
-s, --salt-size int salt size in bytes (default 16)
-v, --variant string variant, options are sha256 and sha512 (default "sha512")
```
### Options inherited from parent commands
```
-c, --config strings configuration files to load (default [configuration.yml])
--no-confirm skip the password confirmation prompt
--password string manually supply the password rather than using the terminal prompt
--random uses a randomly generated password
--random.characters string sets the explicit characters for the random string
--random.charset string sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--random.length int when using a randomly generated password it configures the length (default 72)
```
### SEE ALSO

View File

@ -43,10 +43,10 @@ authelia crypto rand --characters 0123456789ABCDEF
### Options
```
--characters string Sets the explicit characters for the random output
-c, --charset string Sets the charset for the output, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
--characters string Sets the explicit characters for the random string
-c, --charset string Sets the charset for the random string, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex' (default "alphanumeric")
-h, --help help for rand
-n, --length int Sets the length of the random output (default 80)
-n, --length int Sets the length of the random output (default 72)
```
### SEE ALSO

View File

@ -529,21 +529,23 @@ const (
cmdFlagNameBits = "bits"
cmdFlagNameCurve = "curve"
cmdFlagNamePassword = "password"
cmdFlagNameRandom = "random"
cmdFlagNameRandomLength = "random.length"
cmdFlagNameNoConfirm = "no-confirm"
cmdFlagNameVariant = "variant"
cmdFlagNameCost = "cost"
cmdFlagNameIterations = "iterations"
cmdFlagNameParallelism = "parallelism"
cmdFlagNameBlockSize = "block-size"
cmdFlagNameMemory = "memory"
cmdFlagNameKeySize = "key-size"
cmdFlagNameSaltSize = "salt-size"
cmdFlagNameProfile = "profile"
cmdFlagNameSHA512 = "sha512"
cmdFlagNameConfig = "config"
cmdFlagNamePassword = "password"
cmdFlagNameRandom = "random"
cmdFlagNameRandomLength = "random.length"
cmdFlagNameRandomCharSet = "random.charset"
cmdFlagNameRandomCharacters = "random.characters"
cmdFlagNameNoConfirm = "no-confirm"
cmdFlagNameVariant = "variant"
cmdFlagNameCost = "cost"
cmdFlagNameIterations = "iterations"
cmdFlagNameParallelism = "parallelism"
cmdFlagNameBlockSize = "block-size"
cmdFlagNameMemory = "memory"
cmdFlagNameKeySize = "key-size"
cmdFlagNameSaltSize = "salt-size"
cmdFlagNameProfile = "profile"
cmdFlagNameSHA512 = "sha512"
cmdFlagNameConfig = "config"
cmdFlagNameCharSet = "charset"
cmdFlagNameCharacters = "characters"

View File

@ -44,53 +44,15 @@ func newCryptoRandCmd() (cmd *cobra.Command) {
Example: cmdAutheliaCryptoRandExample,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) (err error) {
useCharSet, useCharacters := cmd.Flags().Changed(cmdFlagNameCharSet), cmd.Flags().Changed(cmdFlagNameCharacters)
if useCharSet && useCharacters {
return fmt.Errorf("flags '--%s' and '--%s' are mutually exclusive, only one may be specified", cmdFlagNameCharSet, cmdFlagNameCharacters)
}
var (
charset string
n int
random string
)
if n, err = cmd.Flags().GetInt(cmdFlagNameLength); err != nil {
if random, err = flagsGetRandomCharacters(cmd.Flags(), cmdFlagNameLength, cmdFlagNameCharSet, cmdFlagNameCharacters); err != nil {
return err
}
if n < 1 {
return fmt.Errorf("length must be at least 1")
}
switch {
case useCharSet, !useCharSet && !useCharacters:
var c string
if c, err = cmd.Flags().GetString(cmdFlagNameCharSet); err != nil {
return err
}
switch c {
case "ascii":
charset = utils.CharSetASCII
case "alphanumeric":
charset = utils.CharSetAlphaNumeric
case "alphabetic":
charset = utils.CharSetAlphabetic
case "numeric-hex":
charset = utils.CharSetNumericHex
case "numeric":
charset = utils.CharSetNumeric
default:
return fmt.Errorf("invalid charset '%s', must be one of 'ascii', 'alphanumeric', 'alphabetic', 'numeric', or 'numeric-hex'", c)
}
case useCharacters:
if charset, err = cmd.Flags().GetString(cmdFlagNameCharacters); err != nil {
return err
}
}
fmt.Printf("Random Value: %s\n", utils.RandomString(n, charset, true))
fmt.Printf("Random Value: %s\n", random)
return nil
},
@ -98,9 +60,9 @@ func newCryptoRandCmd() (cmd *cobra.Command) {
DisableAutoGenTag: true,
}
cmd.Flags().StringP(cmdFlagNameCharSet, "c", "alphanumeric", "Sets the charset for the output, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex'")
cmd.Flags().String(cmdFlagNameCharacters, "", "Sets the explicit characters for the random output")
cmd.Flags().IntP(cmdFlagNameLength, "n", 80, "Sets the length of the random output")
cmd.Flags().StringP(cmdFlagNameCharSet, "c", "alphanumeric", "Sets the charset for the random string, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex'")
cmd.Flags().String(cmdFlagNameCharacters, "", "Sets the explicit characters for the random string")
cmd.Flags().IntP(cmdFlagNameLength, "n", 72, "Sets the length of the random output")
return cmd
}

View File

@ -14,7 +14,6 @@ import (
"github.com/authelia/authelia/v4/internal/configuration"
"github.com/authelia/authelia/v4/internal/configuration/schema"
"github.com/authelia/authelia/v4/internal/configuration/validator"
"github.com/authelia/authelia/v4/internal/utils"
)
func newHashPasswordCmd() (cmd *cobra.Command) {
@ -105,6 +104,7 @@ func newCryptoHashGenerateCmd() (cmd *cobra.Command) {
cmdFlagConfig(cmd)
cmdFlagPassword(cmd, true)
cmdFlagRandomPassword(cmd)
for _, use := range []string{cmdUseHashArgon2, cmdUseHashSHA2Crypt, cmdUseHashPBKDF2, cmdUseHashBCrypt, cmdUseHashSCrypt} {
cmd.AddCommand(newCryptoHashGenerateSubCmd(use))
@ -129,10 +129,6 @@ func newCryptoHashGenerateSubCmd(use string) (cmd *cobra.Command) {
DisableAutoGenTag: true,
}
cmdFlagConfig(cmd)
cmdFlagPassword(cmd, true)
cmdFlagRandomPassword(cmd)
switch use {
case cmdUseHashArgon2:
cmdFlagIterations(cmd, schema.DefaultPasswordConfig.Argon2.Iterations)
@ -419,13 +415,7 @@ func cmdCryptoHashGetPassword(cmd *cobra.Command, args []string, useArgs, useRan
switch {
case random:
var length int
if length, err = cmd.Flags().GetInt(cmdFlagNameRandomLength); err != nil {
return
}
password = utils.RandomString(length, utils.CharSetAlphaNumeric, true)
password, err = flagsGetRandomCharacters(cmd.Flags(), cmdFlagNameRandomLength, cmdFlagNameRandomCharSet, cmdFlagNameCharacters)
return
case cmd.Flags().Changed(cmdFlagNamePassword):
@ -494,20 +484,22 @@ func hashReadPasswordWithPrompt(prompt string) (data []byte, err error) {
}
func cmdFlagConfig(cmd *cobra.Command) {
cmd.Flags().StringSliceP(cmdFlagNameConfig, "c", []string{"configuration.yml"}, "configuration files to load")
cmd.PersistentFlags().StringSliceP(cmdFlagNameConfig, "c", []string{"configuration.yml"}, "configuration files to load")
}
func cmdFlagPassword(cmd *cobra.Command, noConfirm bool) {
cmd.Flags().String(cmdFlagNamePassword, "", "manually supply the password rather than using the terminal prompt")
cmd.PersistentFlags().String(cmdFlagNamePassword, "", "manually supply the password rather than using the terminal prompt")
if noConfirm {
cmd.Flags().Bool(cmdFlagNameNoConfirm, false, "skip the password confirmation prompt")
cmd.PersistentFlags().Bool(cmdFlagNameNoConfirm, false, "skip the password confirmation prompt")
}
}
func cmdFlagRandomPassword(cmd *cobra.Command) {
cmd.Flags().Bool(cmdFlagNameRandom, false, "uses a randomly generated password")
cmd.Flags().Int(cmdFlagNameRandomLength, 72, "when using a randomly generated password it configures the length")
cmd.PersistentFlags().Bool(cmdFlagNameRandom, false, "uses a randomly generated password")
cmd.PersistentFlags().Int(cmdFlagNameRandomLength, 72, "when using a randomly generated password it configures the length")
cmd.PersistentFlags().String(cmdFlagNameRandomCharSet, "alphanumeric", "sets the charset for the random password, options are 'ascii', 'alphanumeric', 'alphabetic', 'numeric', and 'numeric-hex'")
cmd.PersistentFlags().String(cmdFlagNameRandomCharacters, "", "sets the explicit characters for the random string")
}
func cmdFlagIterations(cmd *cobra.Command, value int) {

View File

@ -3,6 +3,10 @@ package commands
import (
"fmt"
"os"
"github.com/spf13/pflag"
"github.com/authelia/authelia/v4/internal/utils"
)
func recoverErr(i any) error {
@ -29,3 +33,54 @@ func configFilterExisting(configs []string) (finalConfigs []string) {
return finalConfigs
}
func flagsGetRandomCharacters(flags *pflag.FlagSet, flagNameLength, flagNameCharSet, flagNameCharacters string) (r string, err error) {
var (
n int
charset string
)
if n, err = flags.GetInt(flagNameLength); err != nil {
return "", err
}
if n < 1 {
return "", fmt.Errorf("flag --%s with value '%d' is invalid: must be at least 1", flagNameLength, n)
}
useCharSet, useCharacters := flags.Changed(flagNameCharSet), flags.Changed(flagNameCharacters)
if useCharSet && useCharacters {
return "", fmt.Errorf("flag --%s and flag --%s are mutually exclusive, only one may be used", flagNameCharSet, flagNameCharacters)
}
switch {
case useCharSet, !useCharSet && !useCharacters:
var c string
if c, err = flags.GetString(flagNameCharSet); err != nil {
return "", err
}
switch c {
case "ascii":
charset = utils.CharSetASCII
case "alphanumeric":
charset = utils.CharSetAlphaNumeric
case "alphabetic":
charset = utils.CharSetAlphabetic
case "numeric-hex":
charset = utils.CharSetNumericHex
case "numeric":
charset = utils.CharSetNumeric
default:
return "", fmt.Errorf("flag '--%s' with value '%s' is invalid, must be one of 'ascii', 'alphanumeric', 'alphabetic', 'numeric', or 'numeric-hex'", flagNameCharSet, c)
}
case useCharacters:
if charset, err = flags.GetString(flagNameCharacters); err != nil {
return "", err
}
}
return utils.RandomString(n, charset, true), nil
}

View File

@ -49,7 +49,7 @@ func init() {
SetUp: setup,
SetUpTimeout: 5 * time.Minute,
OnSetupTimeout: displayAutheliaLogs,
TestTimeout: 2 * time.Minute,
TestTimeout: 3 * time.Minute,
TearDown: teardown,
TearDownTimeout: 2 * time.Minute,
})

View File

@ -64,7 +64,7 @@ func init() {
SetUpTimeout: 5 * time.Minute,
OnSetupTimeout: displayAutheliaLogs,
OnError: displayAutheliaLogs,
TestTimeout: 3 * time.Minute,
TestTimeout: 4 * time.Minute,
TearDown: teardown,
TearDownTimeout: 2 * time.Minute,