コード例 #1
0
def _validate_user_rbac(auth_info, username, client=None):
    """Check if a user is active and/or superuser via RBAC."""
    if client is None:
        from maasserver.rbac import RBACClient

        client = RBACClient()

    try:
        is_admin = bool(
            client.allowed_for_user("maas", username, "admin")["admin"]
        )
        access_to_pools = any(
            client.allowed_for_user(
                "resource-pool",
                username,
                "view",
                "view-all",
                "deploy-machines",
                "admin-machines",
            ).values()
        )
        user_details = client.get_user_details(username)
    except APIError:
        raise UserValidationFailed()

    return (is_admin or access_to_pools, is_admin, user_details)
コード例 #2
0
ファイル: test_rbac.py プロジェクト: jamal-fuma/maas
    def setUp(self):
        super().setUp()
        key = PrivateKey.deserialize(
            'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=')
        agent = Agent(url='https://auth.example.com', username='******')
        auth_info = AuthInfo(key=key, agents=[agent])
        url = 'https://rbac.example.com/'

        self.mock_request = self.patch(requests, 'request')
        self.client = RBACClient(url=url, auth_info=auth_info)
コード例 #3
0
def _validate_user_rbac(auth_info, username, client=None):
    """Check if a user is active and/or superuser via RBAC."""
    if client is None:
        from maasserver.rbac import RBACClient
        client = RBACClient()

    try:
        is_admin = bool(
            client.allowed_for_user('maas', username, 'admin')['admin'])
        access_to_pools = any(
            client.allowed_for_user('resource-pool', username, 'view',
                                    'view-all', 'deploy-machines',
                                    'admin-machines').values())
    except APIError:
        raise UserValidationFailed()

    return is_admin or access_to_pools, is_admin
コード例 #4
0
ファイル: macaroon_auth.py プロジェクト: ajeetraina/maas
def _validate_user_rbac(auth_info, username, client=None):
    """Check if a user is active and/or superuser via RBAC."""
    if client is None:
        from maasserver.rbac import RBACClient
        client = RBACClient()

    try:
        admin_resource = client.allowed_for_user('maas', username, 'admin')
        pool_resources = client.allowed_for_user('maas', username,
                                                 'resource-pool')
    except APIError:
        raise UserValidationFailed()

    # and is active if it has access to any resource
    active = any([admin_resource, pool_resources])
    # and is superuser if the admin resource is returned
    superuser = bool(admin_resource)
    return active, superuser
コード例 #5
0
ファイル: test_rbac.py プロジェクト: jamal-fuma/maas
 def test_default_config_from_settings(self):
     Config.objects.set_config('rbac_url', 'https://rbac.example.com')
     Config.objects.set_config('external_auth_url',
                               'https://auth.example.com')
     Config.objects.set_config('external_auth_user', 'user@candid')
     Config.objects.set_config(
         'external_auth_key',
         'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=')
     client = RBACClient()
     self.assertEqual(client._url, 'https://rbac.example.com')
     self.assertEqual(
         client._auth_info.key,
         PrivateKey.deserialize(
             'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY='))
     [agent] = client._auth_info.agents
     self.assertEqual(agent.url, 'https://auth.example.com')
     self.assertEqual(agent.username, 'user@candid')
コード例 #6
0
    def _getRBACClient(self):
        """Return the `RBACClient`.

        This tries to use an already held client when initialized because the
        cookiejar will be updated with the already authenticated macaroon.
        """
        url = Config.objects.get_config('rbac_url')
        if not url:
            # RBAC is not enabled (or no longer enabled).
            self.rbacClient = None
            return None

        auth_info = get_auth_info()
        if (self.rbacClient is None or self.rbacClient._url != url
                or self.rbacClient._auth_info != auth_info):
            self.rbacClient = RBACClient(url, auth_info)

        return self.rbacClient
コード例 #7
0
ファイル: test_rbac.py プロジェクト: ocni-dtu/maas
 def test_default_config_from_settings(self):
     Config.objects.set_config("rbac_url", "https://rbac.example.com")
     Config.objects.set_config("external_auth_url",
                               "https://auth.example.com")
     Config.objects.set_config("external_auth_user", "user@candid")
     Config.objects.set_config(
         "external_auth_key",
         "x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=")
     client = RBACClient()
     self.assertEqual(client._url, "https://rbac.example.com")
     self.assertEqual(
         client._auth_info.key,
         PrivateKey.deserialize(
             "x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY="),
     )
     [agent] = client._auth_info.agents
     self.assertEqual(agent.url, "https://auth.example.com")
     self.assertEqual(agent.username, "user@candid")
コード例 #8
0
ファイル: test_rbac.py プロジェクト: jamal-fuma/maas
class TestRBACClient(MAASServerTestCase):
    def setUp(self):
        super().setUp()
        key = PrivateKey.deserialize(
            'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=')
        agent = Agent(url='https://auth.example.com', username='******')
        auth_info = AuthInfo(key=key, agents=[agent])
        url = 'https://rbac.example.com/'

        self.mock_request = self.patch(requests, 'request')
        self.client = RBACClient(url=url, auth_info=auth_info)

    def test_default_config_from_settings(self):
        Config.objects.set_config('rbac_url', 'https://rbac.example.com')
        Config.objects.set_config('external_auth_url',
                                  'https://auth.example.com')
        Config.objects.set_config('external_auth_user', 'user@candid')
        Config.objects.set_config(
            'external_auth_key',
            'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=')
        client = RBACClient()
        self.assertEqual(client._url, 'https://rbac.example.com')
        self.assertEqual(
            client._auth_info.key,
            PrivateKey.deserialize(
                'x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY='))
        [agent] = client._auth_info.agents
        self.assertEqual(agent.url, 'https://auth.example.com')
        self.assertEqual(agent.username, 'user@candid')

    def test_get_resources(self):
        resources = [
            {
                'identifier': '1',
                'name': 'pool-1',
            },
            {
                'identifier': '2',
                'name': 'pool-2',
            },
        ]
        response = mock.MagicMock(status_code=200)
        response.json.return_value = resources
        self.mock_request.return_value = response
        self.assertCountEqual(self.client.get_resources('resource-pool'), [
            Resource(identifier='1', name='pool-1'),
            Resource(identifier='2', name='pool-2'),
        ])
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith('GET', 'https://rbac.example.com/api/'
                               'service/1.0/resources/resource-pool',
                               auth=mock.ANY,
                               cookies=mock.ANY,
                               json=None))

    def test_update_resources(self):
        updates = [
            Resource(identifier='1', name='pool-1'),
            Resource(identifier='2', name='pool-2'),
        ]
        removals = [11, 22, 33]
        json = {
            'last-sync-id':
            'a-b-c',
            'updates': [
                {
                    'identifier': '1',
                    'name': 'pool-1',
                },
                {
                    'identifier': '2',
                    'name': 'pool-2',
                },
            ],
            'removals': ['11', '22', '33']
        }
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {'sync-id': 'x-y-z'}
        self.mock_request.return_value = response
        sync_id = self.client.update_resources('resource-pool',
                                               updates=updates,
                                               removals=removals,
                                               last_sync_id='a-b-c')
        self.assertEqual(sync_id, 'x-y-z')
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith('POST', 'https://rbac.example.com/api/'
                               'service/1.0/resources/resource-pool',
                               auth=mock.ANY,
                               cookies=mock.ANY,
                               json=json))

    def test_update_resources_no_sync_id(self):
        updates = [
            Resource(identifier='1', name='pool-1'),
            Resource(identifier='2', name='pool-2'),
        ]
        removals = [11, 22, 33]
        # removals are ignored
        json = {
            'last-sync-id':
            None,
            'updates': [
                {
                    'identifier': '1',
                    'name': 'pool-1',
                },
                {
                    'identifier': '2',
                    'name': 'pool-2',
                },
            ],
            'removals': []
        }
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {'sync-id': 'x-y-z'}
        self.mock_request.return_value = response
        sync_id = self.client.update_resources('resource-pool',
                                               updates=updates,
                                               removals=removals)
        self.assertEqual(sync_id, 'x-y-z')
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith('POST', 'https://rbac.example.com/api/'
                               'service/1.0/resources/resource-pool',
                               auth=mock.ANY,
                               cookies=mock.ANY,
                               json=json))

    def test_update_resources_sync_conflict(self):
        updates = [
            Resource(identifier='1', name='pool-1'),
            Resource(identifier='2', name='pool-2'),
        ]
        removals = [11, 22, 33]
        response = mock.MagicMock(status_code=int(http.client.CONFLICT))
        response.json.return_value = {'sync-id': 'x-y-z'}
        self.mock_request.return_value = response
        self.assertRaises(SyncConflictError,
                          self.client.update_resources,
                          'resource-pool',
                          updates=updates,
                          removals=removals,
                          last_sync_id='a-b-c')

    def test_allowed_for_user_all_resources(self):
        response = mock.MagicMock(status_code=200)
        response.json.return_value = [""]
        self.mock_request.return_value = response

        user = factory.make_name('user')
        self.assertEqual(ALL_RESOURCES,
                         self.client.allowed_for_user('maas', user, 'admin'))
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                'GET',
                'https://rbac.example.com/api/'
                'service/1.0/resources/maas/'
                'allowed-for-user?user={}&permission=admin'.format(user),
                auth=mock.ANY,
                cookies=mock.ANY,
                json=None))

    def test_allowed_for_user_resource_ids(self):
        response = mock.MagicMock(status_code=200)
        response.json.return_value = ["1", "2", "3"]
        self.mock_request.return_value = response

        user = factory.make_name('user')
        self.assertEqual([1, 2, 3],
                         self.client.allowed_for_user('maas', user, 'admin'))
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                'GET',
                'https://rbac.example.com/api/'
                'service/1.0/resources/maas/'
                'allowed-for-user?user={}&permission=admin'.format(user),
                auth=mock.ANY,
                cookies=mock.ANY,
                json=None))
コード例 #9
0
ファイル: test_rbac.py プロジェクト: ocni-dtu/maas
class TestRBACClient(MAASServerTestCase):
    def setUp(self):
        super().setUp()
        key = PrivateKey.deserialize(
            "x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=")
        agent = Agent(url="https://auth.example.com", username="******")
        auth_info = AuthInfo(key=key, agents=[agent])
        url = "https://rbac.example.com/"

        self.mock_request = self.patch(requests, "request")
        self.client = RBACClient(url=url, auth_info=auth_info)

    def test_default_config_from_settings(self):
        Config.objects.set_config("rbac_url", "https://rbac.example.com")
        Config.objects.set_config("external_auth_url",
                                  "https://auth.example.com")
        Config.objects.set_config("external_auth_user", "user@candid")
        Config.objects.set_config(
            "external_auth_key",
            "x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY=")
        client = RBACClient()
        self.assertEqual(client._url, "https://rbac.example.com")
        self.assertEqual(
            client._auth_info.key,
            PrivateKey.deserialize(
                "x0NeASLPFhOFfq3Q9M0joMveI4HjGwEuJ9dtX/HTSRY="),
        )
        [agent] = client._auth_info.agents
        self.assertEqual(agent.url, "https://auth.example.com")
        self.assertEqual(agent.username, "user@candid")

    def test_get_user(self):
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {
            "username": "******",
            "name": "A user",
            "email": "*****@*****.**",
        }
        self.mock_request.return_value = response
        details = self.client.get_user_details("user")
        self.assertEqual(details.username, "user")
        self.assertEqual(details.fullname, "A user")
        self.assertEqual(details.email, "*****@*****.**")
        self.mock_request.assert_called_once_with(
            "GET",
            "https://rbac.example.com/api/service/v1/user/user",
            auth=mock.ANY,
            cookies=mock.ANY,
            json=None,
        )

    def test_get_resources(self):
        resources = [
            {
                "identifier": "1",
                "name": "pool-1"
            },
            {
                "identifier": "2",
                "name": "pool-2"
            },
        ]
        response = mock.MagicMock(status_code=200)
        response.json.return_value = resources
        self.mock_request.return_value = response
        self.assertCountEqual(
            self.client.get_resources("resource-pool"),
            [
                Resource(identifier="1", name="pool-1"),
                Resource(identifier="2", name="pool-2"),
            ],
        )
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                "GET",
                "https://rbac.example.com/api/"
                "service/v1/resources/resource-pool",
                auth=mock.ANY,
                cookies=mock.ANY,
                json=None,
            ),
        )

    def test_update_resources(self):
        updates = [
            Resource(identifier="1", name="pool-1"),
            Resource(identifier="2", name="pool-2"),
        ]
        removals = [11, 22, 33]
        json = {
            "last-sync-id":
            "a-b-c",
            "updates": [
                {
                    "identifier": "1",
                    "name": "pool-1"
                },
                {
                    "identifier": "2",
                    "name": "pool-2"
                },
            ],
            "removals": ["11", "22", "33"],
        }
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {"sync-id": "x-y-z"}
        self.mock_request.return_value = response
        sync_id = self.client.update_resources(
            "resource-pool",
            updates=updates,
            removals=removals,
            last_sync_id="a-b-c",
        )
        self.assertEqual(sync_id, "x-y-z")
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                "POST",
                "https://rbac.example.com/api/"
                "service/v1/resources/resource-pool",
                auth=mock.ANY,
                cookies=mock.ANY,
                json=json,
            ),
        )

    def test_update_resources_no_sync_id(self):
        updates = [
            Resource(identifier="1", name="pool-1"),
            Resource(identifier="2", name="pool-2"),
        ]
        removals = [11, 22, 33]
        # removals are ignored
        json = {
            "last-sync-id":
            None,
            "updates": [
                {
                    "identifier": "1",
                    "name": "pool-1"
                },
                {
                    "identifier": "2",
                    "name": "pool-2"
                },
            ],
            "removals": [],
        }
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {"sync-id": "x-y-z"}
        self.mock_request.return_value = response
        sync_id = self.client.update_resources("resource-pool",
                                               updates=updates,
                                               removals=removals)
        self.assertEqual(sync_id, "x-y-z")
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                "POST",
                "https://rbac.example.com/api/"
                "service/v1/resources/resource-pool",
                auth=mock.ANY,
                cookies=mock.ANY,
                json=json,
            ),
        )

    def test_update_resources_sync_conflict(self):
        updates = [
            Resource(identifier="1", name="pool-1"),
            Resource(identifier="2", name="pool-2"),
        ]
        removals = [11, 22, 33]
        response = mock.MagicMock(status_code=int(http.client.CONFLICT))
        response.json.return_value = {"sync-id": "x-y-z"}
        self.mock_request.return_value = response
        self.assertRaises(
            SyncConflictError,
            self.client.update_resources,
            "resource-pool",
            updates=updates,
            removals=removals,
            last_sync_id="a-b-c",
        )

    def test_allowed_for_user_all_resources(self):
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {"admin": [""]}
        self.mock_request.return_value = response

        user = factory.make_name("user")
        self.assertEqual(
            {"admin": ALL_RESOURCES},
            self.client.allowed_for_user("maas", user, "admin"),
        )
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                "GET",
                "https://rbac.example.com/api/"
                "service/v1/resources/maas/"
                "allowed-for-user?u={}&p=admin".format(user),
                auth=mock.ANY,
                cookies=mock.ANY,
                json=None,
            ),
        )

    def test_allowed_for_user_resource_ids(self):
        response = mock.MagicMock(status_code=200)
        response.json.return_value = {"admin": ["1", "2", "3"]}
        self.mock_request.return_value = response

        user = factory.make_name("user")
        self.assertEqual(
            {"admin": [1, 2, 3]},
            self.client.allowed_for_user("maas", user, "admin"),
        )
        self.assertThat(
            self.mock_request,
            MockCalledOnceWith(
                "GET",
                "https://rbac.example.com/api/"
                "service/v1/resources/maas/"
                "allowed-for-user?u={}&p=admin".format(user),
                auth=mock.ANY,
                cookies=mock.ANY,
                json=None,
            ),
        )