2022-08-08 21:50:12 +00:00
package commands
import (
"fmt"
2022-10-17 10:51:59 +00:00
"os"
2022-11-25 12:44:55 +00:00
"syscall"
2022-10-20 20:41:46 +00:00
"github.com/spf13/pflag"
2022-11-25 12:44:55 +00:00
"golang.org/x/term"
2022-10-20 20:41:46 +00:00
"github.com/authelia/authelia/v4/internal/utils"
2022-08-08 21:50:12 +00:00
)
2022-10-05 05:05:23 +00:00
func recoverErr ( i any ) error {
2022-08-08 21:50:12 +00:00
switch v := i . ( type ) {
case nil :
return nil
case string :
return fmt . Errorf ( "recovered panic: %s" , v )
case error :
return fmt . Errorf ( "recovered panic: %w" , v )
default :
return fmt . Errorf ( "recovered panic with unknown type: %v" , v )
}
}
2022-10-17 10:51:59 +00:00
func configFilterExisting ( configs [ ] string ) ( finalConfigs [ ] string ) {
var err error
for _ , c := range configs {
if _ , err = os . Stat ( c ) ; err == nil || ! os . IsNotExist ( err ) {
finalConfigs = append ( finalConfigs , c )
}
}
return finalConfigs
}
2022-10-20 20:41:46 +00:00
2022-11-04 00:32:49 +00:00
//nolint:gocyclo
2022-10-20 20:41:46 +00:00
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
2022-11-04 00:32:49 +00:00
case "alphanumeric-lower" :
charset = utils . CharSetAlphabeticLower + utils . CharSetNumeric
case "alphanumeric-upper" :
charset = utils . CharSetAlphabeticUpper + utils . CharSetNumeric
2022-10-20 20:41:46 +00:00
case "alphabetic" :
charset = utils . CharSetAlphabetic
2022-11-04 00:32:49 +00:00
case "alphabetic-lower" :
charset = utils . CharSetAlphabeticLower
case "alphabetic-upper" :
charset = utils . CharSetAlphabeticUpper
2022-10-20 20:41:46 +00:00
case "numeric-hex" :
charset = utils . CharSetNumericHex
case "numeric" :
charset = utils . CharSetNumeric
2022-11-04 00:32:49 +00:00
case "rfc3986" :
charset = utils . CharSetRFC3986Unreserved
case "rfc3986-lower" :
charset = utils . CharSetAlphabeticLower + utils . CharSetNumeric + utils . CharSetSymbolicRFC3986Unreserved
case "rfc3986-upper" :
charset = utils . CharSetAlphabeticUpper + utils . CharSetNumeric + utils . CharSetSymbolicRFC3986Unreserved
2022-10-20 20:41:46 +00:00
default :
2022-11-04 00:32:49 +00:00
return "" , fmt . Errorf ( "flag '--%s' with value '%s' is invalid, must be one of 'ascii', 'alphanumeric', 'alphabetic', 'numeric', 'numeric-hex', or 'rfc3986'" , flagNameCharSet , c )
2022-10-20 20:41:46 +00:00
}
case useCharacters :
if charset , err = flags . GetString ( flagNameCharacters ) ; err != nil {
return "" , err
}
}
return utils . RandomString ( n , charset , true ) , nil
}
2022-11-25 12:44:55 +00:00
func termReadPasswordStrWithPrompt ( prompt , flag string ) ( data string , err error ) {
var d [ ] byte
if d , err = termReadPasswordWithPrompt ( prompt , flag ) ; err != nil {
return "" , err
}
return string ( d ) , nil
}
func termReadPasswordWithPrompt ( prompt , flag string ) ( data [ ] byte , err error ) {
fd := int ( syscall . Stdin ) //nolint:unconvert,nolintlint
if isTerm := term . IsTerminal ( fd ) ; ! isTerm {
switch len ( flag ) {
case 0 :
return nil , ErrStdinIsNotTerminal
case 1 :
return nil , fmt . Errorf ( "you must either use an interactive terminal or use the -%s flag" , flag )
default :
return nil , fmt . Errorf ( "you must either use an interactive terminal or use the --%s flag" , flag )
}
}
fmt . Print ( prompt )
if data , err = term . ReadPassword ( fd ) ; err != nil {
return nil , fmt . Errorf ( "failed to read the input from the terminal: %w" , err )
}
fmt . Println ( "" )
return data , nil
}