Skip to content

Commit 73fa343

Browse files
committed
Add password generation helper function
1 parent b769439 commit 73fa343

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

modules/common/util/password.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
Copyright 2020 Red Hat
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package util // nolint:revive
18+
19+
import (
20+
"crypto/rand"
21+
"encoding/base64"
22+
)
23+
24+
// GeneratePassword generates a random password of the specified length.
25+
// The password is generated using cryptographically secure random bytes
26+
// and encoded using base64 URL encoding.
27+
func GeneratePassword(length int) (string, error) {
28+
bytes := make([]byte, length)
29+
_, err := rand.Read(bytes)
30+
if err != nil {
31+
return "", err
32+
}
33+
return base64.URLEncoding.EncodeToString(bytes)[:length], nil
34+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package util // nolint:revive
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/gomega" // nolint:revive
7+
)
8+
9+
func TestGeneratePassword(t *testing.T) {
10+
11+
tests := []struct {
12+
name string
13+
length int
14+
}{
15+
{
16+
name: "Generate 16 character password",
17+
length: 16,
18+
},
19+
{
20+
name: "Generate 32 character password",
21+
length: 32,
22+
},
23+
{
24+
name: "Generate 64 character password",
25+
length: 64,
26+
},
27+
}
28+
29+
for _, tt := range tests {
30+
t.Run(tt.name, func(t *testing.T) {
31+
g := NewWithT(t)
32+
33+
password, err := GeneratePassword(tt.length)
34+
35+
g.Expect(err).ToNot(HaveOccurred())
36+
g.Expect(password).To(HaveLen(tt.length))
37+
})
38+
}
39+
}
40+
41+
func TestGeneratePasswordUniqueness(t *testing.T) {
42+
g := NewWithT(t)
43+
44+
// Generate multiple passwords and ensure they're different
45+
passwords := make(map[string]bool)
46+
for i := 0; i < 100; i++ {
47+
password, err := GeneratePassword(32)
48+
g.Expect(err).ToNot(HaveOccurred())
49+
g.Expect(passwords[password]).To(BeFalse(), "Generated duplicate password")
50+
passwords[password] = true
51+
}
52+
}

0 commit comments

Comments
 (0)