mirror of
https://github.com/hashicorp/vault.git
synced 2025-11-17 08:41:12 +01:00
* Add random string generator with rules engine This adds a random string generation library that validates random strings against a set of rules. The library is designed for use as generating passwords, but can be used to generate any random strings.
89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
package random
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/mitchellh/mapstructure"
|
|
)
|
|
|
|
// serializableRules is a slice of rules that can be marshalled to JSON in an HCL format
|
|
type serializableRules []Rule
|
|
|
|
// MarshalJSON in an HCL-friendly way
|
|
func (r serializableRules) MarshalJSON() (b []byte, err error) {
|
|
// Example:
|
|
// [
|
|
// {
|
|
// "testrule": [
|
|
// {
|
|
// "string": "teststring",
|
|
// "int": 123
|
|
// }
|
|
// ]
|
|
// },
|
|
// {
|
|
// "charset": [
|
|
// {
|
|
// "charset": "abcde",
|
|
// "min-chars": 2
|
|
// }
|
|
// ]
|
|
// }
|
|
// ]
|
|
data := []map[string][]map[string]interface{}{} // Totally not confusing at all
|
|
for _, rule := range r {
|
|
ruleData := map[string]interface{}{}
|
|
err = mapstructure.Decode(rule, &ruleData)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("unable to decode rule: %w", err)
|
|
}
|
|
|
|
ruleMap := map[string][]map[string]interface{}{
|
|
rule.Type(): []map[string]interface{}{
|
|
ruleData,
|
|
},
|
|
}
|
|
data = append(data, ruleMap)
|
|
}
|
|
|
|
b, err = json.Marshal(data)
|
|
return b, err
|
|
}
|
|
|
|
func (r *serializableRules) UnmarshalJSON(data []byte) (err error) {
|
|
mapData := []map[string]interface{}{}
|
|
err = json.Unmarshal(data, &mapData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rules, err := parseRules(defaultRegistry, mapData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*r = rules
|
|
return nil
|
|
}
|
|
|
|
type runes []rune
|
|
|
|
func (r runes) Len() int { return len(r) }
|
|
func (r runes) Less(i, j int) bool { return r[i] < r[j] }
|
|
func (r runes) Swap(i, j int) { r[i], r[j] = r[j], r[i] }
|
|
|
|
// MarshalJSON converts the runes to a string for smaller JSON and easier readability
|
|
func (r runes) MarshalJSON() (b []byte, err error) {
|
|
return json.Marshal(string(r))
|
|
}
|
|
|
|
// UnmarshalJSON converts a string to []rune
|
|
func (r *runes) UnmarshalJSON(data []byte) (err error) {
|
|
var str string
|
|
err = json.Unmarshal(data, &str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
*r = []rune(str)
|
|
return nil
|
|
}
|