github.com/tommi2day/pwcli@v0.0.0-20240317203041-4d1177a5ab91/cmd/check.go (about) 1 // Package cmd Commands 2 package cmd 3 4 import ( 5 "errors" 6 "fmt" 7 "strconv" 8 "strings" 9 10 log "github.com/sirupsen/logrus" 11 "github.com/tommi2day/gomodules/pwlib" 12 13 "github.com/spf13/cobra" 14 ) 15 16 // checkCmd represents the check command 17 var checkCmd = &cobra.Command{ 18 Use: "check", 19 Short: "checks a password to given profile", 20 Long: `Checks a password for charset and length rules`, 21 RunE: checkPassword, 22 SilenceUsage: true, 23 Args: func(_ *cobra.Command, args []string) error { 24 if len(args) < 1 { 25 return errors.New("requires password to test as argument") 26 } 27 return nil 28 }, 29 } 30 31 func init() { 32 // hide unused flags 33 checkCmd.SetHelpFunc(func(command *cobra.Command, strings []string) { 34 // Hide flag for this command 35 _ = command.Flags().MarkHidden("app") 36 _ = command.Flags().MarkHidden("keydir") 37 _ = command.Flags().MarkHidden("datadir") 38 _ = command.Flags().MarkHidden("config") 39 _ = command.Flags().MarkHidden("method") 40 // Call parent help func 41 command.Parent().HelpFunc()(command, strings) 42 }) 43 checkCmd.Flags().StringP("special_chars", "s", defaultSpecials, "define allowed special chars") 44 checkCmd.Flags().StringP("profile", "p", defaultProfile, "set profile string as numbers of 'length Upper Lower Digits Special FirstcharFlag(0/1)'") 45 RootCmd.AddCommand(checkCmd) 46 } 47 48 func checkPassword(cmd *cobra.Command, args []string) error { 49 log.Debug("check password profile called") 50 var profile pwlib.PasswordProfile 51 var err error 52 log.Debugf("Args:%v", args) 53 password := args[0] 54 s, _ := cmd.Flags().GetString("special_chars") 55 pwlib.SetSpecialChars(s) 56 p, _ := cmd.Flags().GetString("profile") 57 profile, err = setPasswordProfile(p) 58 if err != nil { 59 return err 60 } 61 if pwlib.DoPasswordCheck(password, profile.Length, profile.Upper, profile.Lower, profile.Digits, profile.Special, profile.Firstchar, "") { 62 fmt.Println("SUCCESS") 63 log.Infof("Password '%s' matches the given profile", password) 64 return nil 65 } 66 err = fmt.Errorf("password '%s' matches NOT the given profile", password) 67 return err 68 } 69 70 func setPasswordProfile(p string) (profile pwlib.PasswordProfile, err error) { 71 if len(p) == 0 { 72 p = defaultProfile 73 log.Infof("Choose default profile %s", defaultProfile) 74 } 75 custom := strings.Split(p, " ") 76 if len(custom) < 6 { 77 err = fmt.Errorf("profile string should have 6 space separated numbers <length> <upper chars> <lower chars> <digits> <special chars> <do firstchar check(0/1)>") 78 return 79 } 80 profile.Length, err = strconv.Atoi(custom[0]) 81 if err == nil { 82 profile.Upper, err = strconv.Atoi(custom[1]) 83 } 84 if err == nil { 85 profile.Lower, err = strconv.Atoi(custom[2]) 86 } 87 if err == nil { 88 profile.Digits, err = strconv.Atoi(custom[3]) 89 } 90 if err == nil { 91 profile.Special, err = strconv.Atoi(custom[4]) 92 } 93 if err == nil { 94 f := custom[5] 95 profile.Firstchar = f == "1" 96 } 97 return 98 }