diff --git a/TODO b/TODO index d083b34..eb43fe9 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,9 @@ - whitespace (specifically, ' ') +- "quick-format" options - json-safe/escaped, mysql-safe/escaped, etc. + +- pretter printing for errors in main? + - "Human Readability"? - Hash/Salted hash generator diff --git a/pwgenerator/errs.go b/pwgenerator/errs.go index 59a404f..ed8126e 100644 --- a/pwgenerator/errs.go +++ b/pwgenerator/errs.go @@ -6,6 +6,7 @@ import ( var ( ErrBadType error = errors.New("cannot typeswitch; unsupported type") + ErrEmptyCharsets error = errors.New("empty character set/no character sets selected") ErrIncompatCharsetFilter error = errors.New("the selected minimum requirements are not possible with selected/enabled charsets") ErrSwitchedLenLimits error = errors.New("the max password length is shorter than the minimum password length") ErrTooSmall error = errors.New("password max length too short for specified required chars") diff --git a/pwgenerator/funcs_genopts.go b/pwgenerator/funcs_genopts.go index 4503b64..a192dd5 100644 --- a/pwgenerator/funcs_genopts.go +++ b/pwgenerator/funcs_genopts.go @@ -10,7 +10,7 @@ import ( func (o *GenOpts) Generate() (passwords []string, err error) { var passwds []string = make([]string, o.Count) - var charset CharSet = o.Chars() + var charset CharSet var errs *multierr.MultiError = multierr.NewMultiError(nil) if o.Count == 0 { @@ -20,6 +20,14 @@ func (o *GenOpts) Generate() (passwords []string, err error) { o.LengthMax = DefMaxLen } + if err = o.sanChk(); err != nil { + return + } + + if charset, err = o.Chars(); err != nil { + return + } + for idx, _ := range passwds { if passwds[idx], err = o.generatePassword(charset); err != nil { errs.AddError(err) @@ -39,7 +47,6 @@ func (o *GenOpts) Generate() (passwords []string, err error) { // generatePassword generates a single password from CharSet c (plus any minimum requirements). func (o *GenOpts) generatePassword(c CharSet) (password string, err error) { - var maxMin uint var trueMinLen uint var passLenGap uint var passLen int @@ -47,36 +54,7 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) { var filter *selectFilter = o.getFilter() var isDisabled bool - // Sanity checks/error conditions. - if o.explicitCharset != nil && len(o.explicitCharset) != 0 { - if o.CountUpper > 0 && !o.Alpha { - err = ErrIncompatCharsetFilter - return - } - if o.CountLower > 0 && !o.Alpha { - err = ErrIncompatCharsetFilter - return - } - if o.CountNumbers > 0 && !o.Numeric { - err = ErrIncompatCharsetFilter - return - } - if o.CountSymbols > 0 && !o.Symbols { - err = ErrIncompatCharsetFilter - return - } - if o.CountExtended > 0 && !o.ExtendedSymbols { - err = ErrIncompatCharsetFilter - return - } - } - maxMin = o.CountUpper + o.CountLower + o.CountNumbers + o.CountSymbols + o.CountExtended - if maxMin > o.LengthMax { - err = ErrTooSmall - return - } - if o.LengthMin > o.LengthMax { - err = ErrSwitchedLenLimits + if err = o.sanChk(); err != nil { return } @@ -204,10 +182,14 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) { } // Chars returns the list of evaluated characters that would be used in a GenOpts. -func (o *GenOpts) Chars() (chars CharSet) { +func (o *GenOpts) Chars() (chars CharSet, err error) { chars = make(CharSet, 0) + if err = o.sanChk(); err != nil { + return + } + if o.explicitCharset != nil && len(o.explicitCharset) != 0 { chars = o.explicitCharset return @@ -226,7 +208,10 @@ func (o *GenOpts) Chars() (chars CharSet) { chars = append(chars, extendedSymbols...) } - // TODO: Count* fields + if chars == nil || len(chars) == 0 { + err = ErrEmptyCharsets + return + } return } @@ -304,3 +289,43 @@ func (o *GenOpts) getFilter() (f *selectFilter) { return } + +func (o *GenOpts) sanChk() (err error) { + + var maxMin uint + + // Sanity checks/error conditions. + if o.explicitCharset != nil && len(o.explicitCharset) != 0 { + if o.CountUpper > 0 && !o.Alpha { + err = ErrIncompatCharsetFilter + return + } + if o.CountLower > 0 && !o.Alpha { + err = ErrIncompatCharsetFilter + return + } + if o.CountNumbers > 0 && !o.Numeric { + err = ErrIncompatCharsetFilter + return + } + if o.CountSymbols > 0 && !o.Symbols { + err = ErrIncompatCharsetFilter + return + } + if o.CountExtended > 0 && !o.ExtendedSymbols { + err = ErrIncompatCharsetFilter + return + } + } + maxMin = o.CountUpper + o.CountLower + o.CountNumbers + o.CountSymbols + o.CountExtended + if maxMin > o.LengthMax { + err = ErrTooSmall + return + } + if o.LengthMin > o.LengthMax { + err = ErrSwitchedLenLimits + return + } + + return +}