|
4 | 4 | "database/sql"
|
5 | 5 | "fmt"
|
6 | 6 | "log"
|
| 7 | + "regexp" |
7 | 8 | "strings"
|
8 | 9 |
|
9 | 10 | "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
@@ -62,13 +63,21 @@ Defines access privileges for users and groups. Privileges include access optio
|
62 | 63 | ForceNew: true,
|
63 | 64 | ExactlyOneOf: []string{grantUserAttr, grantGroupAttr},
|
64 | 65 | Description: "The name of the user to grant privileges on. Either `user` or `group` parameter must be set.",
|
| 66 | + ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile("^(?i)public$"), "User name cannot be 'public'. To use GRANT ... TO PUBLIC set the group name to 'public' instead."), |
65 | 67 | },
|
66 | 68 | grantGroupAttr: {
|
67 | 69 | Type: schema.TypeString,
|
68 | 70 | Optional: true,
|
69 | 71 | ForceNew: true,
|
70 | 72 | ExactlyOneOf: []string{grantUserAttr, grantGroupAttr},
|
71 |
| - Description: "The name of the group to grant privileges on. Either `group` or `user` parameter must be set. Settings the group name to `public` will result in a `GRANT ... TO PUBLIC` statement.", |
| 73 | + Description: "The name of the group to grant privileges on. Either `group` or `user` parameter must be set. Settings the group name to `public` or `PUBLIC` (it is case insensitive in this case) will result in a `GRANT ... TO PUBLIC` statement.", |
| 74 | + StateFunc: func(val interface{}) string { |
| 75 | + name := val.(string) |
| 76 | + if strings.ToLower(name) == grantToPublicName { |
| 77 | + return strings.ToLower(name) |
| 78 | + } |
| 79 | + return name |
| 80 | + }, |
72 | 81 | },
|
73 | 82 | grantSchemaAttr: {
|
74 | 83 | Type: schema.TypeString,
|
@@ -235,7 +244,7 @@ func readDatabaseGrants(db *DBConnection, d *schema.ResourceData) error {
|
235 | 244 | queryArgs := []interface{}{db.client.databaseName, entityName}
|
236 | 245 |
|
237 | 246 | // Handle GRANT TO PUBLIC
|
238 |
| - if entityName == grantToPublicName { |
| 247 | + if isGrantToPublic(d) { |
239 | 248 | query = `
|
240 | 249 | SELECT
|
241 | 250 | decode(charindex('C',split_part(split_part(regexp_replace(replace(array_to_string(db.datacl, '|'), '"', ''),'[^|+]=','__avoidUserPrivs__'), '=', 2) ,'/',1)), 0,0,1) as create,
|
@@ -296,7 +305,7 @@ func readSchemaGrants(db *DBConnection, d *schema.ResourceData) error {
|
296 | 305 | queryArgs := []interface{}{schemaName, entityName}
|
297 | 306 |
|
298 | 307 | // Handle GRANT TO PUBLIC
|
299 |
| - if entityName == grantToPublicName { |
| 308 | + if isGrantToPublic(d) { |
300 | 309 | query = `
|
301 | 310 | SELECT
|
302 | 311 | decode(charindex('C',split_part(split_part(regexp_replace(replace(array_to_string(ns.nspacl, '|'), '"', ''),'[^|+]=','__avoidUserPrivs__'), '=', 2) ,'/',1)), 0,0,1) as create,
|
@@ -376,7 +385,7 @@ func readTableGrants(db *DBConnection, d *schema.ResourceData) error {
|
376 | 385 | pq.Array(grantObjectTypesCodes["table"]), entityName, schemaName,
|
377 | 386 | }
|
378 | 387 |
|
379 |
| - if entityName == grantToPublicName { |
| 388 | + if isGrantToPublic(d) { |
380 | 389 | query = `
|
381 | 390 | SELECT
|
382 | 391 | relname,
|
@@ -498,7 +507,7 @@ func readCallableGrants(db *DBConnection, d *schema.ResourceData) error {
|
498 | 507 | schemaName, entityName, pq.Array(grantObjectTypesCodes[objectType]),
|
499 | 508 | }
|
500 | 509 |
|
501 |
| - if entityName == grantToPublicName { |
| 510 | + if isGrantToPublic(d) { |
502 | 511 | query = `
|
503 | 512 | SELECT
|
504 | 513 | proname,
|
@@ -586,7 +595,7 @@ func readLanguageGrants(db *DBConnection, d *schema.ResourceData) error {
|
586 | 595 | queryArgs := []interface{}{entityName}
|
587 | 596 |
|
588 | 597 | // Handle GRANT TO PUBLIC
|
589 |
| - if entityName == grantToPublicName { |
| 598 | + if isGrantToPublic(d) { |
590 | 599 | query = `
|
591 | 600 | SELECT
|
592 | 601 | lanname,
|
@@ -659,7 +668,7 @@ func createGrantsRevokeQuery(d *schema.ResourceData, databaseName string) string
|
659 | 668 | }
|
660 | 669 |
|
661 | 670 | fromEntityName := pq.QuoteIdentifier(entityName)
|
662 |
| - if entityName == grantToPublicName { |
| 671 | + if isGrantToPublic(d) { |
663 | 672 | toWhomIndicator = ""
|
664 | 673 | fromEntityName = "PUBLIC"
|
665 | 674 | }
|
@@ -745,7 +754,7 @@ func createGrantsQuery(d *schema.ResourceData, databaseName string) string {
|
745 | 754 | }
|
746 | 755 |
|
747 | 756 | toEntityName := pq.QuoteIdentifier(entityName)
|
748 |
| - if entityName == grantToPublicName { |
| 757 | + if isGrantToPublic(d) { |
749 | 758 | toWhomIndicator = ""
|
750 | 759 | toEntityName = "PUBLIC"
|
751 | 760 | }
|
@@ -815,11 +824,26 @@ func createGrantsQuery(d *schema.ResourceData, databaseName string) string {
|
815 | 824 | return query
|
816 | 825 | }
|
817 | 826 |
|
| 827 | +func isGrantToPublic(d *schema.ResourceData) bool { |
| 828 | + if _, isGroup := d.GetOk(grantGroupAttr); isGroup { |
| 829 | + entityName := d.Get(grantGroupAttr).(string) |
| 830 | + |
| 831 | + return strings.ToLower(entityName) == grantToPublicName |
| 832 | + } |
| 833 | + |
| 834 | + return false |
| 835 | +} |
| 836 | + |
818 | 837 | func generateGrantID(d *schema.ResourceData) string {
|
819 | 838 | parts := []string{}
|
820 | 839 |
|
821 | 840 | if _, isGroup := d.GetOk(grantGroupAttr); isGroup {
|
822 |
| - parts = append(parts, fmt.Sprintf("gn:%s", d.Get(grantGroupAttr).(string))) |
| 841 | + name := d.Get(grantGroupAttr).(string) |
| 842 | + if isGrantToPublic(d) { |
| 843 | + name = strings.ToLower(name) |
| 844 | + } |
| 845 | + |
| 846 | + parts = append(parts, fmt.Sprintf("gn:%s", name)) |
823 | 847 | }
|
824 | 848 |
|
825 | 849 | if _, isUser := d.GetOk(grantUserAttr); isUser {
|
|
0 commit comments