summaryrefslogtreecommitdiff
path: root/ick2/client.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2018-04-06 21:48:07 +0300
committerLars Wirzenius <liw@liw.fi>2018-04-07 16:53:19 +0300
commit965f8816c8637bd7441bafd3f2a606664a74e56c (patch)
tree7304a230ef23105a2f3b9932a130df517fb02eae /ick2/client.py
parent2d0d514d1f86e58d965160c28a4954da33b10baf (diff)
downloadick2-965f8816c8637bd7441bafd3f2a606664a74e56c.tar.gz
Add: AuthClient
Diffstat (limited to 'ick2/client.py')
-rw-r--r--ick2/client.py88
1 files changed, 80 insertions, 8 deletions
diff --git a/ick2/client.py b/ick2/client.py
index 8bcf45b..cda3649 100644
--- a/ick2/client.py
+++ b/ick2/client.py
@@ -13,9 +13,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+import base64
import json
import logging
import time
+import urllib
import requests
@@ -64,18 +66,32 @@ class HttpAPI:
self._send_request(self._session.post, url, headers=headers, body=body)
return None
+ def post_auth(self, url, headers=None, body=None, auth=None):
+ assert auth is not None
+ if headers is None:
+ headers = {}
+ headers['Authorization'] = self._basic_auth(auth)
+ return self._send_request(
+ self._session.post, url, headers=headers, body=body, auth=auth)
+
+ def _basic_auth(self, auth):
+ username, password = auth
+ cleartext = '{}:{}'.format(username, password).encode('UTF-8')
+ encoded = base64.b64encode(cleartext)
+ return 'Basic {}'.format(encoded.decode('UTF-8'))
+
def put(self, url, headers=None, body=None):
self._send_request(self._session.put, url, headers=headers, body=body)
return None
- def _send_request(self, func, url, headers=None, body=None):
+ def _send_request(self, func, url, headers=None, body=None, auth=None):
if headers is None:
headers = {}
headers = dict(headers)
- h, body = self._get_content_type_header(body)
- headers.update(h)
- self._request(func, url, headers=headers, data=body)
- return None
+ if not headers.get('Content-Type'):
+ h, body = self._get_content_type_header(body)
+ headers.update(h)
+ return self._request(func, url, headers=headers, data=body, auth=auth)
def _get_content_type_header(self, body):
if isinstance(body, dict):
@@ -94,7 +110,12 @@ class HttpAPI:
def _request(self, func, url, headers=None, **kwargs):
if headers is None:
headers = {}
- headers.update(self._get_authorization_headers())
+
+ auth = kwargs.get('auth')
+ if auth is None:
+ headers.update(self._get_authorization_headers())
+ if 'auth' in kwargs:
+ del kwargs['auth']
r = func(url, headers=headers, verify=self._verify, **kwargs)
if not r.ok:
@@ -108,6 +129,7 @@ class ControllerClient:
self._name = None
self._api = HttpAPI()
self._url = None
+ self._auth_url = None
def set_client_name(self, name):
self._name = name
@@ -127,13 +149,29 @@ class ControllerClient:
def url(self, path):
return '{}{}'.format(self._url, path)
- def get_artifact_store_url(self):
+ def get_version(self):
url = self.url('/version')
- version = self._api.get_dict(url)
+ return self._api.get_dict(url)
+
+ def get_artifact_store_url(self):
+ version = self.version()
url = version.get('artifact_store')
logging.info('Artifact store URL: %r', url)
return url
+ def get_auth_url(self):
+ version = self.get_version()
+ url = version.get('auth_url')
+ logging.info('Authentication URL: %r', url)
+ return url
+
+ def get_auth_client(self):
+ url = self.get_auth_url()
+ ac = AuthClient()
+ ac.set_auth_url(url)
+ ac.set_http_api(self._api)
+ return ac
+
def get_blob_client(self):
url = self.get_artifact_store_url()
blobs = BlobClient()
@@ -169,6 +207,40 @@ class ControllerClient:
self._api.post(url, headers=headers, body=body)
+class AuthClient:
+
+ def __init__(self):
+ self._auth_url = None
+ self._http_api = HttpAPI()
+ self._client_id = None
+ self._client_secret = None
+
+ def set_auth_url(self, url):
+ self._auth_url = url
+
+ def set_http_api(self, api):
+ self._http_api = api
+
+ def set_client_creds(self, client_id, client_secret):
+ self._client_id = client_id
+ self._client_secret = client_secret
+
+ def get_token(self, scope):
+ auth = (self._client_id, self._client_secret)
+ params = {
+ 'grant_type': 'client_credentials',
+ 'scope': scope,
+ }
+ body = urllib.parse.urlencode(params)
+ headers = {
+ 'Content-Type': 'application/x-www-form-urlencoded',
+ }
+ r = self._http_api.post_auth(
+ self._auth_url, headers=headers, body=body, auth=auth)
+ obj = r.json()
+ return obj['access_token']
+
+
class Reporter: # pragma: no cover
def __init__(self, api, work):