cover more default privilege scenarios and always define admin role

This commit is contained in:
Felix Kunde 2019-09-30 18:01:56 +02:00
parent 6aa734cffd
commit 31fd352fbd
3 changed files with 67 additions and 34 deletions

View File

@ -816,22 +816,24 @@ func (c *Cluster) initDefaultRoles(admin, prefix string) error {
for defaultRole, inherits := range defaultRoles {
roleName := prefix + defaultRole
flags := []string{constants.RoleFlagNoLogin}
memberOf := make([]string, 0)
adminRole := ""
if defaultRole[len(defaultRole)-5:] == "_user" {
flags = []string{constants.RoleFlagLogin}
} else {
if defaultRole == "_owner" {
adminRole = admin
} else {
adminRole = prefix + "_owner"
}
}
memberOf := make([]string, 0)
if inherits != "" {
memberOf = append(memberOf, prefix+inherits)
}
adminRole := ""
if strings.Contains(defaultRole, "_owner") {
adminRole = admin
} else {
adminRole = prefix + "_owner"
}
newRole := spec.PgUser{
Origin: spec.RoleOriginBootstrap,
Name: roleName,

View File

@ -32,7 +32,16 @@ const (
createDatabaseSQL = `CREATE DATABASE "%s" OWNER "%s";`
createDatabaseSchemaSQL = `SET ROLE TO "%s"; CREATE SCHEMA "%s" AUTHORIZATION "%s"`
alterDatabaseOwnerSQL = `ALTER DATABASE "%s" OWNER TO "%s";`
defaultPrivilegesSQL = `SET ROLE TO "%s";
globalDefaultPrivilegesSQL = `SET ROLE TO "%s";
ALTER DEFAULT PRIVILEGES GRANT USAGE ON SCHEMAS TO "%s","%s";
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO "%s";
ALTER DEFAULT PRIVILEGES GRANT SELECT ON SEQUENCES TO "%s";
ALTER DEFAULT PRIVILEGES GRANT INSERT, UPDATE, DELETE ON TABLES TO "%s";
ALTER DEFAULT PRIVILEGES GRANT USAGE, UPDATE ON SEQUENCES TO "%s";
ALTER DEFAULT PRIVILEGES GRANT EXECUTE ON FUNCTIONS TO "%s","%s";
ALTER DEFAULT PRIVILEGES GRANT USAGE ON TYPES TO "%s","%s";`
schemaDefaultPrivilegesSQL = `SET ROLE TO "%s";
GRANT USAGE ON SCHEMA "%s" TO "%s","%s";
ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT SELECT ON TABLES TO "%s";
ALTER DEFAULT PRIVILEGES IN SCHEMA "%s" GRANT SELECT ON SEQUENCES TO "%s";
@ -286,23 +295,11 @@ func (c *Cluster) execCreateDatabaseSchema(datname, schemaName, dbOwner, schemaO
if _, err := c.pgDb.Exec(fmt.Sprintf(statement, dbOwner, schemaName, schemaOwner)); err != nil {
return fmt.Errorf("could not execute %s: %v", operation, err)
}
c.execAlterDefaultPrivileges(schemaName, schemaOwner, datname)
c.execAlterDefaultPrivileges(schemaName, schemaOwner, datname+"_"+schemaName)
return nil
}
func (c *Cluster) execAlterDefaultPrivileges(schemaName, owner, rolePrefix string) error {
if _, err := c.pgDb.Exec(fmt.Sprintf(defaultPrivilegesSQL, owner,
schemaName, rolePrefix+"_writer", rolePrefix+"_reader", // schema
schemaName, rolePrefix+"_reader", // tables
schemaName, rolePrefix+"_reader", // sequences
schemaName, rolePrefix+"_writer", // tables
schemaName, rolePrefix+"_writer", // sequences
schemaName, rolePrefix+"_reader", rolePrefix+"_writer", // types
schemaName, rolePrefix+"_reader", rolePrefix+"_writer")); err != nil { // functions
return fmt.Errorf("could not alter default privileges for database schema: %v", err)
}
// set default privileges for schema
c.execAlterSchemaDefaultPrivileges(schemaName, dbOwner, datname+"_"+schemaName)
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner, datname)
c.execAlterSchemaDefaultPrivileges(schemaName, schemaOwner, datname+"_"+schemaName)
return nil
}
@ -315,6 +312,36 @@ func (c *Cluster) databaseSchemaNameValid(schemaName string) bool {
return true
}
func (c *Cluster) execAlterSchemaDefaultPrivileges(schemaName, owner, rolePrefix string) error {
if _, err := c.pgDb.Exec(fmt.Sprintf(schemaDefaultPrivilegesSQL, owner,
schemaName, rolePrefix+"_writer", rolePrefix+"_reader", // schema
schemaName, rolePrefix+"_reader", // tables
schemaName, rolePrefix+"_reader", // sequences
schemaName, rolePrefix+"_writer", // tables
schemaName, rolePrefix+"_writer", // sequences
schemaName, rolePrefix+"_reader", rolePrefix+"_writer", // types
schemaName, rolePrefix+"_reader", rolePrefix+"_writer")); err != nil { // functions
return fmt.Errorf("could not alter default privileges for database schema %s: %v", schemaName, err)
}
return nil
}
func (c *Cluster) execAlterGlobalDefaultPrivileges(owner, rolePrefix string) error {
if _, err := c.pgDb.Exec(fmt.Sprintf(globalDefaultPrivilegesSQL, owner,
rolePrefix+"_writer", rolePrefix+"_reader", // schemas
rolePrefix+"_reader", // tables
rolePrefix+"_reader", // sequences
rolePrefix+"_writer", // tables
rolePrefix+"_writer", // sequences
rolePrefix+"_reader", rolePrefix+"_writer", // types
rolePrefix+"_reader", rolePrefix+"_writer")); err != nil { // functions
return fmt.Errorf("could not alter default privileges for database %s: %v", rolePrefix, err)
}
return nil
}
func makeUserFlags(rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin bool) (result []string) {
if rolsuper {
result = append(result, constants.RoleFlagSuperuser)

View File

@ -553,6 +553,19 @@ func (c *Cluster) syncDatabases() error {
func (c *Cluster) syncPreparedDatabases() error {
c.setProcessName("syncing prepared databases")
for preparedDbName, preparedDB := range c.Spec.PreparedDatabases {
if err := c.initDbConn(preparedDbName); err != nil {
return fmt.Errorf("could not init connection to database %s: %v", preparedDbName, err)
}
defer func() {
if err := c.closeDbConn(); err != nil {
c.logger.Errorf("could not close database connection: %v", err)
}
}()
// first, set default privileges for prepared database
c.execAlterGlobalDefaultPrivileges(preparedDbName+"_owner", preparedDbName)
// now, prepare defined schemas
preparedSchemas := preparedDB.PreparedSchemas
if len(preparedDB.PreparedSchemas) == 0 {
preparedSchemas = map[string]acidv1.PreparedSchema{"data": {DefaultRoles: util.True()}}
@ -568,15 +581,6 @@ func (c *Cluster) syncPreparedDatabases() error {
func (c *Cluster) syncPreparedSchemas(datname string, preparedSchemas map[string]acidv1.PreparedSchema) error {
c.setProcessName("syncing prepared schemas")
if err := c.initDbConn(datname); err != nil {
return fmt.Errorf("could not init connection to database %s: %v", datname, err)
}
defer func() {
if err := c.closeDbConn(); err != nil {
c.logger.Errorf("could not close database connection: %v", err)
}
}()
currentSchemas, err := c.getSchemas()
if err != nil {
return fmt.Errorf("could not get current schemas: %v", err)