From e76db009f079ece9408e37336887bc6457cc1fc6 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <peter_e@gmx.net>
Date: Wed, 15 Mar 2017 13:52:07 -0400
Subject: [PATCH] Add more documentation and tests for publications

Add/correct documentation and add some tests related to how access
control around adding tables to publications works.
---
 doc/src/sgml/logical-replication.sgml     |  6 ++++++
 doc/src/sgml/ref/create_publication.sgml  |  6 +++---
 src/test/regress/expected/publication.out | 20 ++++++++++++++++++-
 src/test/regress/sql/publication.sql      | 24 ++++++++++++++++++++++-
 4 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 7b351f2727c..a6c04e923da 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -307,6 +307,12 @@
    privilege in the database.
   </para>
 
+  <para>
+   To add tables to a publication, the user must have ownership rights on the
+   table.  To create a publication that publishes all tables automatically,
+   the user must be a superuser.
+  </para>
+
   <para>
    To create a subscription, the user must be a superuser.
   </para>
diff --git a/doc/src/sgml/ref/create_publication.sgml b/doc/src/sgml/ref/create_publication.sgml
index 995f2bcf3c1..b00a91ef8a6 100644
--- a/doc/src/sgml/ref/create_publication.sgml
+++ b/doc/src/sgml/ref/create_publication.sgml
@@ -143,9 +143,9 @@ CREATE PUBLICATION <replaceable class="parameter">name</replaceable>
   </para>
 
   <para>
-   To add a table to a publication, the invoking user must have
-   <command>SELECT</command> privilege on given table.  The
-   <command>FOR ALL TABLES</command> clause requires superuser.
+   To add a table to a publication, the invoking user must have ownership
+   rights on the table.  The <command>FOR ALL TABLES</command> clause requires
+   the invoking user to be a superuser.
   </para>
 
   <para>
diff --git a/src/test/regress/expected/publication.out b/src/test/regress/expected/publication.out
index 34320267c3f..f3d60db86b2 100644
--- a/src/test/regress/expected/publication.out
+++ b/src/test/regress/expected/publication.out
@@ -2,6 +2,7 @@
 -- PUBLICATION
 --
 CREATE ROLE regress_publication_user LOGIN SUPERUSER;
+CREATE ROLE regress_publication_user2;
 CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER;
 SET SESSION AUTHORIZATION 'regress_publication_user';
 CREATE PUBLICATION testpub_default;
@@ -140,6 +141,23 @@ Publications:
     "testpib_ins_trunct"
     "testpub_fortbl"
 
+-- permissions
+SET ROLE regress_publication_user2;
+CREATE PUBLICATION testpub2;  -- fail
+ERROR:  permission denied for database regression
+SET ROLE regress_publication_user;
+GRANT CREATE ON DATABASE regression TO regress_publication_user2;
+SET ROLE regress_publication_user2;
+CREATE PUBLICATION testpub2;  -- ok
+ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1;  -- fail
+ERROR:  must be owner of relation testpub_tbl1
+SET ROLE regress_publication_user;
+GRANT regress_publication_user TO regress_publication_user2;
+SET ROLE regress_publication_user2;
+ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1;  -- ok
+DROP PUBLICATION testpub2;
+SET ROLE regress_publication_user;
+REVOKE CREATE ON DATABASE regression FROM regress_publication_user2;
 DROP VIEW testpub_view;
 DROP TABLE testpub_tbl1;
 \dRp+ testpub_default
@@ -168,5 +186,5 @@ DROP PUBLICATION testpub_fortbl;
 DROP SCHEMA pub_test CASCADE;
 NOTICE:  drop cascades to table pub_test.testpub_nopk
 RESET SESSION AUTHORIZATION;
-DROP ROLE regress_publication_user;
+DROP ROLE regress_publication_user, regress_publication_user2;
 DROP ROLE regress_publication_user_dummy;
diff --git a/src/test/regress/sql/publication.sql b/src/test/regress/sql/publication.sql
index de68e61cb3b..522c39029e5 100644
--- a/src/test/regress/sql/publication.sql
+++ b/src/test/regress/sql/publication.sql
@@ -2,6 +2,7 @@
 -- PUBLICATION
 --
 CREATE ROLE regress_publication_user LOGIN SUPERUSER;
+CREATE ROLE regress_publication_user2;
 CREATE ROLE regress_publication_user_dummy LOGIN NOSUPERUSER;
 SET SESSION AUTHORIZATION 'regress_publication_user';
 
@@ -69,6 +70,27 @@ ALTER PUBLICATION testpub_default DROP TABLE pub_test.testpub_nopk;
 
 \d+ testpub_tbl1
 
+-- permissions
+SET ROLE regress_publication_user2;
+CREATE PUBLICATION testpub2;  -- fail
+
+SET ROLE regress_publication_user;
+GRANT CREATE ON DATABASE regression TO regress_publication_user2;
+SET ROLE regress_publication_user2;
+CREATE PUBLICATION testpub2;  -- ok
+
+ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1;  -- fail
+
+SET ROLE regress_publication_user;
+GRANT regress_publication_user TO regress_publication_user2;
+SET ROLE regress_publication_user2;
+ALTER PUBLICATION testpub2 ADD TABLE testpub_tbl1;  -- ok
+
+DROP PUBLICATION testpub2;
+
+SET ROLE regress_publication_user;
+REVOKE CREATE ON DATABASE regression FROM regress_publication_user2;
+
 DROP VIEW testpub_view;
 DROP TABLE testpub_tbl1;
 
@@ -90,5 +112,5 @@ DROP PUBLICATION testpub_fortbl;
 DROP SCHEMA pub_test CASCADE;
 
 RESET SESSION AUTHORIZATION;
-DROP ROLE regress_publication_user;
+DROP ROLE regress_publication_user, regress_publication_user2;
 DROP ROLE regress_publication_user_dummy;
-- 
GitLab