1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
# -------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for
# license information.
# --------------------------------------------------------------------------
import os
import re
from enum import auto, Enum
from devtools_testutils import AzureTestCase
from azure.communication.identity._shared.utils import parse_connection_str
from azure_devtools.scenario_tests import RecordingProcessor, ReplayableTest
from azure_devtools.scenario_tests.utilities import is_text_payload
class ResponseReplacerProcessor(RecordingProcessor):
def __init__(self, keys=None, replacement="sanitized"):
self._keys = keys if keys else []
self._replacement = replacement
def process_response(self, response):
def sanitize_dict(dictionary):
for key in dictionary:
value = dictionary[key]
if isinstance(value, str):
dictionary[key] = re.sub(
r"("+'|'.join(self._keys)+r")",
self._replacement,
dictionary[key])
elif isinstance(value, dict):
sanitize_dict(value)
sanitize_dict(response)
return response
class BodyReplacerProcessor(RecordingProcessor):
"""Sanitize the sensitive info inside request or response bodies"""
def __init__(self, keys=None, replacement="sanitized"):
self._replacement = replacement
self._keys = keys if keys else []
def process_request(self, request):
if is_text_payload(request) and request.body:
request.body = self._replace_keys(request.body.decode()).encode()
return request
def process_response(self, response):
if is_text_payload(response) and response['body']['string']:
response['body']['string'] = self._replace_keys(response['body']['string'])
return response
def _replace_keys(self, body):
def _replace_recursively(obj):
if isinstance(obj, dict):
for key in obj:
value = obj[key]
if key in self._keys:
obj[key] = self._replacement
elif key == 'iceServers':
_replace_recursively(value[0])
elif key == 'urls':
obj[key][0] = "turn.skype.com"
else:
_replace_recursively(value)
elif isinstance(obj, list):
for i in obj:
_replace_recursively(i)
import json
try:
body = json.loads(body)
_replace_recursively(body)
except (KeyError, ValueError):
return body
return json.dumps(body)
class CommunicationTestResourceType(Enum):
"""Type of ACS resource used for livetests."""
UNSPECIFIED = auto()
DYNAMIC = auto()
STATIC = auto()
class CommunicationTestCase(AzureTestCase):
FILTER_HEADERS = ReplayableTest.FILTER_HEADERS + ['x-azure-ref', 'x-ms-content-sha256', 'location']
def __init__(self, method_name, *args, **kwargs):
super(CommunicationTestCase, self).__init__(method_name, *args, **kwargs)
def setUp(self, resource_type=CommunicationTestResourceType.UNSPECIFIED):
super(CommunicationTestCase, self).setUp()
self.connection_str = self._get_connection_str(resource_type)
endpoint, _ = parse_connection_str(self.connection_str)
self._resource_name = endpoint.split(".")[0]
self.scrubber.register_name_pair(self._resource_name, "sanitized")
def _get_connection_str(self, resource_type):
if self.is_playback():
return "endpoint=https://sanitized.communication.azure.com/;accesskey=fake==="
if resource_type == CommunicationTestResourceType.UNSPECIFIED:
return os.getenv('COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING') or \
os.getenv('COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING')
if resource_type == CommunicationTestResourceType.DYNAMIC:
return os.getenv('COMMUNICATION_LIVETEST_DYNAMIC_CONNECTION_STRING')
if resource_type == CommunicationTestResourceType.STATIC:
return os.getenv('COMMUNICATION_LIVETEST_STATIC_CONNECTION_STRING')
|