From af82273948ae36294ca5e0d398592c2a008e2a23 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Thu, 20 Oct 2016 09:37:06 -0400 Subject: [PATCH 1/5] don't double encode channel messages --- awx/main/consumers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/awx/main/consumers.py b/awx/main/consumers.py index fb4bf55fd3..223ff84321 100644 --- a/awx/main/consumers.py +++ b/awx/main/consumers.py @@ -35,5 +35,4 @@ def ws_receive(message): def emit_channel_notification(group, payload): - payload = json.dumps(payload) Group(group).send({"text": json.dumps(payload)}) From bc1561fc672ed3da2a9746d3a5c44b24c48fde2a Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Thu, 20 Oct 2016 09:17:50 -0700 Subject: [PATCH 2/5] Removing front end double parsing of socket messages previously the socket messages were double encoded w/ quotations --- awx/ui/client/src/shared/socket/socket.service.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/awx/ui/client/src/shared/socket/socket.service.js b/awx/ui/client/src/shared/socket/socket.service.js index 056bd09bbf..dfaac460b6 100644 --- a/awx/ui/client/src/shared/socket/socket.service.js +++ b/awx/ui/client/src/shared/socket/socket.service.js @@ -74,9 +74,6 @@ export default // Function called when messages are received on by the UI from // the API over the websocket. This will route each message to // the appropriate controller for the current $state. - e.data = e.data.replace(/\\/g, ''); - e.data = e.data.substr(0, e.data.length-1); - e.data = e.data.substr(1); $log.debug('Received From Server: ' + e.data); var data = JSON.parse(e.data), str = ""; From d84912bb2a36c8cfeb98cab40324c349ceb6a3a9 Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Thu, 20 Oct 2016 10:02:28 -0700 Subject: [PATCH 3/5] potentially adding token to websocket url --- awx/ui/client/src/shared/socket/socket.service.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/awx/ui/client/src/shared/socket/socket.service.js b/awx/ui/client/src/shared/socket/socket.service.js index dfaac460b6..a7d526149a 100644 --- a/awx/ui/client/src/shared/socket/socket.service.js +++ b/awx/ui/client/src/shared/socket/socket.service.js @@ -5,8 +5,8 @@ *************************************************/ import ReconnectingWebSocket from 'reconnectingwebsocket'; export default -['$rootScope', '$location', '$log','$state', '$q', - function ($rootScope, $location, $log, $state, $q) { +['$rootScope', '$location', '$log','$state', '$q', 'Authorization', + function ($rootScope, $location, $log, $state, $q, Authorization) { var needsResubscribing = false, socketPromise = $q.defer(); return { @@ -14,7 +14,8 @@ export default var self = this, host = window.location.host, protocol, - url; + url, + token = Authorization.getToken(); if($location.protocol() === 'http'){ protocol = 'ws'; @@ -26,6 +27,7 @@ export default if (!$rootScope.sessionTimer || ($rootScope.sessionTimer && !$rootScope.sessionTimer.isExpired())) { // We have a valid session token, so attempt socket connection + // url = `${url}?session=${token}`; $log.debug('Socket connecting to: ' + url); self.socket = new ReconnectingWebSocket(url, null, { From 6bd20c643304eef56690f3dc868defefc10279ea Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Thu, 20 Oct 2016 12:58:45 -0700 Subject: [PATCH 4/5] Adding the token to the socket url --- awx/ui/client/src/shared/socket/socket.service.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/ui/client/src/shared/socket/socket.service.js b/awx/ui/client/src/shared/socket/socket.service.js index a7d526149a..632fa812cb 100644 --- a/awx/ui/client/src/shared/socket/socket.service.js +++ b/awx/ui/client/src/shared/socket/socket.service.js @@ -27,7 +27,7 @@ export default if (!$rootScope.sessionTimer || ($rootScope.sessionTimer && !$rootScope.sessionTimer.isExpired())) { // We have a valid session token, so attempt socket connection - // url = `${url}?session=${token}`; + url = `${url}?token=${token}`; $log.debug('Socket connecting to: ' + url); self.socket = new ReconnectingWebSocket(url, null, { From ced3c41df97d588af35c195eefb2326aa003cf84 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Mon, 24 Oct 2016 19:42:53 -0400 Subject: [PATCH 5/5] add auth_token verification to websocket --- awx/main/consumers.py | 44 +++++++++++++++++++++++++++++++++++++++++++ awx/main/routing.py | 1 + 2 files changed, 45 insertions(+) diff --git a/awx/main/consumers.py b/awx/main/consumers.py index 223ff84321..bbd155329a 100644 --- a/awx/main/consumers.py +++ b/awx/main/consumers.py @@ -1,20 +1,64 @@ import json +import urlparse from channels import Group from channels.sessions import channel_session +from django.contrib.auth.models import User +from awx.main.models.organization import AuthToken + def discard_groups(message): if 'groups' in message.channel_session: for group in message.channel_session['groups']: Group(group).discard(message.reply_channel) + +def validate_token(token): + try: + auth_token = AuthToken.objects.get(key=token) + if not auth_token.in_valid_tokens: + return None + except AuthToken.DoesNotExist: + return None + return auth_token + + +def user_from_token(auth_token): + try: + return User.objects.get(pk=auth_token.user_id) + except User.DoesNotExist: + return None + +@channel_session +def ws_connect(message): + token = None + qs = urlparse.parse_qs(message['query_string']) + if 'token' in qs: + if len(qs['token']) > 0: + token = qs['token'].pop() + message.channel_session['token'] = token + + @channel_session def ws_disconnect(message): discard_groups(message) + @channel_session def ws_receive(message): + token = message.channel_session.get('token') + + auth_token = validate_token(token) + if auth_token is None: + message.reply_channel.send({"text": json.dumps({"error": "invalid auth token"})}) + return None + + user = user_from_token(auth_token) + if user is None: + message.reply_channel.send({"text": json.dumps({"error": "no valid user"})}) + return None + raw_data = message.content['text'] data = json.loads(raw_data) diff --git a/awx/main/routing.py b/awx/main/routing.py index 67a08ff1bd..0a49f25c6c 100644 --- a/awx/main/routing.py +++ b/awx/main/routing.py @@ -2,6 +2,7 @@ from channels.routing import route channel_routing = [ + route("websocket.connect", "awx.main.consumers.ws_connect", path=r'^/websocket/$'), route("websocket.disconnect", "awx.main.consumers.ws_disconnect", path=r'^/websocket/$'), route("websocket.receive", "awx.main.consumers.ws_receive", path=r'^/websocket/$'), ]