define default access privileges for default users too (#1512)

* define default access privileges for default users too
* extend docs on defaultUsers
This commit is contained in:
Felix Kunde 2021-06-22 16:45:28 +02:00 committed by GitHub
parent 53fb540c35
commit 54e506c00b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 5 deletions

View File

@ -522,7 +522,8 @@ The roles described in the previous paragraph can be granted to LOGIN roles from
the `users` section in the manifest. Optionally, the Postgres Operator can also
create default LOGIN roles for the database an each schema individually. These
roles will get the `_user` suffix and they inherit all rights from their NOLOGIN
counterparts.
counterparts. Therefore, you cannot have `defaultRoles` set to `false` and enable
`defaultUsers` at the same time.
| Role name | Member of | Admin |
| ------------------- | -------------- | ------------- |
@ -545,6 +546,10 @@ spec:
defaultUsers: true
```
Default access privileges are also defined for LOGIN roles on database and
schema creation. This means they are currently not set when `defaultUsers`
(or `defaultRoles` for schemas) are enabled at a later point in time.
### Schema `search_path` for default roles
The schema [`search_path`](https://www.postgresql.org/docs/13/ddl-schemas.html#DDL-SCHEMAS-PATH)

View File

@ -351,10 +351,30 @@ func (c *Cluster) execCreateDatabaseSchema(databaseName, schemaName, dbOwner, sc
}
// set default privileges for schema
// the schemaOwner defines them for global database roles
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner, databaseName)
// if schemaOwner and dbOwner differ we know that <databaseName>_<schemaName> default roles were created
if schemaOwner != dbOwner {
c.execAlterSchemaDefaultPrivileges(schemaName, dbOwner, databaseName+"_"+schemaName)
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner, databaseName+"_"+schemaName)
defaultUsers := c.Spec.PreparedDatabases[databaseName].PreparedSchemas[schemaName].DefaultUsers
// define schema privileges of <databaseName>_<schemaName>_owner_user for global roles, too
if defaultUsers {
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner+constants.UserRoleNameSuffix, databaseName)
}
// collect all possible owner roles and define default schema privileges
// for <databaseName>_<schemaName>_reader/writer roles
owners := c.getOwnerRoles(databaseName, c.Spec.PreparedDatabases[databaseName].DefaultUsers)
owners = append(owners, c.getOwnerRoles(databaseName+"_"+schemaName, defaultUsers)...)
for _, owner := range owners {
c.execAlterSchemaDefaultPrivileges(schemaName, owner, databaseName+"_"+schemaName)
}
} else {
// define schema privileges of <databaseName>_owner_user for global roles, too
if c.Spec.PreparedDatabases[databaseName].DefaultUsers {
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner+constants.UserRoleNameSuffix, databaseName)
}
}
return nil
@ -418,6 +438,15 @@ func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin
return result
}
func (c *Cluster) getOwnerRoles(dbObjPath string, withUser bool) (owners []string) {
owners = append(owners, dbObjPath+constants.OwnerRoleNameSuffix)
if withUser {
owners = append(owners, dbObjPath+constants.OwnerRoleNameSuffix+constants.UserRoleNameSuffix)
}
return owners
}
// getExtension returns the list of current database extensions
// The caller is responsible for opening and closing the database connection
func (c *Cluster) getExtensions() (dbExtensions map[string]string, err error) {

View File

@ -740,8 +740,11 @@ func (c *Cluster) syncDatabases() error {
if err := c.initDbConnWithName(preparedDatabase); err != nil {
return fmt.Errorf("could not init database connection to %s", preparedDatabase)
}
if err = c.execAlterGlobalDefaultPrivileges(preparedDatabase+constants.OwnerRoleNameSuffix, preparedDatabase); err != nil {
return err
for _, owner := range c.getOwnerRoles(preparedDatabase, c.Spec.PreparedDatabases[preparedDatabase].DefaultUsers) {
if err = c.execAlterGlobalDefaultPrivileges(owner, preparedDatabase); err != nil {
return err
}
}
}