summaryrefslogtreecommitdiffstats
path: root/events/src/utils.py
diff options
context:
space:
mode:
authorAravinda VK <avishwan@redhat.com>2017-09-18 14:34:54 +0530
committerjiffin tony Thottan <jthottan@redhat.com>2017-10-25 11:39:49 +0000
commit9d39bd926006d1b6b4850e8d07f9cc340baa9ed5 (patch)
tree9efc390ed4b44a5908018be41978c6ccb1d1166e /events/src/utils.py
parent5632750c91f349bb10a0a6e5cded02f5efc5b828 (diff)
eventsapi: Add JWT signing support
New argument added to accept secret to generate JWT token. This patch does not affect the backward compatibility. Usage: gluster-eventsapi webhook-add <url> [-t <TOKEN>] \ [-s SECRET] With `--token` argument, Token header will be added as is. Authorization: Bearer <TOKEN> In case of shared secret, Gluster will generate JWT token using the secret and then add it to Authorization header. Authorization: Bearer <GENERATED_TOKEN> Secret/Token can be updated using `webhook-mod` command. Generated token will include the following payload, { "iss": "gluster", "exp": EXPIRY_TIME, "sub": EVENT_TYPE, "iat": EVENT_TIME } Where: iss - Issuer, exp - Expiry Time, sub - Event Type used as Subject, iat - Event Time used as Issue Time BUG: 1501864 Change-Id: Ib6b6fab23fb212d7f5e9bbc9e1416a9e9813ab1b Signed-off-by: Aravinda VK <avishwan@redhat.com> (cherry picked from commit add7116efa1f31e86f9c00c72c71872b1161370f)
Diffstat (limited to 'events/src/utils.py')
-rw-r--r--events/src/utils.py45
1 files changed, 36 insertions, 9 deletions
diff --git a/events/src/utils.py b/events/src/utils.py
index 2a77b13d502..5130720d529 100644
--- a/events/src/utils.py
+++ b/events/src/utils.py
@@ -13,10 +13,11 @@ import json
import os
import logging
import fcntl
-from errno import ESRCH, EBADF
+from errno import EBADF
from threading import Thread
import multiprocessing
from Queue import Queue
+from datetime import datetime, timedelta
from eventsapiconf import (LOG_FILE,
WEBHOOKS_FILE,
@@ -183,15 +184,33 @@ def autoload_webhooks():
load_webhooks()
-def publish_to_webhook(url, token, message_queue):
+def get_jwt_token(secret, event_type, event_ts, jwt_expiry_time_seconds=60):
+ import jwt
+ payload = {
+ "exp": datetime.utcnow() + timedelta(seconds=jwt_expiry_time_seconds),
+ "iss": "gluster",
+ "sub": event_type,
+ "iat": event_ts
+ }
+ return jwt.encode(payload, secret, algorithm='HS256')
+
+
+def publish_to_webhook(url, token, secret, message_queue):
# Import requests here since not used in any other place
import requests
http_headers = {"Content-Type": "application/json"}
while True:
- message_json = message_queue.get()
+ hashval = ""
+ event_type, event_ts, message_json = message_queue.get()
if token != "" and token is not None:
- http_headers["Authorization"] = "Bearer " + token
+ hashval = token
+
+ if secret != "" and secret is not None:
+ hashval = get_jwt_token(secret, event_type, event_ts)
+
+ if hashval:
+ http_headers["Authorization"] = "Bearer " + hashval
try:
resp = requests.post(url, headers=http_headers, data=message_json)
@@ -218,7 +237,7 @@ def publish_to_webhook(url, token, message_queue):
def plugin_webhook(message):
message_json = json.dumps(message, sort_keys=True)
logger.debug("EVENT: {0}".format(message_json))
- webhooks_pool.send(message_json)
+ webhooks_pool.send(message["event"], message["ts"], message_json)
class LockedOpen(object):
@@ -298,9 +317,17 @@ class PidFile(object):
def webhook_monitor(proc_queue, webhooks):
queues = {}
- for url, token in webhooks.items():
+ for url, data in webhooks.items():
+ if isinstance(data, str) or isinstance(data, unicode):
+ token = data
+ secret = None
+ else:
+ token = data["token"]
+ secret = data["secret"]
+
queues[url] = Queue()
- t = Thread(target=publish_to_webhook, args=(url, token, queues[url]))
+ t = Thread(target=publish_to_webhook, args=(url, token, secret,
+ queues[url]))
t.start()
# Get the message sent to Process queue and distribute to all thread queues
@@ -329,8 +356,8 @@ class WebhookThreadPool(object):
self.proc.terminate()
self.start()
- def send(self, message):
- self.queue.put(message)
+ def send(self, event_type, event_ts, message):
+ self.queue.put((event_type, event_ts, message))
def init_webhook_pool():