new-cluster name=s1
----

exec-sql
CREATE DATABASE d;
CREATE TABLE d.t (x INT);
INSERT INTO d.t VALUES (1), (2), (3);
----

# BACKUP is not allowed in a batch-statement.
exec-sql
BACKUP INTO 'userfile:///test-root/';
SELECT 1;
----
pq: BACKUP cannot be used inside a multi-statement transaction without DETACHED option

subtest cluster-backup
# Cluster backup should succeed as a root user.
exec-sql
BACKUP INTO 'userfile:///test-root/'
----

# Backups should succeed as a non-root user with admin role.
exec-sql
CREATE USER testuser;
GRANT ADMIN TO testuser;
----

exec-sql user=testuser
BACKUP INTO 'userfile:///test-nonroot-cluster';
----

exec-sql user=testuser
BACKUP DATABASE d INTO 'userfile:///test-nonroot-db';
----

exec-sql user=testuser
BACKUP TABLE d.t INTO 'userfile:///test-nonroot-table';
----

exec-sql
REVOKE ADMIN FROM testuser
----

# Sanity check that cluster backup is disallowed.
exec-sql user=testuser
BACKUP INTO 'userfile:///test-nonroot-cluster';
----
pq: only users with the admin role or the BACKUP system privilege are allowed to perform full cluster backups: user testuser does not have BACKUP system privilege

# Grant system backup privilege and re-run the backup.
exec-sql
GRANT SYSTEM BACKUP TO testuser;
----

exec-sql user=testuser
BACKUP INTO 'userfile:///test-nonroot-cluster';
----

# System privilege BACKUP does not allow a user to run database/table backups by
# default.
exec-sql user=testuser
BACKUP DATABASE d INTO 'userfile:///test-nonroot-db';
----
pq: user testuser does not have SELECT privilege on relation t
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP DATABASE, user testuser will exclusively require the BACKUP privilege on database d.

exec-sql user=testuser
BACKUP TABLE d.t INTO 'userfile:///test-nonroot-table';
----
pq: user testuser does not have SELECT privilege on relation t
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t.

exec-sql
REVOKE SYSTEM BACKUP FROM testuser;
----

subtest end


subtest database-backup

# A database backup requires the `BACKUP` privilege on the database, make sure
# we are informing users about this even though we check for old-style
# privileges.
exec-sql user=testuser
BACKUP DATABASE d INTO 'userfile:///test-nonroot-db'
----
pq: user testuser does not have SELECT privilege on relation t
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP DATABASE, user testuser will exclusively require the BACKUP privilege on database d.

# Grant the user `BACKUP` on the database.
exec-sql
GRANT BACKUP ON DATABASE d TO testuser
----

# Create some types and schemas.
exec-sql
CREATE SCHEMA d.foo;
CREATE TYPE d.foo.type1 AS ENUM()
----

# Backup should succeed!
exec-sql user=testuser
BACKUP DATABASE d INTO 'userfile:///test-nonroot-db'
----

# Existing tables DO NOT inherit database privileges so a user should not be
# allowed to backup tables in the database.
exec-sql user=testuser
BACKUP TABLE d.t INTO 'userfile:///test-nonroot-table'
----
pq: user testuser does not have SELECT privilege on relation t
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t.

# Set the default privileges on the database and create a new table.
exec-sql
USE d;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT BACKUP ON TABLES TO testuser;
----

exec-sql
CREATE TABLE d.t2 (id INT)
----

exec-sql
CREATE TABLE d.t3 (id INT)
----

# Backups on the new tables will succeed because the default privileges grant
# `BACKUP` on the tables to testuser.
exec-sql user=testuser
BACKUP TABLE d.t2 INTO 'userfile:///test-nonroot-table'
----

exec-sql user=testuser
BACKUP TABLE d.t3 INTO 'userfile:///test-nonroot-table'
----

# Cleanup by revoking `BACKUP` from testuser.
exec-sql
REVOKE BACKUP ON DATABASE d FROM testuser;
REVOKE BACKUP ON TABLE d.t2 FROM testuser;
REVOKE BACKUP ON TABLE d.t3 FROM testuser;
----

subtest end

subtest table-backup

query-sql
SHOW GRANTS ON DATABASE d;
----
d admin ALL true
d public CONNECT false
d root ALL true

# testuser should not be able to backup any table, verify the deprecation notice is accurate.
exec-sql user=testuser
BACKUP TABLE d.t INTO 'userfile:///test-nonroot-table'
----
pq: user testuser does not have SELECT privilege on relation t
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t.

exec-sql user=testuser
BACKUP TABLE d.t2 INTO 'userfile:///test-nonroot-table'
----
pq: user testuser does not have SELECT privilege on relation t2
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t2.

exec-sql user=testuser
BACKUP TABLE d.t3 INTO 'userfile:///test-nonroot-table'
----
pq: user testuser does not have SELECT privilege on relation t3
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t3.

exec-sql
GRANT BACKUP ON TABLE d.t,d.t2,d.t3 TO testuser;
----

exec-sql user=testuser
BACKUP TABLE d.t INTO 'userfile:///test-nonroot-table'
----

exec-sql user=testuser
BACKUP TABLE d.t2 INTO 'userfile:///test-nonroot-table'
----

exec-sql user=testuser
BACKUP TABLE d.t3 INTO 'userfile:///test-nonroot-table'
----

# Create a table with user defined schema + type.
exec-sql
CREATE TABLE d.foo.t1 (hi d.foo.type1)
----

# User requires `BACKUP` on the table, NOT on the schema and type.
exec-sql user=testuser
BACKUP TABLE d.foo.t1 INTO 'userfile:///test-nonroot-table'
----
pq: user testuser does not have USAGE privilege on schema foo
HINT: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP TABLE, user testuser will exclusively require the BACKUP privilege on tables: t1.

exec-sql
GRANT BACKUP ON TABLE foo.t1 TO testuser;
----

exec-sql user=testuser
BACKUP TABLE d.foo.t1 INTO 'userfile:///test-nonroot-table'
----

subtest end

subtest external-io-implicit-access

# testuser has BACKUP privilege but should not be allowed to use implicit
# authentication URIs such as nodelocal.
exec-sql user=testuser
BACKUP TABLE d.foo.t1 INTO 'nodelocal://1/test-nonroot-table'
----
pq: only users with the admin role or the EXTERNALIOIMPLICITACCESS system privilege are allowed to access the specified nodelocal URI

exec-sql
GRANT SYSTEM EXTERNALIOIMPLICITACCESS TO testuser;
----

# testuser should be able to backup and show backup from `nodelocal`
exec-sql user=testuser
BACKUP TABLE d.foo.t1 INTO 'nodelocal://1/test-nonroot-table'
----

query-sql user=testuser
select object_name from [show backup latest in 'nodelocal://1/test-nonroot-table'] order by object_name
----
_type1
d
foo
t1
type1

exec-sql
REVOKE SYSTEM EXTERNALIOIMPLICITACCESS FROM testuser;
----

query-sql user=testuser
select object_name from [show backup latest in 'nodelocal://1/test-nonroot-table'] order by object_name
----
pq: only users with the admin role or the EXTERNALIOIMPLICITACCESS system privilege are allowed to access the specified nodelocal URI

subtest end

subtest udf-permission

exec-sql
CREATE DATABASE d_test_fn;
USE d_test_fn;
CREATE FUNCTION f() RETURNS INT LANGUAGE SQL AS $$ SELECT 1 $$;
USE d;
----

# Cluster backup should succeed as a root user.
exec-sql
BACKUP INTO 'userfile:///test-root/'
----

# Backups should succeed as a non-root user with admin role.
exec-sql
GRANT ADMIN TO testuser;
----

exec-sql user=testuser
BACKUP INTO 'userfile:///test-nonroot-cluster';
----

exec-sql user=testuser
BACKUP DATABASE d_test_fn INTO 'userfile:///test-nonroot-db';
----

exec-sql
REVOKE ADMIN FROM testuser
----

# Grant system backup privilege and re-run the backup.
exec-sql
GRANT SYSTEM BACKUP TO testuser;
----

exec-sql user=testuser
BACKUP INTO 'userfile:///test-nonroot-cluster';
----

# System privilege BACKUP does not allow a user to run database/table backups by
# default.
exec-sql user=testuser
BACKUP DATABASE d_test_fn INTO 'userfile:///test-nonroot-db';
----
NOTICE: The existing privileges are being deprecated in favour of a fine-grained privilege model explained here https://www.cockroachlabs.com/docs/stable/backup.html#required-privileges. In a future release, to run BACKUP DATABASE, user testuser will exclusively require the BACKUP privilege on database d_test_fn.

exec-sql
REVOKE SYSTEM BACKUP FROM testuser;
----

subtest end
