Skip to content

Commit f3eaf43

Browse files
authored
Merge pull request #639 from anxdpanic/pr_isengard
2.6.0~beta6
2 parents 72187bf + 1f66e55 commit f3eaf43

4 files changed

Lines changed: 64 additions & 19 deletions

File tree

addon.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="plugin.video.twitch" version="2.6.0~beta5" name="Twitch" provider-name="anxdpanic, A Talented Community">
2+
<addon id="plugin.video.twitch" version="2.6.0~beta6" name="Twitch" provider-name="anxdpanic, A Talented Community">
33
<requires>
44
<import addon="xbmc.python" version="2.20.0"/>
55
<import addon="script.module.six" version="1.11.0"/>

resources/language/resource.language.en_gb/strings.po

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,3 +981,11 @@ msgstr ""
981981
msgctxt "#30267"
982982
msgid "An OAuth token is required for access, go to '%s' - '%s' - '%s' to generate one"
983983
msgstr ""
984+
985+
msgctxt "#30268"
986+
msgid "Private OAuth authentication error"
987+
msgstr ""
988+
989+
msgctxt "#30269"
990+
msgid "Private OAuth credentials are incorrect, go to '%s' - '%s' - '%s' to correct the issue"
991+
msgstr ""

resources/lib/twitch_addon/addon/api.py

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ def __init__(self):
4343
self.queries.OAUTH_TOKEN = self.access_token
4444
self.queries.APP_TOKEN = self.app_token
4545
self.client = oauth.clients.MobileClient(self.client_id, self.client_secret)
46+
47+
self.private_client_id = utils.get_private_client_id()
48+
self.private_access_token = utils.get_private_oauth_token()
49+
if self.private_access_token:
50+
if not self.valid_private_token(self.private_client_id, self.private_access_token):
51+
self.private_access_token = ''
52+
4653
if self.access_token:
4754
if not self.valid_token(self.client_id, self.access_token, self.required_scopes):
4855
self.queries.OAUTH_TOKEN = ''
@@ -76,7 +83,7 @@ def valid_token(self, client_id, token, scopes): # client_id, token used for un
7683
matches_default = token_check['client_id'] == utils.get_client_id(default=True)
7784
log_utils.log('Error: OAuth Client-ID mismatch', log_utils.LOGERROR)
7885
if matches_default:
79-
result = kodi.Dialog().ok(
86+
_ = kodi.Dialog().ok(
8087
i18n('oauth_token'),
8188
'[CR]'.join([i18n('client_id_mismatch'), i18n('ok_to_resolve')])
8289
)
@@ -85,7 +92,7 @@ def valid_token(self, client_id, token, scopes): # client_id, token used for un
8592
self.queries.CLIENT_ID = self.client_id
8693
self.client = oauth.clients.MobileClient(self.client_id, self.client_secret)
8794
else:
88-
result = kodi.Dialog().ok(
95+
_ = kodi.Dialog().ok(
8996
i18n('oauth_token'),
9097
'[CR]'.join([
9198
i18n('client_id_mismatch'),
@@ -95,11 +102,33 @@ def valid_token(self, client_id, token, scopes): # client_id, token used for un
95102
)
96103
return False
97104

105+
@cache.cache_method(cache_limit=1)
106+
def valid_private_token(self, client_id, token): # client_id used for unique caching only
107+
token_check = self.validate(token)
108+
if token_check['client_id'] != self.private_client_id:
109+
matches_default = token_check['client_id'] == utils.get_client_id(default=True)
110+
log_utils.log('Error: Private OAuth Client-ID mismatch', log_utils.LOGERROR)
111+
if matches_default:
112+
log_utils.log('Private OAuth token matches add-on Client-ID', log_utils.LOGDEBUG)
113+
if not self.access_token:
114+
self.access_token = self.private_access_token
115+
self.queries.OAUTH_TOKEN = self.private_access_token
116+
kodi.set_setting('oauth_token_helix', self.private_access_token)
117+
kodi.set_setting('private_oauth_token', '')
118+
self.private_access_token = ''
119+
return False
120+
return True
121+
98122
@api_error_handler
99123
def root(self):
100124
results = oauth.validation.validate(self.access_token)
101125
return self.error_check(results)
102126

127+
@api_error_handler
128+
def validate(self, token):
129+
results = oauth.validation.validate(token)
130+
return self.error_check(results)
131+
103132
@api_error_handler
104133
@cache.cache_method(cache_limit=1)
105134
def get_user(self, token): # token used for unique caching only
@@ -225,22 +254,22 @@ def check_follow(self, channel_id):
225254
@api_error_handler
226255
def follow(self, channel_id):
227256
results = self.api.users._follow_channel(channel_id=channel_id, headers=self.get_private_credential_headers()) # NOQA
228-
return self.error_check(results)
257+
return self.error_check(results, private=True)
229258

230259
@api_error_handler
231260
def unfollow(self, channel_id):
232261
results = self.api.users._unfollow_channel(channel_id=channel_id, headers=self.get_private_credential_headers()) # NOQA
233-
return self.error_check(results)
262+
return self.error_check(results, private=True)
234263

235264
@api_error_handler
236265
def follow_game(self, game_id):
237266
results = self.api.games._follow(game_id=game_id, headers=self.get_private_credential_headers()) # NOQA
238-
return self.error_check(results)
267+
return self.error_check(results, private=True)
239268

240269
@api_error_handler
241270
def unfollow_game(self, game_id):
242271
results = self.api.games._unfollow(game_id=game_id, headers=self.get_private_credential_headers()) # NOQA
243-
return self.error_check(results)
272+
return self.error_check(results, private=True)
244273

245274
@api_error_handler
246275
def check_subscribed(self, channel_id):
@@ -260,7 +289,7 @@ def _get_video_token(self, video_id):
260289
results = self.usher.vod_token(video_id=video_id, headers=self.get_private_credential_headers())
261290
if 'token' in results:
262291
results = json.loads(results['token'])
263-
return self.error_check(results)
292+
return self.error_check(results, private=True)
264293

265294
@api_error_handler
266295
@cache.cache_method(cache_limit=cache.limit)
@@ -288,7 +317,7 @@ def get_streams_by_channels(self, names, offset, limit):
288317
@cache.cache_method(cache_limit=cache.limit)
289318
def get_followed_games(self, limit):
290319
results = self.api.games._get_followed(limit=limit, headers=self.get_private_credential_headers()) # NOQA
291-
return self.error_check(results)
320+
return self.error_check(results, private=True)
292321

293322
@api_error_handler
294323
@cache.cache_method(cache_limit=cache.limit)
@@ -301,7 +330,7 @@ def get_followed_streams(self, user_id, after='MA==', first=20):
301330
@cache.cache_method(cache_limit=cache.limit)
302331
def get_vod(self, video_id):
303332
results = self.usher.video(video_id, headers=self.get_private_credential_headers())
304-
return self.error_check(results)
333+
return self.error_check(results, private=True)
305334

306335
@api_error_handler
307336
@cache.cache_method(cache_limit=cache.limit)
@@ -312,7 +341,7 @@ def get_clip(self, slug):
312341
@cache.cache_method(cache_limit=cache.limit)
313342
def get_live(self, name):
314343
results = self.usher.live(name, headers=self.get_private_credential_headers())
315-
return self.error_check(results)
344+
return self.error_check(results, private=True)
316345

317346
@api_error_handler
318347
@cache.cache_method(cache_limit=cache.limit)
@@ -321,7 +350,7 @@ def live_request(self, name):
321350
results = self.usher.live_request(name, platform='ps4', headers=self.get_private_credential_headers())
322351
else:
323352
results = self.usher.live_request(name, headers=self.get_private_credential_headers())
324-
return self.error_check(results)
353+
return self.error_check(results, private=True)
325354

326355
@api_error_handler
327356
@cache.cache_method(cache_limit=cache.limit)
@@ -330,10 +359,10 @@ def video_request(self, video_id):
330359
results = self.usher.video_request(video_id, platform='ps4', headers=self.get_private_credential_headers())
331360
else:
332361
results = self.usher.video_request(video_id, headers=self.get_private_credential_headers())
333-
return self.error_check(results)
362+
return self.error_check(results, private=True)
334363

335364
@staticmethod
336-
def error_check(results):
365+
def error_check(results, private=False):
337366
if isinstance(results, list):
338367
return results
339368

@@ -342,12 +371,17 @@ def error_check(results):
342371
payload = payload['response']
343372

344373
if ('error' in payload) and (payload['status'] == 401):
345-
_ = kodi.Dialog().ok(
346-
i18n('oauth_heading'),
347-
i18n('oauth_message') % (i18n('settings'), i18n('login'), i18n('get_oauth_token'))
348-
)
374+
if not private:
375+
_ = kodi.Dialog().ok(
376+
i18n('oauth_heading'),
377+
i18n('oauth_message') % (i18n('settings'), i18n('login'), i18n('get_oauth_token'))
378+
)
379+
else:
380+
_ = kodi.Dialog().ok(
381+
i18n('private_oauth_heading'),
382+
i18n('private_oauth_message') % (i18n('settings'), i18n('login'), i18n('private_credentials'))
383+
)
349384
sys.exit()
350-
351385
if 'stream' in payload and payload['stream'] is None:
352386
raise PlaybackFailed()
353387

resources/lib/twitch_addon/addon/strings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,7 @@
135135
'Add_to_queue': 30266,
136136
'oauth_heading': 30132,
137137
'oauth_message': 30267,
138+
'private_oauth_heading': 30268,
139+
'private_oauth_message': 30269,
140+
'private_credentials': 30261,
138141
}

0 commit comments

Comments
 (0)