def test_handle_response_500_mutual_auth_required_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fail_resp): response_500 = requests.Response() response_500.url = "http://www.example.org/" response_500.status_code = 500 response_500.headers = {} response_500.request = "REQUEST" response_500.connection = "CONNECTION" response_500._content = "CONTENT" response_500.encoding = "ENCODING" response_500.raw = "RAW" response_500.cookies = "COOKIES" auth = requests_gssapi.HTTPKerberosAuth( mutual_authentication=REQUIRED) auth.context = {"www.example.org": "CTX"} r = auth.handle_response(response_500) self.assertTrue( isinstance(r, requests_gssapi.gssapi_.SanitizedResponse)) self.assertNotEqual(r, response_500) self.assertNotEqual(r.headers, response_500.headers) self.assertEqual(r.status_code, response_500.status_code) self.assertEqual(r.encoding, response_500.encoding) self.assertEqual(r.raw, response_500.raw) self.assertEqual(r.url, response_500.url) self.assertEqual(r.reason, response_500.reason) self.assertEqual(r.connection, response_500.connection) self.assertEqual(r.content, '') self.assertNotEqual(r.cookies, response_500.cookies) self.assertFalse(fail_resp.called) # re-test with error response sanitizing disabled auth = requests_gssapi.HTTPKerberosAuth( sanitize_mutual_error_response=False) auth.context = {"www.example.org": "CTX"} r = auth.handle_response(response_500) self.assertFalse( isinstance(r, requests_gssapi.gssapi_.SanitizedResponse))
def test_no_force_preemptive(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): auth = requests_gssapi.HTTPKerberosAuth() request = requests.Request(url="http://www.example.org") auth.__call__(request) self.assertTrue('Authorization' not in request.headers)
def test_force_preemptive(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): auth = requests_gssapi.HTTPKerberosAuth(force_preemptive=True) request = requests.Request(url="http://www.example.org") auth.__call__(request) self.assertTrue('Authorization' in request.headers) self.assertEqual(request.headers.get('Authorization'), 'Negotiate GSSRESPONSE')
def test_generate_request_header_init_error(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fail_resp): response = requests.Response() response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth() self.assertRaises(requests_gssapi.exceptions.SPNEGOExchangeError, auth.generate_request_header, response, host) fake_init.assert_called_with( name=gssapi_name("*****@*****.**"), usage="initiate", flags=gssflags, creds=None)
def test_generate_request_header_custom_service(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth(service="barfoo") auth.generate_request_header(response, host), fake_init.assert_called_with( name=gssapi_name("*****@*****.**"), usage="initiate", flags=gssflags, creds=None) fake_resp.assert_called_with(b"token")
def test_realm_override(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth( hostname_override="otherhost.otherdomain.org") auth.generate_request_header(response, host) fake_init.assert_called_with( name=gssapi_sname("*****@*****.**"), usage="initiate", flags=gssflags, creds=None, mech=None) fake_resp.assert_called_with(b"token")
def test_principal_override(self): with patch.multiple("gssapi.Credentials", __new__=fake_creds), \ patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth(principal="user@REALM") auth.generate_request_header(response, host) fake_creds.assert_called_with(gssapi.creds.Credentials, usage="initiate", name=gssapi_name("user@REALM")) fake_init.assert_called_with( name=gssapi_name("*****@*****.**"), usage="initiate", flags=gssflags, creds=b"fake creds")
def test_handle_response_200_mutual_auth_required_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = {} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": "CTX"} self.assertRaises(requests_gssapi.MutualAuthenticationError, auth.handle_response, response_ok) self.assertFalse(fake_resp.called)
def test_authenticate_server(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { 'www-authenticate': b64_negotiate_server, 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} result = auth.authenticate_server(response_ok) self.assertTrue(result) fake_resp.assert_called_with(b"servertoken")
def test_handle_response_200_mutual_auth_optional_soft_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 auth = requests_gssapi.HTTPKerberosAuth(requests_gssapi.OPTIONAL) auth.context = {"www.example.org": gssapi.SecurityContext} r = auth.handle_response(response_ok) self.assertEqual(r, response_ok) self.assertFalse(fake_resp.called)
def test_handle_response_401_rejected(self): # Get a 401 from server, authenticate, and get another 401 back. # Ensure there is no infinite recursion. with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): connection = Mock() def connection_send(self, *args, **kwargs): reject = requests.Response() reject.url = "http://www.example.org/" reject.status_code = 401 reject.connection = connection return reject connection.send.side_effect = connection_send raw = Mock() raw.release_conn.return_value = None request = requests.Request() response = requests.Response() response.request = request response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" response.raw = raw auth = requests_gssapi.HTTPKerberosAuth() r = auth.handle_response(response) self.assertEqual(r.status_code, 401) self.assertEqual(request.headers['Authorization'], b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi_sname("*****@*****.**"), usage="initiate", flags=gssflags, creds=None, mech=None) fake_resp.assert_called_with(b"token")
def test_generate_request_header(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response = requests.Response() response.url = "http://www.example.org/" response.headers = {'www-authenticate': 'negotiate token'} host = urlparse(response.url).hostname auth = requests_gssapi.HTTPKerberosAuth() self.assertEqual(auth.generate_request_header(response, host), "Negotiate GSSRESPONSE") fake_init.assert_called_with( name=gssapi.Name("*****@*****.**"), creds=None, flags=gssflags, usage="initiate") fake_resp.assert_called_with("token")
def test_handle_response_200_mutual_auth_required_failure_2(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fail_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { 'www-authenticate': b64_negotiate_server, 'authorization': b64_negotiate_response} auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} self.assertRaises(requests_gssapi.MutualAuthenticationError, auth.handle_response, response_ok) fail_resp.assert_called_with(b"servertoken")
def test_handle_response_401(self): # Get a 401 from server, authenticate, and get a 200 back. with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = {'www-authenticate': b64_negotiate_server} connection = Mock() connection.send = Mock(return_value=response_ok) raw = Mock() raw.release_conn = Mock(return_value=None) request = requests.Request() response = requests.Response() response.request = request response.url = "http://www.example.org/" response.headers = {'www-authenticate': b64_negotiate_token} response.status_code = 401 response.connection = connection response._content = "" response.raw = raw auth = requests_gssapi.HTTPKerberosAuth() auth.handle_other = Mock(return_value=response_ok) r = auth.handle_response(response) self.assertTrue(response in r.history) auth.handle_other.assert_called_once_with(response_ok) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], b64_negotiate_response) connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi_sname("*****@*****.**"), usage="initiate", flags=gssflags, creds=None, mech=None) fake_resp.assert_called_with(b"token")
def test_handle_response_200(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = { 'www-authenticate': 'negotiate servertoken', 'authorization': 'Negotiate GSSRESPONSE' } auth = requests_gssapi.HTTPKerberosAuth() auth.context = {"www.example.org": gssapi.SecurityContext} r = auth.handle_response(response_ok) self.assertEqual(r, response_ok) fake_resp.assert_called_with("servertoken")
def test_delegation(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fake_resp): response_ok = requests.Response() response_ok.url = "http://www.example.org/" response_ok.status_code = 200 response_ok.headers = {'www-authenticate': 'negotiate servertoken'} connection = Mock() connection.send = Mock(return_value=response_ok) raw = Mock() raw.release_conn = Mock(return_value=None) request = requests.Request() response = requests.Response() response.request = request response.url = "http://www.example.org/" response.headers = {'www-authenticate': 'negotiate token'} response.status_code = 401 response.connection = connection response._content = "" response.raw = raw auth = requests_gssapi.HTTPKerberosAuth(1, "HTTP", True) r = auth.authenticate_user(response) self.assertTrue(response in r.history) self.assertEqual(r, response_ok) self.assertEqual(request.headers['Authorization'], 'Negotiate GSSRESPONSE') connection.send.assert_called_with(request) raw.release_conn.assert_called_with() fake_init.assert_called_with( name=gssapi.Name("*****@*****.**"), usage="initiate", flags=gssdelegflags, creds=None) fake_resp.assert_called_with("token")
def test_handle_response_500_mutual_auth_optional_failure(self): with patch.multiple("gssapi.SecurityContext", __init__=fake_init, step=fail_resp): response_500 = requests.Response() response_500.url = "http://www.example.org/" response_500.status_code = 500 response_500.headers = {} response_500.request = "REQUEST" response_500.connection = "CONNECTION" response_500._content = "CONTENT" response_500.encoding = "ENCODING" response_500.raw = "RAW" response_500.cookies = "COOKIES" auth = requests_gssapi.HTTPKerberosAuth(requests_gssapi.OPTIONAL) auth.context = {"www.example.org": "CTX"} r = auth.handle_response(response_500) self.assertEqual(r, response_500) self.assertFalse(fail_resp.called)
def cli(comment, waived, product_version, testcase, subject, result_id, config_file): """ Creates new waiver against test results. Examples: waiverdb-cli -r 123 -r 456 -p "fedora-26" -c "It's dead!" or waiverdb-cli -t dist.rpmlint -s '{"item": "python-requests-1.2.3-1.fc26", "type": "koji_build"}' -p "fedora-26" -c "It's dead!" """ config = configparser.SafeConfigParser() config.read(config_file) validate_config(config) result_ids = result_id if not product_version: raise click.ClickException('Please specify product version') if result_ids and (subject or testcase): raise click.ClickException( 'Please specify result_id or subject/testcase. Not both') if not result_ids and not subject: raise click.ClickException('Please specify one subject') if not result_ids and not testcase: raise click.ClickException('Please specify testcase') auth_method = config.get('waiverdb', 'auth_method') data_list = [] if not result_ids: data_list.append({ 'subject': json.loads(subject), 'testcase': testcase, 'waived': waived, 'product_version': product_version, 'comment': comment }) # XXX - TODO - remove this in a future release. (for backwards compat) for result_id in result_ids: data_list.append({ 'result_id': result_id, 'waived': waived, 'product_version': product_version, 'comment': comment }) api_url = config.get('waiverdb', 'api_url') if auth_method == 'OIDC': # Try to import this now so the user gets immediate feedback if # it isn't installed try: import openidc_client # noqa: F401 except ImportError: raise click.ClickException( 'python-openidc-client needs to be installed') # Get the auth token using the OpenID client. oidc_client_secret = None if config.has_option('waiverdb', 'oidc_client_secret'): oidc_client_secret = config.get('waiverdb', 'oidc_client_secret') oidc = openidc_client.OpenIDCClient( 'waiverdb', config.get('waiverdb', 'oidc_id_provider'), { 'Token': 'Token', 'Authorization': 'Authorization' }, config.get('waiverdb', 'oidc_client_id'), oidc_client_secret) scopes = config.get('waiverdb', 'oidc_scopes').strip().splitlines() for data in data_list: resp = oidc.send_request( scopes=scopes, url='{0}/waivers/'.format(api_url.rstrip('/')), data=json.dumps(data), headers={'Content-Type': 'application/json'}, timeout=60) check_response(resp, data, data.get('result_id', None)) elif auth_method == 'Kerberos': # Try to import this now so the user gets immediate feedback if # it isn't installed try: import requests_gssapi # noqa: F401 except ImportError: raise click.ClickException( 'python-requests-gssapi needs to be installed') auth = requests_gssapi.HTTPKerberosAuth( mutual_authentication=requests_gssapi.OPTIONAL) for data in data_list: resp = requests.request( 'POST', '{0}/waivers/'.format(api_url.rstrip('/')), data=json.dumps(data), auth=auth, headers={'Content-Type': 'application/json'}, timeout=60) if resp.status_code == 401: raise click.ClickException( 'WaiverDB authentication using GSSAPI failed. ' 'Make sure you have a valid Kerberos ticket.') check_response(resp, data, data.get('result_id', None)) elif auth_method == 'dummy': for data in data_list: resp = requests.request( 'POST', '{0}/waivers/'.format(api_url.rstrip('/')), data=json.dumps(data), auth=('user', 'pass'), headers={'Content-Type': 'application/json'}, timeout=60) check_response(resp, data, data.get('result_id', None))