def test_malformed_cookies(self): cookiejar = YoutubeDLCookieJar( './test/testdata/cookies/malformed_cookies.txt') cookiejar.load(ignore_discard=True, ignore_expires=True) # Cookies should be empty since all malformed cookie file entries # will be ignored self.assertFalse(cookiejar._cookies)
def _merge_cookie_jars(jars): output_jar = YoutubeDLCookieJar() for jar in jars: for cookie in jar: output_jar.set_cookie(cookie) if jar.filename is not None: output_jar.filename = jar.filename return output_jar
def _extract_firefox_cookies(profile, logger): logger.info('Extracting cookies from firefox') if not SQLITE_AVAILABLE: logger.warning( 'Cannot extract cookies from firefox without sqlite3 support. ' 'Please use a python interpreter compiled with sqlite3 support') return YoutubeDLCookieJar() if profile is None: search_root = _firefox_browser_dir() elif _is_path(profile): search_root = profile else: search_root = os.path.join(_firefox_browser_dir(), profile) cookie_database_path = _find_most_recently_used_file( search_root, 'cookies.sqlite') if cookie_database_path is None: raise FileNotFoundError( 'could not find firefox cookies database in {}'.format( search_root)) logger.debug('extracting from: "{}"'.format(cookie_database_path)) with tempfile.TemporaryDirectory(prefix='youtube_dl') as tmpdir: cursor = None try: cursor = _open_database_copy(cookie_database_path, tmpdir) cursor.execute( 'SELECT host, name, value, path, expiry, isSecure FROM moz_cookies' ) jar = YoutubeDLCookieJar() for host, name, value, path, expiry, is_secure in cursor.fetchall( ): cookie = compat_cookiejar_Cookie( version=0, name=name, value=value, port=None, port_specified=False, domain=host, domain_specified=bool(host), domain_initial_dot=host.startswith('.'), path=path, path_specified=bool(path), secure=is_secure, expires=expiry, discard=False, comment=None, comment_url=None, rest={}) jar.set_cookie(cookie) logger.info('Extracted {} cookies from firefox'.format(len(jar))) return jar finally: if cursor is not None: cursor.connection.close()
def test_strip_httponly_prefix(self): cookiejar = YoutubeDLCookieJar( './test/testdata/cookies/httponly_cookies.txt') cookiejar.load(ignore_discard=True, ignore_expires=True) def assert_cookie_has_value(key): self.assertEqual( cookiejar._cookies['www.foobar.foobar']['/'][key].value, key + '_VALUE') assert_cookie_has_value('HTTPONLY_COOKIE') assert_cookie_has_value('JS_ACCESSIBLE_COOKIE')
def load_cookies(cookie_file, browser_specification, ydl): cookie_jars = [] if browser_specification is not None: browser_name, profile = _parse_browser_specification( *browser_specification) cookie_jars.append( extract_cookies_from_browser(browser_name, profile, YDLLogger(ydl))) if cookie_file is not None: cookie_file = expand_path(cookie_file) jar = YoutubeDLCookieJar(cookie_file) if os.access(cookie_file, os.R_OK): jar.load(ignore_discard=True, ignore_expires=True) cookie_jars.append(jar) return _merge_cookie_jars(cookie_jars)
def parse_safari_cookies(data, jar=None, logger=YDLLogger()): """ References: - https://github.com/libyal/dtformats/blob/main/documentation/Safari%20Cookies.asciidoc - this data appears to be out of date but the important parts of the database structure is the same - there are a few bytes here and there which are skipped during parsing """ if jar is None: jar = YoutubeDLCookieJar() page_sizes, body_start = _parse_safari_cookies_header(data, logger) p = DataParser(data[body_start:], logger) for page_size in page_sizes: _parse_safari_cookies_page(p.read_bytes(page_size), jar, logger) p.skip_to_end('footer') return jar
def test_keep_session_cookies(self): cookiejar = YoutubeDLCookieJar( './test/testdata/cookies/session_cookies.txt') cookiejar.load(ignore_discard=True, ignore_expires=True) tf = tempfile.NamedTemporaryFile(delete=False) try: cookiejar.save(filename=tf.name, ignore_discard=True, ignore_expires=True) temp = tf.read().decode('utf-8') self.assertTrue( re.search( r'www\.foobar\.foobar\s+FALSE\s+/\s+TRUE\s+0\s+YoutubeDLExpiresEmpty\s+YoutubeDLExpiresEmptyValue', temp)) self.assertTrue( re.search( r'www\.foobar\.foobar\s+FALSE\s+/\s+TRUE\s+0\s+YoutubeDLExpires0\s+YoutubeDLExpires0Value', temp)) finally: tf.close() os.remove(tf.name)
def _extract_chrome_cookies(browser_name, profile, logger): logger.info('Extracting cookies from {}'.format(browser_name)) if not SQLITE_AVAILABLE: logger.warning( ('Cannot extract cookies from {} without sqlite3 support. ' 'Please use a python interpreter compiled with sqlite3 support' ).format(browser_name)) return YoutubeDLCookieJar() config = _get_chromium_based_browser_settings(browser_name) if profile is None: search_root = config['browser_dir'] elif _is_path(profile): search_root = profile config['browser_dir'] = os.path.dirname( profile) if config['supports_profiles'] else profile else: if config['supports_profiles']: search_root = os.path.join(config['browser_dir'], profile) else: logger.error('{} does not support profiles'.format(browser_name)) search_root = config['browser_dir'] cookie_database_path = _find_most_recently_used_file( search_root, 'Cookies') if cookie_database_path is None: raise FileNotFoundError( 'could not find {} cookies database in "{}"'.format( browser_name, search_root)) logger.debug('extracting from: "{}"'.format(cookie_database_path)) decryptor = get_cookie_decryptor(config['browser_dir'], config['keyring_name'], logger) with tempfile.TemporaryDirectory(prefix='youtube_dl') as tmpdir: cursor = None try: cursor = _open_database_copy(cookie_database_path, tmpdir) cursor.connection.text_factory = bytes column_names = _get_column_names(cursor, 'cookies') secure_column = 'is_secure' if 'is_secure' in column_names else 'secure' cursor.execute( 'SELECT host_key, name, value, encrypted_value, path, ' 'expires_utc, {} FROM cookies'.format(secure_column)) jar = YoutubeDLCookieJar() failed_cookies = 0 for host_key, name, value, encrypted_value, path, expires_utc, is_secure in cursor.fetchall( ): host_key = host_key.decode('utf-8') name = name.decode('utf-8') value = value.decode('utf-8') path = path.decode('utf-8') if not value and encrypted_value: value = decryptor.decrypt(encrypted_value) if value is None: failed_cookies += 1 continue cookie = compat_cookiejar_Cookie( version=0, name=name, value=value, port=None, port_specified=False, domain=host_key, domain_specified=bool(host_key), domain_initial_dot=host_key.startswith('.'), path=path, path_specified=bool(path), secure=is_secure, expires=expires_utc, discard=False, comment=None, comment_url=None, rest={}) jar.set_cookie(cookie) if failed_cookies > 0: failed_message = ' ({} could not be decrypted)'.format( failed_cookies) else: failed_message = '' logger.info('Extracted {} cookies from {}{}'.format( len(jar), browser_name, failed_message)) return jar finally: if cursor is not None: cursor.connection.close()