Skip to content
This repository has been archived by the owner on Nov 14, 2020. It is now read-only.

Commit

Permalink
Merge pull request #144 from Tommi2Day/feature/grant_function
Browse files Browse the repository at this point in the history
add feature grant functions
  • Loading branch information
cyrilgdn authored Jun 19, 2020
2 parents fa26c41 + 4712ec9 commit 7d6a284
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 15 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
## 1.7.0 (Unreleased)

FEATURES:

* `postgresql_grant`: Implement grant on functions

## 1.6.0 (May 22, 2020)

FEATURES:
Expand Down
1 change: 1 addition & 0 deletions postgresql/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ var allowedPrivileges = map[string][]string{
"database": []string{"ALL", "CREATE", "CONNECT", "TEMPORARY", "TEMP"},
"table": []string{"ALL", "SELECT", "INSERT", "UPDATE", "DELETE", "TRUNCATE", "REFERENCES", "TRIGGER"},
"sequence": []string{"ALL", "USAGE", "SELECT", "UPDATE"},
"function": []string{"ALL", "EXECUTE"},
}

// validatePrivileges checks that privileges to apply are allowed for this object type.
Expand Down
3 changes: 2 additions & 1 deletion postgresql/resource_postgresql_default_privileges.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,9 @@ func resourcePostgreSQLDefaultPrivileges() *schema.Resource {
ValidateFunc: validation.StringInSlice([]string{
"table",
"sequence",
"function",
}, false),
Description: "The PostgreSQL object type to set the default privileges on (one of: table, sequence)",
Description: "The PostgreSQL object type to set the default privileges on (one of: table, sequence, function)",
},
"privileges": &schema.Schema{
Type: schema.TypeSet,
Expand Down
47 changes: 35 additions & 12 deletions postgresql/resource_postgresql_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ var allowedObjectTypes = []string{
"database",
"table",
"sequence",
"function",
}

var objectTypes = map[string]string{
"table": "r",
"sequence": "S",
"function": "f",
}

func resourcePostgreSQLGrant() *schema.Resource {
Expand Down Expand Up @@ -218,16 +220,30 @@ JOIN pg_roles ON grantee = pg_roles.oid WHERE rolname = $2
}

func readRolePrivileges(txn *sql.Tx, d *schema.ResourceData) error {
if d.Get("object_type").(string) == "database" {
var query string
object_type := strings.ToUpper(d.Get("object_type").(string))
switch object_type {
case "DATABASE":
return readDatabaseRolePriviges(txn, d)
}

// This returns, for the specified role (rolname),
// the list of all object of the specified type (relkind) in the specified schema (namespace)
// with the list of the currently applied privileges (aggregation of privilege_type)
//
// Our goal is to check that every object has the same privileges as saved in the state.
query := `
case "FUNCTION":
query = `
SELECT pg_proc.proname, array_remove(array_agg(privilege_type), NULL)
FROM pg_proc
JOIN pg_namespace ON pg_namespace.oid = pg_proc.pronamespace
LEFT JOIN (
select acls.*
from (
SELECT proname, prokind, pronamespace, (aclexplode(proacl)).* FROM pg_proc
) acls
JOIN pg_roles on grantee = pg_roles.oid
WHERE rolname = $1
) privs
USING (proname, pronamespace, prokind)
WHERE nspname = $2 AND prokind = $3
GROUP BY pg_proc.proname
`
default:
query = `
SELECT pg_class.relname, array_remove(array_agg(privilege_type), NULL)
FROM pg_class
JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace
Expand All @@ -240,8 +256,15 @@ LEFT JOIN (
) privs
USING (relname, relnamespace, relkind)
WHERE nspname = $2 AND relkind = $3
GROUP BY pg_class.relname;
GROUP BY pg_class.relname
`
}

// This returns, for the specified role (rolname),
// the list of all object of the specified type (relkind) in the specified schema (namespace)
// with the list of the currently applied privileges (aggregation of privilege_type)
//
// Our goal is to check that every object has the same privileges as saved in the state.

objectType := d.Get("object_type").(string)
rows, err := txn.Query(
Expand Down Expand Up @@ -287,7 +310,7 @@ func createGrantQuery(d *schema.ResourceData, privileges []string) string {
pq.QuoteIdentifier(d.Get("database").(string)),
pq.QuoteIdentifier(d.Get("role").(string)),
)
case "TABLE", "SEQUENCE":
case "TABLE", "SEQUENCE", "FUNCTION":
query = fmt.Sprintf(
"GRANT %s ON ALL %sS IN SCHEMA %s TO %s",
strings.Join(privileges, ","),
Expand All @@ -314,7 +337,7 @@ func createRevokeQuery(d *schema.ResourceData) string {
pq.QuoteIdentifier(d.Get("database").(string)),
pq.QuoteIdentifier(d.Get("role").(string)),
)
case "TABLE", "SEQUENCE":
case "TABLE", "SEQUENCE", "FUNCTION":
query = fmt.Sprintf(
"REVOKE ALL PRIVILEGES ON ALL %sS IN SCHEMA %s FROM %s",
strings.ToUpper(d.Get("object_type").(string)),
Expand Down
9 changes: 9 additions & 0 deletions postgresql/resource_postgresql_grant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ func TestCreateGrantQuery(t *testing.T) {
privileges: []string{"SELECT"},
expected: fmt.Sprintf("GRANT SELECT ON ALL SEQUENCES IN SCHEMA %s TO %s", pq.QuoteIdentifier(databaseName), pq.QuoteIdentifier(roleName)),
},
{
resource: schema.TestResourceDataRaw(t, resourcePostgreSQLGrant().Schema, map[string]interface{}{
"object_type": "function",
"schema": databaseName,
"role": roleName,
}),
privileges: []string{"EXECUTE"},
expected: fmt.Sprintf("GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA %s TO %s", pq.QuoteIdentifier(databaseName), pq.QuoteIdentifier(roleName)),
},
{
resource: schema.TestResourceDataRaw(t, resourcePostgreSQLGrant().Schema, map[string]interface{}{
"object_type": "TABLE",
Expand Down
2 changes: 1 addition & 1 deletion website/docs/r/postgresql_default_privileges.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ resource "postgresql_default_privileges" "read_only_tables" {
* `database` - (Required) The database to grant default privileges for this role.
* `owner` - (Required) Role for which apply default privileges (You can change default privileges only for objects that will be created by yourself or by roles that you are a member of).
* `schema` - (Required) The database schema to set default privileges for this role.
* `object_type` - (Required) The PostgreSQL object type to set the default privileges on (one of: table, sequence).
* `object_type` - (Required) The PostgreSQL object type to set the default privileges on (one of: table, sequence,function).
* `privileges` - (Required) The list of privileges to apply as default privileges.
2 changes: 1 addition & 1 deletion website/docs/r/postgresql_grant.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ resource "postgresql_grant" "readonly_tables" {
* `role` - (Required) The name of the role to grant privileges on.
* `database` - (Required) The database to grant privileges on for this role.
* `schema` - (Required) The database schema to grant privileges on for this role.
* `object_type` - (Required) The PostgreSQL object type to grant the privileges on (one of: table, sequence).
* `object_type` - (Required) The PostgreSQL object type to grant the privileges on (one of: table, sequence,function).
* `privileges` - (Required) The list of privileges to grant.

0 comments on commit 7d6a284

Please sign in to comment.