pyceo/ceo_common/model/HTTPClient.py

71 lines
2.5 KiB
Python
Raw Normal View History

2021-08-23 09:59:01 -04:00
from base64 import b64encode
from typing import Union
2021-07-24 17:09:10 -04:00
import gssapi
import requests
from requests_gssapi import HTTPSPNEGOAuth
from zope import component
from zope.interface import implementer
2021-08-23 09:59:01 -04:00
from ceo_common.krb5.utils import get_fwd_tgt
2021-08-18 19:48:17 -04:00
from ceo_common.interfaces import IConfig, IHTTPClient
2021-07-24 17:09:10 -04:00
@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')
2021-08-03 19:19:33 -04:00
self.base_domain = cfg.get('base_domain')
2021-07-24 17:09:10 -04:00
2021-08-23 09:59:01 -04:00
def request(self, host: str, api_path: str, method: str, principal: str,
need_cred: bool, **kwargs):
2021-08-21 02:27:33 -04:00
# always use the FQDN
if '.' not in host:
host = host + '.' + self.base_domain
2021-08-23 09:59:01 -04:00
# SPNEGO
if principal is not None:
gssapi_name = gssapi.Name(principal)
creds = gssapi.Credentials(name=gssapi_name, usage='initiate')
else:
creds = None
2021-07-24 17:09:10 -04:00
auth = HTTPSPNEGOAuth(
opportunistic_auth=True,
2021-08-21 02:27:33 -04:00
target_name=gssapi.Name('ceod/' + host),
2021-08-17 21:59:24 -04:00
creds=creds,
2021-07-24 17:09:10 -04:00
)
2021-08-23 09:59:01 -04:00
# Forwarded TGT (X-KRB5-CRED)
headers = {}
if need_cred:
b = get_fwd_tgt('ceod/' + host)
headers['X-KRB5-CRED'] = b64encode(b).decode()
2021-07-24 17:09:10 -04:00
return requests.request(
method,
f'{self.scheme}://{host}:{self.ceod_port}{api_path}',
2021-08-23 09:59:01 -04:00
auth=auth, headers=headers, **kwargs,
2021-07-24 17:09:10 -04:00
)
2021-08-23 09:59:01 -04:00
def get(self, host: str, api_path: str, principal: Union[str, None] = None,
need_cred: bool = False, **kwargs):
return self.request(host, api_path, 'GET', principal, need_cred, **kwargs)
def post(self, host: str, api_path: str, principal: Union[str, None] = None,
need_cred: bool = False, **kwargs):
return self.request(host, api_path, 'POST', principal, need_cred, **kwargs)
2021-07-24 17:09:10 -04:00
2021-08-23 09:59:01 -04:00
def patch(self, host: str, api_path: str, principal: Union[str, None] = None,
need_cred: bool = False, **kwargs):
return self.request(host, api_path, 'PATCH', principal, need_cred, **kwargs)
2021-07-24 17:09:10 -04:00
2021-08-23 09:59:01 -04:00
def delete(self, host: str, api_path: str, principal: Union[str, None] = None,
need_cred: bool = False, **kwargs):
return self.request(host, api_path, 'DELETE', principal, need_cred, **kwargs)