feat: unify account environments and work collection
This commit is contained in:
@@ -744,7 +744,7 @@ def valid_douyin_url(raw: object) -> bool:
|
||||
if parsed.path == DOUYIN_PROFILE_OTHER_PATH:
|
||||
return valid_douyin_profile_query(query)
|
||||
if parsed.path == DOUYIN_WORKS_PATH:
|
||||
return valid_douyin_api_query(query, "sec_user_id", "max_cursor")
|
||||
return valid_douyin_works_query(query)
|
||||
if parsed.path == DOUYIN_WORK_DETAIL_PATH:
|
||||
return valid_douyin_work_detail_query(query)
|
||||
if parsed.path == DOUYIN_COMMENTS_PATH:
|
||||
@@ -773,6 +773,37 @@ def valid_douyin_profile_query(query: dict[str, list[str]]) -> bool:
|
||||
)
|
||||
|
||||
|
||||
def valid_douyin_works_query(query: dict[str, list[str]]) -> bool:
|
||||
# Keep the works endpoint pinned to the parameters used by Douyin's web
|
||||
# profile page; do not let the pagination fix widen the restricted URL surface.
|
||||
rest = query
|
||||
if "a_bogus" in query:
|
||||
if len(query["a_bogus"]) != 1 or not DOUYIN_SIGNATURE_RE.fullmatch(
|
||||
query["a_bogus"][0]
|
||||
):
|
||||
return False
|
||||
rest = {key: value for key, value in query.items() if key != "a_bogus"}
|
||||
required = {
|
||||
"aid": ["6383"],
|
||||
"device_platform": ["webapp"],
|
||||
"channel": ["channel_pc_web"],
|
||||
"count": ["18"],
|
||||
"locate_query": ["false"],
|
||||
"show_live_replay_strategy": ["1"],
|
||||
"need_time_list": ["1"],
|
||||
"time_list_query": ["0"],
|
||||
"cut_version": ["1"],
|
||||
"publish_video_strategy_type": ["2"],
|
||||
"from_user_page": ["0"],
|
||||
}
|
||||
return (
|
||||
set(rest) == set(required) | {"sec_user_id", "max_cursor"}
|
||||
and all(rest.get(key) == value for key, value in required.items())
|
||||
and valid_account_key_query(rest, "sec_user_id")
|
||||
and numeric_cursor(rest.get("max_cursor"))
|
||||
)
|
||||
|
||||
|
||||
def valid_douyin_api_query(
|
||||
query: dict[str, list[str]], account_field: str, cursor_field: str
|
||||
) -> bool:
|
||||
|
||||
@@ -198,6 +198,19 @@ class GatewayValidationTests(unittest.TestCase):
|
||||
"https://www.douyin.com/aweme/v1/web/user/profile/other/?aid=6383&device_platform=webapp&user_id=1&count=20"
|
||||
)
|
||||
)
|
||||
works_url = (
|
||||
"https://www.douyin.com/aweme/v1/web/aweme/post/?"
|
||||
"aid=6383&device_platform=webapp&channel=channel_pc_web&"
|
||||
"sec_user_id=MS4wLjABAAAA9f_a7k0bzVizLYXlpC7R61EIaqJ8Ordug7yp7AB8fGKuuF8Fzqk5_DM-eutXnPIK&"
|
||||
"count=18&max_cursor=1746702477000&locate_query=false&"
|
||||
"show_live_replay_strategy=1&need_time_list=1&time_list_query=0&"
|
||||
"cut_version=1&publish_video_strategy_type=2&from_user_page=0"
|
||||
)
|
||||
self.assertTrue(valid_douyin_url(works_url))
|
||||
self.assertTrue(valid_douyin_url(works_url + "&a_bogus=abcdefghijklmnop"))
|
||||
self.assertFalse(valid_douyin_url(works_url + "&unexpected=1"))
|
||||
self.assertFalse(valid_douyin_url(works_url.replace("count=18", "count=20")))
|
||||
self.assertFalse(valid_douyin_url(works_url.replace("max_cursor=1746702477000", "max_cursor=-1")))
|
||||
self.assertFalse(valid_douyin_url("https://www.douyin.com.evil/"))
|
||||
self.assertTrue(is_douyin_url("https://www.douyin.com/video/123"))
|
||||
self.assertFalse(is_douyin_url("https://www.douyin.com.evil/video/123"))
|
||||
|
||||
Reference in New Issue
Block a user