Skip to content

Commit bdb2c9a

Browse files
dubeeJason Peterson
authored andcommitted
Disable triggers for invalid auth when using custom auth handler (#354)
* Disable triggers for invalid auth when using custom auth handler * Fix bad indentation * Call __shouldDisable on auth handler exception * Always dump response on auth handler exception * Use response.ok instead of checking status code * Fix typo
1 parent 9ea0c7e commit bdb2c9a

File tree

2 files changed

+62
-43
lines changed

2 files changed

+62
-43
lines changed

provider/authHandler.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323

2424
from requests.auth import AuthBase
2525

26+
class AuthHandlerException(Exception):
27+
def __init__(self, response):
28+
self.response = response
2629

2730
class IAMAuth(AuthBase):
2831

@@ -35,18 +38,24 @@ def __call__(self, r):
3538
r.headers['Authorization'] = 'Bearer {}'.format(self.__getToken())
3639
return r
3740

38-
3941
def __getToken(self):
4042
if 'expires_in' not in self.tokenInfo or self.__isRefreshTokenExpired():
41-
self.tokenInfo = self.__requestToken()
42-
return self.tokenInfo['access_token']
43+
response = self.__requestToken()
44+
if response.ok and 'access_token' in response.json():
45+
self.tokenInfo = response.json()
46+
return self.tokenInfo['access_token']
47+
else:
48+
raise AuthHandlerException(response)
4349
elif self.__isTokenExpired():
44-
self.tokenInfo = self.__refreshToken()
45-
return self.tokenInfo['access_token']
50+
response = self.__refreshToken()
51+
if response.ok and 'access_token' in response.json():
52+
self.tokenInfo = response.json()
53+
return self.tokenInfo['access_token']
54+
else:
55+
raise AuthHandlerException(response)
4656
else:
4757
return self.tokenInfo['access_token']
4858

49-
5059
def __requestToken(self):
5160
headers = {
5261
'Content-type': 'application/x-www-form-urlencoded',
@@ -86,7 +95,7 @@ def __isTokenExpired(self):
8695

8796
def __isRefreshTokenExpired(self):
8897
if 'expiration' not in self.tokenInfo:
89-
return true
98+
return True
9099

91100
sevenDays = 7 * 24 * 3600
92101
currentTime = int(time.time())
@@ -96,4 +105,4 @@ def __isRefreshTokenExpired(self):
96105

97106
def __sendRequest(self, payload, headers):
98107
response = requests.post(self.endpoint, data=payload, headers=headers)
99-
return response.json()
108+
return response

provider/consumer.py

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
from datetimeutils import secondsSince
3333
from multiprocessing import Process, Manager
3434
from urlparse import urlparse
35+
from authHandler import AuthHandlerException
3536
from authHandler import IAMAuth
3637
from requests.auth import HTTPBasicAuth
3738
from datetime import datetime, timedelta
@@ -409,44 +410,19 @@ def __fireTrigger(self, messages):
409410
self.consumer.commit(offsets=self.__getOffsetList(messages), async=False)
410411
retry = False
411412
elif self.__shouldDisable(status_code):
412-
logging.error('[{}] Error talking to OpenWhisk, status code {}'.format(self.trigger, status_code))
413-
response_dump = {
414-
'request': {
415-
'method': response.request.method,
416-
'url': response.request.url,
417-
'path_url': response.request.path_url,
418-
'headers': response.request.headers,
419-
'body': response.request.body
420-
},
421-
'response': {
422-
'status_code': response.status_code,
423-
'ok': response.ok,
424-
'reason': response.reason,
425-
'url': response.url,
426-
'headers': response.headers,
427-
'content': response.content
428-
}
429-
}
430-
431-
logging.error('[{}] Dumping the content of the request and response:\n{}'.format(self.trigger, response_dump))
432-
433-
# abandon all hope?
434-
self.setDesiredState(Consumer.State.Disabled)
435-
# mark it disabled in the DB
436-
437-
# when failing to establish a database connection, mark the consumer as dead to restart the consumer
438-
try:
439-
self.database = Database()
440-
self.database.disableTrigger(self.trigger, status_code)
441-
except Exception as e:
442-
logging.error('[{}] Uncaught exception: {}'.format(self.trigger, e))
443-
self.__recordState(Consumer.State.Dead)
444-
finally:
445-
self.database.destroy()
446-
447413
retry = False
414+
logging.error('[{}] Error talking to OpenWhisk, status code {}'.format(self.trigger, status_code))
415+
self.__dumpRequestResponse(response)
416+
self.__disableTrigger(status_code)
448417
except requests.exceptions.RequestException as e:
449418
logging.error('[{}] Error talking to OpenWhisk: {}'.format(self.trigger, e))
419+
except AuthHandlerException as e:
420+
logging.error("[{}] Encountered an exception from auth handler, status code {}").format(self.trigger, e.response.status_code)
421+
self.__dumpRequestResponse(e.response)
422+
423+
if self.__shouldDisable(e.response.status_code):
424+
retry = False
425+
self.__disableTrigger(e.response.status_code)
450426

451427
if retry:
452428
retry_count += 1
@@ -460,6 +436,40 @@ def __fireTrigger(self, messages):
460436
self.consumer.commit(offsets=self.__getOffsetList(messages), async=False)
461437
retry = False
462438

439+
def __disableTrigger(self, status_code):
440+
self.setDesiredState(Consumer.State.Disabled)
441+
442+
# when failing to establish a database connection, mark the consumer as dead to restart the consumer
443+
try:
444+
self.database = Database()
445+
self.database.disableTrigger(self.trigger, status_code)
446+
except Exception as e:
447+
logging.error('[{}] Uncaught exception: {}'.format(self.trigger, e))
448+
self.__recordState(Consumer.State.Dead)
449+
finally:
450+
self.database.destroy()
451+
452+
def __dumpRequestResponse(self, response):
453+
response_dump = {
454+
'request': {
455+
'method': response.request.method,
456+
'url': response.request.url,
457+
'path_url': response.request.path_url,
458+
'headers': response.request.headers,
459+
'body': response.request.body
460+
},
461+
'response': {
462+
'status_code': response.status_code,
463+
'ok': response.ok,
464+
'reason': response.reason,
465+
'url': response.url,
466+
'headers': response.headers,
467+
'content': response.content
468+
}
469+
}
470+
471+
logging.error('[{}] Dumping the content of the request and response:\n{}'.format(self.trigger, response_dump))
472+
463473
# return the dict that will be sent as the trigger payload
464474
def __getMessagePayload(self, message):
465475
return {

0 commit comments

Comments
 (0)