Skip to content

Commit

Permalink
Merge pull request #15 from Riskified/DEV-89026-system-privs
Browse files Browse the repository at this point in the history
Dev 89026 system privs
  • Loading branch information
TomaBere authored Sep 9, 2024
2 parents 989f0f5 + 1686e84 commit f3a2427
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
3 changes: 3 additions & 0 deletions postgresql/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const (
fetureRoleEncryptedPass
featureAdvisoryXactLock
featureTransactionIsolation
featureSysPrivileges
)

var (
Expand Down Expand Up @@ -154,6 +155,7 @@ var (
featureAdvisoryXactLock: semver.MustParseRange(">=9.1.0"),
//Postgresql do not support transaction isolation in Role level
featureTransactionIsolation: semver.MustParseRange("<1.0.0"),
featureSysPrivileges: semver.MustParseRange("<1.0.0"),
}

// Mapping of feature flags to versions
Expand Down Expand Up @@ -266,6 +268,7 @@ var (
featureAdvisoryXactLock: semver.MustParseRange("<1.0.0"),

featureTransactionIsolation: semver.MustParseRange(">=23.2.0"),
featureSysPrivileges: semver.MustParseRange(">=22.2.0"),
}
)

Expand Down
1 change: 1 addition & 0 deletions postgresql/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ func sliceContainsStr(haystack []string, needle string) bool {
// allowedPrivileges is the list of privileges allowed per object types in Postgres.
// see: https://www.postgresql.org/docs/current/sql-grant.html
var allowedPrivileges = map[string][]string{
"system": {"ALL", "BACKUP", "CANCELQUERY", "CONTROLJOB", "CREATEDB", "CREATELOGIN", "CREATEROLE", "EXTERNALCONNECTION", "EXTERNALIOIMPLICITACCESS", "MODIFYCLUSTERSETTING", "MODIFYSQLCLUSTERSETTING", "NOSQLLOGIN", "REPLICATION", "RESTORE", "VIEWACTIVITY", "VIEWACTIVITYREDACTED", "VIEWCLUSTERMETADATA", "VIEWCLUSTERSETTING", "VIEWDEBUG", "VIEWJOB", "VIEWSYSTEMTABLE"},
"database": {"ALL", "CREATE", "CONNECT", "TEMPORARY", "BACKUP", "RESTORE", "ZONECONFIG"},
"table": {"ALL", "SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER", "DROP", "CHANGEFEED", "RESTORE", "ZONECONFIG"},
"sequence": {"ALL", "USAGE", "SELECT", "UPDATE", "CREATE", "DELETE", "INSERT", "ZONECONFIG"},
Expand Down
36 changes: 33 additions & 3 deletions postgresql/resource_postgresql_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
)

var allowedObjectTypes = []string{
"system",
"database",
"function",
"procedure",
Expand Down Expand Up @@ -255,6 +256,16 @@ func resourcePostgreSQLGrantDelete(db *DBConnection, d *schema.ResourceData) err
return nil
}

func readSystemRolePriviges(txn *sql.Tx, role string) error {
var query string
var privileges pq.ByteaArray
query = fmt.Sprintf(`with a as (show system grants for %s) select array_agg(privilege_type) from a`, role)
if err := txn.QueryRow(query).Scan(&privileges); err != nil {
return fmt.Errorf("could not read system privileges: %w", err)
}
return nil
}

func readDatabaseRolePriviges(txn *sql.Tx, db *DBConnection, d *schema.ResourceData, roleOID uint32, role string) error {
dbName := d.Get("database").(string)
var query string
Expand Down Expand Up @@ -443,6 +454,8 @@ func readRolePrivileges(txn *sql.Tx, db *DBConnection, d *schema.ResourceData) e
var rows *sql.Rows

switch objectType {
case "system":
return readSystemRolePriviges(txn, role)
case "database":
return readDatabaseRolePriviges(txn, db, d, roleOID, role)

Expand Down Expand Up @@ -547,6 +560,12 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
var query string

switch strings.ToUpper(d.Get("object_type").(string)) {
case "SYSTEM":
query = fmt.Sprintf(
"GRANT SYSTEM %s TO %s",
strings.Join(privileges, ","),
pq.QuoteIdentifier(d.Get("role").(string)),
)
case "DATABASE":
query = fmt.Sprintf(
"GRANT %s ON DATABASE %s TO %s",
Expand Down Expand Up @@ -618,6 +637,11 @@ func createRevokeQuery(d *schema.ResourceData) string {
var query string

switch strings.ToUpper(d.Get("object_type").(string)) {
case "SYSTEM":
query = fmt.Sprintf(
"REVOKE SYSTEM ALL FROM %s",
pq.QuoteIdentifier(d.Get("role").(string)),
)
case "DATABASE":
query = fmt.Sprintf(
"REVOKE ALL PRIVILEGES ON DATABASE %s FROM %s",
Expand Down Expand Up @@ -839,19 +863,25 @@ func getRolesToGrant(txn *sql.Tx, d *schema.ResourceData) ([]string, error) {
func validateFeatureSupport(db *DBConnection, d *schema.ResourceData) error {
if !db.featureSupported(featurePrivileges) {
return fmt.Errorf(
"postgresql_grant resource is not supported for this Postgres version (%s)",
"postgresql_grant resource is not supported for this version (%s)",
db.version,
)
}
if d.Get("object_type") == "procedure" && !db.featureSupported(featureProcedure) {
return fmt.Errorf(
"object type PROCEDURE is not supported for this Postgres version (%s)",
"object type PROCEDURE is not supported for this version (%s)",
db.version,
)
}
if d.Get("object_type") == "routine" && !db.featureSupported(featureRoutine) {
return fmt.Errorf(
"object type ROUTINE is not supported for this Postgres version (%s)",
"object type ROUTINE is not supported for this version (%s)",
db.version,
)
}
if d.Get("object_type") == "system" && !db.featureSupported(featureSysPrivileges) {
return fmt.Errorf(
"privelege type System is not supported for this version (%s)",
db.version,
)
}
Expand Down

0 comments on commit f3a2427

Please sign in to comment.