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  }