Skip to content

Commit e23d4e3

Browse files
author
Javier Cacheiro
committed
Token Redis: Support both json and plain text tokens
1 parent 8121a52 commit e23d4e3

File tree

2 files changed

+91
-8
lines changed

2 files changed

+91
-8
lines changed

tests/test_token_plugins.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,60 @@ def test_simple(self, mock_redis):
204204
self.assertEqual(result[0], 'remote_host')
205205
self.assertEqual(result[1], 'remote_port')
206206

207+
@patch('redis.Redis')
208+
def test_json_token_with_spaces(self, mock_redis):
209+
plugin = TokenRedis('127.0.0.1:1234')
210+
211+
instance = mock_redis.return_value
212+
instance.get.return_value = b' {"host": "remote_host:remote_port"} '
213+
214+
result = plugin.lookup('testhost')
215+
216+
instance.get.assert_called_once_with('testhost')
217+
self.assertIsNotNone(result)
218+
self.assertEqual(result[0], 'remote_host')
219+
self.assertEqual(result[1], 'remote_port')
220+
221+
@patch('redis.Redis')
222+
def test_text_token(self, mock_redis):
223+
plugin = TokenRedis('127.0.0.1:1234')
224+
225+
instance = mock_redis.return_value
226+
instance.get.return_value = b'remote_host:remote_port'
227+
228+
result = plugin.lookup('testhost')
229+
230+
instance.get.assert_called_once_with('testhost')
231+
self.assertIsNotNone(result)
232+
self.assertEqual(result[0], 'remote_host')
233+
self.assertEqual(result[1], 'remote_port')
234+
235+
@patch('redis.Redis')
236+
def test_text_token_with_spaces(self, mock_redis):
237+
plugin = TokenRedis('127.0.0.1:1234')
238+
239+
instance = mock_redis.return_value
240+
instance.get.return_value = b' remote_host:remote_port '
241+
242+
result = plugin.lookup('testhost')
243+
244+
instance.get.assert_called_once_with('testhost')
245+
self.assertIsNotNone(result)
246+
self.assertEqual(result[0], 'remote_host')
247+
self.assertEqual(result[1], 'remote_port')
248+
249+
@patch('redis.Redis')
250+
def test_invalid_token(self, mock_redis):
251+
plugin = TokenRedis('127.0.0.1:1234')
252+
253+
instance = mock_redis.return_value
254+
instance.get.return_value = b'{"host": "remote_host:remote_port" '
255+
256+
result = plugin.lookup('testhost')
257+
258+
instance.get.assert_called_once_with('testhost')
259+
self.assertIsNone(result)
260+
207261
def test_src_only_host(self):
208262
plugin = TokenRedis('127.0.0.1')
209263

websockify/token_plugins.py

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -174,18 +174,32 @@ class TokenRedis(BasePlugin):
174174
175175
my-redis-host:6379:0:verysecretpass
176176
177-
The TokenRedis plugin expects the format of the data in a form of json.
177+
The TokenRedis plugin expects the format of the target in one of these two
178+
formats:
179+
180+
- JSON
181+
182+
{"host": "target-host:target-port"}
183+
184+
- Plain text
185+
186+
target-host:target-port
178187
179188
Prepare data with:
180-
redis-cli set hello '{"host":"127.0.0.1:5000"}'
189+
190+
redis-cli set my-token '{"host": "127.0.0.1:5000"}'
181191
182192
Verify with:
183-
redis-cli --raw get hello
193+
194+
redis-cli --raw get my-token
184195
185196
Spawn a test "server" using netcat
197+
186198
nc -l 5000 -v
187199
188-
Note: you have to install also the 'redis' module
200+
Note: This Token Plugin depends on the 'redis' module, so you have
201+
to install it before using this plugin:
202+
189203
pip install redis
190204
"""
191205
def __init__(self, src):
@@ -234,11 +248,26 @@ def lookup(self, token):
234248
if stuff is None:
235249
return None
236250
else:
237-
responseStr = stuff.decode("utf-8")
251+
responseStr = stuff.decode("utf-8").strip()
238252
logger.debug("response from redis : %s" % responseStr)
239-
combo = json.loads(responseStr)
240-
(host, port) = combo["host"].split(':')
241-
logger.debug("host: %s, port: %s" % (host,port))
253+
if responseStr.startswith("{"):
254+
try:
255+
combo = json.loads(responseStr)
256+
host, port = combo["host"].split(":")
257+
except ValueError:
258+
logger.error("Unable to decode JSON token: %s" %
259+
responseStr)
260+
return None
261+
except KeyError:
262+
logger.error("Unable to find 'host' key in JSON token: %s" %
263+
responseStr)
264+
return None
265+
elif re.match(r'\S+:\S+', responseStr):
266+
host, port = responseStr.split(":")
267+
else:
268+
logger.error("Unable to parse token: %s" % responseStr)
269+
return None
270+
logger.debug("host: %s, port: %s" % (host, port))
242271
return [host, port]
243272

244273

0 commit comments

Comments
 (0)