class TestLogoutUsers(BaseUserTest): @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_logout_user(self): self.register_user('user', '123') self.assertIn('token', self.last_result, 'Session token is present') _token = self.last_result['token'] self.api(_token, 'DELETE', self.prefix + '/session', expected_code=http.HTTPStatus.NO_CONTENT) self.api(_token, 'DELETE', self.prefix + '/session', expected_code=http.HTTPStatus.UNAUTHORIZED) self.api(_token, 'GET', self.prefix + '/session', expected_code=http.HTTPStatus.UNAUTHORIZED)
def setUp(self): self.flush_db_at_the_end = True # flush db on the tearDown. Set this to False in test not to flush db import os config.load_from_yaml( current_file_folder + f'/../config/config.{os.getenv("ENVIRONMENT", "local")}.yaml') config.conf['test'] = True from base import store # store engine has to be patched not to use redis and not to change the config option with patch('base.store.Store.engine', store.DictStore()): asyncio_current_loop = self.get_new_ioloop() asyncio_current_loop.run_sync(app.init_orm) _models = config.conf['tortoise']['apps'][ base.config.conf['name']]['models'] _db_url = base.config.get_db_url(test=True) initializer(_models, app_label=base.config.conf['name'], db_url=_db_url, loop=asyncio_current_loop.asyncio_loop) registry.test = True self.prefix = config.conf['prefix'] config.init_logging() config.conf['verbose'] = False self.my_app = app.make_app(debug=True) with open(f'{root_folder}/keys/users.key.pem') as pubkey: store.set('users_service_public_key', pubkey.read()) config.load_private_key(f'{root_folder}/keys/users.key') super().setUp() registry.test_port = self.get_http_port()
class BaseUserTest(test.BaseTest): def setUp(self): self.flush_db_at_the_end = True # flush db on the tearDown. Set this to False in test not to flush db import os config.load_from_yaml( current_file_folder + f'/../config/config.{os.getenv("ENVIRONMENT", "local")}.yaml') config.conf['test'] = True from base import store # store engine has to be patched not to use redis and not to change the config option with patch('base.store.Store.engine', store.DictStore()): asyncio_current_loop = self.get_new_ioloop() asyncio_current_loop.run_sync(app.init_orm) _models = config.conf['tortoise']['apps'][ base.config.conf['name']]['models'] _db_url = base.config.get_db_url(test=True) initializer(_models, app_label=base.config.conf['name'], db_url=_db_url, loop=asyncio_current_loop.asyncio_loop) registry.test = True self.prefix = config.conf['prefix'] config.init_logging() config.conf['verbose'] = False self.my_app = app.make_app(debug=True) with open(f'{root_folder}/keys/users.key.pem') as pubkey: store.set('users_service_public_key', pubkey.read()) config.load_private_key(f'{root_folder}/keys/users.key') super().setUp() registry.test_port = self.get_http_port() # base.route.print_all_routes() def tearDown(self) -> None: _flush_db = not hasattr( self, 'flush_db_at_the_end') or self.flush_db_at_the_end if _flush_db: finalizer() @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def register_user(self, username, password, data=None, user_data=None, role_flags=USER): _data = { 'user': { 'username': username, 'password': password, 'role_flags': role_flags }, 'user_data': { 'first_name': 'User', 'last_name': 'Test', 'email': '*****@*****.**', 'notification_type': EMAIL, 'alarm_type': ALARM1, 'phone': '+33333333333', } } if data: _data['user'].update(data) if user_data: _data['user_data'].update(data) self.api(None, 'POST', f'{self.prefix}/register', body=_data, expected_code=http.status.CREATED, expected_result_contain_keys=['id', 'token']) self.token = self.last_result['token'] @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def add_tenant(self, name='Tenant'): _data = {'tenant': {'name': name}} self.api(self.last_result['token'], 'POST', self.prefix + '/tenants', body=_data, expected_code=http.status.CREATED, expected_result_contain_keys=['id']) self.assertIsNotNone(self.last_result['id']) return self.last_result
class TestUsersScopes(BaseUserTest): @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_get_available_scopes(self): self.register_user('admin', '123', role_flags=ADMIN) _admin_token = self.last_result['token'] _admin_id = self.last_result['id'] self.api(_admin_token, 'GET', f'{self.prefix}/users-scopes', expected_code=http.HTTPStatus.OK, expected_result={ 'scopes': ['OPENCOUNTER', 'OPENLIGHT', 'OPENWASTE', 'OPENWATER'] }) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_add_scopes_to_users_unauthorized(self): self.register_user('user', '123') _data = {'scope': {'NoName': 2}} self.api(self.last_result['token'], 'POST', f'{self.prefix}/users-scopes/1', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_add_scopes_to_users(self, *_): self.register_user('admin', '123', role_flags=ADMIN) _admin_token = self.last_result['token'] _admin_id = self.last_result['id'] self.register_user('user', '123') _user_token = self.last_result['token'] _user_id = self.last_result['id'] _data = {'scopes': {'NoName': base.scope_permissions.READ}} self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_user_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_admin_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_user_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertEqual(base.scope_permissions.READ, self.last_result['scopes']['NoName']) self.api(_admin_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertEqual(base.scope_permissions.READ, self.last_result['scopes']['NoName']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_edit_scopes_for_users(self, *_): self.register_user('admin', '123', role_flags=ADMIN) _admin_token = self.last_result['token'] _admin_id = self.last_result['id'] _data = {'scopes': {'NoName': base.scope_permissions.READ}} self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_admin_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_admin_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertEqual(base.scope_permissions.READ, self.last_result['scopes']['NoName']) _data = {'scopes': {'NoName': base.scope_permissions.ALL}} self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_admin_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_admin_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertEqual(base.scope_permissions.ALL, self.last_result['scopes']['NoName']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_remove_scopes_for_users(self, *_): self.register_user('admin', '123', role_flags=ADMIN) _admin_token = self.last_result['token'] _admin_id = self.last_result['id'] _data = {'scopes': {'NoName': base.scope_permissions.READ}} self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_admin_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_admin_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertEqual(base.scope_permissions.READ, self.last_result['scopes']['NoName']) _data = {'scopes': {}} self.api(_admin_token, 'POST', f'{self.prefix}/users-scopes/{_admin_id}', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_admin_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['scopes']) self.assertIsNone(self.last_result['scopes'])
class TestLoggedUsers(BaseUserTest): @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('base.src.base.token.token2user', token2user) def test_get_user_unauthorized(self): self.api(None, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_get_logged_users_data(self, *_): self.register_user(f'user', '123') self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'first_name', 'last_name' ]) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_edit_user_data(self, *_): self.register_user('user', '123') self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'email', 'first_name', 'last_name', 'display_name' ]) _data = { 'role_flags': SUPERUSER, 'first_name': 'First', 'last_name': 'Last', 'email': '*****@*****.**', 'phone_number': '+22222222222', 'language': 'de', } self.api(self.token, 'PATCH', f'{self.prefix}/me/change-data', body=_data, expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['changes']) self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'email', 'first_name', 'last_name', 'display_name' ]) self.assertEqual('*****@*****.**', self.last_result['email']) self.assertEqual('First', self.last_result['first_name']) self.assertEqual('Last', self.last_result['last_name']) self.assertEqual('First Last', self.last_result['display_name']) self.assertEqual('+22222222222', self.last_result['phone']) self.assertEqual('*****@*****.**', self.last_result['email']) self.assertEqual('de', self.last_result['language']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_edit_user_username(self, *_): self.register_user('user', '123') _user_id = self.last_result['id'] self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'email', 'first_name', 'last_name', 'display_name' ]) _login_data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_login_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) self.api(self.token, 'POST', f'{self.prefix}/me/change-username', body=_login_data, expected_code=http.HTTPStatus.UNAUTHORIZED) _login_data['password'] = '******' self.api(self.token, 'POST', f'{self.prefix}/me/change-username', body=_login_data, expected_code=http.HTTPStatus.NO_CONTENT) self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'email', 'first_name', 'last_name', 'display_name' ]) self.assertEqual('user_new', self.last_result['username']) self.api(None, 'POST', self.prefix + '/session', body=_login_data, expected_code=http.HTTPStatus.CREATED, expected_result_contain_keys=['id', 'token']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_change_user_password(self, *_): self.register_user('user', '123') _user_id = self.last_result['id'] self.api(self.token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'email', 'first_name', 'last_name', 'display_name' ]) _data = { 'password': '******', 'new_password': '******', } self.api(self.token, 'POST', f'{self.prefix}/me/change-password', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED) _data['password'] = '******' self.api(self.token, 'POST', f'{self.prefix}/me/change-password', body=_data, expected_code=http.HTTPStatus.NO_CONTENT) _login_data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_login_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) _login_data['password'] = '******' self.api(None, 'POST', self.prefix + '/session', body=_login_data, expected_code=http.HTTPStatus.CREATED, expected_result_contain_keys=['id', 'token'])
class TestTenants(BaseUserTest): @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('base.src.base.token.token2user', token2user) def test_add_tenant_as_non_authorized_user(self, *_): _data = {'tenant': {'name': 'Tenant'}} self.api(None, 'POST', self.prefix + '/tenants', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) self.register_user('user', '123') self.api(self.last_result['token'], 'POST', self.prefix + '/tenants', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=['message']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_add_tenant(self, *_): self.register_user('user', '123', role_flags=SUPERUSER) _data = {'tenant': {'name': 'Tenant'}} self.api(self.last_result['token'], 'POST', self.prefix + '/tenants', body=_data, expected_code=http.HTTPStatus.CREATED, expected_result_contain_keys=['id']) self.assertIsNotNone(self.last_result['id']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('base.src.base.token.token2user', token2user) def test_get_tenants_unauthorized(self, *_): self.api(None, 'GET', self.prefix + '/tenants', expected_code=http.HTTPStatus.UNAUTHORIZED) self.register_user('user', '123') _token = self.last_result['token'] self.api(_token, 'GET', self.prefix + '/tenants', expected_code=http.HTTPStatus.UNAUTHORIZED) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_get_tenants(self): self.register_user('user', '123', role_flags=SUPERUSER) _token = self.last_result['token'] self.add_tenant() self.api(_token, 'GET', self.prefix + '/tenants', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['tenants']) _tenants = self.last_result['tenants'] self.assertEqual(1, len(_tenants)) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_get_tenant(self): self.register_user('user', '123', role_flags=SUPERUSER) _token = self.last_result['token'] self.add_tenant() _id = self.last_result['id'] self.api(_token, 'GET', f'{self.prefix}/tenants/{_id}', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['id', 'name', 'created']) self.assertEqual('Tenant', self.last_result['name']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_edit_tenant(self, *_): self.register_user('user', '123', role_flags=SUPERUSER) _token = self.last_result['token'] self.add_tenant() _id = self.last_result['id'] _data = {'new_tenant': {'name': 'New Tenant'}} self.api(_token, 'PUT', f'{self.prefix}/tenants/{_id}', body=_data, expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['changes']) self.api(_token, 'GET', f'{self.prefix}/tenants/{_id}', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['id', 'name', 'created']) self.assertEqual('New Tenant', self.last_result['name']) # self.show_last_result() # self.flush_db_at_the_end = False @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_add_user_to_tenant(self, *_): self.register_user('user', '123', role_flags=SUPERUSER) _token = self.last_result['token'] _id_superuser = self.last_result['id'] self.add_tenant() _id = self.last_result['id'] self.register_user('user2', '123') _id_user = self.last_result['id'] _token_user = self.last_result['token'] self.api(_token, 'POST', f'{self.prefix}/tenants/{_id}', body={'user': _id_user}, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_token, 'POST', f'{self.prefix}/tenants/{_id}', body={'user': _id_superuser}, expected_code=http.HTTPStatus.NO_CONTENT) self.api(_token, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['tenant']) self.assertEqual('Tenant', self.last_result['tenant']['name']) self.api(_token_user, 'GET', f'{self.prefix}/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=['tenant']) self.assertEqual('Tenant', self.last_result['tenant']['name'])
class TestLoginUsers(BaseUserTest): @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_login_user(self, *_): self.register_user('user', '123') _data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_data, expected_code=http.HTTPStatus.CREATED, expected_result_contain_keys=['id', 'token']) def test_login_non_existing_user(self): _data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=[ 'id', 'message', 'method', 'uri', 'code' ]) # self.show_last_result() @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_login_user_with_wrong_password(self): self.register_user('user', '123') _data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=[ 'id', 'message', 'method', 'uri', 'code' ]) # self.show_last_result() @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config def test_login_not_active_user(self): _data = {'active': False} self.register_user('user', '123', data=_data) _data = { 'username': '******', 'password': '******', } self.api(None, 'POST', self.prefix + '/session', body=_data, expected_code=http.HTTPStatus.UNAUTHORIZED, expected_result_contain_keys=[ 'id', 'message', 'method', 'uri', 'code' ]) # self.show_last_result() @patch('base.store.Store.engine', store.DictStore() ) # has to be patched not to use redis without the config @patch('api.users_login.UsersLoginHandler.get_profile_image', return_value=None) def test_check_users_session(self, *_): self.register_user('user', '123') self.assertIn('token', self.last_result, 'Session token is present') self.api(self.last_result['token'], 'GET', self.prefix + '/session', expected_code=http.HTTPStatus.OK, expected_result_contain_keys=[ 'id', 'username', 'first_name', 'last_name', 'active' ]) self.register_user('user2', '123') self.assertIn('token', self.last_result, 'Session token is present') self.api( self.last_result['token'], 'GET', self.prefix + '/session', expected_code=http.HTTPStatus.OK, expected_result_subset={ # 'id': 'd5ce260a-5ad3-4026-938d-b56e35703a79', 'username': '******', 'first_name': 'User', 'last_name': 'Test', 'display_name': 'User Test', 'email': '*****@*****.**', 'active': True, 'alarm_type': ALARM1, 'notification_type': EMAIL, 'phone': '+33333333333' })