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()
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
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)