from flask import g import gssapi import requests from requests_gssapi import HTTPSPNEGOAuth from zope import component from zope.interface import implementer from ceo_common.interfaces import IConfig, IHTTPClient @implementer(IHTTPClient) class HTTPClient: def __init__(self): # Determine how to connect to other ceod instances cfg = component.getUtility(IConfig) if cfg.get('ceod_use_https'): self.scheme = 'https' else: self.scheme = 'http' self.ceod_port = cfg.get('ceod_port') self.base_domain = cfg.get('base_domain') self.krb_realm = cfg.get('ldap_sasl_realm') def request(self, host: str, api_path: str, method='GET', **kwargs): principal = g.sasl_user if '@' not in principal: principal = principal + '@' + self.krb_realm gssapi_name = gssapi.Name(principal) creds = gssapi.Credentials(name=gssapi_name, usage='initiate') auth = HTTPSPNEGOAuth( opportunistic_auth=True, target_name='ceod', creds=creds, ) # always use the FQDN, for HTTPS purposes if '.' not in host: host = host + '.' + self.base_domain return requests.request( method, f'{self.scheme}://{host}:{self.ceod_port}{api_path}', auth=auth, **kwargs, ) def get(self, host: str, api_path: str, **kwargs): return self.request(host, api_path, 'GET', **kwargs) def post(self, host: str, api_path: str, **kwargs): return self.request(host, api_path, 'POST', **kwargs) def delete(self, host: str, api_path: str, **kwargs): return self.request(host, api_path, 'DELETE', **kwargs)