Beispiel #1
0
    def test_get_all_pending_requests_api(self, mock_auth,
                                          mock_user_dynamo_handler):
        """Chuck Norris has a request and is an secondary approver for group1"""
        from consoleme.lib.requests import get_all_pending_requests_api

        mock_user = "******"
        mock_requests = [
            {
                "username": mock_user,
                "status": "pending"
            },
            {
                "username": "******",
                "group": "group1",
                "status": "pending"
            },
            {
                "username": "******",
                "status": "approved"
            },
        ]
        mock_secondary_approver = {"group1": ["group1"]}
        mock_user_dynamo_handler.return_value.get_all_requests.return_value = (
            create_future(mock_requests))

        mock_auth.get_secondary_approvers.return_value = create_future(
            mock_secondary_approver)

        requests = asyncio.get_event_loop().run_until_complete(
            get_all_pending_requests_api(mock_user))
        self.assertEqual(
            requests,
            mock_requests[:len(mock_requests) - 1],
            "Only clair should be missing",
        )
Beispiel #2
0
    def test_resource_typeahead(self, mock_redis_hgetall, mock_auth):
        from consoleme.config import config

        mock_auth.validate_certificate.return_value = create_future(True)
        mock_auth.extract_user_from_certificate.return_value = create_future(
            {"name": "*****@*****.**"})
        mock_auth.get_cert_age_seconds.return_value = create_future(100)
        headers = {
            config.get("auth.user_header_name"): "*****@*****.**",
            config.get("auth.groups_header_name"): "groupa,groupb,groupc",
        }

        # Invalid resource, no search string
        resource = "fake"
        response = self.fetch(
            f"/api/v1/policies/typeahead?resource={resource}",
            headers=headers,
            method="GET",
        )
        self.assertEqual(response.code, 400)

        # Valid resource, no search string
        resource = "s3"
        response = self.fetch(
            f"/api/v1/policies/typeahead?resource={resource}",
            headers=headers,
            method="GET",
        )
        self.assertEqual(response.code, 400)
        result = create_future({"123456789012": '["abucket1", "abucket2"]'})
        mock_redis_hgetall.return_value = result
        account_id = "123456789012"
        resource = "s3"
        search = "a"
        response = self.fetch(
            f"/api/v1/policies/typeahead?resource={resource}&search={search}&account_id={account_id}",
            headers=headers,
            method="GET",
        )
        self.assertEqual(response.code, 200)
        self.assertIsInstance(json.loads(response.body), list)
        self.assertEqual(
            json.loads(response.body),
            [
                {
                    "title": "abucket1",
                    "account_id": "123456789012"
                },
                {
                    "title": "abucket2",
                    "account_id": "123456789012"
                },
            ],
        )
Beispiel #3
0
    def test_get_user_requests(self, mock_auth, mock_user_dynamo_handler):
        from consoleme.lib.requests import get_user_requests
        """Chuck Norris has a request and is an secondary approver for group1"""
        mock_user = "******"
        mock_requests = [
            {
                "username": mock_user
            },
            {
                "username": "******",
                "group": "group1"
            },
            {
                "username": "******"
            },
        ]
        mock_secondary_approver = [{"name": "group1"}]
        mock_user_dynamo_handler.return_value.get_all_requests.return_value = (
            create_future(mock_requests))

        mock_sa = Future()
        mock_sa.set_result(mock_secondary_approver)
        mock_auth.query_cached_groups.return_value = mock_sa

        requests = asyncio.get_event_loop().run_until_complete(
            get_user_requests(mock_user, ["group1"]))
        self.assertEqual(
            requests,
            mock_requests[:len(mock_requests) - 1],
            "Only clair should be missing",
        )
Beispiel #4
0
 def test_delete_no_user(self, mock_auth):
     mock_auth.return_value = create_future(None)
     expected = {"status": 403, "title": "Forbidden", "message": "No user detected"}
     response = self.fetch(
         "/api/v2/roles/012345678901/fake_account_admin", method="DELETE"
     )
     self.assertEqual(response.code, 403)
     self.assertDictEqual(json.loads(response.body), expected)
Beispiel #5
0
    def test_get_resource_account(self, mock_aws_config_resources_redis):
        from consoleme.lib.aws import get_resource_account

        mock_aws_config_resources_redis.return_value = create_future(None)
        test_cases = [
            {
                "arn": "arn:aws:s3:::nope",
                "expected": "",
                "description": "external S3 bucket",
            },
            {
                "arn": "arn:aws:waddup:us-east-1:987654321000:cool-resource",
                "expected": "987654321000",
                "description": "arbitrary resource with account in ARN",
            },
            {
                "arn": "arn:aws:waddup:us-east-1::cool-resource",
                "expected": "",
                "description": "arbitrary resource without account in ARN",
            },
        ]
        loop = asyncio.get_event_loop()
        for tc in test_cases:
            result = loop.run_until_complete(get_resource_account(tc["arn"]))
            self.assertEqual(tc["expected"], result,
                             f"Test case failed: {tc['description']}")

        aws_config_resources_test_case = {
            "arn": "arn:aws:s3:::foobar",
            "expected": "123456789012",
            "description": "internal S3 bucket",
        }
        aws_config_resources_test_case_redis_result = {
            "accountId": "123456789012"
        }
        mock_aws_config_resources_redis.return_value = create_future(
            json.dumps(aws_config_resources_test_case_redis_result))
        result = loop.run_until_complete(
            get_resource_account(aws_config_resources_test_case["arn"]))
        self.assertEqual(
            aws_config_resources_test_case["expected"],
            result,
            f"Test case failed: "
            f"{aws_config_resources_test_case['description']}",
        )
Beispiel #6
0
    def test_cache_self_service_template_and_typeahead(self):
        from consoleme.lib.templated_resources import (
            TemplatedFileModelArray,
            TemplateFile,
        )

        mock_template_file_model_array = TemplatedFileModelArray(
            templated_resources=[
                TemplateFile(
                    name="fake_test_template_1",
                    repository_name="fake_repo",
                    owner="fake_owner",
                    include_accounts=["fake_account_1"],
                    exclude_accounts=None,
                    number_of_accounts=1,
                    resource="path/to/file.yaml",
                    file_path="path/to/file.yaml",
                    web_path=
                    "http://github.example.com/fake_repo/browse/master/path/to/file.yaml",
                    resource_type="iam_role",
                    template_language="honeybee",
                )
            ])

        mock_template_typeahead_model = SelfServiceTypeaheadModel(
            details_endpoint=
            "/api/v2/templated_resource/fake_repo/path/to/file.yaml",
            display_text="fake_test_template_1",
            icon="users",
            number_of_affected_resources=1,
            principal={
                "principal_type":
                "HoneybeeAwsResourceTemplate",
                "repository_name":
                "fake_repo",
                "resource_identifier":
                "path/to/file.yaml",
                "resource_url":
                "http://github.example.com/fake_repo/browse/master/path/to/file.yaml",
            },
        )

        patch_cache_resource_templates_for_repository = patch(
            "consoleme.lib.templated_resources.cache_resource_templates_for_repository",
            Mock(return_value=create_future(mock_template_file_model_array)),
        )

        # Cache resource templates, but let's not go down the rabbit hole of trying to mock a Git repo
        patch_cache_resource_templates_for_repository.start()
        from consoleme.lib.templated_resources import cache_resource_templates

        result = async_to_sync(cache_resource_templates)()
        patch_cache_resource_templates_for_repository.stop()
        self.assertEqual(result, mock_template_file_model_array)

        # Retrieve cached resource templates and ensure it is correct
        from consoleme.lib.templated_resources import retrieve_cached_resource_templates

        result = async_to_sync(retrieve_cached_resource_templates)()
        self.assertEqual(result, mock_template_file_model_array)

        # Cache and verify Self Service Typeahead
        from consoleme.lib.self_service.typeahead import cache_self_service_typeahead

        result = async_to_sync(cache_self_service_typeahead)()
        self.assertIsInstance(result, SelfServiceTypeaheadModelArray)
        self.assertGreater(len(result.typeahead_entries), 15)
        expected_entry = SelfServiceTypeaheadModel(
            account="default_account",
            details_endpoint="/api/v2/roles/123456789012/RoleNumber5",
            display_text="RoleNumber5",
            icon="user",
            number_of_affected_resources=1,
            principal=AwsResourcePrincipalModel(
                principal_type="AwsResource",
                principal_arn="arn:aws:iam::123456789012:role/RoleNumber5",
            ),
        )
        # Pre-existing role is in results
        self.assertIn(expected_entry, result.typeahead_entries)
        # HB template is in results
        self.assertIn(mock_template_typeahead_model, result.typeahead_entries)

        # Now let's mock the web requests
        from consoleme.config import config

        headers = {
            config.get("auth.user_header_name"): "*****@*****.**",
            config.get("auth.groups_header_name"): "groupa,groupb,groupc",
        }

        response = self.fetch(
            "/api/v2/templated_resource/fake_repo/path/to/file.yaml",
            method="GET",
            headers=headers,
        )
        self.assertEqual(response.code, 200)
        response_body = json.loads(response.body)
        self.assertEqual(
            response_body,
            {
                "name": "fake_test_template_1",
                "owner": "fake_owner",
                "include_accounts": ["fake_account_1"],
                "exclude_accounts": None,
                "number_of_accounts": 1,
                "resource": "path/to/file.yaml",
                "resource_type": "iam_role",
                "repository_name": "fake_repo",
                "template_language": "honeybee",
                "web_path":
                "http://github.example.com/fake_repo/browse/master/path/to/file.yaml",
                "file_path": "path/to/file.yaml",
                "content": None,
            },
        )
import asyncio
from unittest import TestCase

import ujson as json
from mock import MagicMock, patch

from tests.conftest import create_future

mock_aws_config_resources_redis = MagicMock(
    return_value=create_future(json.dumps({"accountId": "123456789012"}))
)


class TestPoliciesLib(TestCase):
    def test_get_actions_for_resource(self):
        from consoleme.lib.policies import get_actions_for_resource

        test_cases = [
            {
                "arn": "arn:aws:s3:::foobar",
                "statement": {
                    "Action": ["s3:PutObject", "s3:GetObject", "ec2:DescribeInstances"],
                    "Resource": ["arn:aws:s3:::foobar", "arn:aws:s3:::foobar/*"],
                    "Effect": "Allow",
                },
                "expected": ["s3:PutObject", "s3:GetObject"],
                "description": "Statement with list Action and Resource",
            },
            {
                "arn": "arn:aws:s3:::foobar",
                "statement": {