Skip to content

Commit 61ede66

Browse files
committed
Dont include token in URLs unless show_secrets set in config; All functions that return a URL such as stream urls and thumbnails still include token
1 parent 68f73e1 commit 61ede66

File tree

9 files changed

+40
-35
lines changed

9 files changed

+40
-35
lines changed

plexapi/alert.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self, server, callback=None):
2929

3030
def run(self):
3131
# create the websocket connection
32-
url = self._server.url(self.key).replace('http', 'ws')
32+
url = self._server.url(self.key, includeToken=True).replace('http', 'ws')
3333
log.info('Starting AlertListener: %s', url)
3434
self._ws = websocket.WebSocketApp(url, on_message=self._onMessage,
3535
on_error=self._onError)

plexapi/audio.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,17 @@ def _loadData(self, data):
4545
def thumbUrl(self):
4646
""" Return url to for the thumbnail image. """
4747
key = self.firstAttr('thumb', 'parentThumb', 'granparentThumb')
48-
return self._server.url(key) if key else None
48+
return self._server.url(key, includeToken=True) if key else None
4949

5050
@property
5151
def artUrl(self):
52-
""" Return the first first art url starting on the most specific for that item."""
52+
""" Return the first art url starting on the most specific for that item."""
5353
art = self.firstAttr('art', 'grandparentArt')
54-
return self._server.url(art) if art else None
54+
return self._server.url(art, includeToken=True) if art else None
5555

5656
def url(self, part):
57-
""" Returns the full URL for something. Typically used for getting a specific image. """
58-
if part:
59-
return self._server.url(part)
57+
""" Returns the full URL for this audio item. Typically used for getting a specific track. """
58+
return self._server.url(part, includeToken=True) if part else None
6059

6160

6261
@utils.registerPlexObject

plexapi/base.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ def getStreamURL(self, **params):
479479
# sort the keys since the randomness fucks with my tests..
480480
sorted_params = sorted(params.items(), key=lambda val: val[0])
481481
return self._server.url('/%s/:/transcode/universal/start.m3u8?%s' %
482-
(streamtype, urlencode(sorted_params)))
482+
(streamtype, urlencode(sorted_params)), includeToken=True)
483483

484484
def iterParts(self):
485485
""" Iterates over the parts of this media item. """
@@ -530,9 +530,8 @@ def download(self, savepath=None, keep_orginal_name=False, **kwargs):
530530
download_url = self.getStreamURL(**kwargs)
531531
else:
532532
download_url = self._server.url('%s?download=1' % location.key)
533-
534-
filepath = utils.download(download_url, filename=filename,
535-
savepath=savepath, session=self._server._session)
533+
filepath = utils.download(download_url, self._server._token, filename=filename,
534+
savepath=savepath, session=self._server._session)
536535
if filepath:
537536
filepaths.append(filepath)
538537
return filepaths

plexapi/client.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def __init__(self, server=None, data=None, initpath=None, baseurl=None,
6565
super(PlexClient, self).__init__(server, data, initpath)
6666
self._baseurl = baseurl.strip('/') if baseurl else None
6767
self._token = logfilter.add_secret(token)
68+
self._showSecrets = CONFIG.get('log.show_secrets', '').lower() == 'true'
6869
server_session = server._session if server else None
6970
self._session = session or server_session or requests.Session()
7071
self._proxyThroughServer = False
@@ -193,11 +194,13 @@ def sendCommand(self, command, proxy=None, **params):
193194
return self._server.query(key, headers=headers)
194195
return self.query(key, headers=headers)
195196

196-
def url(self, key):
197-
""" Build a URL string with proper token argument. """
197+
def url(self, key, includeToken=False):
198+
""" Build a URL string with proper token argument. Token will be appended to the URL
199+
if either includeToken is True or CONFIG.log.show_secrets is 'true'.
200+
"""
198201
if not self._baseurl:
199202
raise BadRequest('PlexClient object missing baseurl.')
200-
if self._token:
203+
if self._token and (includeToken or self._showSecrets):
201204
delim = '&' if '?' in key else '?'
202205
return '%s%s%sX-Plex-Token=%s' % (self._baseurl, key, delim, self._token)
203206
return '%s%s' % (self._baseurl, key)

plexapi/server.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class PlexServer(PlexObject):
9494
def __init__(self, baseurl=None, token=None, session=None, timeout=None):
9595
self._baseurl = baseurl or CONFIG.get('auth.server_baseurl', 'http://localhost:32400')
9696
self._token = logfilter.add_secret(token or CONFIG.get('auth.server_token'))
97+
self._showSecrets = CONFIG.get('log.show_secrets', '').lower() == 'true'
9798
self._session = session or requests.Session()
9899
self._library = None # cached library
99100
self._settings = None # cached settings
@@ -265,7 +266,7 @@ def downloadDatabases(self, savepath=None, unpack=False):
265266
unpack (bool): Unpack the zip file.
266267
"""
267268
url = self.url('/diagnostics/databases')
268-
filepath = utils.download(url, None, savepath, self._session, unpack=unpack)
269+
filepath = utils.download(url, self._token, None, savepath, self._session, unpack=unpack)
269270
return filepath
270271

271272
def downloadLogs(self, savepath=None, unpack=False):
@@ -276,7 +277,7 @@ def downloadLogs(self, savepath=None, unpack=False):
276277
unpack (bool): Unpack the zip file.
277278
"""
278279
url = self.url('/diagnostics/logs')
279-
filepath = utils.download(url, None, savepath, self._session, unpack=unpack)
280+
filepath = utils.download(url, self._token, None, savepath, self._session, unpack=unpack)
280281
return filepath
281282

282283
def check_for_update(self, force=True, download=False):
@@ -410,11 +411,13 @@ def transcodeImage(self, media, height, width, opacity=100, saturation=100):
410411
if media:
411412
transcode_url = '/photo/:/transcode?height=%s&width=%s&opacity=%s&saturation=%s&url=%s' % (
412413
height, width, opacity, saturation, media)
413-
return self.url(transcode_url)
414+
return self.url(transcode_url, includeToken=True)
414415

415-
def url(self, key):
416-
""" Build a URL string with proper token argument. """
417-
if self._token:
416+
def url(self, key, includeToken=None):
417+
""" Build a URL string with proper token argument. Token will be appended to the URL
418+
if either includeToken is True or CONFIG.log.show_secrets is 'true'.
419+
"""
420+
if self._token and (includeToken or self._showSecrets):
418421
delim = '&' if '?' in key else '?'
419422
return '%s%s%sX-Plex-Token=%s' % (self._baseurl, key, delim, self._token)
420423
return '%s%s' % (self._baseurl, key)

plexapi/utils.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,13 +223,14 @@ def downloadSessionImages(server, filename=None, height=150, width=150,
223223
return info
224224

225225

226-
def download(url, filename=None, savepath=None, session=None, chunksize=4024,
226+
def download(url, token, filename=None, savepath=None, session=None, chunksize=4024,
227227
unpack=False, mocked=False, showstatus=False):
228228
""" Helper to download a thumb, videofile or other media item. Returns the local
229229
path to the downloaded file.
230230
231231
Parameters:
232232
url (str): URL where the content be reached.
233+
token (str): Plex auth token to include in headers.
233234
filename (str): Filename of the downloaded file, default None.
234235
savepath (str): Defaults to current working dir.
235236
chunksize (int): What chunksize read/write at the time.
@@ -245,7 +246,8 @@ def download(url, filename=None, savepath=None, session=None, chunksize=4024,
245246
from plexapi import log
246247
# fetch the data to be saved
247248
session = session or requests.Session()
248-
response = session.get(url, stream=True)
249+
headers = {'X-Plex-Token': token}
250+
response = session.get(url, headers=headers, stream=True)
249251
# make sure the savepath directory exists
250252
savepath = savepath or os.getcwd()
251253
compat.makedirs(savepath, exist_ok=True)

plexapi/video.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,17 @@ def thumbUrl(self):
5353
the most specific thumbnail for that item.
5454
"""
5555
thumb = self.firstAttr('thumb', 'parentThumb', 'granparentThumb')
56-
return self._server.url(thumb) if thumb else None
56+
return self._server.url(thumb, includeToken=True) if thumb else None
5757

5858
@property
5959
def artUrl(self):
6060
""" Return the first first art url starting on the most specific for that item."""
6161
art = self.firstAttr('art', 'grandparentArt')
62-
return self._server.url(art) if art else None
62+
return self._server.url(art, includeToken=True) if art else None
6363

6464
def url(self, part):
6565
""" Returns the full url for something. Typically used for getting a specific image. """
66-
if part:
67-
return self._server.url(part)
66+
return self._server.url(part, includeToken=True) if part else None
6867

6968
def markWatched(self):
7069
""" Mark video as watched. """
@@ -193,10 +192,10 @@ def download(self, savepath=None, keep_orginal_name=False, **kwargs):
193192
url = self.getStreamURL(**kwargs)
194193
else:
195194
self._server.url('%s?download=1' % location.key)
196-
filepath = utils.download(url, filename=name, savepath=savepath, session=self._server._session)
195+
filepath = utils.download(url, self._server._token, filename=name,
196+
savepath=savepath, session=self._server._session)
197197
if filepath:
198198
filepaths.append(filepath)
199-
200199
return filepaths
201200

202201

tests/test_server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def test_server_transcodeImage(tmpdir, plex, show):
5858
width, height = 500, 500
5959
imgurl = plex.transcodeImage(show.banner, height, width)
6060
gray = imgurl = plex.transcodeImage(show.banner, height, width, saturation=0)
61-
resized_img = download(imgurl, savepath=str(tmpdir), filename='resize_image')
62-
original_img = download(show._server.url(show.banner), savepath=str(tmpdir), filename='original_img')
63-
grayscale_img = download(gray, savepath=str(tmpdir), filename='grayscale_img')
61+
resized_img = download(imgurl, plex._token, savepath=str(tmpdir), filename='resize_image')
62+
original_img = download(show._server.url(show.banner), plex._token, savepath=str(tmpdir), filename='original_img')
63+
grayscale_img = download(gray, plex._token, savepath=str(tmpdir), filename='grayscale_img')
6464
with Image.open(resized_img) as image:
6565
assert width, height == image.size
6666
with Image.open(original_img) as image:

tests/test_utils.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ def test_utils_cast():
6060
bool_str = utils.cast(bool, 'kek')
6161

6262

63-
def test_utils_download(episode):
63+
def test_utils_download(plex, episode):
6464
url = episode.getStreamURL()
6565
locations = episode.locations[0]
6666
session = episode._server._session
67-
assert utils.download(url, filename=locations, mocked=True)
68-
assert utils.download(url, filename=locations, session=session, mocked=True)
69-
assert utils.download(episode.thumbUrl, filename=episode.title, mocked=True)
67+
assert utils.download(url, plex._token, filename=locations, mocked=True)
68+
assert utils.download(url, plex._token, filename=locations, session=session, mocked=True)
69+
assert utils.download(episode.thumbUrl, plex._token, filename=episode.title, mocked=True)

0 commit comments

Comments
 (0)