Example #1
0
    def user_exist(self, uid):
        """Cache the results of looking up the user in Keycloak"""
        if not LOCAL_KEYCLOAK_TESTING:
            with KeyCloakClient('BOSS') as kc:
                return kc.user_exist(uid)

        # Code for local testing with KeyCloak.
        try:
            kc = KeyCloakClient('BOSS',
                                url_base='http://localhost:8080/auth',
                                https=False)
            kc.login(username=KEYCLOAK_ADMIN_USER,
                     password=KEYCLOAK_ADMIN_PASSWORD,
                     client_id='admin-cli',
                     login_realm='master')
            return kc.user_exist(uid)
        finally:
            kc.logout()
Example #2
0
    def get_keycloak_client(self):
        """
        Get the KeyCloak client.

        If LOCAL_KEYCLOAK_TESTING set in the Django settings, logs in using to the
        local test KeyCloak server.

        Returns:
            (KeyCloakClient)
        """
        if LOCAL_KEYCLOAK_TESTING:
            kc = KeyCloakClient('BOSS',
                                url_base='http://localhost:8080/auth',
                                https=False)
            kc.login(username=KEYCLOAK_ADMIN_USER,
                     password=KEYCLOAK_ADMIN_PASSWORD,
                     client_id='admin-cli',
                     login_realm='master')
        else:
            kc = KeyCloakClient('BOSS')

        return kc
Example #3
0
class TestAuthentication(unittest.TestCase):
    """Test the login/logout methods and the context manager that wraps login/logout"""

    def setUp(self):
        self.client = KeyCloakClient(REALM, BASE)

    @mock.patch(prefix + 'keycloak.Vault', autospec = True)
    @mock.patch(prefix + 'keycloak.requests.post', autospec = True)
    def test_login(self, mPost, mVault):
        """Test that login() make the correct POST call with data from Vault and created the internal token variable"""
        mPost.return_value = MockResponse(200, json.dumps(TOKEN))
        mVault.return_value.read = lambda p, k: k

        self.assertIsNone(self.client.token)

        self.client.login()

        self.assertEqual(self.client.token, TOKEN)

        # DP NOTE: since the post call contains information read from Vault
        #          I don't explicitly check for the calls to Vault, because
        #          if they didn't happen, they the post call assert will fail

        url = BASE + '/realms/realm/protocol/openid-connect/token'
        data = {'grant_type': 'password',
                'client_id': 'client_id',
                'username': '******',
                'password': '******' }
        call = mock.call(url, data = data, verify = True)
        self.assertEqual(mPost.mock_calls, [call])

    @mock.patch(prefix + 'keycloak.Vault', autospec = True)
    @mock.patch(prefix + 'keycloak.requests.post', autospec = True)
    def test_failed_login(self, mPost, mVault):
        """Test that if there is an error from Keycloak when logging in that a KeyCloakError is raised"""
        mPost.return_value = MockResponse(500, '[]')
        mVault.return_value.read = lambda p, k: k

        with self.assertRaises(KeyCloakError):
            self.client.login()

    @mock.patch(prefix + 'keycloak.requests.post', autospec = True)
    def test_logout(self, mPost):
        """Test that logout() makes the correct POST call with data used in login and clears the token variable"""
        mPost.return_value = MockResponse(200, '[]')

        self.client.login = MethodType(mock_login, self.client) # See comment in TestRequests.setUp()
        self.client.login()

        self.assertEqual(self.client.token, TOKEN)

        self.client.logout()

        self.assertIsNone(self.client.token)

        url = BASE + '/realms/realm/protocol/openid-connect/logout'
        data = {'refresh_token': 'refresh_token',
                'client_id': 'client_id' }
        call = mock.call(url, data = data, verify = True)
        self.assertEqual(mPost.mock_calls, [call])

    @mock.patch(prefix + 'keycloak.requests.post', autospec = True)
    def test_failed_logout(self, mPost):
        """Test that if there is an error from Keycloak when logging out that a KeyCloakError is raised"""
        mPost.return_value = MockResponse(500, '[]')

        self.client.login = MethodType(mock_login, self.client) # See comment in TestRequests.setUp()
        self.client.login()

        with self.assertRaises(KeyCloakError):
            self.client.logout()

    def test_with(self):
        """Test that that when in a 'using' block that login and logout are called"""
        self.client.loginCalled = False
        self.client.logoutCalled = False

        def call_login(self):
            self.loginCalled = True

        def call_logout(self):
            self.logoutCalled = True

        self.client.login = MethodType(call_login, self.client)
        self.client.logout = MethodType(call_logout, self.client)

        with self.client as kc:
            pass

        self.assertTrue(self.client.loginCalled)
        self.assertTrue(self.client.logoutCalled)

    def test_failed_with(self):
        """Test that if there is an exception in a 'using' block that it is propogated correctly"""
        self.client.loginCalled = False
        self.client.logoutCalled = False

        def call_login(self):
            self.loginCalled = True

        def call_logout(self):
            self.logoutCalled = True

        self.client.login = MethodType(call_login, self.client)
        self.client.logout = MethodType(call_logout, self.client)

        with self.assertRaises(Exception):
            with self.client as kc:
                raise Exception()

        self.assertTrue(self.client.loginCalled)
        self.assertTrue(self.client.logoutCalled)

    def test_failed_with_login(self):
        """Test that when in a 'using' block if login() fails logout() is not called"""
        self.client.loginCalled = False
        self.client.logoutCalled = False

        def call_login(self):
            self.loginCalled = True
            raise Exception()

        def call_logout(self):
            self.logoutCalled = True

        self.client.login = MethodType(call_login, self.client)
        self.client.logout = MethodType(call_logout, self.client)

        with self.assertRaises(Exception):
            with self.client as kc:
                pass

        self.assertTrue(self.client.loginCalled)
        self.assertFalse(self.client.logoutCalled)

    def test_failed_with_logout(self):
        """Test that when in a 'using' block if logout() fails no exception is propogated"""
        self.client.loginCalled = False
        self.client.logoutCalled = False

        def call_login(self):
            self.loginCalled = True

        def call_logout(self):
            self.logoutCalled = True
            raise Exception()

        self.client.login = MethodType(call_login, self.client)
        self.client.logout = MethodType(call_logout, self.client)

        with self.client as kc:
            pass

        self.assertTrue(self.client.loginCalled)
        self.assertTrue(self.client.logoutCalled)