/
user.go
155 lines (127 loc) · 4.18 KB
/
user.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package internal
import (
"crypto/rand"
"encoding/base64"
"fmt"
"time"
"github.com/cloudfoundry-incubator/cf-test-helpers/generator"
"github.com/cloudfoundry-incubator/cf-test-helpers/internal"
"github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"
. "github.com/onsi/gomega/gexec"
)
type TestUser struct {
username string
password string
cmdStarter internal.Starter
timeout time.Duration
shouldKeepUser bool
}
type UserConfig interface {
GetUseExistingUser() bool
GetExistingUser() string
GetExistingUserPassword() string
GetShouldKeepUser() bool
GetConfigurableTestPassword() string
}
type userConfig interface {
UserConfig
GetScaledTimeout(time.Duration) time.Duration
GetNamePrefix() string
}
type AdminUserConfig interface {
GetAdminUser() string
GetAdminPassword() string
}
type ClientConfig interface {
GetExistingClient() string
GetExistingClientSecret() string
}
type AdminClientConfig interface {
GetAdminClient() string
GetAdminClientSecret() string
}
func NewTestUser(config userConfig, cmdStarter internal.Starter) *TestUser {
var regUser, regUserPass string
if config.GetUseExistingUser() {
regUser = config.GetExistingUser()
regUserPass = config.GetExistingUserPassword()
} else {
regUser = generator.PrefixedRandomName(config.GetNamePrefix(), "USER")
regUserPass = generatePassword()
}
if config.GetConfigurableTestPassword() != "" {
regUserPass = config.GetConfigurableTestPassword()
}
return &TestUser{
username: regUser,
password: regUserPass,
cmdStarter: cmdStarter,
timeout: config.GetScaledTimeout(1 * time.Minute),
shouldKeepUser: config.GetShouldKeepUser(),
}
}
func NewAdminUser(config AdminUserConfig, cmdStarter internal.Starter) *TestUser {
return &TestUser{
username: config.GetAdminUser(),
password: config.GetAdminPassword(),
cmdStarter: cmdStarter,
}
}
func NewAdminClient(config AdminClientConfig, cmdStarter internal.Starter) *TestUser {
return &TestUser{
username: config.GetAdminClient(),
password: config.GetAdminClientSecret(),
cmdStarter: cmdStarter,
}
}
func NewTestClient(config ClientConfig, cmdStarter internal.Starter) *TestUser {
return &TestUser{
username: config.GetExistingClient(),
password: config.GetExistingClientSecret(),
cmdStarter: cmdStarter,
}
}
func (user *TestUser) Create() {
redactor := internal.NewRedactor(user.password)
redactingReporter := internal.NewRedactingReporter(ginkgo.GinkgoWriter, redactor)
session := internal.CfWithCustomReporter(user.cmdStarter, redactingReporter, "create-user", user.username, user.password)
EventuallyWithOffset(1, session, user.timeout).Should(Exit())
if session.ExitCode() != 0 {
ExpectWithOffset(1, combineOutputAndRedact(session, redactor)).Should(Say("scim_resource_already_exists"))
}
}
func (user *TestUser) Destroy() {
session := internal.Cf(user.cmdStarter, "delete-user", "-f", user.username)
EventuallyWithOffset(1, session, user.timeout).Should(Exit(0))
}
func (user *TestUser) Username() string {
return user.username
}
func (user *TestUser) Password() string {
return user.password
}
func (user *TestUser) ShouldRemain() bool {
return user.shouldKeepUser
}
func combineOutputAndRedact(session *Session, redactor internal.Redactor) *Buffer {
stdout := redactor.Redact(string(session.Out.Contents()))
stderr := redactor.Redact(string(session.Err.Contents()))
return BufferWithBytes(append([]byte(stdout), []byte(stderr)...))
}
// The key thing that makes a password secure is the _entropy_ that comes from a
// generator of true random numbers. But many password rules require a mixure
// of cases, numbers and special characters. Here we meet these rules by starting
// the password with the required upper/lower case, number and special. Then we make
// it secure by adding truly random characters.
func generatePassword() string {
const randomBytesLength = 16
encoding := base64.RawURLEncoding
randomBytes := make([]byte, encoding.DecodedLen(randomBytesLength))
_, err := rand.Read(randomBytes)
if err != nil {
panic(fmt.Errorf("Could not generate random password: %s", err.Error()))
}
return "A0a!" + encoding.EncodeToString(randomBytes)
}