import subprocess from typing import Any from unittest.mock import patch import orjson from django.http import HttpResponse from zerver.lib.test_classes import ZulipTestCase from zerver.lib.users import get_api_key from zerver.models import get_realm, get_user class ZephyrTest(ZulipTestCase): def test_webathena_kerberos_login(self) -> None: user = self.example_user('hamlet') self.login_user(user) def post(subdomain: Any, **kwargs: Any) -> HttpResponse: params = {k: orjson.dumps(v).decode() for k, v in kwargs.items()} return self.client_post( '/accounts/webathena_kerberos_login/', params, subdomain=subdomain ) result = post("zulip") self.assert_json_error(result, 'Could not find Kerberos credential') result = post("zulip", cred='whatever') self.assert_json_error(result, 'Webathena login not enabled') email = str(self.mit_email("starnine")) realm = get_realm('zephyr') user = get_user(email, realm) api_key = get_api_key(user) self.login_user(user) def ccache_mock(**kwargs: Any) -> Any: return patch('zerver.views.zephyr.make_ccache', **kwargs) def ssh_mock(**kwargs: Any) -> Any: return patch('zerver.views.zephyr.subprocess.check_call', **kwargs) def mirror_mock() -> Any: return self.settings(PERSONAL_ZMIRROR_SERVER='server') cred = dict(cname=dict(nameString=['starnine'])) with ccache_mock(side_effect=KeyError('foo')): result = post("zephyr", cred=cred) self.assert_json_error(result, 'Invalid Kerberos cache') with ccache_mock(return_value=b'1234'), ssh_mock( side_effect=subprocess.CalledProcessError(1, []) ), self.assertLogs(level='ERROR') as log: result = post("zephyr", cred=cred) self.assert_json_error(result, 'We were unable to setup mirroring for you') self.assertIn("Error updating the user's ccache", log.output[0]) with ccache_mock(return_value=b'1234'), mirror_mock(), ssh_mock() as ssh: result = post("zephyr", cred=cred) self.assert_json_success(result) ssh.assert_called_with( [ 'ssh', 'server', '--', f'/home/zulip/python-zulip-api/zulip/integrations/zephyr/process_ccache starnine {api_key} MTIzNA==', ] ) # Accounts whose Kerberos usernames are known not to match their # zephyr accounts are hardcoded, and should be handled properly. def kerberos_alter_egos_mock() -> Any: return patch( 'zerver.views.zephyr.kerberos_alter_egos', {'kerberos_alter_ego': 'starnine'} ) cred = dict(cname=dict(nameString=['kerberos_alter_ego'])) with ccache_mock( return_value=b'1234' ), mirror_mock(), ssh_mock() as ssh, kerberos_alter_egos_mock(): result = post("zephyr", cred=cred) self.assert_json_success(result) ssh.assert_called_with( [ 'ssh', 'server', '--', f'/home/zulip/python-zulip-api/zulip/integrations/zephyr/process_ccache starnine {api_key} MTIzNA==', ] )