diff --git a/pkg/cluster/cluster.go b/pkg/cluster/cluster.go index b1445ce20..dd54f2dc3 100644 --- a/pkg/cluster/cluster.go +++ b/pkg/cluster/cluster.go @@ -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, diff --git a/pkg/cluster/database.go b/pkg/cluster/database.go index abd613869..907140284 100644 --- a/pkg/cluster/database.go +++ b/pkg/cluster/database.go @@ -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) diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index e3ccd1050..b08d5f5d3 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -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)