@@ -49,6 +49,24 @@ func TestCreateGrantQuery(t *testing.T) {
49
49
privileges : []string {"EXECUTE" },
50
50
expected : fmt .Sprintf ("GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA %s TO %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
51
51
},
52
+ {
53
+ resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
54
+ "object_type" : "procedure" ,
55
+ "schema" : databaseName ,
56
+ "role" : roleName ,
57
+ }),
58
+ privileges : []string {"EXECUTE" },
59
+ expected : fmt .Sprintf ("GRANT EXECUTE ON ALL PROCEDURES IN SCHEMA %s TO %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
60
+ },
61
+ {
62
+ resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
63
+ "object_type" : "routine" ,
64
+ "schema" : databaseName ,
65
+ "role" : roleName ,
66
+ }),
67
+ privileges : []string {"EXECUTE" },
68
+ expected : fmt .Sprintf ("GRANT EXECUTE ON ALL ROUTINES IN SCHEMA %s TO %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
69
+ },
52
70
{
53
71
resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
54
72
"object_type" : "TABLE" ,
@@ -171,6 +189,30 @@ func TestCreateRevokeQuery(t *testing.T) {
171
189
}),
172
190
expected : fmt .Sprintf ("REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA %s FROM %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
173
191
},
192
+ {
193
+ resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
194
+ "object_type" : "function" ,
195
+ "schema" : databaseName ,
196
+ "role" : roleName ,
197
+ }),
198
+ expected : fmt .Sprintf ("REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA %s FROM %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
199
+ },
200
+ {
201
+ resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
202
+ "object_type" : "procedure" ,
203
+ "schema" : databaseName ,
204
+ "role" : roleName ,
205
+ }),
206
+ expected : fmt .Sprintf ("REVOKE ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA %s FROM %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
207
+ },
208
+ {
209
+ resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
210
+ "object_type" : "routine" ,
211
+ "schema" : databaseName ,
212
+ "role" : roleName ,
213
+ }),
214
+ expected : fmt .Sprintf ("REVOKE ALL PRIVILEGES ON ALL ROUTINES IN SCHEMA %s FROM %s" , pq .QuoteIdentifier (databaseName ), pq .QuoteIdentifier (roleName )),
215
+ },
174
216
{
175
217
resource : schema .TestResourceDataRaw (t , resourcePostgreSQLGrant ().Schema , map [string ]interface {}{
176
218
"object_type" : "database" ,
@@ -608,6 +650,7 @@ func TestAccPostgresqlGrantFunction(t *testing.T) {
608
650
dbExecute (t , dsn , fmt .Sprintf ("CREATE ROLE test_role LOGIN PASSWORD '%s'" , testRolePassword ))
609
651
dbExecute (t , dsn , "CREATE SCHEMA test_schema" )
610
652
dbExecute (t , dsn , "GRANT USAGE ON SCHEMA test_schema TO test_role" )
653
+ dbExecute (t , dsn , "ALTER DEFAULT PRIVILEGES REVOKE ALL ON FUNCTIONS FROM PUBLIC" )
611
654
612
655
// Create test function in this schema
613
656
dbExecute (t , dsn , `
@@ -658,6 +701,137 @@ resource postgresql_grant "test" {
658
701
}
659
702
}
660
703
704
+ func TestAccPostgresqlGrantProcedure (t * testing.T ) {
705
+ skipIfNotAcc (t )
706
+ testCheckCompatibleVersion (t , featureProcedure )
707
+
708
+ config := getTestConfig (t )
709
+ dsn := config .connStr ("postgres" )
710
+
711
+ // Create a test role and a schema as public has too wide open privileges
712
+ dbExecute (t , dsn , fmt .Sprintf ("CREATE ROLE test_role LOGIN PASSWORD '%s'" , testRolePassword ))
713
+ dbExecute (t , dsn , "CREATE SCHEMA test_schema" )
714
+ dbExecute (t , dsn , "GRANT USAGE ON SCHEMA test_schema TO test_role" )
715
+ dbExecute (t , dsn , "ALTER DEFAULT PRIVILEGES REVOKE ALL ON FUNCTIONS FROM PUBLIC" )
716
+
717
+ // Create test procedure in this schema
718
+ dbExecute (t , dsn , `
719
+ CREATE PROCEDURE test_schema.test()
720
+ AS $$ select 'foo'::text $$
721
+ LANGUAGE SQL;
722
+ ` )
723
+ defer func () {
724
+ dbExecute (t , dsn , "DROP SCHEMA test_schema CASCADE" )
725
+ dbExecute (t , dsn , "DROP ROLE test_role" )
726
+ }()
727
+
728
+ // Test to grant directly to test_role and to public
729
+ // in both case test_case should have the right
730
+ for _ , role := range []string {"test_role" , "public" } {
731
+ t .Run (role , func (t * testing.T ) {
732
+
733
+ tfConfig := fmt .Sprintf (`
734
+ resource postgresql_grant "test" {
735
+ database = "postgres"
736
+ role = "%s"
737
+ schema = "test_schema"
738
+ object_type = "procedure"
739
+ privileges = ["EXECUTE"]
740
+ }
741
+ ` , role )
742
+
743
+ resource .Test (t , resource.TestCase {
744
+ PreCheck : func () {
745
+ testAccPreCheck (t )
746
+ testCheckCompatibleVersion (t , featurePrivileges )
747
+ },
748
+ Providers : testAccProviders ,
749
+ Steps : []resource.TestStep {
750
+ {
751
+ Config : tfConfig ,
752
+ Check : resource .ComposeTestCheckFunc (
753
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "id" , fmt .Sprintf ("%s_postgres_test_schema_procedure" , role )),
754
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "privileges.#" , "1" ),
755
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "privileges.0" , "EXECUTE" ),
756
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "with_grant_option" , "false" ),
757
+ testCheckProcedureExecutable (t , "test_role" , "test_schema.test" ),
758
+ ),
759
+ },
760
+ },
761
+ })
762
+ })
763
+ }
764
+ }
765
+
766
+ func TestAccPostgresqlGrantRoutine (t * testing.T ) {
767
+ skipIfNotAcc (t )
768
+ testCheckCompatibleVersion (t , featureRoutine )
769
+
770
+ config := getTestConfig (t )
771
+ dsn := config .connStr ("postgres" )
772
+
773
+ // Create a test role and a schema as public has too wide open privileges
774
+ dbExecute (t , dsn , fmt .Sprintf ("CREATE ROLE test_role LOGIN PASSWORD '%s'" , testRolePassword ))
775
+ dbExecute (t , dsn , "CREATE SCHEMA test_schema" )
776
+ dbExecute (t , dsn , "GRANT USAGE ON SCHEMA test_schema TO test_role" )
777
+ dbExecute (t , dsn , "ALTER DEFAULT PRIVILEGES REVOKE ALL ON FUNCTIONS FROM PUBLIC" )
778
+
779
+ // Create test function in this schema
780
+ dbExecute (t , dsn , `
781
+ CREATE FUNCTION test_schema.test_function() RETURNS text
782
+ AS $$ select 'foo'::text $$
783
+ LANGUAGE SQL;
784
+ ` )
785
+ // Create test procedure in this schema
786
+ dbExecute (t , dsn , `
787
+ CREATE PROCEDURE test_schema.test_procedure()
788
+ AS $$ select 'foo'::text $$
789
+ LANGUAGE SQL;
790
+ ` )
791
+ defer func () {
792
+ dbExecute (t , dsn , "DROP SCHEMA test_schema CASCADE" )
793
+ dbExecute (t , dsn , "DROP ROLE test_role" )
794
+ }()
795
+
796
+ // Test to grant directly to test_role and to public
797
+ // in both case test_case should have the right
798
+ for _ , role := range []string {"test_role" , "public" } {
799
+ t .Run (role , func (t * testing.T ) {
800
+
801
+ tfConfigRoutine := fmt .Sprintf (`
802
+ resource postgresql_grant "test" {
803
+ database = "postgres"
804
+ role = "%s"
805
+ schema = "test_schema"
806
+ object_type = "routine"
807
+ privileges = ["EXECUTE"]
808
+ }
809
+ ` , role )
810
+
811
+ resource .Test (t , resource.TestCase {
812
+ PreCheck : func () {
813
+ testAccPreCheck (t )
814
+ testCheckCompatibleVersion (t , featurePrivileges )
815
+ },
816
+ Providers : testAccProviders ,
817
+ Steps : []resource.TestStep {
818
+ {
819
+ Config : tfConfigRoutine ,
820
+ Check : resource .ComposeTestCheckFunc (
821
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "id" , fmt .Sprintf ("%s_postgres_test_schema_routine" , role )),
822
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "privileges.#" , "1" ),
823
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "privileges.0" , "EXECUTE" ),
824
+ resource .TestCheckResourceAttr ("postgresql_grant.test" , "with_grant_option" , "false" ),
825
+ testCheckFunctionExecutable (t , "test_role" , "test_schema.test_function" ),
826
+ testCheckProcedureExecutable (t , "test_role" , "test_schema.test_procedure" ),
827
+ ),
828
+ },
829
+ },
830
+ })
831
+ })
832
+ }
833
+ }
834
+
661
835
func TestAccPostgresqlGrantDatabase (t * testing.T ) {
662
836
// create a TF config with placeholder for privileges
663
837
// it will be filled in each step.
@@ -931,6 +1105,18 @@ func testCheckFunctionExecutable(t *testing.T, role, function string) func(*terr
931
1105
}
932
1106
}
933
1107
1108
+ func testCheckProcedureExecutable (t * testing.T , role , procedure string ) func (* terraform.State ) error {
1109
+ return func (* terraform.State ) error {
1110
+ db := connectAsTestRole (t , role , "postgres" )
1111
+ defer db .Close ()
1112
+
1113
+ if err := testHasGrantForQuery (db , fmt .Sprintf ("CALL %s()" , procedure ), true ); err != nil {
1114
+ return err
1115
+ }
1116
+ return nil
1117
+ }
1118
+ }
1119
+
934
1120
func testCheckSchemaPrivileges (t * testing.T , usage , create bool ) func (* terraform.State ) error {
935
1121
return func (* terraform.State ) error {
936
1122
config := getTestConfig (t )
0 commit comments