Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/tennistv.py (Python)

Code before:
            'title': 'Fernando Verdasco v Taylor Fritz',
            'description': 're:^After his stunning victory.{174}$',
            'thumbnail': 'https://atp-prod.akamaized.net/api/images/v1/images/112831/landscape/1242/0',
            'timestamp': 1521017381,
            'upload_date': '20180314',
        },
        'params': {
            'skip_download': True,
        },
        'skip': 'Requires email and password of a subscribed account',
    }
    _NETRC_MACHINE = 'tennistv'

    ACCESS_TOKEN = None
    REFRESH_TOKEN = None
    PARTNER_ID = 3001482
    _FORMAT_URL = 'https://open.http.mp.streamamg.com/p/{partner}/sp/{partner}00/playManifest/entryId/{entry}/format/applehttp/protocol/https/a.m3u8?ks={session}'
    headers = {
        'origin': 'https://www.tennistv.com',
        'referer': 'https://www.tennistv.com/',
        'content-Type': 'application/x-www-form-urlencoded'
    }

    def _perform_login(self, username, password):

        BASE_URL = 'https://sso.tennistv.com/auth/realms/TennisTV/protocol/openid-connect/auth'
        login_form = {
            'username': username,
            'password': password,
            'submitAction': 'Log In'
        }

        login_page = self._download_webpage(BASE_URL, None, query={
            'client_id': 'tennis-tv-web',
            'redirect_uri': 'https://tennistv.com',
            'response_mode': 'fragment',
            'response_type': 'code',
            'scope': 'openid'
        })
        post_url = self._html_search_regex(r'action=["\'](.+?)["\']\s+?method=["\']post["\']', login_page, None)

        temp_page = self._download_webpage(post_url, None, 'Sending login data', 'Unable to send login data',
                                           data=urlencode_postdata(login_form), headers=self.headers)

        if 'Your username or password was incorrect' in temp_page:
            raise ExtractorError('Your username or password was incorrect', expected=True)
        handle = self._request_webpage(BASE_URL, None, headers=self.headers, query={
            'client_id': 'tennis-tv-web',
            'redirect_uri': 'https://www.tennistv.com/resources/v1.1.10/html/silent-check-sso.html',
            'state': random_uuidv4(),
            'response_mode': 'fragment',

Review comment (security):
makes more sense to put `https://sso.tennistv.com/auth/realms/TennisTV/protocol` in a class var instead imo. This is also used in `get_token`

Code after:
            'upload_date': '20180314',
        },
        'params': {
            'skip_download': True,
        },
        'skip': 'Requires email and password of a subscribed account',
    }, {
        'url': 'https://www.tennistv.com/videos/2650480/best-matches-of-2022-part-5',
        'info_dict': {
            'id': '2650480',
            'ext': 'mp4',
            'title': 'Best Matches of 2022 - Part 5',
            'description': 'md5:36dec3bfae7ed74bd79e48045b17264c',
            'thumbnail': 'https://open.http.mp.streamamg.com/p/3001482/sp/300148200/thumbnail/entry_id/0_myef18pd/version/100001/height/1920',
        },
        'params': {'skip_download': 'm3u8'},
        'skip': 'Requires email and password of a subscribed account',
    }]
    _NETRC_MACHINE = 'tennistv'

    access_token, refresh_token = None, None
    _PARTNER_ID = 3001482
    _FORMAT_URL = 'https://open.http.mp.streamamg.com/p/{partner}/sp/{partner}00/playManifest/entryId/{entry}/format/applehttp/protocol/https/a.m3u8?ks={session}'
    _AUTH_BASE_URL = 'https://sso.tennistv.com/auth/realms/TennisTV/protocol/openid-connect'
    _HEADERS = {
        'origin': 'https://www.tennistv.com',
        'referer': 'https://www.tennistv.com/',
        'content-Type': 'application/x-www-form-urlencoded'
    }

    def _perform_login(self, username, password):
        login_page = self._download_webpage(
            f'{self._AUTH_BASE_URL}/auth', None, 'Downloading login page',
            query={
                'client_id': 'tennis-tv-web',
                'redirect_uri': 'https://tennistv.com',
                'response_mode': 'fragment',
                'response_type': 'code',
                'scope': 'openid'
            })

        post_url = self._html_search_regex(r'action=["\']([^"\']+?)["\']\s+method=["\']post["\']', login_page, 'login POST url')
        temp_page = self._download_webpage(
            post_url, None, 'Sending login data', 'Unable to send login data',
            headers=self._HEADERS, data=urlencode_postdata({
                'username': username,
                'password': password,
                'submitAction': 'Log In'
            }))
        if 'Your username or password was incorrect' in temp_page:
            raise ExtractorError('Your username or password was incorrect', expected=True)