FIXED:
* XML, YAML marshaling/unmarshaling of pwgenerator.CharSet.
This commit is contained in:
brent saner
2024-07-17 04:03:31 -04:00
parent c6050a2dc4
commit cbecd9caec
10 changed files with 465 additions and 178 deletions

View File

@@ -1,13 +1,48 @@
package pwgenerator
import (
"encoding/xml"
"strings"
"time"
`encoding/xml`
`strings`
`time`
"r00t2.io/goutils/multierr"
)
// Chars returns the list of evaluated characters that would be used in a GenOpts.
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
}
if o.Alpha {
chars = append(chars, alpha...)
}
if o.Numeric {
chars = append(chars, numeric...)
}
if o.Symbols {
chars = append(chars, symbols...)
}
if o.ExtendedSymbols {
chars = append(chars, extendedSymbols...)
}
if chars == nil || len(chars) == 0 {
err = ErrEmptyCharsets
return
}
return
}
// Generate generates a list of passwords for a GenOpts.
func (o *GenOpts) Generate() (passwords []string, err error) {
@@ -46,49 +81,6 @@ func (o *GenOpts) Generate() (passwords []string, err error) {
return
}
// MustGenerate is like Generate, but will panic on error instead of returning.
func (o *GenOpts) MustGenerate() (passwords []string) {
var err error
if passwords, err = o.Generate(); err != nil {
panic(err)
}
return
}
/*
GenOnce generates a *single* password from a GenOpts.
This method is particularly useful/convenient if GenOpts.Count is 1
and you don't want to have to assign to a slice and then get the first index.
*/
func (o GenOpts) GenerateOnce() (password string, err error) {
var passwds []string
o.Count = 1
if passwds, err = o.Generate(); err != nil {
return
}
password = passwds[0]
return
}
// MustGenerateOnce is like GenerateOnce, but will panic on error instead of returning.
func (o *GenOpts) MustGenerateOnce() (password string) {
var err error
if password, err = o.GenerateOnce(); err != nil {
panic(err)
}
return
}
/*
GenerateCollection returns a PwCollection instead of a slice of password text.
@@ -99,8 +91,8 @@ func (o *GenOpts) MustGenerateOnce() (password string) {
func (o *GenOpts) GenerateCollection(hashAlgos []pwHash) (collection *PwCollection, err error) {
var charset CharSet
var errs *multierr.MultiError = multierr.NewMultiError(nil)
var passwd string
var errs *multierr.MultiError = multierr.NewMultiError(nil)
collection = &PwCollection{
XMLName: xml.Name{
@@ -144,6 +136,109 @@ func (o *GenOpts) GenerateCollection(hashAlgos []pwHash) (collection *PwCollecti
return
}
/*
GenOnce generates a *single* password from a GenOpts.
This method is particularly useful/convenient if GenOpts.Count is 1
and you don't want to have to assign to a slice and then get the first index.
*/
func (o *GenOpts) GenerateOnce() (password string, err error) {
var passwds []string
o.Count = 1
if passwds, err = o.Generate(); err != nil {
return
}
password = passwds[0]
return
}
// MustGenerate is like Generate, but will panic on error instead of returning.
func (o *GenOpts) MustGenerate() (passwords []string) {
var err error
if passwords, err = o.Generate(); err != nil {
panic(err)
}
return
}
// MustGenerateOnce is like GenerateOnce, but will panic on error instead of returning.
func (o *GenOpts) MustGenerateOnce() (password string) {
var err error
if password, err = o.GenerateOnce(); err != nil {
panic(err)
}
return
}
/*
SetExplicitCharset sets a GenOpts' charset to an explicit selection. It is deduplicated before being used unless inclDupes is true.
(Duplicate runes can be used to increase the likelihood of specific characters.)
Note that if an explicit charset is defined, the following opts will have NO effect:
Alpha
Numeric
Symbols
ExtendedSymbols
CountUpper
CountLower
CountSymbols
CountExtended
DisabledChars
To have these fields be used again, call GenOpts.UnsetExplicitCharset.
chars can be a CharSet, []rune, []byte, []string, or string
*/
func (o *GenOpts) SetExplicitCharset(chars interface{}, inclDupes bool) (err error) {
var charset CharSet
switch t := chars.(type) {
case []rune:
charset = CharSet(string(t))
case []byte:
charset = CharSet(string(t))
case []string:
s := strings.Join(t, "")
charset = CharSet(s)
case string:
charset = CharSet(t)
default:
err = ErrBadType
return
}
if !inclDupes {
sortDedupe(&charset)
}
o.explicitCharset = charset
return
}
/*
UnsetExplicitCharset removes the explicit charset used for generation and instead uses the fields specified in the actual GenOpts.
See GenOpts.SetExplicitCharset for more details.
*/
func (o *GenOpts) UnsetExplicitCharset() {
o.explicitCharset = nil
return
}
// generatePassword generates a single password from CharSet c (plus any minimum requirements).
func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
@@ -281,101 +376,6 @@ func (o *GenOpts) generatePassword(c CharSet) (password string, err error) {
return
}
// Chars returns the list of evaluated characters that would be used in a GenOpts.
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
}
if o.Alpha {
chars = append(chars, alpha...)
}
if o.Numeric {
chars = append(chars, numeric...)
}
if o.Symbols {
chars = append(chars, symbols...)
}
if o.ExtendedSymbols {
chars = append(chars, extendedSymbols...)
}
if chars == nil || len(chars) == 0 {
err = ErrEmptyCharsets
return
}
return
}
/*
SetExplicitCharset sets a GenOpts' charset to an explicit selection. It is deduplicated before being used unless inclDupes is true.
(Duplicate runes can be used to increase the likelihood of specific characters.)
Note that if an explicit charset is defined, the following opts will have NO effect:
Alpha
Numeric
Symbols
ExtendedSymbols
CountUpper
CountLower
CountSymbols
CountExtended
DisabledChars
To have these fields be used again, call GenOpts.UnsetExplicitCharset.
chars can be a CharSet, []rune, []byte, []string, or string
*/
func (o *GenOpts) SetExplicitCharset(chars interface{}, inclDupes bool) (err error) {
var charset CharSet
switch t := chars.(type) {
case []rune:
charset = CharSet(string(t))
case []byte:
charset = CharSet(string(t))
case []string:
s := strings.Join(t, "")
charset = CharSet(s)
case string:
charset = CharSet(t)
default:
err = ErrBadType
return
}
if !inclDupes {
sortDedupe(&charset)
}
o.explicitCharset = charset
return
}
/*
UnsetExplicitCharset removes the explicit charset used for generation and instead uses the fields specified in the actual GenOpts.
See GenOpts.SetExplicitCharset for more details.
*/
func (o *GenOpts) UnsetExplicitCharset() {
o.explicitCharset = nil
return
}
// getFilter gets a filter counter.
func (o *GenOpts) getFilter() (f *selectFilter) {