6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-23 22:13:05 +01:00
firebird-qa/tests/bugs/test_user_management.py

305 lines
11 KiB
Python

#coding:utf-8
"""
ID: user-management
ISSUE:
TITLE: Incorrect results when left join on subquery with constant column
DESCRIPTION:
NOTE: there is no difference between user who is granted with admin role when it was created and user who has no granted with this but
has system privilege 'USER_MANAGEMENT': both of them can *only* add/edit/drop another users and no other actions.
For example, they can give grants to just created users and can not select for any user-defined tables (until this was explicitly granted).
But if we create user <U01> on SELF-SECURITY database and give to him adminn role ('CREATE USER ... GRANT ADMIN ROLE') then this <U01> will
be able to do such actions: he can grant rights to other users etc.
In contrary to this, if we create user <U02> in such self-security DB but instead grant to him sytem privilege USER_MANAGEMENT then he
will NOT be able to do these actions. Only create/alter/drop users will be avaliable to him.
Test verifies exactly this case: abilities of user created inSELF-SECURITY database with granting to him privilege USER_MANAGEMENT.
We make back-copy of databases.conf and change it by adding alias for new DB which will be self-security and has alias = 'syspriv_usermgr'.
Then we make file-level copy of security.db to database defined by alias 'self_usermgr', do connect and apply SQL script that does all
necessary actions. NOTE that some actions must fail (see comments below, in generated .sql script).
Finally, test restores back copy of databases.conf file.
Checked on 5.0.0.139 (SS/CS), 4.0.1.2568 (SS/CS).
FBTEST: bugs.user_management
"""
import pytest
from firebird.qa import *
db = db_factory()
act = python_act('db', substitutions=[('.*After line \\d+.*', '')])
expected_stdout = """
STDOUT: WHO_AM_I JOHN_SMITH_DBA_HELPER
STDOUT: RDB$ROLE_NAME RDB$ADMIN
STDOUT: RDB$ROLE_IN_USE <false>
STDOUT: RDB$SYSTEM_PRIVILEGES FFFFFFFFFFFFFFFF
STDOUT: MON$SEC_DATABASE Self
STDOUT: WHO_AM_I JOHN_SMITH_DBA_HELPER
STDOUT: RDB$ROLE_NAME R_FOR_GRANT_REVOKE_ANY_DDL_RIGHT
STDOUT: RDB$ROLE_IN_USE <true>
STDOUT: RDB$SYSTEM_PRIVILEGES 0200000000000000
STDOUT: MON$SEC_DATABASE Self
STDOUT: Records affected: 2
STDOUT: SEC$USER_NAME STOCK_BOSS
STDOUT: SEC$FIRST_NAME foo-rio-bar
STDOUT: SEC$ADMIN <false>
STDOUT: SEC$ACTIVE <true>
STDOUT: SEC$USER_NAME STOCK_MNGR
STDOUT: SEC$FIRST_NAME <null>
STDOUT: SEC$ADMIN <false>
STDOUT: SEC$ACTIVE <false>
STDOUT: Records affected: 2
STDOUT: Records affected: 0
STDERR: Statement failed, SQLSTATE = 42000
STDERR: unsuccessful metadata update
STDERR: -GRANT failed
STDERR: -no SELECT privilege with grant option on table/view TEST_SS
STDERR: Statement failed, SQLSTATE = 28000
STDERR: no permission for SELECT access to TABLE TEST_SS
STDERR: -Effective user is JOHN_SMITH_DBA_HELPER
"""
@pytest.mark.skip('FIXME: databases.conf')
@pytest.mark.version('>=4.0.1')
def test_1(act: Action):
pytest.fail("Not IMPLEMENTED")
# test_script_1
#---
# import os
# import sys
# import subprocess
# from subprocess import Popen
# import datetime
# import time
# import shutil
# from fdb import services
# from datetime import datetime as dt
# from datetime import timedelta
#
# os.environ["ISC_USER"] = user_name
# os.environ["ISC_PASSWORD"] = user_password
#
# db_conn.close()
#
# #-----------------------------------
# def showtime():
# global dt
# return ''.join( (dt.now().strftime("%H:%M:%S.%f")[:11],'.') )
#
# #--------------------------------------------
#
# def flush_and_close( file_handle ):
# # https://docs.python.org/2/library/os.html#os.fsync
# # If you're starting with a Python file object f,
# # first do f.flush(), and
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
# global os
#
# file_handle.flush()
# if file_handle.mode not in ('r', 'rb') and file_handle.name != os.devnull:
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
# os.fsync(file_handle.fileno())
# file_handle.close()
#
# #--------------------------------------------
#
# def cleanup( f_names_list ):
# global os
# for i in range(len( f_names_list )):
# if type(f_names_list[i]) == file:
# del_name = f_names_list[i].name
# elif type(f_names_list[i]) == str:
# del_name = f_names_list[i]
# else:
# print('Unrecognized type of element:', f_names_list[i], ' - can not be treated as file.')
# print('type(f_names_list[i])=',type(f_names_list[i]))
# del_name = None
#
# if del_name and os.path.isfile( del_name ):
# os.remove( del_name )
#
# #--------------------------------------------
#
#
# FB_HOME = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
# # Resut: FB_HOME is full path to FB instance home (with trailing slash).
#
# if os.name == 'nt':
# # For Windows we assume that client library is always in FB_HOME dir:
# FB_CLNT=os.path.join(FB_HOME, 'fbclient.dll')
# else:
# # For Linux client library will be searched in 'lib' subdirectory of FB_HOME:
# FB_CLNT=os.path.join(FB_HOME, 'lib', 'libfbclient.so' )
#
#
# dts = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
#
# dbconf_cur = os.path.join(FB_HOME, 'databases.conf')
# dbconf_bak = os.path.join(context['temp_directory'], 'databases_'+dts+'.bak')
#
# shutil.copy2( dbconf_cur, dbconf_bak )
#
# sec_db = context['isc4_path']
# tmp_alias = 'syspriv_usermgr'
#
# ##############################################################
#
# tmp_fdb = os.path.join(context['temp_directory'],'tmp_syspriv_usermgr.fdb')
# alias_data='''
# # Temporary added for performing test functional/syspriv/user_management.fbt
# #
# %(tmp_alias)s = %(tmp_fdb)s {
# RemoteAccess = true
# SecurityDatabase = %(tmp_alias)s
# }
# ''' % locals()
#
# cleanup( (tmp_fdb,) )
# shutil.copy2( sec_db, tmp_fdb )
#
#
# f_dbconf=open( dbconf_cur, 'a')
# f_dbconf.seek(0, 2)
# f_dbconf.write( alias_data )
# flush_and_close( f_dbconf )
#
#
# sql_txt = '''
# set list on;
# set wng off;
# set count on;
# set width mon$user 15;
# set width mon$role 15;
# set width sec$plugin 10;
#
# -- Create record for SYSDBA in self-security database, table sec$users:
# connect 'localhost:%(tmp_alias)s' user %(user_name)s password '%(user_password)s';
#
# -- not helps... ALTER DATABASE SET LINGER TO 0;
#
# create or alter user john_smith_dba_helper password '123';
# commit;
#
# recreate table test_ss(id int);
# commit;
#
# create or alter view v_check as
# select sec$user_name, sec$first_name, sec$admin,sec$active
# from sec$users where sec$user_name in (upper('stock_boss'), upper('stock_mngr'))
# ;
# grant select on v_check to public;
# commit;
#
# set term ^;
# execute block as
# begin
# execute statement 'drop role r_for_user_management';
# when any do begin end
# end^
# set term ;^
# commit;
#
# -- Add/change/delete non-system records in RDB$TYPES
# create role r_for_grant_revoke_any_ddl_right set system privileges to USER_MANAGEMENT;
# commit;
# grant default r_for_grant_revoke_any_ddl_right to user john_smith_dba_helper;
# commit;
#
# connect 'localhost:%(tmp_alias)s' user john_smith_dba_helper password '123';
#
# select current_user as who_am_i,r.rdb$role_name,rdb$role_in_use(r.rdb$role_name),r.rdb$system_privileges,m.mon$sec_database
# from mon$database m cross join rdb$roles r
# ;
# commit;
#
# -- set echo on;
#
# -- Must PASS:
# create or alter user stock_boss password '123';
# alter user stock_boss firstname 'foo-rio-bar' password '456';
# create or alter user stock_mngr password '123';
# alter user stock_mngr inactive;
# commit;
#
# -- Must show 2 records (for users who have been just created):
# select * from v_check;
#
# -- must FAIL!
# grant select on test_ss to stock_mngr;
# commit;
#
# -- must FAIL!
# select * from test_ss;
# commit;
#
# -- Must PASS:
# drop user stock_boss;
# drop user stock_mngr;
# commit;
#
# -- Must show NO records (because users must be successfully dropped):
# select * from v_check;
#
# -- set echo off;
# commit;
# connect 'localhost:%(tmp_alias)s';
# drop user john_smith_dba_helper;
# commit;
# ''' % dict(globals(), **locals())
#
# f_isql_cmd=open( os.path.join(context['temp_directory'],'tmp_syspriv_usermgr.sql'), 'w')
# f_isql_cmd.write(sql_txt)
# flush_and_close( f_isql_cmd )
#
# f_isql_log = open( os.path.splitext(f_isql_cmd.name)[0] + '.log', 'w' )
# f_isql_err = open( os.path.splitext(f_isql_cmd.name)[0] + '.err', 'w' )
# subprocess.call( [ context['isql_path'], '-q', '-i', f_isql_cmd.name], stdout=f_isql_log, stderr=f_isql_err )
# flush_and_close( f_isql_log )
# flush_and_close( f_isql_err )
#
# with open( f_isql_log.name, 'r' ) as f:
# for line in f:
# if line.split():
# print('STDOUT: ' + line)
#
# with open( f_isql_err.name, 'r' ) as f:
# for line in f:
# if line.split():
# print('STDERR: ' + line)
#
#
# f_shutdown_log=open( os.path.join(context['temp_directory'],'tmp_syspriv_usermgr_shutdown.log'), 'w')
# subprocess.call( [context['fbsvcmgr_path'],
# "localhost:service_mgr",
# "user", user_name, "password", user_password,
# "expected_db", tmp_fdb,
# "action_properties", "prp_shutdown_mode", "prp_sm_full", "prp_shutdown_db", "0", "dbname", tmp_fdb,
# ],
# stdout = f_shutdown_log,
# stderr = subprocess.STDOUT
# )
# flush_and_close( f_shutdown_log )
#
# with open( f_shutdown_log.name, 'r' ) as f:
# for line in f:
# if line:
# print("Unexpected STDERR when try to make full shutdown: "+line)
#
# cleanup( (tmp_fdb,) )
# cleanup( (f_isql_err,f_isql_log,f_isql_cmd,f_shutdown_log) )
#
# # Restore original content of databases.conf:
# ##################
# shutil.move( dbconf_bak, dbconf_cur )
#
#---