-
Notifications
You must be signed in to change notification settings - Fork 20
/
password.go
133 lines (115 loc) · 3.27 KB
/
password.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package generator
import (
"bytes"
"context"
"crypto/rand"
"fmt"
"math/big"
b64 "encoding/base64"
corev1 "k8s.io/api/core/v1"
"github.com/ForgeRock/secret-agent/api/v1alpha1"
"github.com/ForgeRock/secret-agent/pkg/secretsmanager"
"github.com/pkg/errors"
)
// Password randomly generated of specified length
type Password struct {
Name string
Length int
Value []byte
BinaryMode bool
}
// References return names of secrets that should be looked up
func (pwd *Password) References() ([]string, []string) {
return []string{}, []string{}
}
// LoadReferenceData loads references from data
func (pwd *Password) LoadReferenceData(data map[string][]byte) error {
return nil
}
// LoadSecretFromManager populates Password data from secret manager
func (pwd *Password) LoadSecretFromManager(context context.Context, sm secretsmanager.SecretManager, namespace, secretName string) error {
var err error
pwdFmt := fmt.Sprintf("%s_%s_%s", namespace, secretName, pwd.Name)
pwd.Value, err = sm.LoadSecret(context, pwdFmt)
if err != nil {
return err
}
return nil
}
// EnsureSecretManager populates secrets manager from Password data
func (pwd *Password) EnsureSecretManager(context context.Context, sm secretsmanager.SecretManager, namespace, secretName string) error {
var err error
pwdFmt := fmt.Sprintf("%s_%s_%s", namespace, secretName, pwd.Name)
err = sm.EnsureSecret(context, pwdFmt, pwd.Value)
if err != nil {
return err
}
return nil
}
// InSecret return true if the key is one found in the secret
func (pwd *Password) InSecret(secObject *corev1.Secret) bool {
if secObject.Data == nil || secObject.Data[pwd.Name] == nil || pwd.IsEmpty() {
return false
}
if bytes.Compare(pwd.Value, secObject.Data[pwd.Name]) == 0 {
return true
}
return false
}
// Generate generates data
func (pwd *Password) Generate() error {
var max *big.Int
alphanumericBytes := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
bytes := make([]byte, pwd.Length)
for i := range bytes {
if pwd.BinaryMode {
max = big.NewInt(int64(255))
} else {
max = big.NewInt(int64(len(alphanumericBytes)))
}
randInt, err := rand.Int(rand.Reader, max)
if err != nil {
return errors.WithStack(err)
}
if pwd.BinaryMode {
bytes[i] = uint8(randInt.Int64())
} else {
bytes[i] = alphanumericBytes[int(randInt.Int64())]
}
}
if pwd.BinaryMode {
pwd.Value = []byte(b64.StdEncoding.EncodeToString(bytes))
return nil
}
pwd.Value = bytes
return nil
}
// IsEmpty boolean determines if the struct is empty
func (pwd *Password) IsEmpty() bool {
if len(pwd.Value) == 0 {
return true
}
return false
}
// LoadFromData loads data from kubernetes secret
func (pwd *Password) LoadFromData(secData map[string][]byte) {
pwd.Value = secData[pwd.Name]
return
}
// ToKubernetes "marshals" object to kubernetes object
func (pwd *Password) ToKubernetes(secret *corev1.Secret) {
// data could be nil
if secret.Data == nil {
secret.Data = make(map[string][]byte)
}
secret.Data[pwd.Name] = pwd.Value
}
// NewPassword creates new Password type for reconciliation
func NewPassword(keyConfig *v1alpha1.KeyConfig) *Password {
password := &Password{
Name: keyConfig.Name,
Length: *keyConfig.Spec.Length,
BinaryMode: keyConfig.Spec.UseBinaryCharacters,
}
return password
}