- update regular expression for usernames
- add test to allow check for valid usernames
- create pg roles with namespace (if any) appended in rolename
This commit is contained in:
Rafia Sabih 2021-05-27 13:25:54 +02:00
parent f57204721d
commit fd5edea670
4 changed files with 26 additions and 23 deletions

View File

@ -41,7 +41,7 @@ import (
var (
alphaNumericRegexp = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9]*$")
databaseNameRegexp = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
userRegexp = regexp.MustCompile(`^[a-z0-9]([-_a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-_a-z0-9]*[a-z0-9])?)*$`)
userRegexp = regexp.MustCompile(`^[a-z0-9,]+\.?[-_a-z0-9,]+[a-z0-9,]$`)
patroniObjectSuffixes = []string{"config", "failover", "sync"}
)
@ -1093,16 +1093,12 @@ func (c *Cluster) initRobotUsers() error {
if c.shouldAvoidProtectedOrSystemRole(username, "manifest robot role") {
continue
}
name := username
namespace := c.Namespace
//more than one dot in the username is reported invalid by regexp
if strings.Contains(username, ".") {
splits := strings.Split(username, ".")
name = splits[1]
if len(splits[0]) > 0 {
namespace = splits[0]
}
username = name
namespace = splits[0]
}
flags, err := normalizeUserFlags(userFlags)
@ -1115,18 +1111,14 @@ func (c *Cluster) initRobotUsers() error {
}
newRole := spec.PgUser{
Origin: spec.RoleOriginManifest,
Name: name,
Name: username,
Namespace: namespace,
Password: util.RandomPassword(constants.PasswordLength),
Flags: flags,
AdminRole: adminRole,
}
if currentRole, present := c.pgUsers[username]; present {
if namespace == c.pgUsers[username].Namespace {
c.pgUsers[username] = c.resolveNameConflict(&currentRole, &newRole)
} else {
c.pgUsers[username+"."+namespace] = newRole
}
c.pgUsers[username] = c.resolveNameConflict(&currentRole, &newRole)
} else {
c.pgUsers[username] = newRole
}

View File

@ -902,7 +902,7 @@ func TestCrossNamespacedSecrets(t *testing.T) {
userNamespaceMap := map[string]string{
cluster.Namespace: "db_user",
"appspace": "db_user",
"appspace": "appspace.db_user",
}
err := cluster.initRobotUsers()
@ -912,7 +912,19 @@ func TestCrossNamespacedSecrets(t *testing.T) {
for _, u := range cluster.pgUsers {
if u.Name != userNamespaceMap[u.Namespace] {
t.Errorf("%s: Could not create namespaced user in its correct namespaces", testName)
t.Errorf("%s: Could not create namespaced user in its correct namespaces for user %s in namespace %s", testName, u.Name, u.Namespace)
}
}
}
func TestValidUsernames(t *testing.T) {
testName := "test username validity"
invalidUsernames := []string{"_", ".", ".user", "appspace.", "appspace.user.extra", "user_", "_user", "-user", "user-"}
for _, username := range invalidUsernames {
if isValidUsername(username) {
t.Errorf("%s Invalid username is allowed: %s", testName, username)
}
}
}

View File

@ -1581,13 +1581,10 @@ func (c *Cluster) generateSingleUserSecret(namespace string, pgUser spec.PgUser)
if username == constants.ConnectionPoolerUserName {
lbls = c.connectionPoolerLabels("", false).MatchLabels
}
secret_name := username
if pgUser.Namespace != c.Namespace {
secret_name = username + "." + pgUser.Namespace
}
secret := v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: c.credentialSecretName(secret_name),
Name: c.credentialSecretName(username),
Namespace: pgUser.Namespace,
Labels: lbls,
Annotations: c.annotationsSet(nil),

View File

@ -552,11 +552,13 @@ func (c *Cluster) syncRoles() (err error) {
}()
for _, u := range c.pgUsers {
pg_role := u.Name
if u.Namespace != c.Namespace {
userNames = append(userNames, u.Name+"."+"u.Namespace")
} else {
userNames = append(userNames, u.Name)
// to avoid the conflict of having multiple users of same name
// but each in different namespace.
pg_role = fmt.Sprintf("%s.%s", u.Name, u.Namespace)
}
userNames = append(userNames, pg_role)
}
if needMasterConnectionPooler(&c.Spec) || needReplicaConnectionPooler(&c.Spec) {