Ejemplo n.º 1
0
    def get_conn(self):
        """
        Returns an authentication with app in box.
        """

        try:
            client = CerberusClient('https://prod.cerberus.nikecloud.com')
            sdk = JWTAuth(
                client_id=client.get_secrets_data(
                    "shared/ngap-box/client_id")["client_id"],
                client_secret=client.get_secrets_data(
                    "shared/ngap-box/client_secret")["client_secret"],
                enterprise_id=client.get_secrets_data(
                    "shared/ngap-box/enterprise_id")["enterprise_id"],
                jwt_key_id=client.get_secrets_data(
                    "shared/ngap-box/jwt_key_id")["jwt_key_id"],
                rsa_private_key_data=((client.get_secrets_data(
                    "shared/ngap-box/boxpemkey")["pemkey"]).replace(
                        '\\n', '\n')),
                rsa_private_key_passphrase=bytes(
                    (client.get_secrets_data(
                        "shared/ngap-box/rsa_private_key_passphrase")
                     ["rsa_private_key_passphrase"]).encode('utf-8')))
            client = Client(sdk)
            return client
        except TypeError as e:
            print(e)
 def setUp(self, *args):
     self.cerberus_url = "https://cerberus.fake.com"
     self.client = CerberusClient(self.cerberus_url, 'testuser',
                                  'hardtoguesspasswd')
     self.auth_resp = {
         "status": "mfa_req",
         "data": {
             "username": "******",
             "state_token": "0127a384d305138d4e",
             "client_token": "None",
             "user_id": "1325",
             "devices": [{
                 "id": "223",
                 "name": "Google Authenticator"
             }]
         }
     }
     self.sdb_data = {
         "id":
         "5f0-99-414-bc-e5909c",
         "name":
         "Disco Events",
         "description":
         "Studio 54",
         "path":
         "app/disco-events/",
         'iam_principal_permissions': [{
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-dancefloor',
             'id':
             'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }, {
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-bar',
             'id':
             'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }, {
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-office',
             'id':
             '27731199-7055-3c4b-3883-9f01f17bc034',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }],
     }
class TestCerberusClient(unittest.TestCase):
    """Class to test the cerberus client. Mock is used to mock external calls"""
    @patch('cerberus.client.CerberusClient.set_token',
           return_value='1234-asdf-1234hy-qwer6')
    def setUp(self, *args):
        self.cerberus_url = "https://cerberus.fake.com"
        self.client = CerberusClient(self.cerberus_url, 'testuser',
                                     'hardtoguesspasswd')
        self.auth_resp = {
            "status": "mfa_req",
            "data": {
                "username": "******",
                "state_token": "0127a384d305138d4e",
                "client_token": "None",
                "user_id": "1325",
                "devices": [{
                    "id": "223",
                    "name": "Google Authenticator"
                }]
            }
        }
        self.sdb_data = {
            "id":
            "5f0-99-414-bc-e5909c",
            "name":
            "Disco Events",
            "description":
            "Studio 54",
            "path":
            "app/disco-events/",
            'iam_principal_permissions': [{
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'id':
                'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-bar',
                'id':
                'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-office',
                'id':
                '27731199-7055-3c4b-3883-9f01f17bc034',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }],
        }

    @staticmethod
    def _mock_response(status=200, reason='OK', content=''):
        mock_resp = requests.Response()
        mock_resp.status_code = status
        # Reason the status code occurred.
        mock_resp.reason = reason
        # Raw content in byte
        mock_resp._content = bytes(content.encode('utf-8'))
        return mock_resp

    @staticmethod
    def _mock_response_raw(status=200, reason='OK', content=''):
        mock_resp = requests.Response()
        mock_resp.status_code = status
        # Reason the status code occurred.
        mock_resp.reason = reason
        mock_resp._content = bytes(content.encode('utf-8'))
        return mock_resp.json()

    def test_username(self):
        """ Testing that correct username is returned"""
        assert_equals(self.client.username, 'testuser')

    def test_get_token(self):
        """ Testing that get_token returns the correct token"""
        token = self.client.get_token()
        assert_equals(token, self.client.token)

    @patch('requests.get')
    def test_get_sdb_id(self, mock_get):
        """ Testing that get_sdb_id returns the correct ID"""
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id("snowflake")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_sdb_id_by_path(self, mock_get):
        """ Testing that get_sdb_id_by_path returns the correct ID"""
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id_by_path("app/snowflake/")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_sdb_id_by_path_no_slash(self, mock_get):
        """
        Testing that get_sdb_id_by_path returns the correct ID \
        even when the requested path lacks a trailing slash '/'
        """
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id_by_path("app/snowflake")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_id(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_id returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_id("5f0-99-414-bc-e5909c")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_name(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_name returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_name("Disco Events")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id_by_path',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_path(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_path returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_path("app/disco-events/")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_path(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_path returns the correct path """
        sdb_data = {
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "description": "Studio 54",
            "path": "app/disco-events/"
        }

        mock_resp = self._mock_response(content=json.dumps(sdb_data))
        mock_get.return_value = mock_resp

        path = self.client.get_sdb_path("Disco Events")

        assert_equals(path, sdb_data['path'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v1/safe-deposit-box/5f0-99-414-bc-e5909c/',
            headers=self.client.HEADERS)

    @patch('requests.post')
    def test_create_sdb(self, mock_get):
        """ Test creation of sdb """
        sdb_data = {
            'id':
            '5f0-99-414-bc-e5909c',
            'name':
            'Disco Events',
            'description':
            'Studio 54',
            'path':
            'app/disco-events/',
            'category_id':
            '244cfc0d-4beb-8189-5056-194f18ead6f4',
            'created_by':
            '*****@*****.**',
            'created_ts':
            '1978-11-27T23:08:14.027Z',
            'iam_principal_permissions': [{
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'id':
                'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-bar',
                'id':
                'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-office',
                'id':
                '27731199-7055-3c4b-3883-9f01f17bc034',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }],
            'owner':
            'Admin.Studio.54',
            'user_group_permissions': []
        }
        mock_resp = mock.Mock()
        mock_resp.json.return_value = sdb_data
        #mock_resp = self._mock_response(content=json.dumps(sdb_data))
        mock_get.return_value = mock_resp

        create = self.client.create_sdb(
            'Disco Events', '244cfc0d-4beb-8189-5056-194f18ead6f4',
            'Admin.Studio.54', 'Studio 54', [], [
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-dancefloor',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-bar',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-office',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
            ])

        assert_equals(create, sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        #mock_get.assert_called_once_with(self.cerberus_url + '/v2/safe-deposit-box')
        #mock_get.assert_called_with(
        #    self.cerberus_url + '/v2/safe-deposit-box',
        #    data={"owner": "Admin.Studio.54", "iam_principal_permissions": [{"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-dancefloor", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}, {"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-bar", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}, {"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-office", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}], "description": "Studio 54", "category_id": "244cfc0d-4beb-8189-5056-194f18ead6f4", "name": "Disco Events"},
        #    headers=self.client.HEADERS
        #)

    @patch('requests.get')
    def test_get_sdb_keys(self, mock_get):
        """ Testing that get_sdb_keys returns the correct key """
        list_data = {
            "lease_id": "",
            "renewable": False,
            "lease_duration": 0,
            "data": {
                "keys": ["magic", "princess"]
            },
            "wrap_info": None,
            "warnings": None,
            "auth": None
        }

        mock_resp = self._mock_response(content=json.dumps(list_data))
        mock_get.return_value = mock_resp

        keys = self.client.get_sdb_keys('fake/path')

        assert_equals(keys[0], 'magic')
        assert_equals(keys[1], 'princess')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secret/fake/path/?list=true',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_a_secret(self, mock_get):
        """ Testing the correct secret is returned"""
        secret_data = {
            "data": {
                "mykey": "mysecretdata",
                "myotherkey": "moretopsecretstuff"
            }
        }

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp

        secret = self.client.get_secret('fake/path', 'myotherkey')

        # check to make sure we got the right secret
        assert_equals(secret, 'moretopsecretstuff')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v1/secret/fake/path',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_secrets_data(self, mock_get):
        """ Testing the correct secrets are returned"""
        secret_data = {"data": {"sushi": "ikenohana", "ramen": "yuzu"}}

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp

        secrets = self.client.get_secrets_data('fake/path')

        # check to make sure we got the right secret
        assert_equals(secrets['sushi'], 'ikenohana')
        assert_equals(secrets['ramen'], 'yuzu')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v1/secret/fake/path',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_secrets_invalid_path(self, mget):
        """ Ensure that a Cerberus exception is raised if the path is invalid. """
        mget.return_value = self._mock_response(status=401)
        with self.assertRaises(CerberusClientException):
            self.client.get_secrets('this/path/does/not/exist')

    @patch('requests.get')
    def test_get_secret_invalid_path(self, mget):
        """ Ensure that a Cerberus exception is raised if the path or key is invalid. """
        data = json.dumps({"data": {}})
        mget.return_value = self._mock_response(content=data)
        with self.assertRaises(CerberusClientException):
            self.client.get_secret('this/path/does/not/exist', 'null')

    @patch('requests.get')
    def test_get_sdb_id_invalid_response(self, mget):
        """ Ensure a Cerberus exception is raised if the sdb request failed. """
        mget.return_value = self._mock_response(status=401)
        with self.assertRaises(CerberusClientException):
            self.client.get_sdb_id('some_id')

    @patch('requests.get')
    def test_get_sdb_id_missing_id(self, mget):
        """ Ensure a Cerberus exception is raised if the sdb id is not found. """
        data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }]
        mget.return_value = self._mock_response(content=json.dumps(data))
        with self.assertRaises(CerberusClientException):
            self.client.get_sdb_id('not_found')
Ejemplo n.º 4
0
 def test_environment_variable_does_not_overrides_token_parameter(self):
     anotherClient = CerberusClient(self.cerberus_url,
                                    token="overridetoken")
     assert_equals(anotherClient.get_token(), "overridetoken")
Ejemplo n.º 5
0
 def test_environment_variable_overrides_lambda_context(self):
     anotherClient = CerberusClient(self.cerberus_url,
                                    lambda_context="whatever object")
     assert_equals(anotherClient.get_token(), "dashboardtoken")
Ejemplo n.º 6
0
 def test_environment_variable_overrides_default_auth(self):
     anotherClient = CerberusClient(self.cerberus_url)
     assert_equals(anotherClient.get_token(), "dashboardtoken")
Ejemplo n.º 7
0
 def test_environment_variable_overrides_user_auth(self):
     anotherClient = CerberusClient(self.cerberus_url, 'testuser',
                                    'hardtoguesspasswd')
     assert_equals(anotherClient.get_token(), "dashboardtoken")
Ejemplo n.º 8
0
 def setUp(self, *args):
     self.cerberus_url = "https://cerberus.fake.com"
     self.client = CerberusClient(self.cerberus_url, 'testuser',
                                  'hardtoguesspasswd')
     self.auth_resp = {
         "status": "mfa_req",
         "data": {
             "username": "******",
             "state_token": "0127a384d305138d4e",
             "client_token": "None",
             "user_id": "1325",
             "devices": [{
                 "id": "223",
                 "name": "Google Authenticator"
             }]
         }
     }
     self.sdb_data = {
         "id":
         "5f0-99-414-bc-e5909c",
         "name":
         "Disco Events",
         "description":
         "Studio 54",
         "path":
         "app/disco-events/",
         'iam_principal_permissions': [{
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-dancefloor',
             'id':
             'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }, {
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-bar',
             'id':
             'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }, {
             'created_by':
             '*****@*****.**',
             'iam_principal_arn':
             'arn:aws:iam::292800423415:role/studio54-office',
             'id':
             '27731199-7055-3c4b-3883-9f01f17bc034',
             'last_updated_by':
             '*****@*****.**',
             'last_updated_ts':
             '1974-11-17T00:02:30Z',
             'role_id':
             '8609a0c3-31e5-49ab-914d-c70c35da9478'
         }],
     }
     self.file_data = {
         'Date':
         'Sun, 17 November 1974 00:02:30 GMT',
         'Content-Type':
         'image/png; charset=UTF-8',
         'Content-Length':
         '237',
         'Connection':
         'keep-alive',
         'Content-Disposition':
         'attachment; filename="test.png"',
         'Strict-Transport-Security':
         'max-age=31536000; includeSubDomains',
         'X-B3-TraceId':
         'fa533432fe425da9',
         'filename':
         'test.png',
         'data':
         '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x12\x00\x00\x00\x07\x08\x06\x00\x00\x00\x05\xd5\x1d\x7f\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\tpHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07tIME\x07\xe2\x05\t\x16(\n\x87\x93H\xa5\x00\x00\x00\x19tEXtComment\x00Created with GIMPW\x81\x0e\x17\x00\x00\x00UIDAT\x18\xd3\x9d\x90A\n\xc0@\x08\x03\'e\xff\xff\xe5\xf4R\x8bX\xa5\xcbzs\xd0\x10F\xb6-\t\xdb\x9cL\xfc\nx\x13"L\x12\x95u<\xef+@\x0e\xa9\xcf\xf5\xa6\xe3k\xaa[\'7\xb0\xfdQ\xd1\x06M\xbe\xa6\xd6\x00\xd7\x8e\xcc??\x00\xf2\x13]=\xed\xc8\xce\xfc\x06\x0f\xbfK\x06s\xd8\x7f\x99\x00\x00\x00\x00IEND\xaeB`\x82'
     }
     # Json parsing is differnt on python 2.7
     if int(platform.python_version_tuple()[0]) < 3:
         self.file_data['data'] = "Test String"
Ejemplo n.º 9
0
class TestCerberusClient(unittest.TestCase):
    """Class to test the cerberus client. Mock is used to mock external calls"""
    @patch('cerberus.client.CerberusClient._set_token',
           return_value='1234-asdf-1234hy-qwer6')
    def setUp(self, *args):
        self.cerberus_url = "https://cerberus.fake.com"
        self.client = CerberusClient(self.cerberus_url, 'testuser',
                                     'hardtoguesspasswd')
        self.auth_resp = {
            "status": "mfa_req",
            "data": {
                "username": "******",
                "state_token": "0127a384d305138d4e",
                "client_token": "None",
                "user_id": "1325",
                "devices": [{
                    "id": "223",
                    "name": "Google Authenticator"
                }]
            }
        }
        self.sdb_data = {
            "id":
            "5f0-99-414-bc-e5909c",
            "name":
            "Disco Events",
            "description":
            "Studio 54",
            "path":
            "app/disco-events/",
            'iam_principal_permissions': [{
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'id':
                'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-bar',
                'id':
                'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-office',
                'id':
                '27731199-7055-3c4b-3883-9f01f17bc034',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }],
        }
        self.file_data = {
            'Date':
            'Sun, 17 November 1974 00:02:30 GMT',
            'Content-Type':
            'image/png; charset=UTF-8',
            'Content-Length':
            '237',
            'Connection':
            'keep-alive',
            'Content-Disposition':
            'attachment; filename="test.png"',
            'Strict-Transport-Security':
            'max-age=31536000; includeSubDomains',
            'X-B3-TraceId':
            'fa533432fe425da9',
            'filename':
            'test.png',
            'data':
            '\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x12\x00\x00\x00\x07\x08\x06\x00\x00\x00\x05\xd5\x1d\x7f\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x00\tpHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\x00\x00\x00\x07tIME\x07\xe2\x05\t\x16(\n\x87\x93H\xa5\x00\x00\x00\x19tEXtComment\x00Created with GIMPW\x81\x0e\x17\x00\x00\x00UIDAT\x18\xd3\x9d\x90A\n\xc0@\x08\x03\'e\xff\xff\xe5\xf4R\x8bX\xa5\xcbzs\xd0\x10F\xb6-\t\xdb\x9cL\xfc\nx\x13"L\x12\x95u<\xef+@\x0e\xa9\xcf\xf5\xa6\xe3k\xaa[\'7\xb0\xfdQ\xd1\x06M\xbe\xa6\xd6\x00\xd7\x8e\xcc??\x00\xf2\x13]=\xed\xc8\xce\xfc\x06\x0f\xbfK\x06s\xd8\x7f\x99\x00\x00\x00\x00IEND\xaeB`\x82'
        }
        # Json parsing is differnt on python 2.7
        if int(platform.python_version_tuple()[0]) < 3:
            self.file_data['data'] = "Test String"

    @staticmethod
    def _mock_response(status=200, reason='OK', content=''):
        mock_resp = requests.Response()
        mock_resp.status_code = status
        # Reason the status code occurred.
        mock_resp.reason = reason
        # Raw content in byte
        mock_resp._content = bytes(content.encode('utf-8'))
        return mock_resp

    @staticmethod
    def _mock_response_raw(status=200, reason='OK', content=''):
        mock_resp = requests.Response()
        mock_resp.status_code = status
        # Reason the status code occurred.
        mock_resp.reason = reason
        mock_resp._content = bytes(content.encode('utf-8'))
        return mock_resp.json()

    def test_username(self):
        """ Testing that correct username is returned"""
        assert_equals(self.client.username, 'testuser')

    def test_get_token(self):
        """ Testing that get_token returns the correct token"""
        token = self.client.get_token()
        assert_equals(token, self.client.token)

    @patch('requests.get')
    def test_get_sdbs(self, mock_get):
        """ get_sdbs: Testing that get_sdbs returns the correct SDBs """
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdbs()

        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    sdb_data = [{
        "id": "5f0-99-414-bc-e5909c",
        "name": "Disco Events",
        "path": "app/disco-events/",
        "category_id": "b07-42d0-e6-9-0a47c03"
    }, {
        "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
        "name": "snowflake",
        "path": "app/snowflake/",
        "category_id": "b042d0-e6-90-0aec03"
    }]

    @patch('requests.get')
    def test_list_sdbs(self, mock_get):
        """ list_sdbs: Testing that list_sdbs returns the correct SDBs names """
        sdb_data = [{"name": "Disco Events"}, {"name": "snowflake"}]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.list_sdbs()

        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_sdb_id(self, mock_get):
        """ Testing that get_sdb_id returns the correct ID"""
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id("snowflake")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_sdb_id_by_path(self, mock_get):
        """ Testing that get_sdb_id_by_path returns the correct ID"""
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id_by_path("app/snowflake/")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_sdb_id_by_path_no_slash(self, mock_get):
        """
        Testing that get_sdb_id_by_path returns the correct ID \
        even when the requested path lacks a trailing slash '/'
        """
        sdb_data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }, {
            "id": "a7192aa7-83f0-45b7-91fb-f6b0eb",
            "name": "snowflake",
            "path": "app/snowflake/",
            "category_id": "b042d0-e6-90-0aec03"
        }]

        mock_get.return_value = self._mock_response(
            content=json.dumps(sdb_data))
        sdb_id = self.client.get_sdb_id_by_path("app/snowflake")

        # confirm the id matches
        assert_equals(sdb_id, sdb_data[1]['id'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v2/safe-deposit-box',
                                    headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_id(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_id returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_id("5f0-99-414-bc-e5909c")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_name(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_name returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_name("Disco Events")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id_by_path',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_by_path(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_by_path returns some details of the sdb """

        mock_resp = self._mock_response(content=json.dumps(self.sdb_data))
        mock_get.return_value = mock_resp

        details = self.client.get_sdb_by_path("app/disco-events/")

        assert_equals(details, self.sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v2/safe-deposit-box/5f0-99-414-bc-e5909c',
            headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient.get_sdb_id',
           return_value="5f0-99-414-bc-e5909c")
    @patch('requests.get')
    def test_get_sdb_path(self, mock_get, mock_sdb_id):
        """ Test that get_sdb_path returns the correct path """
        sdb_data = {
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "description": "Studio 54",
            "path": "app/disco-events/"
        }

        mock_resp = self._mock_response(content=json.dumps(sdb_data))
        mock_get.return_value = mock_resp

        path = self.client.get_sdb_path("Disco Events")

        assert_equals(path, sdb_data['path'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(
            self.cerberus_url + '/v1/safe-deposit-box/5f0-99-414-bc-e5909c/',
            headers=self.client.HEADERS)

    @patch('requests.post')
    def test_create_sdb(self, mock_get):
        """ Test creation of sdb """
        sdb_data = {
            'id':
            '5f0-99-414-bc-e5909c',
            'name':
            'Disco Events',
            'description':
            'Studio 54',
            'path':
            'app/disco-events/',
            'category_id':
            '244cfc0d-4beb-8189-5056-194f18ead6f4',
            'created_by':
            '*****@*****.**',
            'created_ts':
            '1978-11-27T23:08:14.027Z',
            'iam_principal_permissions': [{
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'id':
                'c8549195-5f2c-ba2c-eb0e-2605d1e58816',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-bar',
                'id':
                'f57741a2-79c0-7e35-bbf9-82a32a1827eb',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }, {
                'created_by':
                '*****@*****.**',
                'iam_principal_arn':
                'arn:aws:iam::292800423415:role/studio54-office',
                'id':
                '27731199-7055-3c4b-3883-9f01f17bc034',
                'last_updated_by':
                '*****@*****.**',
                'last_updated_ts':
                '1974-11-17T00:02:30Z',
                'role_id':
                '8609a0c3-31e5-49ab-914d-c70c35da9478'
            }],
            'owner':
            'Admin.Studio.54',
            'user_group_permissions': []
        }
        mock_resp = self._mock_response(content=json.dumps(sdb_data))
        mock_get.return_value = mock_resp

        create = self.client.create_sdb(
            'Disco Events', '244cfc0d-4beb-8189-5056-194f18ead6f4',
            'Admin.Studio.54', 'Studio 54', [], [
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-dancefloor',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-bar',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
                {
                    'iam_principal_arn':
                    'arn:aws:iam::292800423415:role/studio54-office',
                    'role_id': '8609a0c3-31e5-49ab-914d-c70c35da9478'
                },
            ])

        assert_equals(create, sdb_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        #mock_get.assert_called_once_with(self.cerberus_url + '/v2/safe-deposit-box')
        #mock_get.assert_called_with(
        #    self.cerberus_url + '/v2/safe-deposit-box',
        #    data={"owner": "Admin.Studio.54", "iam_principal_permissions": [{"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-dancefloor", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}, {"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-bar", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}, {"iam_principal_arn": "arn:aws:iam::292800423415:role/studio54-office", "role_id": "8609a0c3-31e5-49ab-914d-c70c35da9478"}], "description": "Studio 54", "category_id": "244cfc0d-4beb-8189-5056-194f18ead6f4", "name": "Disco Events"},
        #    headers=self.client.HEADERS
        #)

    @patch('requests.get')
    def test_get_sdb_keys(self, mock_get):
        """ Testing that get_sdb_keys returns the correct key """
        list_data = {
            "lease_id": "",
            "renewable": False,
            "lease_duration": 0,
            "data": {
                "keys": ["magic", "princess"]
            },
            "wrap_info": None,
            "warnings": None,
            "auth": None
        }

        mock_resp = self._mock_response(content=json.dumps(list_data))
        mock_get.return_value = mock_resp

        keys = self.client.get_sdb_keys('fake/path')

        assert_equals(keys[0], 'magic')
        assert_equals(keys[1], 'princess')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secret/fake/path/?list=true',
                                    headers=self.client.HEADERS)

## ---- files ----

    @patch('requests.get')
    def test_list_files(self, mock_get):
        """ Testing that list_files returns the correct files """
        list_data = {
            'has_next':
            False,
            'next_offset':
            None,
            'limit':
            100,
            'offset':
            0,
            'file_count_in_result':
            3,
            'total_file_count':
            3,
            'secure_file_summaries': [{
                'sdbox_id': '244cfc0d-4beb-8189-5056-194f18ead6f4',
                'path': 'studio54/test.py',
                'size_in_bytes': 1323,
                'name': 'test.py',
                'created_by': '*****@*****.**',
                'created_ts': '1974-11-17T00:02:30Z',
                'last_updated_by': '*****@*****.**',
                'last_updated_ts': '1974-11-17T00:02:30Z'
            }, {
                'sdbox_id': '244cfc0d-4beb-8189-5056-194f18ead6f4',
                'path': 'studio54/test.gif',
                'size_in_bytes': 686,
                'name': 'test.gif',
                'created_by': '*****@*****.**',
                'created_ts': '1974-11-17T00:02:30Z',
                'last_updated_by': '*****@*****.**',
                'last_updated_ts': '1974-11-17T00:02:30Z'
            }, {
                'sdbox_id': '244cfc0d-4beb-8189-5056-194f18ead6f4',
                'path': 'studio54/5621.gif',
                'size_in_bytes': 686,
                'name': '5621.gif',
                'created_by': '*****@*****.**',
                'created_ts': '1974-11-17T00:02:30Z',
                'last_updated_by': '*****@*****.**',
                'last_updated_ts': '1974-11-17T00:02:30Z'
            }]
        }

        payload = {'limit': '100', 'offset': '0'}
        mock_resp = self._mock_response(content=json.dumps(list_data))
        mock_get.return_value = mock_resp

        keys = self.client.list_files('fake/path')

        assert_equals(keys['limit'], 100)
        assert_equals(keys['offset'], 0)
        assert_equals(keys, list_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secure-files/fake/path/',
                                    params=payload,
                                    headers=self.client.HEADERS)

    @patch('cerberus.client.CerberusClient._parse_metadata_filename')
    @patch('requests.get')
    def test_getting_a_file(self, mock_get, mock_parse):
        """ get_file: Testing the correct file is returned"""

        mock_parse.return_value = self.file_data
        mock_resp = self._mock_response(
            content=json.dumps(self.file_data, ensure_ascii=False))
        mock_get.return_value = mock_resp

        secret_file = self.client.get_file('fake/path/test.png')

        # check to make sure we got the right file
        #assert_equals(secret_file, file_data)
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secure-file/fake/path/test.png',
                                    params={'versionId': 'CURRENT'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_file_data(self, mock_get):
        """ get_file_data: Testing the correct file data is returned"""

        mock_resp = self._mock_response(content=self.file_data['data'])
        mock_get.return_value = mock_resp

        secret_file = self.client.get_file_data('fake/path/test.png')

        # check to make sure we got the right file
        #assert_equals(secret_file, self.file_data['data'])
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secure-file/fake/path/test.png',
                                    params={'versionId': 'CURRENT'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_files_data_version(self, mock_get):
        """ get_file_data: Testing the correct files are returned when a version is passed """

        mock_resp = self._mock_response(content=json.dumps(self.file_data))
        mock_get.return_value = mock_resp

        files = self.client.get_file_data('fake/path/test.png',
                                          version='12345')

        # check to make sure we got the right file
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secure-file/fake/path/test.png',
                                    params={'versionId': '12345'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_file_versions(self, mock_get):
        """ get_file_versions: Ensure that the version information of a file is returned """
        version_data = {
            'has_next':
            False,
            'next_offset':
            None,
            'limit':
            1,
            'offset':
            1,
            'version_count_in_result':
            1,
            'total_version_count':
            2,
            'secure_data_version_summaries': [{
                'id':
                '00000000-0000-0000-0000-000000012345',
                'sdbox_id':
                '244cfc0d-4beb-8189-5056-194f18ead6f4',
                'path':
                'fake/path',
                'action':
                'UPDATE',
                'version_created_by':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'version_created_ts':
                '1978-11-27T23:08:14.027Z',
                'action_principal':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'action_ts':
                '1978-11-27T23:08:14.027Z'
            }]
        }

        mock_resp = self._mock_response(content=json.dumps(version_data))
        mock_get.return_value = mock_resp

        files = self.client.get_file_versions('fake/path', limit=1, offset=1)

        # check to make sure we got the right file
        assert_equals(files['limit'], 1)
        assert_equals(files['offset'], 1)
        assert_equals(files['secure_data_version_summaries'][0]['id'],
                      '00000000-0000-0000-0000-000000012345')
        assert_equals(files['secure_data_version_summaries'][0]['path'],
                      'fake/path')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secret-versions/fake/path',
                                    params={
                                        'limit': '1',
                                        'offset': '1'
                                    },
                                    headers=self.client.HEADERS)

## ---- secrets ----

    @patch('requests.get')
    def test_getting_a_secret(self, mock_get):
        """ get_secret: Testing the correct secret is returned"""
        secret_data = {
            "data": {
                "mykey": "mysecretdata",
                "myotherkey": "moretopsecretstuff"
            }
        }

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp

        secret = self.client.get_secret('fake/path', 'myotherkey')

        # check to make sure we got the right secret
        assert_equals(secret, 'moretopsecretstuff')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v1/secret/fake/path',
                                    params={'versionId': 'CURRENT'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_secrets_data(self, mock_get):
        """ get_secrets_data: Testing the correct secrets are returned"""
        secret_data = {"data": {"sushi": "ikenohana", "ramen": "yuzu"}}

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp

        secrets = self.client.get_secrets_data('fake/path')

        # check to make sure we got the right secret
        assert_equals(secrets['sushi'], 'ikenohana')
        assert_equals(secrets['ramen'], 'yuzu')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v1/secret/fake/path',
                                    params={'versionId': 'CURRENT'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_secrets_data_version(self, mock_get):
        """ get_secrets_data: Testing the correct secrets are returned when a version is passed """
        secret_data = {"data": {"sushi": "ikenohana", "ramen": "yuzu"}}

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp

        secrets = self.client.get_secrets_data('fake/path', version='12345')

        # check to make sure we got the right secret
        assert_equals(secrets['sushi'], 'ikenohana')
        assert_equals(secrets['ramen'], 'yuzu')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url + '/v1/secret/fake/path',
                                    params={'versionId': '12345'},
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_getting_secret_versions(self, mock_get):
        """ get_secret_versions: Ensure that the version information of a secret is returned """
        version_data = {
            'has_next':
            False,
            'next_offset':
            None,
            'limit':
            1,
            'offset':
            1,
            'version_count_in_result':
            1,
            'total_version_count':
            2,
            'secure_data_version_summaries': [{
                'id':
                '00000000-0000-0000-0000-000000012345',
                'sdbox_id':
                '244cfc0d-4beb-8189-5056-194f18ead6f4',
                'path':
                'fake/path',
                'action':
                'UPDATE',
                'version_created_by':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'version_created_ts':
                '1978-11-27T23:08:14.027Z',
                'action_principal':
                'arn:aws:iam::292800423415:role/studio54-dancefloor',
                'action_ts':
                '1978-11-27T23:08:14.027Z'
            }]
        }

        mock_resp = self._mock_response(content=json.dumps(version_data))
        mock_get.return_value = mock_resp

        secrets = self.client.get_secret_versions('fake/path',
                                                  limit=1,
                                                  offset=1)

        # check to make sure we got the right secret
        assert_equals(secrets['limit'], 1)
        assert_equals(secrets['offset'], 1)
        assert_equals(secrets['secure_data_version_summaries'][0]['id'],
                      '00000000-0000-0000-0000-000000012345')
        assert_equals(secrets['secure_data_version_summaries'][0]['path'],
                      'fake/path')
        assert_in('X-Cerberus-Client', self.client.HEADERS)
        mock_get.assert_called_with(self.cerberus_url +
                                    '/v1/secret-versions/fake/path',
                                    params={
                                        'limit': '1',
                                        'offset': '1'
                                    },
                                    headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_secrets_invalid_path(self, mget):
        """ Ensure that a Cerberus exception is raised if the path is invalid. """
        data = json.dumps({"error_id": "123", "errors": []})
        mget.return_value = self._mock_response(status=401, content=data)
        with self.assertRaises(CerberusClientException):
            self.client.get_secrets('this/path/does/not/exist')

    @patch('requests.get')
    def test_get_secrets_retry_on_5xx(self, mget):
        """Ensure that the client retries on 5xx response. """
        error_data = json.dumps({"error_id": "123", "errors": []})
        secret_data = json.dumps(
            {"data": {
                "sushi": "ikenohana",
                "ramen": "yuzu"
            }})

        mget.side_effect = [
            self._mock_response(status=500, content=error_data),
            self._mock_response(status=502, content=error_data),
            self._mock_response(status=200, content=secret_data)
        ]
        self.client.get_secrets_data('fake/path')

    @patch('requests.get')
    def test_get_secrets_retry_stop_after_limit(self, mget):
        """Ensure that the client does not retry too many times. """
        error_data = json.dumps({"error_id": "123", "errors": []})
        secret_data = json.dumps(
            {"data": {
                "sushi": "ikenohana",
                "ramen": "yuzu"
            }})

        mget.side_effect = [
            self._mock_response(status=500, content=error_data),
            self._mock_response(status=502, content=error_data),
            self._mock_response(status=500, content=error_data),
            self._mock_response(status=200, content=secret_data)
        ]
        with self.assertRaises(CerberusClientException):
            self.client.get_secrets_data('fake/path')

    @patch('requests.get')
    def test_get_secrets_does_not_retry_on_200(self, mget):
        """ Ensure that the client does not retry on 200 response. """
        error_data = json.dumps({"error_id": "123", "errors": []})
        secret_data = json.dumps(
            {"data": {
                "sushi": "ikenohana",
                "ramen": "yuzu"
            }})

        mget.side_effect = [
            self._mock_response(status=200, content=secret_data),
            self._mock_response(status=500, content=error_data)
        ]
        self.client.get_secrets_data('fake/path')

    @patch('requests.get')
    def test_get_secrets_does_not_retry_on_4xx(self, mget):
        """ Ensure that the client does not retry on 4xx response. """
        error_data = json.dumps({"error_id": "123", "errors": []})

        mget.side_effect = [
            self._mock_response(status=403, content=error_data),
            self._mock_response(status=403, content=error_data)
        ]
        with self.assertRaises(CerberusClientException):
            self.client.get_secrets_data('fake/path')
        mget.assert_called_once_with(self.cerberus_url +
                                     '/v1/secret/fake/path',
                                     params={'versionId': 'CURRENT'},
                                     headers=self.client.HEADERS)

    @patch('requests.get')
    def test_get_secret_invalid_path(self, mget):
        """ Ensure that a Cerberus exception is raised if the path or key is invalid. """
        data = json.dumps({"data": {}})
        mget.return_value = self._mock_response(content=data)
        with self.assertRaises(CerberusClientException):
            self.client.get_secret('this/path/does/not/exist', 'null')

    @patch('requests.get')
    def test_get_sdb_id_invalid_response(self, mget):
        """ Ensure a Cerberus exception is raised if the sdb request failed. """
        data = json.dumps({"error_id": "123", "errors": []})
        mget.return_value = self._mock_response(status=401, content=data)
        with self.assertRaises(CerberusClientException):
            self.client.get_sdb_id('some_id')

    @patch('requests.get')
    def test_get_sdb_id_missing_id(self, mget):
        """ Ensure a Cerberus exception is raised if the sdb id is not found. """
        data = [{
            "id": "5f0-99-414-bc-e5909c",
            "name": "Disco Events",
            "path": "app/disco-events/",
            "category_id": "b07-42d0-e6-9-0a47c03"
        }]
        mget.return_value = self._mock_response(content=json.dumps(data))
        with self.assertRaises(CerberusClientException):
            self.client.get_sdb_id('not_found')

    @patch('requests.get')
    def test_request_headers_has_client_version(self, mock_get):
        secret_data = {"data": {"sushi": "ikenohana", "ramen": "yuzu"}}

        mock_resp = self._mock_response(content=json.dumps(secret_data))
        mock_get.return_value = mock_resp
        self.client.get_secrets_data("fake/path", "ramen")
        mock_get.assert_called_with(
            ANY, headers=AnyDictWithKey('X-Cerberus-Client'), params=ANY)

    @patch.dict('os.environ', {"CERBERUS_TOKEN": "dashboardtoken"})
    def test_environment_variable_overrides_user_auth(self):
        anotherClient = CerberusClient(self.cerberus_url, 'testuser',
                                       'hardtoguesspasswd')
        assert_equals(anotherClient.get_token(), "dashboardtoken")

    @patch.dict('os.environ', {"CERBERUS_TOKEN": "dashboardtoken"})
    def test_environment_variable_overrides_default_auth(self):
        anotherClient = CerberusClient(self.cerberus_url)
        assert_equals(anotherClient.get_token(), "dashboardtoken")

    @patch.dict('os.environ', {"CERBERUS_TOKEN": "dashboardtoken"})
    def test_environment_variable_overrides_lambda_context(self):
        anotherClient = CerberusClient(self.cerberus_url,
                                       lambda_context="whatever object")
        assert_equals(anotherClient.get_token(), "dashboardtoken")

    @patch.dict('os.environ', {"CERBERUS_TOKEN": "dashboardtoken"})
    def test_environment_variable_does_not_overrides_token_parameter(self):
        anotherClient = CerberusClient(self.cerberus_url,
                                       token="overridetoken")
        assert_equals(anotherClient.get_token(), "overridetoken")