From f9d0a8cdcdf5c2edee13468125486c30f41f6af8 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 3 Oct 2020 13:24:35 -0400 Subject: [PATCH] [AdobePass] Add Spectrum as an Adobe Pass provider Some services no longer allow for the older services (ex. `Charter_Direct`) to be used and just return a generic 401 response. Going through their login flow manually, the new provider name appears to be `Spectrum`. This provider seems to work even place of services that still allow for `Charter_Direct` to be used. The Spectrum login form also needs special handling since it's dynamically loaded via JS thus we cannot simply capture the POST url and hidden form fields. Instead we need to hardcode the POST URL and recreate the request manually. Thankfully the SAMLRequest and RelayState are in the HTML response. --- youtube_dl/extractor/adobepass.py | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/youtube_dl/extractor/adobepass.py b/youtube_dl/extractor/adobepass.py index 38dca1b0a..377220c72 100644 --- a/youtube_dl/extractor/adobepass.py +++ b/youtube_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 @@ -60,6 +61,11 @@ MSO_INFO = { 'username_field': 'IDToken1', 'password_field': 'IDToken2', }, + 'Spectrum': { + 'name': 'Spectrum', + 'username_field': 'IDToken1', + 'password_field': 'IDToken2', + }, 'Verizon': { 'name': 'Verizon FiOS', 'username_field': 'IDToken1', @@ -1496,6 +1502,41 @@ 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.+?)";', + saml_login_page, 'RelayState', group='relay') + saml_request = self._search_regex( + r'SAMLRequest\s*=\s*"(?P.+?)";', + 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' + }) else: # Some providers (e.g. DIRECTV NOW) have another meta refresh # based redirect that should be followed.