6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 21:43:06 +01:00
firebird-qa/tests/bugs/core_1815_test.py

440 lines
26 KiB
Python

#coding:utf-8
#
# id: bugs.core_1815
# title: Ability to grant role to another role
# decription:
# ### NB ### This test was NOT completed!
# One need to check all nuances related to granting and revoking that is issued by NON sysdba user
# which was granted admin option to manupulate appropriate DB objects.
# Also, there is not clarity about issue 08/Aug/16 06:31 AM (when user Boss2 does grant-and-revoke
# sequence with some role to other user Sales but this role already was granted by _other_ user, Boss1).
#
# We create two users (acnt and pdsk) and two roles for them (racnt and rpdsk).
# Then we create two tables (tacnt & tpdsk) and grant access on these tables for acnt & pdsk.
# Then we create user boss, role for him (rboss) and grant IMPLICITLY access on tables tacnt and tpdsk
# to user boss via his role (rboss).
# Check is made to ensure that user boss HAS ability to read from both tables (being connected with role Rboss).
# After all, we IMPLICITLY revoke access from these tables and check again that user boss now has NO access
# on tables tacnt and tpdsk.
#
# Checked on WI-T4.0.0.322 -- all fine.
#
# tracker_id: CORE-1815
# min_versions: ['4.0']
# versions: 4.0
# qmid: None
import pytest
from firebird.qa import db_factory, isql_act, Action
# version: 4.0
# resources: None
substitutions_1 = []
init_script_1 = """"""
db_1 = db_factory(sql_dialect=3, init=init_script_1)
test_script_1 = """
set wng off;
--show version;
--set bail on;
--set echo on;
set list on;
set width whoami 16;
set width my_role 7;
set width r_name 10;
set width r_owner 10;
create or alter user tmp$c1815_boss password 'boss' revoke admin role; -- boss
create or alter user tmp$c1815_acnt password 'acnt' revoke admin role; -- accountant
create or alter user tmp$c1815_pdsk password 'pdsk' revoke admin role; -- paydesk
commit;
revoke all on all from tmp$c1815_boss;
revoke all on all from tmp$c1815_acnt;
revoke all on all from tmp$c1815_pdsk;
commit;
create or alter view v_role_info as
select
current_user as whoami,
current_role as my_role,
rdb$role_name as r_name,
rdb$owner_name r_owner,
rdb$role_in_use(rdb$role_name) r_in_use
from rdb$roles
where coalesce(rdb$system_flag,0) = 0
;
commit;
set term ^;
execute block as
begin
begin execute statement 'drop role rboss'; when any do begin end end
begin execute statement 'drop role racnt'; when any do begin end end
begin execute statement 'drop role rpdsk'; when any do begin end end
end
^
set term ^;
commit;
create role rboss;
create role racnt;
create role rpdsk;
commit;
grant select on v_role_info to user tmp$c1815_acnt;
grant select on v_role_info to user tmp$c1815_pdsk;
grant select on v_role_info to user tmp$c1815_boss;
commit;
grant racnt to user tmp$c1815_acnt;
grant rpdsk to user tmp$c1815_pdsk;
commit;
------------------------------------------------------------------------
recreate table tacnt(id int, s varchar(5));
recreate table tpdsk(id int, s varchar(5));
commit;
grant all on tacnt to role racnt;
grant all on tpdsk to role rpdsk;
commit;
------------------------------------------------------------------------
grant racnt to rboss; -- make RBOSS role able to do the same as role RACNT
grant rpdsk to rboss; -- make RBOSS role able to do the same as role RPDSK
grant rboss to tmp$c1815_boss; -- let user BOSS to use role RBOSS
commit;
--show grants; -- [ 1 ]
------------------------------------------------------------------------
insert into tacnt(id, s) values(1,'acnt');
insert into tpdsk(id, s) values(2,'pdsk');
commit;
connect '$(DSN)' user tmp$c1815_acnt password 'acnt' role 'racnt';
select * from v_role_info;
select current_user as whoami, a.* from tacnt a;
commit;
connect '$(DSN)' user tmp$c1815_pdsk password 'pdsk' role 'rpdsk';
select * from v_role_info;
select current_user as whoami, p.* from tpdsk p;
commit;
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss';
select * from v_role_info;
commit;
select current_user as whoami, a.* from tacnt a;
select current_user as whoami, p.* from tpdsk p;
commit;
--################################################################################################
connect '$(DSN)' user sysdba password 'masterkey';
revoke racnt from user tmp$c1815_acnt; -- REVOKE role from *other* USER; grant to RBoss should be reserved!
commit;
-- check that *role* RBoss still HAS grants to both RAcnt and RPdsk roles:
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss';
select * from v_role_info; -- should contain <true> in all three rows
-- should PASS because we revoked role from other USER (accountant)
-- rather than from current user (Boss) or its role (Rboss):
select current_user as whoami, a.* from tacnt a;
commit;
--####################################################################################################
connect '$(DSN)' user sysdba password 'masterkey';
-- check that if we try to revoke role RPdsk from __USER__ Boss than
-- this action will not has effect because this USER got access through the ROLE (i.e. indirectly):
revoke rpdsk from user tmp$c1815_boss; -- this is no-op action! We did NOT granted role to USER!
commit;
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss'; -- now check: is role Rboss really affected ?
select * from v_role_info; -- should contain <true> in all lines because we did not affect __role__ RBOSS
select current_user as whoami, p.* from tpdsk p; -- should PASS!
commit;
--################################################################################################
connect '$(DSN)' user sysdba password 'masterkey';
-- check that if we revoke access to a table from ROLE RPdsk (and this role was granted to role RBoss)
-- then Rboss also will not be able to select from this table:
revoke all on tpdsk from rpdsk;
commit;
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss';
select * from v_role_info; -- should contain <true> in all lines because we did not affect __role__ RBOSS
select current_user as whoami, p.* from tpdsk p; -- should FAIL
commit;
--################################################################################################
connect '$(DSN)' user sysdba password 'masterkey';
-- check that if we revoke ROLE 'racnt' which was granted before to ROLE 'rboss'
-- then user Boss will not be able to access table 'tacnt' (i.e. we revoke this access indirectly):
revoke racnt from rboss;
commit;
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss';
select * from v_role_info; -- should contain <false> for line with 'racnt'
select current_user as whoami, a.* from tacnt a; -- should FAIL
commit;
-- ###############################################################################################
connect '$(DSN)' user sysdba password 'masterkey';
-- check that if we GRANT again ROLE 'racnt' which was revoked before from ROLE 'rboss'
-- then user Boss WILL be able to access table 'tacnt' (we grant access indirectly after revoking):
grant racnt to rboss; -- RESTORE access for role Rboss
commit;
connect '$(DSN)' user tmp$c1815_boss password 'boss' role 'rboss';
select * from v_role_info; -- should contain <true> for line with 'racnt'
select current_user as whoami, a.* from tacnt a; -- should PASS
commit;
-- cleanup
connect '$(DSN)' user sysdba password 'masterkey';
drop user tmp$c1815_boss;
drop user tmp$c1815_acnt;
drop user tmp$c1815_pdsk;
commit;
"""
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
expected_stdout_1 = """
WHOAMI TMP$C1815_ACNT
MY_ROLE RACNT
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <false>
WHOAMI TMP$C1815_ACNT
MY_ROLE RACNT
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_ACNT
MY_ROLE RACNT
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <false>
WHOAMI TMP$C1815_ACNT
ID 1
S acnt
WHOAMI TMP$C1815_PDSK
MY_ROLE RPDSK
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <false>
WHOAMI TMP$C1815_PDSK
MY_ROLE RPDSK
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <false>
WHOAMI TMP$C1815_PDSK
MY_ROLE RPDSK
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_PDSK
ID 2
S pdsk
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
ID 1
S acnt
WHOAMI TMP$C1815_BOSS
ID 2
S pdsk
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
ID 1
S acnt
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
ID 2
S pdsk
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <false>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RBOSS
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RACNT
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
MY_ROLE RBOSS
R_NAME RPDSK
R_OWNER SYSDBA
R_IN_USE <true>
WHOAMI TMP$C1815_BOSS
ID 1
S acnt
"""
expected_stderr_1 = """
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TPDSK
-Effective user is TMP$C1815_BOSS
Statement failed, SQLSTATE = 28000
no permission for SELECT access to TABLE TACNT
-Effective user is TMP$C1815_BOSS
"""
@pytest.mark.version('>=4.0')
def test_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