diff options
author | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
---|---|---|
committer | qrort <qrort@yandex-team.com> | 2022-11-30 23:47:12 +0300 |
commit | 22f8ae0e3f5d68b92aecccdf96c1d841a0334311 (patch) | |
tree | bffa27765faf54126ad44bcafa89fadecb7a73d7 /library/python/tvmauth/src/ut | |
parent | 332b99e2173f0425444abb759eebcb2fafaa9209 (diff) | |
download | ydb-22f8ae0e3f5d68b92aecccdf96c1d841a0334311.tar.gz |
validate canons without yatest_common
Diffstat (limited to 'library/python/tvmauth/src/ut')
-rw-r--r-- | library/python/tvmauth/src/ut/test_client.py | 897 | ||||
-rw-r--r-- | library/python/tvmauth/src/ut/test_common.py | 24 | ||||
-rw-r--r-- | library/python/tvmauth/src/ut/test_service.py | 249 | ||||
-rw-r--r-- | library/python/tvmauth/src/ut/test_user.py | 231 |
4 files changed, 1401 insertions, 0 deletions
diff --git a/library/python/tvmauth/src/ut/test_client.py b/library/python/tvmauth/src/ut/test_client.py new file mode 100644 index 0000000000..3e59d9defe --- /dev/null +++ b/library/python/tvmauth/src/ut/test_client.py @@ -0,0 +1,897 @@ +#!/usr/bin/env python +from __future__ import print_function + +import datetime +import logging +from multiprocessing import Process +import os +import shutil +import socket +import sys +import time + +import mock +import pytest +from six import StringIO +from six.moves import ( + BaseHTTPServer, + socketserver as SocketServer, +) +import tvmauth +import tvmauth.deprecated +from tvmauth.exceptions import ( + BrokenTvmClientSettings, + NonRetriableException, + PermissionDenied, + RetriableException, + TicketParsingException, + TvmException, +) +from tvmauth.mock import ( + MockedTvmClient, + TvmClientPatcher, +) +import tvmauth.unittest as tp2u +import yatest.common as yc +from yatest.common import network + + +SRV_TICKET = ( + "3:serv:CBAQ__________9_IgYIexCUkQY:GioCM49Ob6_f80y6FY0XBVN4hLXuMlFeyMvIMiDuQnZkbkLpRp" + "QOuQo5YjWoBjM0Vf-XqOm8B7xtrvxSYHDD7Q4OatN2l-Iwg7i71lE3scUeD36x47st3nd0OThvtjrFx_D8mw_" + "c0GT5KcniZlqq1SjhLyAk1b_zJsx8viRAhCU" +) +PROD_TICKET = ( + "3:user:CAsQ__________9_Gg4KAgh7EHsg0oXYzAQoAA:N8PvrDNLh-5JywinxJntLeQGDEHBUxfzjuvB8-_B" + "EUv1x9CALU7do8irDlDYVeVVDr4AIpR087YPZVzWPAqmnBuRJS0tJXekmDDvrivLnbRrzY4IUXZ_fImB0fJhTy" + "VetKv6RD11bGqnAJeDpIukBwPTbJc_EMvKDt8V490CJFw" +) +TEST_TICKET = ( + "3:user:CA0Q__________9_Gg4KAgh7EHsg0oXYzAQoAQ:FSADps3wNGm92Vyb1E9IVq5M6ZygdGdt1vafWWEh" + "fDDeCLoVA-sJesxMl2pGW4OxJ8J1r_MfpG3ZoBk8rLVMHUFrPa6HheTbeXFAWl8quEniauXvKQe4VyrpA1SPgt" + "RoFqi5upSDIJzEAe1YRJjq1EClQ_slMt8R0kA_JjKUX54" +) +PROD_YATEAM_TICKET = ( + "3:user:CAwQ__________9_Gg4KAgh7EHsg0oXYzAQoAg:JBYQYr71TnozlBiJhGVyCKdAhlDtrEda1ofe4mCz" + "0OkxWi4J1EtB3CeYUkxSO4iTSAqJVq8bFdneyS7YCVOt4u69E-SClzRgZ6v7A36l4Z25XNovqC-0o1h-IwFTgy" + "CZfoPJVfkEOmAYXV4YINBca6L2lZ7ux6q0s5Q5_kUnkAk" +) +TEST_YATEAM_TICKET = ( + "3:user:CA4Q__________9_GhIKBAjAxAcQwMQHINKF2MwEKAM:CpRDQBbh5icA3NCuKuSZUIO0gNyWXej1XfI" + "nEiSvhs6wcrDHCeQbxzYOfeq2wM801DkaebSmnDBgoWjC7C9hMj4xpmOF_QhRfhFibXbm0O-7lbczO8zLL080m" + "s59rpaEU3SOKLJ-HaaXrjPCIGSTAIJRvWnck-QXJXPpqmPETr8" +) + +TVM_RESP = '{"19" : { "ticket" : "3:serv:CBAQ__________9_IgYIKhCUkQY:CX"}}'.encode('utf-8') + +log_stream = StringIO() +logger = logging.getLogger('TVM') +handler = logging.StreamHandler(stream=log_stream) +handler.setLevel(logging.DEBUG) +logger.addHandler(handler) + + +def get_log_stream_value(): + return log_stream.getvalue().lstrip('\x00') + + +def test_settings(): + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings(self_tvm_id=0) + + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings(enable_service_ticket_checking=True) + tvmauth.TvmApiClientSettings(enable_service_ticket_checking=True, self_tvm_id=123) + + tvmauth.TvmApiClientSettings(enable_user_ticket_checking=tvmauth.BlackboxEnv.Test) + + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings() + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings(self_secret='asd', dsts={'qwe': 1}) + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings(self_secret='', dsts={'qwe': 1}) + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmApiClientSettings(self_secret='asd', dsts={}) + with pytest.raises(TvmException): + tvmauth.TvmApiClientSettings(self_secret='asd', dsts='kek', self_tvm_id=123) + tvmauth.TvmApiClientSettings(self_secret='asd', dsts={'qwe': 1}, self_tvm_id=123) + + tvmauth.TvmApiClientSettings(enable_user_ticket_checking=tvmauth.BlackboxEnv.Test) + with pytest.raises(PermissionDenied): + tvmauth.TvmApiClientSettings( + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + disk_cache_dir='/', + ) + tvmauth.TvmApiClientSettings( + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + disk_cache_dir='./', + ) + + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmClient('kek') + + +def test_full_client(): + path = yc.source_path() + '/library/cpp/tvmauth/client/ut/files/' + shutil.copyfile(path + 'public_keys', './public_keys') + shutil.copyfile(path + 'service_tickets', './service_tickets') + + c = None + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + enable_service_ticket_checking=True, + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + self_secret='qwerty', + dsts={'dest': 19}, + disk_cache_dir='./', + ) + c = tvmauth.TvmClient(s) + time.sleep(1) + + exp = "File './service_tickets' was successfully read\n" + exp += "Got 1 service ticket(s) from disk\n" + exp += "Cache was updated with 1 service ticket(s): 2050-01-01T00:00:00.000000Z\n" + exp += "File './public_keys' was successfully read\n" + exp += "Cache was updated with public keys: 2050-01-01T00:00:00.000000Z\n" + exp += "File './retry_settings' does not exist\n" + exp += "Thread-worker started\n" + assert exp == get_log_stream_value() + + st = c.status + assert st == tvmauth.TvmClientStatus.Ok + + assert '3:serv:CBAQ__________9_IgYIKhCUkQY:CX' == c.get_service_ticket_for('dest') + assert '3:serv:CBAQ__________9_IgYIKhCUkQY:CX' == c.get_service_ticket_for(alias='dest') + assert '3:serv:CBAQ__________9_IgYIKhCUkQY:CX' == c.get_service_ticket_for(tvm_id=19) + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for('dest2') + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for(tvm_id=20) + with pytest.raises(TvmException): + c.get_service_ticket_for() + + assert c.check_service_ticket(SRV_TICKET) + with pytest.raises(TicketParsingException): + c.check_service_ticket(PROD_TICKET) + with pytest.raises(TicketParsingException): + c.check_service_ticket(TEST_TICKET) + + assert c.check_user_ticket(TEST_TICKET) + with pytest.raises(TicketParsingException): + c.check_user_ticket(PROD_TICKET) + with pytest.raises(TicketParsingException): + c.check_user_ticket(SRV_TICKET) + + with pytest.raises(TicketParsingException): + assert c.check_user_ticket(TEST_TICKET, overrided_bb_env=tvmauth.BlackboxEnv.Prod) + c.check_user_ticket(PROD_TICKET, overrided_bb_env=tvmauth.BlackboxEnv.Prod) + + except Exception: + print(get_log_stream_value()) + raise + finally: + print('==test_full_client: 1') + if c is not None: + c.stop() + print('==test_full_client: 2') + + +def test_client_with_roles(): + os.environ['TZ'] = 'Europe/Moscow' + time.tzset() + + path = yc.source_path() + '/library/cpp/tvmauth/client/ut/files/' + shutil.copyfile(path + 'service_tickets', './service_tickets') + shutil.copyfile(path + 'roles', './roles') + + c = None + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + self_secret='qwerty', + dsts={'dest': 19}, + disk_cache_dir='./', + tirole_host='localhost', + tirole_port=1, + tirole_tvmid=19, + fetch_roles_for_idm_system_slug='femida', + ) + c = tvmauth.TvmClient(s) + time.sleep(1) + + exp = "File './service_tickets' was successfully read\n" + exp += "Got 1 service ticket(s) from disk\n" + exp += "Cache was updated with 1 service ticket(s): 2050-01-01T00:00:00.000000Z\n" + exp += "File './retry_settings' does not exist\n" + exp += "File './roles' was successfully read\n" + exp += "Succeed to read roles with revision 100501 from ./roles\n" + exp += "Thread-worker started\n" + assert exp == get_log_stream_value() + + st = c.status + assert st == tvmauth.TvmClientStatus.Ok + + roles = c.get_roles() + applied = roles.meta['applied'] + assert roles.meta == { + 'applied': applied, + 'born_time': datetime.datetime(1970, 1, 1, 3, 0, 42), + 'revision': '100501', + } + + assert roles.get_service_roles(tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501)) == { + "role#1": [{"attr#1": "val#1"}], + "role#2": [{"attr#1": "val#2"}], + } + + assert roles.get_service_roles(tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100502)) == {} + + assert roles.get_user_roles( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005001, env=tvmauth.BlackboxEnv.ProdYateam), + ) == { + "role#3": [{"attr#3": "val#3"}], + "role#4": [{"attr#3": "val#4"}], + "role#5": [{"attr#3": "val#4", "attr#5": "val#5"}], + } + + assert ( + roles.get_user_roles( + tp2u.create_user_ticket_for_unittest( + tvmauth.TicketStatus.Ok, 10005002, env=tvmauth.BlackboxEnv.ProdYateam + ), + ) + == {} + ) + + with pytest.raises(AttributeError): + roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#1', + {"attr#1": 42}, + ) + + assert roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#1', + ) + assert not roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100502), + 'role#1', + ) + assert not roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#42', + ) + + assert roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#1', + {"attr#1": "val#1"}, + ) + assert roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#2', + {"attr#1": "val#2"}, + ) + assert not roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#1', + {"attr#1": "val#2"}, + ) + assert not roles.check_service_role( + tp2u.create_service_ticket_for_unittest(tvmauth.TicketStatus.Ok, 100501), + 'role#2', + {"attr#1": "val#1"}, + ) + + assert roles.check_user_role( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005001, env=tvmauth.BlackboxEnv.ProdYateam), + 'role#3', + ) + assert roles.check_user_role( + tp2u.create_user_ticket_for_unittest( + tvmauth.TicketStatus.Ok, + 10005000, + uids=[10005000, 10005001, 10005002], + env=tvmauth.BlackboxEnv.ProdYateam, + ), + 'role#3', + 10005001, + ) + assert not roles.check_user_role( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005002, env=tvmauth.BlackboxEnv.ProdYateam), + 'role#1', + ) + assert not roles.check_user_role( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005001, env=tvmauth.BlackboxEnv.ProdYateam), + 'role#42', + ) + assert not roles.check_user_role( + tp2u.create_user_ticket_for_unittest( + tvmauth.TicketStatus.Ok, + 10005000, + uids=[10005000, 10005001, 10005002], + env=tvmauth.BlackboxEnv.ProdYateam, + ), + 'role#3', + 10005002, + ) + + assert roles.check_user_role( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005001, env=tvmauth.BlackboxEnv.ProdYateam), + 'role#3', + exact_entity={"attr#3": "val#3"}, + ) + assert not roles.check_user_role( + tp2u.create_user_ticket_for_unittest(tvmauth.TicketStatus.Ok, 10005001, env=tvmauth.BlackboxEnv.ProdYateam), + 'role#3', + exact_entity={"attr#3": "val#4"}, + ) + except Exception: + print(get_log_stream_value()) + raise + finally: + if c is not None: + c.stop() + + +def test_getting_client_without_aliases(): + path = yc.source_path() + '/library/cpp/tvmauth/client/ut/files/' + shutil.copyfile(path + 'public_keys', './public_keys') + shutil.copyfile(path + 'service_tickets', './service_tickets') + + c = None + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + enable_service_ticket_checking=True, + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + self_secret='qwerty', + dsts=[19], + disk_cache_dir='./', + ) + + c = tvmauth.TvmClient(s) + time.sleep(1) + + exp = "File './service_tickets' was successfully read\n" + exp += "Got 1 service ticket(s) from disk\n" + exp += "Cache was updated with 1 service ticket(s): 2050-01-01T00:00:00.000000Z\n" + exp += "File './public_keys' was successfully read\n" + exp += "Cache was updated with public keys: 2050-01-01T00:00:00.000000Z\n" + exp += "File './retry_settings' does not exist\n" + exp += "Thread-worker started\n" + assert exp == get_log_stream_value() + + st = c.status + assert st == tvmauth.TvmClientStatus.Ok + + assert '3:serv:CBAQ__________9_IgYIKhCUkQY:CX' == c.get_service_ticket_for(tvm_id=19) + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for(tvm_id=20) + + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for('dest') + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for(alias='dest') + with pytest.raises(BrokenTvmClientSettings): + c.get_service_ticket_for('dest2') + + except Exception: + print(get_log_stream_value()) + raise + finally: + print('==test_getting_client_without_aliases: 1') + if c is not None: + c.stop() + print('==test_getting_client_without_aliases: 2') + + +def test_checking_client(): + path = yc.source_path() + '/library/cpp/tvmauth/client/ut/files/' + shutil.copyfile(path + 'public_keys', './public_keys') + + c = None + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + disk_cache_dir='./', + ) + c = tvmauth.TvmClient(s) + assert c.status == tvmauth.TvmClientStatus.Ok + + with pytest.raises(BrokenTvmClientSettings): + c.check_service_ticket(SRV_TICKET) + assert c.check_user_ticket(TEST_TICKET) + + print('==test_checking_client: 1') + c.stop() + print('==test_checking_client: 2') + + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + enable_service_ticket_checking=True, + disk_cache_dir='./', + ) + c = tvmauth.TvmClient(s) + assert c.status == tvmauth.TvmClientStatus.Ok + + with pytest.raises(BrokenTvmClientSettings): + c.check_user_ticket(TEST_TICKET) + assert c.check_service_ticket(SRV_TICKET) + + print('==test_checking_client: 3') + c.stop() + print('==test_checking_client: 4') + except Exception: + print(get_log_stream_value()) + raise + finally: + print('==test_checking_client: 5') + if c is not None: + c.stop() + print('==test_checking_client: 6') + + +class myHTTPServer(SocketServer.ForkingMixIn, BaseHTTPServer.HTTPServer): + address_family = socket.AF_INET6 + pass + + +class myHandler(BaseHTTPServer.BaseHTTPRequestHandler): + def log_message(self, format, *args): + sys.stdout.write("%s - - [%s] %s\n" % (self.address_string(), self.log_date_time_string(), format % args)) + + +def test_user_bad_api(): + myHandler.log_message + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), myHandler) + thread = Process(target=server.serve_forever) + thread.start() + + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + enable_user_ticket_checking=tvmauth.BlackboxEnv.Test, + localhost_port=port, + ) + + with pytest.raises(RetriableException): + tvmauth.TvmClient(s) + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + + +def test_service_bad_api(): + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), myHandler) + thread = Process(target=server.serve_forever) + thread.start() + + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + enable_service_ticket_checking=True, + localhost_port=port, + ) + + with pytest.raises(RetriableException): + tvmauth.TvmClient(s) + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + + +def test_tickets_bad_api(): + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), myHandler) + thread = Process(target=server.serve_forever) + thread.start() + + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + self_secret='qwerty', + dsts={'dest': 19}, + localhost_port=port, + ) + + with pytest.raises(RetriableException): + tvmauth.TvmClient(s) + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + + +class myGoodHandler(myHandler): + def do_GET(self): + if self.path.startswith("/2/keys"): + self.send_response(200) + self.send_header('Content-type', 'text/plain') + self.send_header('Content-Length', len(tp2u.TVMKNIFE_PUBLIC_KEYS)) + self.end_headers() + self.wfile.write(tp2u.TVMKNIFE_PUBLIC_KEYS.encode('utf-8')) + return + + self.send_error(404, 'Not Found: %s' % self.path) + + def do_POST(self): + if self.path.startswith("/2/ticket"): + + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.send_header('Content-Length', len(TVM_RESP)) + self.end_headers() + self.wfile.write(TVM_RESP) + return + + self.send_error(404, 'Not Found: %s' % self.path) + + +def test_ok_api(): + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), myGoodHandler) + thread = Process(target=server.serve_forever) + thread.start() + + c = None + log_stream.truncate(0) + try: + s = tvmauth.TvmApiClientSettings( + self_tvm_id=100500, + enable_service_ticket_checking=True, + self_secret='qwerty', + dsts={'dest': 19}, + localhost_port=port, + ) + + c = tvmauth.TvmClient(s) + + time.sleep(1) + assert c.status == tvmauth.TvmClientStatus.Ok + + slept = 0.0 + while get_log_stream_value().count('Thread-worker started') != 1 and slept < 10: + slept += 0.1 + time.sleep(0.1) + assert get_log_stream_value().count('Thread-worker started') == 1 + + print('==test_ok_api: 1') + c.stop() + print('==test_ok_api: 2') + + with pytest.raises(NonRetriableException): + c.status + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + if c is not None: + c.stop() + + +AUTH_TOKEN = 'some string' +META = """{ +"bb_env" : "ProdYaTeam", +"tenants" : [ + { + "self": { + "alias" : "me", + "client_id": 100500 + }, + "dsts" : [ + { + "alias" : "bbox", + "client_id": 242 + }, + { + "alias" : "pass_likers", + "client_id": 11 + } + ] + }, + { + "self": { + "alias" : "push-client", + "client_id": 100501 + }, + "dsts" : [ + { + "alias" : "pass_likers", + "client_id": 100502 + } + ] + }, + { + "self": { + "alias" : "something_else", + "client_id": 100503 + }, + "dsts" : [ + ] + } +] +}""".encode( + 'utf-8' +) +TICKETS_ME = """{ + "pass_likers": { + "ticket": "3:serv:CBAQ__________9_IgYIKhCUkQY:CX", + "tvm_id": 11 + }, + "bbox": { + "ticket": "3:serv:CBAQ__________9_IgcIlJEGEPIB:N7luw0_rVmBosTTI130jwDbQd0-cMmqJeEl0ma4ZlIo_mHXjBzpOuMQ3A9YagbmOBOt8TZ_gzGvVSegWZkEeB24gM22acw0w-RcHaQKrzSOA5Zq8WLNIC8QUa4_WGTlAsb7R7eC4KTAGgouIquNAgMBdTuGOuZHnMLvZyLnOMKc", + "tvm_id": 242 + } +}""".encode( # noqa + 'utf-8' +) +BIRTH_TIME = 14380887840 + + +class tvmtoolGoodHandler(myHandler): + def do_GET(self): + if self.path.startswith("/tvm/ping"): + self.send_response(200) + self.end_headers() + self.wfile.write("OK".encode('utf-8')) + return + + if self.headers.get('Authorization', '') != AUTH_TOKEN: + self.send_error(401, 'Unauthorized') + return + + if self.path.startswith("/tvm/keys"): + self.send_response(200) + self.send_header('Content-type', 'text/plain') + self.send_header('Content-Length', len(tp2u.TVMKNIFE_PUBLIC_KEYS)) + self.send_header('X-Ya-Tvmtool-Data-Birthtime', BIRTH_TIME) + self.end_headers() + self.wfile.write(tp2u.TVMKNIFE_PUBLIC_KEYS.encode('utf-8')) + return + + if self.path.startswith("/tvm/tickets"): + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.send_header('Content-Length', len(TICKETS_ME)) + self.send_header('X-Ya-Tvmtool-Data-Birthtime', BIRTH_TIME) + self.end_headers() + self.wfile.write(TICKETS_ME) + return + + if self.path.startswith("/tvm/private_api/__meta__"): + self.send_response(200) + self.send_header('Content-type', 'application/json') + self.send_header('Content-Length', len(META)) + self.end_headers() + self.wfile.write(META) + return + + self.send_error(404, 'Not Found: %s' % self.path) + + +def test_bad_tool(): + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), tvmtoolGoodHandler) + thread = Process(target=server.serve_forever) + thread.start() + + log_stream.truncate(0) + try: + s = tvmauth.TvmToolClientSettings( + self_alias='no one', + auth_token=AUTH_TOKEN, + port=port, + ) + + print("=====test_bad_tool 01") + with pytest.raises(NonRetriableException): + tvmauth.TvmClient(s) + print("=====test_bad_tool 02") + + exp = "Meta info fetched from localhost:%d\n" % port + assert get_log_stream_value() == exp + log_stream.truncate(0) + + s = tvmauth.TvmToolClientSettings( + self_alias='me', + auth_token=AUTH_TOKEN, + port=0, + ) + + with pytest.raises(NonRetriableException): + tvmauth.TvmClient(s) + + s = tvmauth.TvmToolClientSettings( + self_alias='me', + auth_token=AUTH_TOKEN, + hostname='::1', + port=port, + override_bb_env=tvmauth.BlackboxEnv.Stress, + ) + + assert get_log_stream_value() == '' + + with pytest.raises(BrokenTvmClientSettings): + tvmauth.TvmClient(s) + + exp = "Meta info fetched from ::1:%d\n" % port + exp += "Meta: self_tvm_id=100500, bb_env=ProdYateam, idm_slug=<NULL>, dsts=[(pass_likers:11)(bbox:242)]\n" + assert get_log_stream_value() == exp + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + + +def test_ok_tool(): + pm = network.PortManager() + port = pm.get_tcp_port(8080) + server = myHTTPServer(('', port), tvmtoolGoodHandler) + thread = Process(target=server.serve_forever) + thread.start() + + log_stream.truncate(0) + c = None + try: + s = tvmauth.TvmToolClientSettings( + self_alias='me', + auth_token=AUTH_TOKEN, + port=port, + ) + + c = tvmauth.TvmClient(s) + + assert c.check_service_ticket(SRV_TICKET) + assert c.check_user_ticket(PROD_YATEAM_TICKET) + with pytest.raises(TvmException): + c.check_user_ticket(TEST_YATEAM_TICKET) + + assert c.status == tvmauth.TvmClientStatus.Ok + assert c.status.code == tvmauth.TvmClientStatus.Ok + assert c.status.last_error == 'OK' + + assert ( + '3:serv:CBAQ__________9_IgcIlJEGEPIB:N7luw0_rVmBosTTI130jwDbQd0-cMmqJeEl0ma4ZlIo_mHXjBzpOuMQ3A9YagbmOBOt8TZ_gzGvVSegWZkEeB24gM22acw0w-RcHaQKrzSOA5Zq8WLNIC8QUa4_WGTlAsb7R7eC4KTAGgouIquNAgMBdTuGOuZHnMLvZyLnOMKc' # noqa + == c.get_service_ticket_for('bbox') + ) + assert '3:serv:CBAQ__________9_IgYIKhCUkQY:CX' == c.get_service_ticket_for(tvm_id=11) + + c.stop() + c.stop() + + exp = "Meta info fetched from localhost:%d\n" % port + exp += "Meta: self_tvm_id=100500, bb_env=ProdYateam, idm_slug=<NULL>, dsts=[(pass_likers:11)(bbox:242)]\n" + exp += "Tickets fetched from tvmtool: 2425-09-17T11:04:00.000000Z\n" + exp += "Public keys fetched from tvmtool: 2425-09-17T11:04:00.000000Z\n" + exp += "Thread-worker started\n" + exp += "Thread-worker stopped\n" + assert get_log_stream_value() == exp + + s = tvmauth.TvmToolClientSettings( + self_alias='me', + auth_token=AUTH_TOKEN, + port=port, + override_bb_env=tvmauth.BlackboxEnv.Prod, + ) + + c = tvmauth.TvmClient(s) + + assert c.check_service_ticket(SRV_TICKET) + assert c.check_user_ticket(PROD_TICKET) + with pytest.raises(TvmException): + c.check_user_ticket(TEST_TICKET) + + c.stop() + except Exception: + print(get_log_stream_value()) + raise + finally: + thread.terminate() + print('==test_ok_tool: 1') + if c is not None: + c.stop() + print('==test_ok_tool: 2') + + +def test_fake_mock(): + fake_tvm_client = mock.Mock() + with TvmClientPatcher(fake_tvm_client): + fake_tvm_client.get_service_ticket_for.return_value = 'ololo' + assert 'ololo' == tvmauth.TvmClient().get_service_ticket_for() + fake_tvm_client.check_service_ticket.return_value = tvmauth.deprecated.ServiceContext( + 100500, 'qwerty', tp2u.TVMKNIFE_PUBLIC_KEYS + ).check(SRV_TICKET) + assert 123 == tvmauth.TvmClient().check_service_ticket('').src + + with TvmClientPatcher(MockedTvmClient()) as p: + p.get_mocked_tvm_client().check_service_ticket = mock.Mock( + side_effect=TicketParsingException("Unsupported version", tvmauth.TicketStatus.UnsupportedVersion, "2:err"), + ) + + c = tvmauth.TvmClient() + assert tvmauth.TvmClientStatus.Ok == c.status + with pytest.raises(TicketParsingException): + c.check_service_ticket(SRV_TICKET) + + m = MockedTvmClient() + m.get_service_ticket_for = mock.Mock( + side_effect=['SERVICE_TICKET_FOR_MY_FIRST_CALL', 'SERVICE_TICKET_FOR_MY_SECOND_CALL'], + ) + with TvmClientPatcher(m): + c = tvmauth.TvmClient() + assert tvmauth.TvmClientStatus.Ok == c.status + assert 'SERVICE_TICKET_FOR_MY_FIRST_CALL' == c.get_service_ticket_for() + assert 'SERVICE_TICKET_FOR_MY_SECOND_CALL' == c.get_service_ticket_for() + + +def test_default_mock(): + with TvmClientPatcher(): + c = tvmauth.TvmClient() + assert tvmauth.TvmClientStatus.Ok == c.status + assert 123 == c.check_service_ticket(SRV_TICKET).src + assert 123 == c.check_user_ticket(TEST_TICKET).default_uid + assert 'Some service ticket' == c.get_service_ticket_for("foo") + + c.stop() + with pytest.raises(NonRetriableException): + c.status + with pytest.raises(NonRetriableException): + c.check_service_ticket(SRV_TICKET) + with pytest.raises(NonRetriableException): + c.check_user_ticket(TEST_TICKET) + with pytest.raises(NonRetriableException): + c.get_service_ticket_for("foo") + + +def test_mock(): + with TvmClientPatcher(MockedTvmClient(self_tvm_id=100501)): + c = tvmauth.TvmClient() + assert tvmauth.TvmClientStatus.Ok == c.status + with pytest.raises(TicketParsingException): + c.check_service_ticket(SRV_TICKET) + assert 123 == c.check_user_ticket(TEST_TICKET).default_uid + assert 'Some service ticket' == c.get_service_ticket_for("foo") + + +def test_client_status(): + assert tvmauth.TvmClientStatus.Ok == tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek") + assert tvmauth.TvmClientStatus.Ok == tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek").code + assert "kek" == tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek").last_error + assert tvmauth.TvmClientStatus.Ok != tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Warn, "kek") + + assert tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Warn, "kek") != tvmauth.TvmClientStatusExt( + tvmauth.TvmClientStatus.Ok, "kek" + ) + assert tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek1") != tvmauth.TvmClientStatusExt( + tvmauth.TvmClientStatus.Ok, "kek2" + ) + assert tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek") == tvmauth.TvmClientStatusExt( + tvmauth.TvmClientStatus.Ok, "kek" + ) + + with pytest.raises(TypeError): + tvmauth.TvmClientStatusExt(tvmauth.TvmClientStatus.Ok, "kek") == 42 diff --git a/library/python/tvmauth/src/ut/test_common.py b/library/python/tvmauth/src/ut/test_common.py new file mode 100644 index 0000000000..cad40f4532 --- /dev/null +++ b/library/python/tvmauth/src/ut/test_common.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +from __future__ import print_function + +import tvmauth +from tvmauth import BlackboxTvmId +from tvmauth.exceptions import TicketParsingException + + +def test_version(): + assert tvmauth.__version__[:-5] == 'py_' + + +def test_blackbox_tvm_id(): + assert BlackboxTvmId.Prod.value == '222' + assert BlackboxTvmId.Test.value == '224' + assert BlackboxTvmId.ProdYateam.value == '223' + assert BlackboxTvmId.TestYateam.value == '225' + assert BlackboxTvmId.Stress.value == '226' + assert BlackboxTvmId.Mimino.value == '239' + + +def test_exceptions(): + e = TicketParsingException('aaa', 'bbb', 'ccc') + assert str(e) == 'aaa: ccc' diff --git a/library/python/tvmauth/src/ut/test_service.py b/library/python/tvmauth/src/ut/test_service.py new file mode 100644 index 0000000000..eed7322178 --- /dev/null +++ b/library/python/tvmauth/src/ut/test_service.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function + +import pytest +import six +from tvmauth import ( + CheckedServiceTicket, + TicketStatus, +) +from tvmauth.deprecated import ServiceContext +from tvmauth.exceptions import ( + ContextException, + EmptyTvmKeysException, + MalformedTvmKeysException, + MalformedTvmSecretException, + TicketParsingException, +) +import tvmauth.unittest as tau +import tvmauth.utils + + +EMPTY_TVM_KEYS = ( + '1:CpgCCpMCCAEQABqIAjCCAQQCggEAcLEXeH67FQESFUn4_7wnX7wN0PUrBoUsm3QQ4W5vC-qz6sXaEjSwnTV8w1o-z6X9KPL' + 'lhzMQvuS38NCNfK4uvJ4Zvfp3YsXJ25-rYtbnrYJHNvHohD-kPCCw_yZpMp21JdWigzQGuV7CtrxUhF-NNrsnUaJrE5-OpEWN' + 't4X6nCItKIYeVcSK6XJUbEWbrNCRbvkSc4ak2ymFeMuHYJVjxh4eQbk7_ZPzodP0WvF6eUYrYeb42imVEOR8ofVLQWE5DVnb1' + 'z_TqZm4i1XkS7jMwZuBxBRw8DGdYei0lT_sAf7KST2jC0590NySB3vsBgWEVs1OdUUWA6r-Dvx9dsOQtSCVkQYQAAqZAgqUAg' + 'gCEAAaiQIwggEFAoIBAQDhEBM5-6YsPWfogKtbluJoCX1WV2KdzOaQ0-OlRbBzeCzw-eQKu12c8WakHBbeCMd1I1TU64SDkDo' + 'rWjXGIa_2xT6N3zzNAE50roTbPCcmeQrps26woTYfYIuqDdoxYKZNr0lvNLLW47vBr7EKqo1S4KSj7aXK_XYeEvUgIgf3nVIc' + 'Nrio7VTnFmGGVQCepaL1Hi1gN4yIXjVZ06PBPZ-DxSRu6xOGbFrfKMJeMPs7KOyE-26Q3xOXdTIa1X-zYIucTd_bxUCL4BVbw' + 'W2AvbbFsaG7ISmVdGu0XUTmhXs1KrEfUVLRJhE4Dx99hAZXm1_HlYMUeJcMQ_oHOhV94ENFIJaRBhACCpYBCpEBCAMQABqGAT' + 'CBgwKBgF9t2YJGAJkRRFq6fWhi3m1TFW1UOE0f6ZrfYhHAkpqGlKlh0QVfeTNPpeJhi75xXzCe6oReRUm-0DbqDNhTShC7uGU' + 'v1INYnRBQWH6E-5Fc5XrbDFSuGQw2EYjNfHy_HefHJXxQKAqPvxBDKMKkHgV58WtM6rC8jRi9sdX_ig2NIJeRBhABCpYBCpEB' + 'CAQQABqGATCBgwKBgGB4d6eLGUBv-Q6EPLehC4S-yuE2HB-_rJ7WkeYwyp-xIPolPrd-PQme2utHB4ZgpXHIu_OFksDe_0bPg' + 'ZniNRSVRbl7W49DgS5Ya3kMfrYB4DnF5Fta5tn1oV6EwxYD4JONpFTenOJALPGTPawxXEfon_peiHOSBuQMu3_Vn-l1IJiRBh' + 'ADCpcBCpIBCAUQABqHATCBhAKBgQCTJMKIfmfeZpaI7Q9rnsc29gdWawK7TnpVKRHws1iY7EUlYROeVcMdAwEqVM6f8BVCKLG' + 'gzQ7Gar_uuxfUGKwqEQzoppDraw4F75J464-7D5f6_oJQuGIBHZxqbMONtLjBCXRUhQW5szBLmTQ_R3qaJb5vf-h0APZfkYhq' + '1cTttSCZkQYQBAqWAQqRAQgLEAAahgEwgYMCgYBvvGVH_M2H8qxxv94yaDYUTWbRnJ1uiIYc59KIQlfFimMPhSS7x2tqUa2-h' + 'I55JiII0Xym6GNkwLhyc1xtWChpVuIdSnbvttbrt4weDMLHqTwNOF6qAsVKGKT1Yh8yf-qb-DSmicgvFc74mBQm_6gAY1iQsf' + '33YX8578ClhKBWHSCVkQYQAAqXAQqSAQgMEAAahwEwgYQCgYEAkuzFcd5TJu7lYWYe2hQLFfUWIIj91BvQQLa_Thln4YtGCO8' + 'gG1KJqJm-YlmJOWQG0B7H_5RVhxUxV9KpmFnsDVkzUFKOsCBaYGXc12xPVioawUlAwp5qp3QQtZyx_se97YIoLzuLr46UkLcL' + 'nkIrp-Jo46QzYi_QHq45WTm8MQ0glpEGEAIKlwEKkgEIDRAAGocBMIGEAoGBAIUzbxOknXf_rNt17_ir8JlWvrtnCWsQd1MAn' + 'l5mgArvavDtKeBYHzi5_Ak7DHlLzuA6YE8W175FxLFKpN2hkz-l-M7ltUSd8N1BvJRhK4t6WffWfC_1wPyoAbeSN2Yb1jygtZ' + 'JQ8wGoXHcJQUXiMit3eFNyylwsJFj1gzAR4JCdIJeRBhABCpYBCpEBCA4QABqGATCBgwKBgFMcbEpl9ukVR6AO_R6sMyiU11I' + '8b8MBSUCEC15iKsrVO8v_m47_TRRjWPYtQ9eZ7o1ocNJHaGUU7qqInFqtFaVnIceP6NmCsXhjs3MLrWPS8IRAy4Zf4FKmGOx3' + 'N9O2vemjUygZ9vUiSkULdVrecinRaT8JQ5RG4bUMY04XGIwFIJiRBhADCpYBCpEBCA8QABqGATCBgwKBgGpCkW-NR3li8GlRv' + 'qpq2YZGSIgm_PTyDI2Zwfw69grsBmPpVFW48Vw7xoMN35zcrojEpialB_uQzlpLYOvsMl634CRIuj-n1QE3-gaZTTTE8mg-AR' + '4mcxnTKThPnRQpbuOlYAnriwiasWiQEMbGjq_HmWioYYxFo9USlklQn4-9IJmRBhAE' +) +INVALID_SERVICE_TICKET = ( + '3:serv:CBAQ__________9_czEaCGJiOnNlc3My:WUPx1cTf05fjD1exB35T5j2DCHWH1YaLJon_a4rN-D7JfXHK1Ai4wM4uS' + 'fboHD9xmGQH7extqtlEk1tCTCGm5qbRVloJwWzCZBXo3zKX6i1oBYP_89WcjCNPVe1e8jwGdLsnu6PpxL5cn0xCksiStILH5U' + 'mDR6xfkJdnmMG94o8' +) +MALFORMED_TVM_KEYS = ( + '1:CpgCCpMCCAEQABqIAjCCAQQCggEAcLEXeH67FQESFUn4_7wnX7wN0PUrBoUsm3QQ4W5vC-qz6sXaEjSwnTV8w1o-z6X9KPL' + 'lhzMQvuS38NCNfK4uvJ4Zvfp3YsXJ25-rYtbnrYJHNvHohD-kPCCw_yZpMp21JdWigzQGuV7CtrxUhF-NNrsnUaJrE5-OpEWN' + 't4X6nCItKIYeVcSK6XJUbEWbrNCRbvkSc4ak2ymFeMuHYJVjxh4eQbk7_ZPzodP0WvF6eUYrYeb42imVEOR8ofVLQWE5DVnb1' + 'z_TqZm4i1XkS7jMwZuBxBRw8DGdYei0lT_sAf7KST2jC0590NySB3vsBgWEVs1OdUUWA6r-Dvx9dsOQtSCVkQYQAAqZAgqUAg' + 'gCEAAaiQIwggEFAoIBAQDhEBM5-6YsPWfogKtbluJoCX1WV2KdzOaQ0-OlRbBzeCzw-eQKu12c8WakHBbeCMd1I1TU64SDkDo' + 'rWjXGIa_2xT6N3zzNAE50roTbPCcmeQrps26woTYfYIuqDdoxYKZNr0lvNLLW47vBr7EKqo1S4KSj7aXK_XYeEvUgIgf3nVIc' + 'Nrio7VTnFmGGVQCepaL1Hi1gN4yIXjVZ06PBPZ-DxSRu6xOGbFrfKMJeMPs7KOyE-26Q3xOXdTIa1X-zYIucTd_bxUCL4BVbw' + 'W2AvbbFsaG7ISmVdGu0XUTmhXs1KrEfUVLRJhE4Dx99hAZXm1_HlYMUeJcMQ_oHOhV94ENFIJaRBhACCpYBCpEBCAMQABqGAT' + 'CBgwKBgF9t2YJGAJkRRFq6fWhi3m1TFW1UOE0f6ZrfYhHAkpqGlKlh0QVfeTNPpeJhi75xXzCe6oReRUm-0DbqDNhTShC7uGU' + 'v1INYnRBQWH6E-5Fc5XrbDFSuGQw2EYjNfHy_HefHJXxQKAqPvxBDKMKkHgV58WtM6rC8jRi9sdX_ig2NIJeRBhABCpYBCpEB' + 'CAQQABqGATCBgwKBgGB4d6eLGUBv-Q6EPLehC4S-yuE2HB-_rJ7WkeYwyp-xIPolPrd-PQme2utHB4ZgpXHIu_OFksDe_0bPg' + 'ZniNRSVRbl7W49DgS5Ya3kMfrYB4DnF5Fta5tn1oV6EwxYD4JONpFTenOJALPGTPawxXEfon_peiHOSBuQMu3_Vn-l1IJiRBh' + 'ADCpcBCpIBCAUQABqHATCBhAKBgQCTJMKIfmfeZpaI7Q9rnsc29gdWawK7TnpVKRHws1iY7EUlYROeVcMdAwEqVM6f8BVCKLG' + 'gzQ7Gar_uuxfUGKwqEQzoppDraw4F75J464-7D5f6_oJQuGIBHZxqbMONtLjBCXRUhQW5szBLmTQ_R3qaJb5vf-h0APZfkYhq' + '1cTttSCZkQYQBAqWAQqRAQgLEAAahgEwgYMCgYBvvGVH_M2H8qxxv94yaDYUTWbRnJ1uiIYc59KIQlfFimMPhSS7x2tqUa2-h' + 'I55JiII0Xym6GNkwLhyc1xtWChpVuIdSnbvttbrt4weDMLHqTwNOF6qAsVKGKT1Yh8yf-qb-DSmicgvFc74mBQm_6gAY1iQsf' + '33YX8578ClhKBWHSCVkQYQAAqXAQqSAQgMEAAahwEwgYQCgYEAkuzFcd5TJu7lYWYe2hQLFfUWIIj91BvQQLa_Thln4YtGCO8' + 'gG1KJqJm-YlmJOWQG0B7H_5RVhxUxV9KpmFnsDVkzUFKOsCBaYGXc12xPVioawUlAwp5qp3QQtZyx_se97YIoLzuLr46UkLcL' + 'nkIrp-Jo46QzYi_QHq45WTm8MQ0glpEGEAIKlwEKkgEIDRAAGocBMIGEAoGBAIUzbxOknXf_rNt17_ir8JlWvrtnCWsQd1MAn' + 'l5mgArvavDtKeBYHzi5_Ak7DHlLzuA6YE8W175FxLFKpN2hkz-l-M7ltUSd8N1BvJRhK4t6WffWfC_1wPyoAbeSN2Yb1jygtZ' + 'JQ8wGoXHcJQUXiMit3eFNyylwsJFj1gzAR4JCdIJeRBhABCpYBCpEBCA4QABqGATCBgwKBgFMcbEpl9ukVR6AO_R6sMyiU11I' + '8b8MBSUCEC15iKsrVO8v_m47_TRRjWPYtQ9eZ7o1ocNJHaGUU7qqInFqtFaVnIceP6NmCsXhjs3MLrWPS8IRAy4Zf4FKmGOx3' + 'N9O2vemjUygZ9vUiSkULdVrecinRaT8JQ5RG4bUMY04XGIwFIJiRBhADCpYBCpEBCA8QABqGATCBgwKBgGpCkW-NR3li8GlRv' + 'qpq2YZGSIgm_PTyDI2Zwfw69grsBmPpVFW48Vw7xoMN35zcrojEpialB_uQzlpLYOvsMl634CRIuj-n1QE3-gaZTTTE8mg-AR' + '4mcxnTKThPnRQpbuOlYAnriwiasWiQEMbGjq_HmWioYYxFo9USlklQn4-9IJmRBhAEEpUBCpIBCAYQABqHATCBhAKBgQCoZkF' + 'Gm9oLTqjeXZAq6j5S6i7K20V0lNdBBLqfmFBIRuTkYxhs4vUYnWjZrKRAd5bp6_py0csmFmpl_5Yh0b-2pdo_E5PNP7LGRzKy' + 'KSiFddyykKKzVOazH8YYldDAfE8Z5HoS9e48an5JsPg0jr-TPu34DnJq3yv2a6dqiKL9zSCakQYSlQEKkgEIEBAAGocBMIGEA' + 'oGBALhrihbf3EpjDQS2sCQHazoFgN0nBbE9eesnnFTfzQELXb2gnJU9enmV_aDqaHKjgtLIPpCgn40lHrn5k6mvH5OdedyI6c' + 'CzE-N-GFp3nAq0NDJyMe0fhtIRD__CbT0ulcvkeow65ubXWfw6dBC2gR_34rdMe_L_TGRLMWjDULbNIJ' +) +MALFORMED_TVM_SECRET = 'adcvxcv./-+' +OUR_ID = 28 +SECRET = 'GRMJrKnj4fOVnvOqe-WyD1' +SRC_ID = 229 + +UNSUPPORTED_VERSION_SERVICE_TICKET = ( + '2:serv:CBAQ__________9_IhkI5QEQHBoIYmI6c2VzczEaCGJiOnNlc3My:WUPx1cTf05fjD1exB35T5j2DCHWH1YaLJon_a' + '4rN-D7JfXHK1Ai4wM4uSfboHD9xmGQH7extqtlEk1tCTCGm5qbRVloJwWzCZBXo3zKX6i1oBYP_89WcjCNPVe1e8jwGdLsnu6' + 'PpxL5cn0xCksiStILH5UmDR6xfkJdnmMG94o8' +) +VALID_SERVICE_TICKET_1 = ( + '3:serv:CBAQ__________9_IhkI5QEQHBoIYmI6c2VzczEaCGJiOnNlc3My:WUPx1cTf05fjD1exB35T5j2DCHWH1YaLJon_a' + '4rN-D7JfXHK1Ai4wM4uSfboHD9xmGQH7extqtlEk1tCTCGm5qbRVloJwWzCZBXo3zKX6i1oBYP_89WcjCNPVe1e8jwGdLsnu6' + 'PpxL5cn0xCksiStILH5UmDR6xfkJdnmMG94o8' +) +VALID_SERVICE_TICKET_SIGNLESS_1 = '3:serv:CBAQ__________9_IhkI5QEQHBoIYmI6c2VzczEaCGJiOnNlc3My:' +VALID_SERVICE_TICKET_2 = ( + '3:serv:CBAQ__________9_IskICOUBEBwaCGJiOnNlc3MxGgliYjpzZXNzMTAaCmJiOnNlc3MxMDAaCWJiOnNlc3MxMRoJYm' + 'I6c2VzczEyGgliYjpzZXNzMTMaCWJiOnNlc3MxNBoJYmI6c2VzczE1GgliYjpzZXNzMTYaCWJiOnNlc3MxNxoJYmI6c2VzczE' + '4GgliYjpzZXNzMTkaCGJiOnNlc3MyGgliYjpzZXNzMjAaCWJiOnNlc3MyMRoJYmI6c2VzczIyGgliYjpzZXNzMjMaCWJiOnNl' + 'c3MyNBoJYmI6c2VzczI1GgliYjpzZXNzMjYaCWJiOnNlc3MyNxoJYmI6c2VzczI4GgliYjpzZXNzMjkaCGJiOnNlc3MzGgliY' + 'jpzZXNzMzAaCWJiOnNlc3MzMRoJYmI6c2VzczMyGgliYjpzZXNzMzMaCWJiOnNlc3MzNBoJYmI6c2VzczM1GgliYjpzZXNzMz' + 'YaCWJiOnNlc3MzNxoJYmI6c2VzczM4GgliYjpzZXNzMzkaCGJiOnNlc3M0GgliYjpzZXNzNDAaCWJiOnNlc3M0MRoJYmI6c2V' + 'zczQyGgliYjpzZXNzNDMaCWJiOnNlc3M0NBoJYmI6c2VzczQ1GgliYjpzZXNzNDYaCWJiOnNlc3M0NxoJYmI6c2VzczQ4Ggli' + 'YjpzZXNzNDkaCGJiOnNlc3M1GgliYjpzZXNzNTAaCWJiOnNlc3M1MRoJYmI6c2VzczUyGgliYjpzZXNzNTMaCWJiOnNlc3M1N' + 'BoJYmI6c2VzczU1GgliYjpzZXNzNTYaCWJiOnNlc3M1NxoJYmI6c2VzczU4GgliYjpzZXNzNTkaCGJiOnNlc3M2GgliYjpzZX' + 'NzNjAaCWJiOnNlc3M2MRoJYmI6c2VzczYyGgliYjpzZXNzNjMaCWJiOnNlc3M2NBoJYmI6c2VzczY1GgliYjpzZXNzNjYaCWJ' + 'iOnNlc3M2NxoJYmI6c2VzczY4GgliYjpzZXNzNjkaCGJiOnNlc3M3GgliYjpzZXNzNzAaCWJiOnNlc3M3MRoJYmI6c2Vzczcy' + 'GgliYjpzZXNzNzMaCWJiOnNlc3M3NBoJYmI6c2Vzczc1GgliYjpzZXNzNzYaCWJiOnNlc3M3NxoJYmI6c2Vzczc4GgliYjpzZ' + 'XNzNzkaCGJiOnNlc3M4GgliYjpzZXNzODAaCWJiOnNlc3M4MRoJYmI6c2VzczgyGgliYjpzZXNzODMaCWJiOnNlc3M4NBoJYm' + 'I6c2Vzczg1GgliYjpzZXNzODYaCWJiOnNlc3M4NxoJYmI6c2Vzczg4GgliYjpzZXNzODkaCGJiOnNlc3M5GgliYjpzZXNzOTA' + 'aCWJiOnNlc3M5MRoJYmI6c2VzczkyGgliYjpzZXNzOTMaCWJiOnNlc3M5NBoJYmI6c2Vzczk1GgliYjpzZXNzOTYaCWJiOnNl' + 'c3M5NxoJYmI6c2Vzczk4GgliYjpzZXNzOTk:JYmABAVLM6y7_T4n1pRcwBfwDfzMV4JJ3cpbEG617zdGgKRZwL7MalsYn5bq1' + 'F2ibujMrsF9nzZf8l4s_e-Ivjkz_xu4KMzSp-pUh9V7XIF_smj0WHYpv6gOvWNuK8uIvlZTTKwtQX0qZOL9m-MEeZiHoQPKZG' + 'CfJ_qxMUp-J8I' +) +VALID_SERVICE_TICKET_3 = ( + '3:serv:CBAQ__________9_IgUI5QEQHA:Sd6tmA1CNy2Nf7XevC3x7zr2DrGNRmcl-TxUsDtDW2xI3YXyCxBltWeg0-KtDlq' + 'yYuPOP5Jd_-XXNA12KlOPnNzrz3jm-5z8uQl6CjCcrVHUHJ75pGC8r9UOlS8cOgeXQB5dYP-fOWyo5CNadlozx1S2meCIxncb' + 'QRV1kCBi4KU' +) +VALID_SERVICE_TICKET_ISSUER = ( + '3:serv:CBAQ__________9_IgsI5QEQHCDr1MT4Ag:Gu66XJT_nKnIRJjFy1561wFhIqkJItcSTGftLo7Yvi7i5wIdV-QuKT_' + '-IMPpgjxnnGbt1Dy3Ys2TEoeJAb0TdaCYG1uy3vpoLONmTx9AenN5dx1HHf46cypLK5D3OdiTjxvqI9uGmSIKrSdRxU8gprpu' + '5QiBDPZqVCWhM60FVSY' +) + + +def test_context(): + ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + + +def test_context_exceptions(): + with pytest.raises(MalformedTvmSecretException): + ServiceContext(OUR_ID, MALFORMED_TVM_SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + with pytest.raises(MalformedTvmKeysException): + ServiceContext(OUR_ID, SECRET, MALFORMED_TVM_KEYS) + with pytest.raises(EmptyTvmKeysException): + ServiceContext(OUR_ID, SECRET, EMPTY_TVM_KEYS) + + service_context = ServiceContext(OUR_ID, None, tau.TVMKNIFE_PUBLIC_KEYS) + with pytest.raises(MalformedTvmSecretException): + service_context.sign(1490000001, 13) + + service_context = ServiceContext(OUR_ID, SECRET, None) + with pytest.raises(EmptyTvmKeysException): + service_context.check('abcde') + + with pytest.raises(ContextException): + service_context = ServiceContext(OUR_ID, None, None) + + +def test_context_sign(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + assert '6H8RjdP4cCrTpMEd3XArBTrKFMQbgXLHbB2FJgQ-yO0' == service_context.sign('1490000001', '13,19', 'bb:sess1') + assert 'HAes0pEg8wb9M9YmKWPjwxm91mDp-GMTruOb6bzmuRE' == service_context.sign( + 1490000001, [13, 19], ['bb:sess1', 'bb:sess2'] + ) + assert 'JU5tIwr3qS1K4dse2KafQzRXX_TGtlS3jE1inK7QyRM' == service_context.sign(1490000001, 13, []) + assert 'JU5tIwr3qS1K4dse2KafQzRXX_TGtlS3jE1inK7QyRM' == service_context.sign(1490000001, 13) + + +def test_ticket1(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + ticket = service_context.check(VALID_SERVICE_TICKET_1) + assert ticket.src == SRC_ID + assert ( + ticket.debug_info + == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;scope=bb:sess1;scope=bb:sess2;' + ) + assert VALID_SERVICE_TICKET_SIGNLESS_1 == tvmauth.utils.remove_ticket_signature(VALID_SERVICE_TICKET_1) + assert ticket.issuer_uid is None + assert ( + repr(ticket) + == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;scope=bb:sess1;scope=bb:sess2;' + ) + assert ( + str(ticket) + == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;scope=bb:sess1;scope=bb:sess2;' + ) + + +def test_ticket2(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + ticket = service_context.check(VALID_SERVICE_TICKET_2) + assert ( + ticket.debug_info + == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;scope=bb:sess1;scope=bb:sess10;scope=bb:sess100;scope=bb:sess11;scope=bb:sess12;scope=bb:sess13;scope=bb:sess14;scope=bb:sess15;scope=bb:sess16;scope=bb:sess17;scope=bb:sess18;scope=bb:sess19;scope=bb:sess2;scope=bb:sess20;scope=bb:sess21;scope=bb:sess22;scope=bb:sess23;scope=bb:sess24;scope=bb:sess25;scope=bb:sess26;scope=bb:sess27;scope=bb:sess28;scope=bb:sess29;scope=bb:sess3;scope=bb:sess30;scope=bb:sess31;scope=bb:sess32;scope=bb:sess33;scope=bb:sess34;scope=bb:sess35;scope=bb:sess36;scope=bb:sess37;scope=bb:sess38;scope=bb:sess39;scope=bb:sess4;scope=bb:sess40;scope=bb:sess41;scope=bb:sess42;scope=bb:sess43;scope=bb:sess44;scope=bb:sess45;scope=bb:sess46;scope=bb:sess47;scope=bb:sess48;scope=bb:sess49;scope=bb:sess5;scope=bb:sess50;scope=bb:sess51;scope=bb:sess52;scope=bb:sess53;scope=bb:sess54;scope=bb:sess55;scope=bb:sess56;scope=bb:sess57;scope=bb:sess58;scope=bb:sess59;scope=bb:sess6;scope=bb:sess60;scope=bb:sess61;scope=bb:sess62;scope=bb:sess63;scope=bb:sess64;scope=bb:sess65;scope=bb:sess66;scope=bb:sess67;scope=bb:sess68;scope=bb:sess69;scope=bb:sess7;scope=bb:sess70;scope=bb:sess71;scope=bb:sess72;scope=bb:sess73;scope=bb:sess74;scope=bb:sess75;scope=bb:sess76;scope=bb:sess77;scope=bb:sess78;scope=bb:sess79;scope=bb:sess8;scope=bb:sess80;scope=bb:sess81;scope=bb:sess82;scope=bb:sess83;scope=bb:sess84;scope=bb:sess85;scope=bb:sess86;scope=bb:sess87;scope=bb:sess88;scope=bb:sess89;scope=bb:sess9;scope=bb:sess90;scope=bb:sess91;scope=bb:sess92;scope=bb:sess93;scope=bb:sess94;scope=bb:sess95;scope=bb:sess96;scope=bb:sess97;scope=bb:sess98;scope=bb:sess99;' # noqa + ) + assert ticket.issuer_uid is None + + +def test_ticket3(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + ticket = service_context.check(VALID_SERVICE_TICKET_3) + assert ticket.debug_info == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;' + assert ticket.issuer_uid is None + + +def test_ticket_issuer(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + ticket = service_context.check(VALID_SERVICE_TICKET_ISSUER) + assert ( + ticket.debug_info == 'ticket_type=serv;expiration_time=9223372036854775807;src=229;dst=28;issuer_uid=789654123;' + ) + assert 789654123 == ticket.issuer_uid + + +def test_ticket_exceptions(): + service_context = ServiceContext(OUR_ID, SECRET, tau.TVMKNIFE_PUBLIC_KEYS) + with pytest.raises(TicketParsingException) as ex: + service_context.check(INVALID_SERVICE_TICKET) + assert ex.value.status == TicketStatus.Malformed + + with pytest.raises(TicketParsingException) as ex: + service_context.check(UNSUPPORTED_VERSION_SERVICE_TICKET) + assert ex.value.status == TicketStatus.UnsupportedVersion + + +def test_create_ticket_for_tests(): + with pytest.raises(TicketParsingException): + tau.create_service_ticket_for_unittest(TicketStatus.Expired, 42) + s = tau.create_service_ticket_for_unittest(TicketStatus.Ok, 42) + assert s + assert s.src == 42 + assert s.issuer_uid is None + assert s.debug_info == 'ticket_type=serv;src=42;dst=100500;' + + s = tau.create_service_ticket_for_unittest(TicketStatus.Ok, 42, 100501) + assert s + assert s.src == 42 + assert s.issuer_uid == 100501 + assert s.debug_info == 'ticket_type=serv;src=42;dst=100500;issuer_uid=100501;' + + +def test_non_ascii(): + class _Ins(object): + def debug_info(self): + return u'Люблю яблоки' + + u = CheckedServiceTicket(_Ins()) + assert str(u) == 'Люблю яблоки' + if six.PY2: + assert unicode(u) == u'Люблю яблоки' # noqa diff --git a/library/python/tvmauth/src/ut/test_user.py b/library/python/tvmauth/src/ut/test_user.py new file mode 100644 index 0000000000..76371c718b --- /dev/null +++ b/library/python/tvmauth/src/ut/test_user.py @@ -0,0 +1,231 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import print_function + +import pytest +import six +from tvmauth import ( + BlackboxEnv, + CheckedUserTicket, + TicketStatus, +) +from tvmauth.deprecated import UserContext +from tvmauth.exceptions import ( + EmptyTvmKeysException, + MalformedTvmKeysException, + TicketParsingException, +) +import tvmauth.unittest as tau +import tvmauth.utils + + +EMPTY_TVM_KEYS = ( + '1:EpUBCpIBCAYQABqHATCBhAKBgQCoZkFGm9oLTqjeXZAq6j5S6i7K20V0lNdBBLqfmFBIRuTkYxhs4vUYnWjZrKRAd5bp6_p' + 'y0csmFmpl_5Yh0b-2pdo_E5PNP7LGRzKyKSiFddyykKKzVOazH8YYldDAfE8Z5HoS9e48an5JsPg0jr-TPu34DnJq3yv2a6dq' + 'iKL9zSCakQY' +) +EXPIRED_USER_TICKET = ( + '3:user:CA0QABokCgMIyAMKAgh7EMgDGghiYjpzZXNzMRoIYmI6c2VzczIgEigB:D0CmYVwWg91LDYejjeQ2UP8AeiA_mr1q1' + 'CUD_lfJ9zQSEYEOYGDTafg4Um2rwOOvQnsD1JHM4zHyMUJ6Jtp9GAm5pmhbXBBZqaCcJpyxLTEC8a81MhJFCCJRvu_G1FiAgR' + 'gB25gI3HIbkvHFUEqAIC_nANy7NFQnbKk2S-EQPGY' +) +MALFORMED_TVM_KEYS = ( + '1:CpgCCpMCCAEQABqIAjCCAQQCggEAcLEXeH67FQESFUn4_7wnX7wN0PUrBoUsm3QQ4W5vC-qz6sXaEjSwnTV8w1o-z6X9KPL' + 'lhzMQvuS38NCNfK4uvJ4Zvfp3YsXJ25-rYtbnrYJHNvHohD-kPCCw_yZpMp21JdWigzQGuV7CtrxUhF-NNrsnUaJrE5-OpEWN' + 't4X6nCItKIYeVcSK6XJUbEWbrNCRbvkSc4ak2ymFeMuHYJVjxh4eQbk7_ZPzodP0WvF6eUYrYeb42imVEOR8ofVLQWE5DVnb1' + 'z_TqZm4i1XkS7jMwZuBxBRw8DGdYei0lT_sAf7KST2jC0590NySB3vsBgWEVs1OdUUWA6r-Dvx9dsOQtSCVkQYQAAqZAgqUAg' + 'gCEAAaiQIwggEFAoIBAQDhEBM5-6YsPWfogKtbluJoCX1WV2KdzOaQ0-OlRbBzeCzw-eQKu12c8WakHBbeCMd1I1TU64SDkDo' + 'rWjXGIa_2xT6N3zzNAE50roTbPCcmeQrps26woTYfYIuqDdoxYKZNr0lvNLLW47vBr7EKqo1S4KSj7aXK_XYeEvUgIgf3nVIc' + 'Nrio7VTnFmGGVQCepaL1Hi1gN4yIXjVZ06PBPZ-DxSRu6xOGbFrfKMJeMPs7KOyE-26Q3xOXdTIa1X-zYIucTd_bxUCL4BVbw' + 'W2AvbbFsaG7ISmVdGu0XUTmhXs1KrEfUVLRJhE4Dx99hAZXm1_HlYMUeJcMQ_oHOhV94ENFIJaRBhACCpYBCpEBCAMQABqGAT' + 'CBgwKBgF9t2YJGAJkRRFq6fWhi3m1TFW1UOE0f6ZrfYhHAkpqGlKlh0QVfeTNPpeJhi75xXzCe6oReRUm-0DbqDNhTShC7uGU' + 'v1INYnRBQWH6E-5Fc5XrbDFSuGQw2EYjNfHy_HefHJXxQKAqPvxBDKMKkHgV58WtM6rC8jRi9sdX_ig2NIJeRBhABCpYBCpEB' + 'CAQQABqGATCBgwKBgGB4d6eLGUBv-Q6EPLehC4S-yuE2HB-_rJ7WkeYwyp-xIPolPrd-PQme2utHB4ZgpXHIu_OFksDe_0bPg' + 'ZniNRSVRbl7W49DgS5Ya3kMfrYB4DnF5Fta5tn1oV6EwxYD4JONpFTenOJALPGTPawxXEfon_peiHOSBuQMu3_Vn-l1IJiRBh' + 'ADCpcBCpIBCAUQABqHATCBhAKBgQCTJMKIfmfeZpaI7Q9rnsc29gdWawK7TnpVKRHws1iY7EUlYROeVcMdAwEqVM6f8BVCKLG' + 'gzQ7Gar_uuxfUGKwqEQzoppDraw4F75J464-7D5f6_oJQuGIBHZxqbMONtLjBCXRUhQW5szBLmTQ_R3qaJb5vf-h0APZfkYhq' + '1cTttSCZkQYQBAqWAQqRAQgLEAAahgEwgYMCgYBvvGVH_M2H8qxxv94yaDYUTWbRnJ1uiIYc59KIQlfFimMPhSS7x2tqUa2-h' + 'I55JiII0Xym6GNkwLhyc1xtWChpVuIdSnbvttbrt4weDMLHqTwNOF6qAsVKGKT1Yh8yf-qb-DSmicgvFc74mBQm_6gAY1iQsf' + '33YX8578ClhKBWHSCVkQYQAAqXAQqSAQgMEAAahwEwgYQCgYEAkuzFcd5TJu7lYWYe2hQLFfUWIIj91BvQQLa_Thln4YtGCO8' + 'gG1KJqJm-YlmJOWQG0B7H_5RVhxUxV9KpmFnsDVkzUFKOsCBaYGXc12xPVioawUlAwp5qp3QQtZyx_se97YIoLzuLr46UkLcL' + 'nkIrp-Jo46QzYi_QHq45WTm8MQ0glpEGEAIKlwEKkgEIDRAAGocBMIGEAoGBAIUzbxOknXf_rNt17_ir8JlWvrtnCWsQd1MAn' + 'l5mgArvavDtKeBYHzi5_Ak7DHlLzuA6YE8W175FxLFKpN2hkz-l-M7ltUSd8N1BvJRhK4t6WffWfC_1wPyoAbeSN2Yb1jygtZ' + 'JQ8wGoXHcJQUXiMit3eFNyylwsJFj1gzAR4JCdIJeRBhABCpYBCpEBCA4QABqGATCBgwKBgFMcbEpl9ukVR6AO_R6sMyiU11I' + '8b8MBSUCEC15iKsrVO8v_m47_TRRjWPYtQ9eZ7o1ocNJHaGUU7qqInFqtFaVnIceP6NmCsXhjs3MLrWPS8IRAy4Zf4FKmGOx3' + 'N9O2vemjUygZ9vUiSkULdVrecinRaT8JQ5RG4bUMY04XGIwFIJiRBhADCpYBCpEBCA8QABqGATCBgwKBgGpCkW-NR3li8GlRv' + 'qpq2YZGSIgm_PTyDI2Zwfw69grsBmPpVFW48Vw7xoMN35zcrojEpialB_uQzlpLYOvsMl634CRIuj-n1QE3-gaZTTTE8mg-AR' + '4mcxnTKThPnRQpbuOlYAnriwiasWiQEMbGjq_HmWioYYxFo9USlklQn4-9IJmRBhAEEpUBCpIBCAYQABqHATCBhAKBgQCoZkF' + 'Gm9oLTqjeXZAq6j5S6i7K20V0lNdBBLqfmFBIRuTkYxhs4vUYnWjZrKRAd5bp6_py0csmFmpl_5Yh0b-2pdo_E5PNP7LGRzKy' + 'KSiFddyykKKzVOazH8YYldDAfE8Z5HoS9e48an5JsPg0jr-TPu34DnJq3yv2a6dqiKL9zSCakQYSlQEKkgEIEBAAGocBMIGEA' + 'oGBALhrihbf3EpjDQS2sCQHazoFgN0nBbE9eesnnFTfzQELXb2gnJU9enmV_aDqaHKjgtLIPpCgn40lHrn5k6mvH5OdedyI6c' + 'CzE-N-GFp3nAq0NDJyMe0fhtIRD__CbT0ulcvkeow65ubXWfw6dBC2gR_34rdMe_L_TGRLMWjDULbNIJ' +) +MALFORMED_USER_TICKET = ( + '3:user:CA0Q__________9_GiQKAwjIAwoCCHsQyAMaCGJiOnNlc3MxcXn9krYk19LCvlFrhMW-R4q8mKfXJXCd-RBVBgUQzC' + 'OR1Dx2FiOyU-BxUoIsaU0PiwTjbVY5I2onJDilge70Cl5zEPI9pfab2qwklACq_ZBUvD1tzrfNUr88otBGAziHASJWgyVDkhy' + 'Q3p7YbN38qpb0vGQrYNxlk4e2I' +) +SIGN_BROKEN_USER_TICKET = ( + '3:user:CA0Q__________9_GiQKAwjIAwoCCHsQyAMaCGJiOnNlc3MxGghiYjpzZXNzMiASKAE:KJFv5EcXn9krYk19LCvlFr' + 'hMW-R4q8mKfXJXCd-RBVBgUQzCOR1Dx2FiOyU-BxUoIsaU0PiwI2onJDilge70Cl5zEPI9pfab2qwklACq_ZBUvD1tzrfNUr8' + '8otBGAziHASJWgyVDkhyQ3p7YbN38qpb0vGQrYNxlk4e2' +) +UNSUPPORTED_VERSION_USER_TICKET = ( + '2:user:CA0Q__________9_GiQKAwjIAwoCCHsQyAMaCGJiOnNlc3MxGghiYjpzZXNzMiASKAE:KJFv5EcXn9krYk19LCvlFr' + 'hMW-R4q8mKfXJXCd-RBVBgUQzCOR1Dx2FiOyU-BxUoIsaU0PiwTjbVY5I2onJDilge70Cl5zEPI9pfab2qwklACq_ZBUvD1tz' + 'rfNUr88otBGAziHASJWgyVDkhyQ3p7YbN38qpb0vGQrYNxlk4e2I' +) +VALID_SERVICE_TICKET = ( + '3:serv:CBAQ__________9_IhkI5QEQHBoIYmI6c2VzczEaCGJiOnNlc3My:WUPx1cTf05fjD1exB35T5j2DCHWH1YaLJon_a' + '4rN-D7JfXHK1Ai4wM4uSfboHD9xmGQH7extqtlEk1tCTCGm5qbRVloJwWzCZBXo3zKX6i1oBYP_89WcjCNPVe1e8jwGdLsnu6' + 'PpxL5cn0xCksiStILH5UmDR6xfkJdnmMG94o8' +) +VALID_USER_TICKET_1 = ( + '3:user:CA0Q__________9_GiQKAwjIAwoCCHsQyAMaCGJiOnNlc3MxGghiYjpzZXNzMiASKAE:KJFv5EcXn9krYk19LCvlFr' + 'hMW-R4q8mKfXJXCd-RBVBgUQzCOR1Dx2FiOyU-BxUoIsaU0PiwTjbVY5I2onJDilge70Cl5zEPI9pfab2qwklACq_ZBUvD1tz' + 'rfNUr88otBGAziHASJWgyVDkhyQ3p7YbN38qpb0vGQrYNxlk4e2I' +) +VALID_USER_TICKET_SIGNLESS_1 = '3:user:CA0Q__________9_GiQKAwjIAwoCCHsQyAMaCGJiOnNlc3MxGghiYjpzZXNzMiASKAE:' +VALID_USER_TICKET_2 = ( + '3:user:CA0Q__________9_GhAKAwjIAwoCCHsQyAMgEigB:KRibGYTJUA2ns0Fn7VYqeMZ1-GdscB1o9pRzELyr7QJrJsfsE' + '8Y_HoVvB8Npr-oalv6AXOpagSc8HpZjAQz8zKMAVE_tI0tL-9DEsHirpawEbpy7OWV7-k18o1m-RaDaKeTlIB45KHbBul1-9a' + 'eKkortBfbbXtz_Qy9r_mfFPiQ' +) +VALID_USER_TICKET_3 = ( + '3:user:CA0Q__________9_Go8bCgIIAAoCCAEKAggCCgIIAwoCCAQKAggFCgIIBgoCCAcKAggICgIICQoCCAoKAggLCgIIDA' + 'oCCA0KAggOCgIIDwoCCBAKAggRCgIIEgoCCBMKAggUCgIIFQoCCBYKAggXCgIIGAoCCBkKAggaCgIIGwoCCBwKAggdCgIIHgo' + 'CCB8KAgggCgIIIQoCCCIKAggjCgIIJAoCCCUKAggmCgIIJwoCCCgKAggpCgIIKgoCCCsKAggsCgIILQoCCC4KAggvCgIIMAoC' + 'CDEKAggyCgIIMwoCCDQKAgg1CgIINgoCCDcKAgg4CgIIOQoCCDoKAgg7CgIIPAoCCD0KAgg-CgIIPwoCCEAKAghBCgIIQgoCC' + 'EMKAghECgIIRQoCCEYKAghHCgIISAoCCEkKAghKCgIISwoCCEwKAghNCgIITgoCCE8KAghQCgIIUQoCCFIKAghTCgIIVAoCCF' + 'UKAghWCgIIVwoCCFgKAghZCgIIWgoCCFsKAghcCgIIXQoCCF4KAghfCgIIYAoCCGEKAghiCgIIYwoCCGQKAghlCgIIZgoCCGc' + 'KAghoCgIIaQoCCGoKAghrCgIIbAoCCG0KAghuCgIIbwoCCHAKAghxCgIIcgoCCHMKAgh0CgIIdQoCCHYKAgh3CgIIeAoCCHkK' + 'Agh6CgIIewoCCHwKAgh9CgIIfgoCCH8KAwiAAQoDCIEBCgMIggEKAwiDAQoDCIQBCgMIhQEKAwiGAQoDCIcBCgMIiAEKAwiJA' + 'QoDCIoBCgMIiwEKAwiMAQoDCI0BCgMIjgEKAwiPAQoDCJABCgMIkQEKAwiSAQoDCJMBCgMIlAEKAwiVAQoDCJYBCgMIlwEKAw' + 'iYAQoDCJkBCgMImgEKAwibAQoDCJwBCgMInQEKAwieAQoDCJ8BCgMIoAEKAwihAQoDCKIBCgMIowEKAwikAQoDCKUBCgMIpgE' + 'KAwinAQoDCKgBCgMIqQEKAwiqAQoDCKsBCgMIrAEKAwitAQoDCK4BCgMIrwEKAwiwAQoDCLEBCgMIsgEKAwizAQoDCLQBCgMI' + 'tQEKAwi2AQoDCLcBCgMIuAEKAwi5AQoDCLoBCgMIuwEKAwi8AQoDCL0BCgMIvgEKAwi_AQoDCMABCgMIwQEKAwjCAQoDCMMBC' + 'gMIxAEKAwjFAQoDCMYBCgMIxwEKAwjIAQoDCMkBCgMIygEKAwjLAQoDCMwBCgMIzQEKAwjOAQoDCM8BCgMI0AEKAwjRAQoDCN' + 'IBCgMI0wEKAwjUAQoDCNUBCgMI1gEKAwjXAQoDCNgBCgMI2QEKAwjaAQoDCNsBCgMI3AEKAwjdAQoDCN4BCgMI3wEKAwjgAQo' + 'DCOEBCgMI4gEKAwjjAQoDCOQBCgMI5QEKAwjmAQoDCOcBCgMI6AEKAwjpAQoDCOoBCgMI6wEKAwjsAQoDCO0BCgMI7gEKAwjv' + 'AQoDCPABCgMI8QEKAwjyAQoDCPMBCgMI9AEKAwj1AQoDCPYBCgMI9wEKAwj4AQoDCPkBCgMI-gEKAwj7AQoDCPwBCgMI_QEKA' + 'wj-AQoDCP8BCgMIgAIKAwiBAgoDCIICCgMIgwIKAwiEAgoDCIUCCgMIhgIKAwiHAgoDCIgCCgMIiQIKAwiKAgoDCIsCCgMIjA' + 'IKAwiNAgoDCI4CCgMIjwIKAwiQAgoDCJECCgMIkgIKAwiTAgoDCJQCCgMIlQIKAwiWAgoDCJcCCgMImAIKAwiZAgoDCJoCCgM' + 'ImwIKAwicAgoDCJ0CCgMIngIKAwifAgoDCKACCgMIoQIKAwiiAgoDCKMCCgMIpAIKAwilAgoDCKYCCgMIpwIKAwioAgoDCKkC' + 'CgMIqgIKAwirAgoDCKwCCgMIrQIKAwiuAgoDCK8CCgMIsAIKAwixAgoDCLICCgMIswIKAwi0AgoDCLUCCgMItgIKAwi3AgoDC' + 'LgCCgMIuQIKAwi6AgoDCLsCCgMIvAIKAwi9AgoDCL4CCgMIvwIKAwjAAgoDCMECCgMIwgIKAwjDAgoDCMQCCgMIxQIKAwjGAg' + 'oDCMcCCgMIyAIKAwjJAgoDCMoCCgMIywIKAwjMAgoDCM0CCgMIzgIKAwjPAgoDCNACCgMI0QIKAwjSAgoDCNMCCgMI1AIKAwj' + 'VAgoDCNYCCgMI1wIKAwjYAgoDCNkCCgMI2gIKAwjbAgoDCNwCCgMI3QIKAwjeAgoDCN8CCgMI4AIKAwjhAgoDCOICCgMI4wIK' + 'AwjkAgoDCOUCCgMI5gIKAwjnAgoDCOgCCgMI6QIKAwjqAgoDCOsCCgMI7AIKAwjtAgoDCO4CCgMI7wIKAwjwAgoDCPECCgMI8' + 'gIKAwjzAgoDCPQCCgMI9QIKAwj2AgoDCPcCCgMI-AIKAwj5AgoDCPoCCgMI-wIKAwj8AgoDCP0CCgMI_gIKAwj_AgoDCIADCg' + 'MIgQMKAwiCAwoDCIMDCgMIhAMKAwiFAwoDCIYDCgMIhwMKAwiIAwoDCIkDCgMIigMKAwiLAwoDCIwDCgMIjQMKAwiOAwoDCI8' + 'DCgMIkAMKAwiRAwoDCJIDCgMIkwMKAwiUAwoDCJUDCgMIlgMKAwiXAwoDCJgDCgMImQMKAwiaAwoDCJsDCgMInAMKAwidAwoD' + 'CJ4DCgMInwMKAwigAwoDCKEDCgMIogMKAwijAwoDCKQDCgMIpQMKAwimAwoDCKcDCgMIqAMKAwipAwoDCKoDCgMIqwMKAwisA' + 'woDCK0DCgMIrgMKAwivAwoDCLADCgMIsQMKAwiyAwoDCLMDCgMItAMKAwi1AwoDCLYDCgMItwMKAwi4AwoDCLkDCgMIugMKAw' + 'i7AwoDCLwDCgMIvQMKAwi-AwoDCL8DCgMIwAMKAwjBAwoDCMIDCgMIwwMKAwjEAwoDCMUDCgMIxgMKAwjHAwoDCMgDCgMIyQM' + 'KAwjKAwoDCMsDCgMIzAMKAwjNAwoDCM4DCgMIzwMKAwjQAwoDCNEDCgMI0gMKAwjTAwoDCNQDCgMI1QMKAwjWAwoDCNcDCgMI' + '2AMKAwjZAwoDCNoDCgMI2wMKAwjcAwoDCN0DCgMI3gMKAwjfAwoDCOADCgMI4QMKAwjiAwoDCOMDCgMI5AMKAwjlAwoDCOYDC' + 'gMI5wMKAwjoAwoDCOkDCgMI6gMKAwjrAwoDCOwDCgMI7QMKAwjuAwoDCO8DCgMI8AMKAwjxAwoDCPIDCgMI8wMQyAMaCGJiOn' + 'Nlc3MxGgliYjpzZXNzMTAaCmJiOnNlc3MxMDAaCWJiOnNlc3MxMRoJYmI6c2VzczEyGgliYjpzZXNzMTMaCWJiOnNlc3MxNBo' + 'JYmI6c2VzczE1GgliYjpzZXNzMTYaCWJiOnNlc3MxNxoJYmI6c2VzczE4GgliYjpzZXNzMTkaCGJiOnNlc3MyGgliYjpzZXNz' + 'MjAaCWJiOnNlc3MyMRoJYmI6c2VzczIyGgliYjpzZXNzMjMaCWJiOnNlc3MyNBoJYmI6c2VzczI1GgliYjpzZXNzMjYaCWJiO' + 'nNlc3MyNxoJYmI6c2VzczI4GgliYjpzZXNzMjkaCGJiOnNlc3MzGgliYjpzZXNzMzAaCWJiOnNlc3MzMRoJYmI6c2VzczMyGg' + 'liYjpzZXNzMzMaCWJiOnNlc3MzNBoJYmI6c2VzczM1GgliYjpzZXNzMzYaCWJiOnNlc3MzNxoJYmI6c2VzczM4GgliYjpzZXN' + 'zMzkaCGJiOnNlc3M0GgliYjpzZXNzNDAaCWJiOnNlc3M0MRoJYmI6c2VzczQyGgliYjpzZXNzNDMaCWJiOnNlc3M0NBoJYmI6' + 'c2VzczQ1GgliYjpzZXNzNDYaCWJiOnNlc3M0NxoJYmI6c2VzczQ4GgliYjpzZXNzNDkaCGJiOnNlc3M1GgliYjpzZXNzNTAaC' + 'WJiOnNlc3M1MRoJYmI6c2VzczUyGgliYjpzZXNzNTMaCWJiOnNlc3M1NBoJYmI6c2VzczU1GgliYjpzZXNzNTYaCWJiOnNlc3' + 'M1NxoJYmI6c2VzczU4GgliYjpzZXNzNTkaCGJiOnNlc3M2GgliYjpzZXNzNjAaCWJiOnNlc3M2MRoJYmI6c2VzczYyGgliYjp' + 'zZXNzNjMaCWJiOnNlc3M2NBoJYmI6c2VzczY1GgliYjpzZXNzNjYaCWJiOnNlc3M2NxoJYmI6c2VzczY4GgliYjpzZXNzNjka' + 'CGJiOnNlc3M3GgliYjpzZXNzNzAaCWJiOnNlc3M3MRoJYmI6c2VzczcyGgliYjpzZXNzNzMaCWJiOnNlc3M3NBoJYmI6c2Vzc' + 'zc1GgliYjpzZXNzNzYaCWJiOnNlc3M3NxoJYmI6c2Vzczc4GgliYjpzZXNzNzkaCGJiOnNlc3M4GgliYjpzZXNzODAaCWJiOn' + 'Nlc3M4MRoJYmI6c2VzczgyGgliYjpzZXNzODMaCWJiOnNlc3M4NBoJYmI6c2Vzczg1GgliYjpzZXNzODYaCWJiOnNlc3M4Nxo' + 'JYmI6c2Vzczg4GgliYjpzZXNzODkaCGJiOnNlc3M5GgliYjpzZXNzOTAaCWJiOnNlc3M5MRoJYmI6c2VzczkyGgliYjpzZXNz' + 'OTMaCWJiOnNlc3M5NBoJYmI6c2Vzczk1GgliYjpzZXNzOTYaCWJiOnNlc3M5NxoJYmI6c2Vzczk4GgliYjpzZXNzOTkgEigB:' + 'CX8PIOrxJnQqFXl7wAsiHJ_1VGjoI-asNlCXb8SE8jtI2vdh9x6CqbAurSgIlAAEgotVP-nuUR38x_a9YJuXzmG5AvJ458apW' + 'QtODHIDIX6ZaIwMxjS02R7S5LNqXa0gAuU_R6bCWpZdWe2uLMkdpu5KHbDgW08g-uaP_nceDOk' +) + + +def test_context(): + UserContext(BlackboxEnv.Test, tau.TVMKNIFE_PUBLIC_KEYS) + + +def test_context_exceptions(): + with pytest.raises(MalformedTvmKeysException): + UserContext(BlackboxEnv.Test, MALFORMED_TVM_KEYS) + with pytest.raises(EmptyTvmKeysException): + UserContext(BlackboxEnv.Stress, EMPTY_TVM_KEYS) + + +def test_ticket(): + user_context = UserContext(BlackboxEnv.Test, tau.TVMKNIFE_PUBLIC_KEYS) + ticket = user_context.check(VALID_USER_TICKET_1) + assert ticket.scopes == ['bb:sess1', 'bb:sess2'] + assert ticket.has_scope('bb:sess1') + assert ticket.has_scope('bb:sess2') + assert not ticket.has_scope('bb:sess3') + assert ticket.uids == [456, 123] + assert ticket.default_uid == 456 + assert ( + ticket.debug_info + == 'ticket_type=user;expiration_time=9223372036854775807;scope=bb:sess1;scope=bb:sess2;default_uid=456;uid=456;uid=123;env=Test;' + ) + assert VALID_USER_TICKET_SIGNLESS_1 == tvmauth.utils.remove_ticket_signature(VALID_USER_TICKET_1) + assert ( + repr(ticket) + == 'ticket_type=user;expiration_time=9223372036854775807;scope=bb:sess1;scope=bb:sess2;default_uid=456;uid=456;uid=123;env=Test;' + ) + assert ( + str(ticket) + == 'ticket_type=user;expiration_time=9223372036854775807;scope=bb:sess1;scope=bb:sess2;default_uid=456;uid=456;uid=123;env=Test;' + ) + + +def test_ticket_exceptions(): + user_context = UserContext(BlackboxEnv.Test, tau.TVMKNIFE_PUBLIC_KEYS) + with pytest.raises(TicketParsingException) as ex: + user_context.check(SIGN_BROKEN_USER_TICKET) + assert ex.value.status == TicketStatus.SignBroken + assert ( + ex.value.debug_info + == 'ticket_type=user;expiration_time=9223372036854775807;scope=bb:sess1;scope=bb:sess2;default_uid=456;uid=456;uid=123;env=Test;' + ) + + with pytest.raises(TicketParsingException) as ex: + user_context.check(MALFORMED_USER_TICKET) + assert ex.value.status == TicketStatus.Malformed + assert ex.value.debug_info == 'status=malformed;' + + with pytest.raises(TicketParsingException) as ex: + user_context.check(VALID_SERVICE_TICKET) + assert ex.value.status == TicketStatus.InvalidTicketType + assert ex.value.debug_info == 'ticket_type=not-user;' + + user_context = UserContext(BlackboxEnv.Prod, tau.TVMKNIFE_PUBLIC_KEYS) + with pytest.raises(TicketParsingException) as ex: + user_context.check(VALID_USER_TICKET_1) + assert ex.value.status == TicketStatus.InvalidBlackboxEnv + + +def test_create_ticket_for_tests(): + with pytest.raises(TicketParsingException): + tau.create_user_ticket_for_unittest(TicketStatus.Expired, 42, ['ololo', 'abc']) + u = tau.create_user_ticket_for_unittest(TicketStatus.Ok, 42, ['ololo', 'abc'], [23, 56]) + assert u + assert u.default_uid == 42 + assert u.scopes == ['abc', 'ololo'] + assert u.uids == [23, 42, 56] + assert u.debug_info == 'ticket_type=user;scope=abc;scope=ololo;default_uid=42;uid=23;uid=42;uid=56;env=Test;' + + with pytest.raises(Exception): + tau.create_user_ticket_for_unittest(TicketStatus.Ok, 0) + + +def test_non_ascii(): + class _Ins(object): + def debug_info(self): + return u'Люблю яблоки' + + u = CheckedUserTicket(_Ins()) + assert str(u) == 'Люблю яблоки' + if six.PY2: + assert unicode(u) == u'Люблю яблоки' # noqa |