diff options
Diffstat (limited to 'hypervideo_dl/extractor/adobepass.py')
-rw-r--r-- | hypervideo_dl/extractor/adobepass.py | 155 |
1 files changed, 149 insertions, 6 deletions
diff --git a/hypervideo_dl/extractor/adobepass.py b/hypervideo_dl/extractor/adobepass.py index 38dca1b..9378c33 100644 --- a/hypervideo_dl/extractor/adobepass.py +++ b/hypervideo_dl/extractor/adobepass.py @@ -1,6 +1,7 @@ # coding: utf-8 from __future__ import unicode_literals +import json import re import time import xml.etree.ElementTree as etree @@ -9,6 +10,7 @@ from .common import InfoExtractor from ..compat import ( compat_kwargs, compat_urlparse, + compat_getpass ) from ..utils import ( unescapeHTML, @@ -35,6 +37,11 @@ MSO_INFO = { 'username_field': 'email', 'password_field': 'loginpassword', }, + 'RCN': { + 'name': 'RCN', + 'username_field': 'UserName', + 'password_field': 'UserPassword', + }, 'Rogers': { 'name': 'Rogers', 'username_field': 'UserName', @@ -60,11 +67,25 @@ MSO_INFO = { 'username_field': 'IDToken1', 'password_field': 'IDToken2', }, + 'Spectrum': { + 'name': 'Spectrum', + 'username_field': 'IDToken1', + 'password_field': 'IDToken2', + }, + 'Philo': { + 'name': 'Philo', + 'username_field': 'ident' + }, 'Verizon': { 'name': 'Verizon FiOS', 'username_field': 'IDToken1', 'password_field': 'IDToken2', }, + 'Cablevision': { + 'name': 'Optimum/Cablevision', + 'username_field': 'j_username', + 'password_field': 'j_password', + }, 'thr030': { 'name': '3 Rivers Communications' }, @@ -1319,6 +1340,11 @@ MSO_INFO = { 'cou060': { 'name': 'Zito Media' }, + 'slingtv': { + 'name': 'Sling TV', + 'username_field': 'username', + 'password_field': 'password', + }, } @@ -1409,7 +1435,7 @@ class AdobePassIE(InfoExtractor): authn_token = None if not authn_token: # TODO add support for other TV Providers - mso_id = self._downloader.params.get('ap_mso') + mso_id = self.get_param('ap_mso') if not mso_id: raise_mvpd_required() username, password = self._get_login_info('ap_username', 'ap_password', mso_id) @@ -1438,6 +1464,13 @@ class AdobePassIE(InfoExtractor): provider_redirect_page, 'oauth redirect') self._download_webpage( oauth_redirect_url, video_id, 'Confirming auto login') + elif 'automatically signed in with' in provider_redirect_page: + # Seems like comcast is rolling up new way of automatically signing customers + oauth_redirect_url = self._html_search_regex( + r'continue:\s*"(https://oauth.xfinity.com/oauth/authorize\?.+)"', provider_redirect_page, + 'oauth redirect (signed)') + # Just need to process the request. No useful data comes back + self._download_webpage(oauth_redirect_url, video_id, 'Confirming auto login') else: if '<form name="signin"' in provider_redirect_page: provider_login_page_res = provider_redirect_page_res @@ -1460,11 +1493,28 @@ class AdobePassIE(InfoExtractor): mvpd_confirm_page, urlh = mvpd_confirm_page_res if '<button class="submit" value="Resume">Resume</button>' in mvpd_confirm_page: post_form(mvpd_confirm_page_res, 'Confirming Login') + elif mso_id == 'Philo': + # Philo has very unique authentication method + self._download_webpage( + 'https://idp.philo.com/auth/init/login_code', video_id, 'Requesting auth code', data=urlencode_postdata({ + 'ident': username, + 'device': 'web', + 'send_confirm_link': False, + 'send_token': True + })) + philo_code = compat_getpass('Type auth code you have received [Return]: ') + self._download_webpage( + 'https://idp.philo.com/auth/update/login_code', video_id, 'Submitting token', data=urlencode_postdata({ + 'token': philo_code + })) + mvpd_confirm_page_res = self._download_webpage_handle('https://idp.philo.com/idp/submit', video_id, 'Confirming Philo Login') + post_form(mvpd_confirm_page_res, 'Confirming Login') elif mso_id == 'Verizon': # In general, if you're connecting from a Verizon-assigned IP, # you will not actually pass your credentials. provider_redirect_page, urlh = provider_redirect_page_res - if 'Please wait ...' in provider_redirect_page: + # From non-Verizon IP, still gave 'Please wait', but noticed N==Y; will need to try on Verizon IP + if 'Please wait ...' in provider_redirect_page and '\'N\'== "Y"' not in provider_redirect_page: saml_redirect_url = self._html_search_regex( r'self\.parent\.location=(["\'])(?P<url>.+?)\1', provider_redirect_page, @@ -1472,7 +1522,8 @@ class AdobePassIE(InfoExtractor): saml_login_page = self._download_webpage( saml_redirect_url, video_id, 'Downloading SAML Login Page') - else: + elif 'Verizon FiOS - sign in' in provider_redirect_page: + # FXNetworks from non-Verizon IP saml_login_page_res = post_form( provider_redirect_page_res, 'Logging in', { mso_info['username_field']: username, @@ -1482,6 +1533,26 @@ class AdobePassIE(InfoExtractor): if 'Please try again.' in saml_login_page: raise ExtractorError( 'We\'re sorry, but either the User ID or Password entered is not correct.') + else: + # ABC from non-Verizon IP + saml_redirect_url = self._html_search_regex( + r'var\surl\s*=\s*(["\'])(?P<url>.+?)\1', + provider_redirect_page, + 'SAML Redirect URL', group='url') + saml_redirect_url = saml_redirect_url.replace(r'\/', '/') + saml_redirect_url = saml_redirect_url.replace(r'\-', '-') + saml_redirect_url = saml_redirect_url.replace(r'\x26', '&') + saml_login_page = self._download_webpage( + saml_redirect_url, video_id, + 'Downloading SAML Login Page') + saml_login_page, urlh = post_form( + [saml_login_page, saml_redirect_url], 'Logging in', { + mso_info['username_field']: username, + mso_info['password_field']: password, + }) + if 'Please try again.' in saml_login_page: + raise ExtractorError( + 'Failed to login, incorrect User ID or Password.') saml_login_url = self._search_regex( r'xmlHttp\.open\("POST"\s*,\s*(["\'])(?P<url>.+?)\1', saml_login_page, 'SAML Login URL', group='url') @@ -1496,6 +1567,75 @@ class AdobePassIE(InfoExtractor): }), headers={ 'Content-Type': 'application/x-www-form-urlencoded' }) + elif mso_id == 'Spectrum': + # Spectrum's login for is dynamically loaded via JS so we need to hardcode the flow + # as a one-off implementation. + provider_redirect_page, urlh = provider_redirect_page_res + provider_login_page_res = post_form( + provider_redirect_page_res, self._DOWNLOADING_LOGIN_PAGE) + saml_login_page, urlh = provider_login_page_res + relay_state = self._search_regex( + r'RelayState\s*=\s*"(?P<relay>.+?)";', + saml_login_page, 'RelayState', group='relay') + saml_request = self._search_regex( + r'SAMLRequest\s*=\s*"(?P<saml_request>.+?)";', + saml_login_page, 'SAMLRequest', group='saml_request') + login_json = { + mso_info['username_field']: username, + mso_info['password_field']: password, + 'RelayState': relay_state, + 'SAMLRequest': saml_request, + } + saml_response_json = self._download_json( + 'https://tveauthn.spectrum.net/tveauthentication/api/v1/manualAuth', video_id, + 'Downloading SAML Response', + data=json.dumps(login_json).encode(), + headers={ + 'Content-Type': 'application/json', + 'Accept': 'application/json', + }) + self._download_webpage( + saml_response_json['SAMLRedirectUri'], video_id, + 'Confirming Login', data=urlencode_postdata({ + 'SAMLResponse': saml_response_json['SAMLResponse'], + 'RelayState': relay_state, + }), headers={ + 'Content-Type': 'application/x-www-form-urlencoded' + }) + elif mso_id == 'slingtv': + # SlingTV has a meta-refresh based authentication, but also + # looks at the tab history to count the number of times the + # browser has been on a page + + first_bookend_page, urlh = provider_redirect_page_res + + hidden_data = self._hidden_inputs(first_bookend_page) + hidden_data['history'] = 1 + + provider_login_page_res = self._download_webpage_handle( + urlh.geturl(), video_id, 'Sending first bookend', + query=hidden_data) + + provider_association_redirect, urlh = post_form( + provider_login_page_res, 'Logging in', { + mso_info['username_field']: username, + mso_info['password_field']: password + }) + + provider_refresh_redirect_url = extract_redirect_url( + provider_association_redirect, url=urlh.geturl()) + + last_bookend_page, urlh = self._download_webpage_handle( + provider_refresh_redirect_url, video_id, + 'Downloading Auth Association Redirect Page') + hidden_data = self._hidden_inputs(last_bookend_page) + hidden_data['history'] = 3 + + mvpd_confirm_page_res = self._download_webpage_handle( + urlh.geturl(), video_id, 'Sending final bookend', + query=hidden_data) + + post_form(mvpd_confirm_page_res, 'Confirming Login') else: # Some providers (e.g. DIRECTV NOW) have another meta refresh # based redirect that should be followed. @@ -1508,10 +1648,13 @@ class AdobePassIE(InfoExtractor): 'Downloading Provider Redirect Page (meta refresh)') provider_login_page_res = post_form( provider_redirect_page_res, self._DOWNLOADING_LOGIN_PAGE) - mvpd_confirm_page_res = post_form(provider_login_page_res, 'Logging in', { + form_data = { mso_info.get('username_field', 'username'): username, - mso_info.get('password_field', 'password'): password, - }) + mso_info.get('password_field', 'password'): password + } + if mso_id == 'Cablevision': + form_data['_eventId_proceed'] = '' + mvpd_confirm_page_res = post_form(provider_login_page_res, 'Logging in', form_data) if mso_id != 'Rogers': post_form(mvpd_confirm_page_res, 'Confirming Login') |