6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-02-02 10:50:42 +01:00

Added/Updated bugs\core_6143_test.py. Self-security database is used to avoid any problems with global mappings. See notes. Checked on Linux and Windows: 3.0.8.33535 (SS/CS), 4.0.1.2692 (SS/CS)

This commit is contained in:
zotov 2022-09-22 13:47:58 +03:00
parent 2228b6a51d
commit e2c848eea7

View File

@ -2,183 +2,160 @@
""" """
ID: issue-6392 ID: issue-6392
ISSUE: 6392 ISSUE: https://github.com/FirebirdSQL/firebird/issues/6392
TITLE: Error 'Multiple maps found for ...' is raised in not appropriate case TITLE: Error 'Multiple maps found for ...' is raised in not appropriate case
DESCRIPTION: DESCRIPTION:
There was issue about mapping of ROLES: currently mapping can be done only for trusted role. There was issue about mapping of ROLES: currently mapping can be done only for trusted role.
But documentation does not mention about this. One can conclude that mapping should work But documentation does not mention about this. One can conclude that mapping should work
as for trusted role and also for "usual" way (i.e. when used specifies 'ROLE ...' clause). as for trusted role and also for "usual" way (i.e. when used specifies 'ROLE ...' clause).
Discussion about this with Alex was in 23-sep-2019, and his solution not yet known. Discussion about this with Alex was in 23-sep-2019, and his solution not yet known.
For this reason it was decided to comment code that relates tgo ROLE mapping in this test. For this reason it was decided to REMOVE code that relates tgo ROLE mapping in this test.
NOTES:
[3.11.2021] pcisar
This test fails for 4.0, WHO_AM_I = TMP$C6143_FOO instead TMP$C6143_RIO
JIRA: CORE-6143 JIRA: CORE-6143
FBTEST: bugs.core_6143 FBTEST: bugs.core_6143
NOTES:
[03.11.2021] pcisar
This test fails for 4.0, WHO_AM_I = TMP$C6143_FOO instead global_mapped_user
[22.09.2022] pzotov
0. Totally reimplemented. Test uses self-security database by creating its alias that is defined
in the pre-created databases.conf (together with Auth* and UserManager plugins).
This removes any problems that can raise with global mappings because they are created actually
in the temporary FDB file rather than in default security DB.
1. One need to be sure that firebird.conf does NOT contain DatabaseAccess = None.
2. Value of REQUIRED_ALIAS must be EXACTLY the same as alias specified in the pre-created databases.conf
(for LINUX this equality is case-sensitive, even when aliases are compared!)
3. Content of databases.conf must be taken from $QA_ROOT/files/qa-databases.conf (one need to replace it before every test session).
Discussed with pcisar, letters since 30-may-2022 13:48, subject:
"new qa, core_4964_test.py: strange outcome when use... shutil.copy() // comparing to shutil.copy2()"
Checked on Linux and Windows: 3.0.8.33535 (SS/CS), 4.0.1.2692 (SS/CS)
""" """
import os
import re
import locale
import subprocess
from pathlib import Path
import time
import pytest import pytest
from firebird.qa import * from firebird.qa import *
# Name of alias for self-security DB in the QA_root/files/qa-databases.conf.
# This file must be copied manually to each testing FB homw folder, with replacing
# databases.conf there:
#
REQUIRED_ALIAS = 'tmp_core_6143_alias'
tmp_user = user_factory('db', name='tmp$c6143_foo', password='123', plugin='Srp')
db = db_factory() db = db_factory()
act = python_act('db')
user_foo = user_factory('db', name='tmp$c6143_foo', password='123', plugin='Srp') @pytest.mark.version('>=3')
role_boss = role_factory('db', name='tmp$r6143_boss') def test_1(act: Action, tmp_user: User, capsys):
test_script = """ # Scan line-by-line through databases.conf, find line starting with REQUIRED_ALIAS and extract name of file that
-- set echo on; # must be created in the $(dir_sampleDb)/qa/ folder. This name will be used further as target database (tmp_fdb).
set list on; # NOTE: we have to SKIP lines which are commented out, i.e. if they starts with '#':
p_required_alias_ptn = re.compile( '^(?!#)((^|\\s+)' + REQUIRED_ALIAS + ')\\s*=\\s*\\$\\(dir_sampleDb\\)/qa/', re.IGNORECASE )
fname_in_dbconf = None
with open(act.home_dir/'databases.conf', 'r') as f:
for line in f:
if p_required_alias_ptn.search(line):
# If databases.conf contains line like this:
# tmp_6147_alias = $(dir_sampleDb)/qa/tmp_core_6147.fdb
# - then we extract filename: 'tmp_core_6147.fdb' (see below):
fname_in_dbconf = Path(line.split('=')[1].strip()).name
break
# if 'fname_in_dbconf' remains undefined here then propably REQUIRED_ALIAS not equals to specified in the databases.conf!
#
assert fname_in_dbconf
# Full path + filename of database to which we will try to connect:
#
tmp_fdb = Path( act.vars['sample_dir'], 'qa', fname_in_dbconf )
tmp_dba_pswd = 'alterkey'
USER_PLUGIN = 'Srp'
AUTH_PLUGIN = 'Srp'
sql_txt = f"""
set bail on;
set wng off; set wng off;
set list on;
-- set echo on;
create database '{REQUIRED_ALIAS}' user {act.db.user};
create user {act.db.user} password '{tmp_dba_pswd}' using plugin {USER_PLUGIN};
create or alter view v_show_mapping as
select select
a.rdb$map_name m.mon$sec_database as mon_sec_db
,a.rdb$map_using from mon$database m;
,a.rdb$map_plugin
,a.rdb$map_db
,a.rdb$map_from_type
,a.rdb$map_from
,a.rdb$map_to_type
,a.rdb$map_to
from rdb$database d
left join rdb$auth_mapping a on 1=1
where rdb$map_from containing 'tmp$c6143' or rdb$map_from containing 'tmp$r6143'
;
commit; commit;
grant select on v_show_mapping to public;
--create or alter user tmp$c6143_foo password '123' using plugin Srp; create or alter user {tmp_user.name} password '{tmp_user.password}' using plugin {USER_PLUGIN};
--commit; commit;
--revoke all on all from tmp$c6143_foo;
--commit;
--create role tmp$r6143_boss;
--commit;
-- ++++++++++++++++++++++++ T E S T L O C A L M A P P I N G +++++++++++++++++++++++ -- ++++++++++++++++++++++++ T E S T L O C A L M A P P I N G +++++++++++++++++++++++
create or alter mapping local_map_for_user_1 using plugin {AUTH_PLUGIN} from user {tmp_user.name} to user local_mapped_user;
create or alter mapping lmap_foo2bar_a using plugin srp from user tmp$c6143_foo to user tmp$c6143_bar; create or alter mapping local_map_for_user_2 using plugin {AUTH_PLUGIN} from user {tmp_user.name} to user local_mapped_user;
create or alter mapping lmap_foo2bar_b using plugin srp from user tmp$c6143_foo to user tmp$c6143_bar;
create or alter mapping lmap_boss2acnt_a using plugin srp from role tmp$r6143_boss to role tmp$r6143_acnt;
create or alter mapping lmap_boss2acnt_b using plugin srp from role tmp$c6143_boss to role tmp$r6143_acnt;
commit; commit;
grant tmp$r6143_boss to user tmp$c6143_bar; connect 'localhost:{REQUIRED_ALIAS}' user {tmp_user.name} password '{tmp_user.password}';
commit;
connect '$(DSN)' user tmp$c6143_foo password '123' role tmp$r6143_boss;
select select
'Connected OK when local mapping is duplicated.' as msg 'Connected OK when local mapping is duplicated.' as msg
,current_user as who_am_i -- <<< TMP$C6143_BAR must be shown here, *NOT* tmp$c6143_foo ,current_user as who_am_i -- <<< 'local_mapped_user' must be shown here, *NOT* {tmp_user.name}
-- temply disabled, wait for solution by Alex, see letters to him 23.09.2019 12:02:
-- ,current_role as what_my_role -- <<< WHAT ROLE MUST BE SHOWN HERE, *BOSS or *ACNT ???
from rdb$database; from rdb$database;
set count on;
select * from v_show_mapping;
set count on;
commit; commit;
-- for SELF-SECURITY database we have to DROP local mappings
connect '$(DSN)' user sysdba password 'masterkey'; -- otherwise subsequent connect will fail with 08004 (multiple mappings):
commit; connect 'localhost:{REQUIRED_ALIAS}' user {act.db.user} password '{tmp_dba_pswd}';
drop mapping lmap_foo2bar_a; drop mapping local_map_for_user_1;
drop mapping lmap_foo2bar_b; drop mapping local_map_for_user_2;
drop mapping lmap_boss2acnt_a;
drop mapping lmap_boss2acnt_b;
commit; commit;
-- ++++++++++++++++++++++++ T E S T G L O B A L M A P P I N G +++++++++++++++++++++++ -- ++++++++++++++++++++++++ T E S T G L O B A L M A P P I N G +++++++++++++++++++++++
create or alter global mapping global_map_for_user_1 using plugin {AUTH_PLUGIN} from user {tmp_user.name} to user global_mapped_user;
create or alter global mapping gmap_foo2rio_a using plugin srp from user tmp$c6143_foo to user tmp$c6143_rio; create or alter global mapping global_map_for_user_2 using plugin {AUTH_PLUGIN} from user {tmp_user.name} to user global_mapped_user;
create or alter global mapping gmap_foo2rio_b using plugin srp from user tmp$c6143_foo to user tmp$c6143_rio;
create or alter global mapping gmap_boss2mngr_a using plugin srp from role tmp$r6143_boss to role tmp$r6143_mngr;
create or alter global mapping gmap_boss2mngr_b using plugin srp from role tmp$c6143_boss to role tmp$r6143_mngr;
commit; commit;
connect '$(DSN)' user tmp$c6143_foo password '123' role tmp$r6143_boss; connect 'localhost:{REQUIRED_ALIAS}' user {tmp_user.name} password '{tmp_user.password}';
select select
'Connected OK when global mapping is duplicated.' as msg 'Connected OK when global mapping is duplicated.' as msg
,current_user as who_am_i -- <<< TMP$C6143_RIO must be shown here, *NOT* tmp$c6143_foo ,current_user as who_am_i -- <<< 'global_mapped_user' must be shown here, *NOT* {tmp_user.name}
-- temply diabled, wait for solution by Alex, see letters to him 23.09.2019 12:02:
-- ,current_role as what_my_role -- <<< WHAT ROLE MUST BE SHOWN HERE, *BOSS or *MNGR or... NONE ???
from rdb$database; from rdb$database;
commit; commit;
connect '$(DSN)' user sysdba password 'masterkey';
commit;
drop global mapping gmap_foo2rio_a;
drop global mapping gmap_foo2rio_b;
drop global mapping gmap_boss2mngr_a;
drop global mapping gmap_boss2mngr_b;
commit;
""" """
act = isql_act('db', test_script) try:
act.expected_stdout = """
expected_stdout = """ MON_SEC_DB Self
MSG Connected OK when local mapping is duplicated. MSG Connected OK when local mapping is duplicated.
WHO_AM_I TMP$C6143_BAR WHO_AM_I LOCAL_MAPPED_USER
RDB$MAP_NAME LMAP_FOO2BAR_A
RDB$MAP_USING P
RDB$MAP_PLUGIN SRP
RDB$MAP_DB <null>
RDB$MAP_FROM_TYPE USER
RDB$MAP_FROM TMP$C6143_FOO
RDB$MAP_TO_TYPE 0
RDB$MAP_TO TMP$C6143_BAR
RDB$MAP_NAME LMAP_FOO2BAR_B
RDB$MAP_USING P
RDB$MAP_PLUGIN SRP
RDB$MAP_DB <null>
RDB$MAP_FROM_TYPE USER
RDB$MAP_FROM TMP$C6143_FOO
RDB$MAP_TO_TYPE 0
RDB$MAP_TO TMP$C6143_BAR
RDB$MAP_NAME LMAP_BOSS2ACNT_A
RDB$MAP_USING P
RDB$MAP_PLUGIN SRP
RDB$MAP_DB <null>
RDB$MAP_FROM_TYPE ROLE
RDB$MAP_FROM TMP$R6143_BOSS
RDB$MAP_TO_TYPE 1
RDB$MAP_TO TMP$R6143_ACNT
RDB$MAP_NAME LMAP_BOSS2ACNT_B
RDB$MAP_USING P
RDB$MAP_PLUGIN SRP
RDB$MAP_DB <null>
RDB$MAP_FROM_TYPE ROLE
RDB$MAP_FROM TMP$C6143_BOSS
RDB$MAP_TO_TYPE 1
RDB$MAP_TO TMP$R6143_ACNT
Records affected: 4
MSG Connected OK when global mapping is duplicated. MSG Connected OK when global mapping is duplicated.
WHO_AM_I TMP$C6143_RIO WHO_AM_I GLOBAL_MAPPED_USER
Records affected: 1
""" """
act.isql(switches = ['-q'], input = sql_txt, connect_db=False, credentials = False, combine_output = True, io_enc = locale.getpreferredencoding())
@pytest.mark.version('>=3.0.5,<4')
def test_1(act: Action, role_boss: Role, user_foo: User):
act.expected_stdout = expected_stdout
act.execute()
assert act.clean_stdout == act.clean_expected_stdout assert act.clean_stdout == act.clean_expected_stdout
act.reset()
@pytest.mark.skip("FIXME: see notes") finally:
@pytest.mark.version('>=4') if Path.exists(tmp_fdb):
def test_1(act: Action, role_boss: Role, user_foo: User): # Change DB state to full shutdown in order to have ability to drop database file.
act.expected_stdout = expected_stdout # This is needed because when DB is self-security then it will be kept opened for 10s
act.execute() # (as it always occurs for common security.db). Set linger to 0 does not help.
# Attempt to use 'drop database' fails with:
# "SQLSTATE = 40001 / lock time-out on wait transaction / -object ... is in use"
act.gfix(switches=['-shut', 'full', '-force', '0', f'localhost:{REQUIRED_ALIAS}', '-user', act.db.user, '-pas', tmp_dba_pswd], io_enc = locale.getpreferredencoding(), credentials = False, combine_output = True)
tmp_fdb.unlink()
act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout assert act.clean_stdout == act.clean_expected_stdout
act.reset()