6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-23 14:03:06 +01:00
firebird-qa/tests/functional/tabloid/test_dml_privileges_sufficiency.py

350 lines
11 KiB
Python

#coding:utf-8
#
# id: functional.tabloid.dml_privileges_sufficiency
# title: Verify sufficiency of privileges for performing DML actions. Verify that RETURNING clause can not be used without SELECT privilege.
# decription:
# Test creates three users (for I/U/D) and gives them initial privileges for INSERT, UPDATE and DELETE (but without SELECT).
# Then we check that each user:
# 1) can do "his" DML without using RETURNING clause and this action must pass;
# 2) can NOT do "his" DML with using RETURNING clause because of absense of SELETC privilege.
# After this we add SELECT privilege for all of them and repeat. All actions must pased in this case.
#
# Created by request of dimitr, letter 16.06.2020 13:54.
# Checked on 4.0.0.2066.
# ::: NB :::
# Do NOT use this test on 4.0.0.2046 and 4.0.0.2048 - these snapshots have bug and will crash on this test.
#
# tracker_id:
# min_versions: ['4.0.0']
# versions: 4.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 4.0
# resources: None
substitutions_1 = [('[ \t]+', ' ')]
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
test_script_1 = """
set wng off;
set list on;
set term ^;
execute block as
begin
begin
execute statement 'drop user tmp$modifier_ins' with autonomous transaction;
when any do begin end
end
begin
execute statement 'drop user tmp$modifier_upd' with autonomous transaction;
when any do begin end
end
begin
execute statement 'drop user tmp$modifier_del' with autonomous transaction;
when any do begin end
end
end^
set term ;^
commit; --------------- 4.0.0.2046, 4.0.0.2048: crash here
set bail off;
create user tmp$modifier_ins password '123';
create user tmp$modifier_upd password '123';
create user tmp$modifier_del password '123';
revoke all on all from tmp$modifier_ins;
revoke all on all from tmp$modifier_upd;
revoke all on all from tmp$modifier_del;
create sequence g;
recreate table test(id int primary key, x int);
insert into test(id,x) values( gen_id(g,1), 100);
commit;
grant usage on sequence g to tmp$modifier_ins;
grant usage on sequence g to tmp$modifier_upd;
grant insert on test to tmp$modifier_ins;
grant update on test to tmp$modifier_upd;
grant delete on test to tmp$modifier_del;
commit;
create or alter view v_privs as
select
rdb$user -- tmp$c6317
,rdb$relation_name -- test
,rdb$privilege -- S
,rdb$grant_option -- 0
,rdb$field_name -- <null>
,rdb$object_type -- 0
from rdb$user_privileges p
where rdb$user in ( upper('tmp$modifier_ins'), upper('tmp$modifier_upd'), upper('tmp$modifier_del') )
order by rdb$user, rdb$privilege
;
commit;
-- ####### P R I V I L E G E O N L Y F O R I N S E R T ########
connect '$(DSN)' user tmp$modifier_ins password '123';
select current_user as whoami, 'Has only INSERT privilege' as msg from rdb$database;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_ins':
select * from test;
-- no exception must be here:
insert into test(id,x) values(gen_id(g,1), 200);
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_ins':
insert into test(id,x) values(gen_id(g,1), 1234567) returning id,x;
rollback;
-- must PASS: we have privilege to add record and RETURNING clause
-- does NOT contain anything from *table*:
insert into test(id,x) values(gen_id(g,1), 1234567) returning pi();
rollback;
-- ####### P R I V I L E G E O N L Y F O R U P D A T E ########
connect '$(DSN)' user tmp$modifier_upd password '123';
select current_user as whoami, 'Has only UPDATE privilege' as msg from rdb$database;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_upd':
select * from test;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_upd'
-- NB: "set x = -x" - this statement DOES query to old value of 'x',
-- i.e. is SELECTS table thust must fail:
update test set x = -x;
rollback;
-- must PASS, no exception must be here: we do NOT interesting on old value of 'x':
update test set x = 0;
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_upd':
update test set x = 0 order by id rows 1;
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_upd':
update test set x = 111 where id = 1;
rollback;
-- must PASS: we have privilege to change column and RETURNING clause
-- does NOT contain anything from *table*:
update test set x = 0 returning pi();
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_upd':
update test set x = 0 returning x;
rollback;
-- ####### P R I V I L E G E O N L Y F O R D E L E T E ########
connect '$(DSN)' user tmp$modifier_del password '123';
select current_user as whoami, 'Has only DELETE privilege' as msg from rdb$database;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_del':
select * from test;
-- must PASS: user has privilege to DELETE rows from this table:
delete from test;
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_del':
delete from test where id > 0;
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_del':
delete from test order by id rows 1;
rollback;
-- must fail because no 'select' privilege was granted to 'tmp$modifier_del':
delete from test returning id;
rollback;
-- ##############################################################
-- ### A D D P R I V I L E G E F O R S E L E C T ###
-- ##############################################################
connect '$(DSN)' user SYSDBA password 'masterkey';
grant select on test to tmp$modifier_ins;
grant select on test to tmp$modifier_upd;
grant select on test to tmp$modifier_del;
commit;
-- #### P R I V I L E G E F O R I N S E R T + S E L E C T #####
connect '$(DSN)' user tmp$modifier_ins password '123';
select current_user as whoami, 'Has INSERT + SELECT privileges' as msg from rdb$database;
-- All subsequent statements must PASS:
select * from test;
insert into test(id,x) values(-1, 1234567) returning id,x;
rollback;
-- #### P R I V I L E G E F O R U P D A T E + S E L E C T #####
connect '$(DSN)' user tmp$modifier_upd password '123';
select current_user as whoami, 'Has UPDATE + SELECT privileges' as msg from rdb$database;
-- All subsequent statements must PASS:
select * from test;
update test set x = -x;
rollback;
update test set x = 0;
rollback;
update test set x = 0 order by id rows 1;
rollback;
update test set x = 111 where id = 1;
rollback;
update test set x = 0 returning x;
rollback;
-- #### P R I V I L E G E F O R D E L E T E + S E L E C T #####
connect '$(DSN)' user tmp$modifier_del password '123';
select current_user as whoami, 'Has DELETE + SELECT privileges' as msg from rdb$database;
-- All subsequent statements must PASS:
select * from test;
delete from test where id > 0;
rollback;
delete from test order by id rows 1;
rollback;
delete from test returning id;
rollback;
-- #########################
-- ### C L E A N U P ###
-- #########################
connect '$(DSN)' user SYSDBA password 'masterkey';
drop user tmp$modifier_ins;
drop user tmp$modifier_upd;
drop user tmp$modifier_del;
commit;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
WHOAMI TMP$MODIFIER_INS
MSG Has only INSERT privilege
PI 3.141592653589793
WHOAMI TMP$MODIFIER_UPD
MSG Has only UPDATE privilege
PI 3.141592653589793
WHOAMI TMP$MODIFIER_DEL
MSG Has only DELETE privilege
WHOAMI TMP$MODIFIER_INS
MSG Has INSERT + SELECT privileges
ID 1
X 100
ID -1
X 1234567
WHOAMI TMP$MODIFIER_UPD
MSG Has UPDATE + SELECT privileges
ID 1
X 100
X 0
WHOAMI TMP$MODIFIER_DEL
MSG Has DELETE + SELECT privileges
ID 1
X 100
ID 1
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_INS
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_INS
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_UPD
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_UPD
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_UPD
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_UPD
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_UPD
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_DEL
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_DEL
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_DEL
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TEST
-Effective user is TMP$MODIFIER_DEL
"""
@pytest.mark.version('>=4.0')
def test_dml_privileges_sufficiency_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr
assert act_1.clean_expected_stdout == act_1.clean_stdout