From 869a99d9a3d63c979dfaa5cf2157fc61475837cf Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 7 Mar 2021 23:03:10 -0600 Subject: [PATCH] nijie: clear session cookie if it's expired (#4665). If we detect that the session cookie has expired (by the presence of the `#login_illust` element on the page), then clear the cached session cookie. The current source fetch will still fail, but the next fetch will try to login again and hopefully succeed. --- app/logical/sources/strategies/nijie.rb | 67 +++++++++++++++++-------- test/unit/sources/nijie_test.rb | 12 +++++ 2 files changed, 57 insertions(+), 22 deletions(-) diff --git a/app/logical/sources/strategies/nijie.rb b/app/logical/sources/strategies/nijie.rb index 9d4fd3dd7..bebec0720 100644 --- a/app/logical/sources/strategies/nijie.rb +++ b/app/logical/sources/strategies/nijie.rb @@ -212,34 +212,57 @@ module Sources return nil if page_url.blank? || client.blank? response = client.cache(1.minute).get(page_url) - return nil unless response.status == 200 - response&.parse + if response.status != 200 || response.parse.search("#login_illust").present? + clear_cached_session_cookie! + else + response.parse + end end memoize :page def client - nijie = http.timeout(60).use(retriable: { max_retries: 20 }) - - cookie = Cache.get("nijie-session-cookie", 60.minutes) do - login_page = nijie.get("https://nijie.info/login.php").parse - form = { - email: Danbooru.config.nijie_login, - password: Danbooru.config.nijie_password, - url: login_page.at("input[name='url']")["value"], - save: "on", - ticket: "" - } - response = nijie.post("https://nijie.info/login_int.php", form: form) - DanbooruLogger.info "Nijie login failed (#{url}, #{response.status})" if response.status != 200 - return nil unless response.status == 200 - - response.cookies.select { |c| c.name == "NIJIEIJIEID" }.compact.first - end - - nijie.cookies(NIJIEIJIEID: cookie, R18: 1) + return nil if cached_session_cookie.nil? + http.cookies(NIJIEIJIEID: cached_session_cookie, R18: 1) end - memoize :client + + def http + super.timeout(60).use(retriable: { max_retries: 20 }) + end + + def cached_session_cookie + Cache.get("nijie-session-cookie", 60.minutes, skip_nil: true) do + session_cookie + end + end + + def clear_cached_session_cookie! + flush_cache # clear memoized session cookie + Cache.delete("nijie-session-cookie") + end + + def session_cookie + login_page = http.get("https://nijie.info/login.php").parse + + form = { + email: Danbooru.config.nijie_login, + password: Danbooru.config.nijie_password, + url: login_page.at("input[name='url']")["value"], + save: "on", + ticket: "" + } + + response = http.post("https://nijie.info/login_int.php", form: form) + + if response.status == 200 + response.cookies.select { |c| c.name == "NIJIEIJIEID" }.compact.first + else + DanbooruLogger.info "Nijie login failed (#{url}, #{response.status})" + nil + end + end + + memoize :client, :cached_session_cookie end end end diff --git a/test/unit/sources/nijie_test.rb b/test/unit/sources/nijie_test.rb index c90357278..ba10b6b2f 100644 --- a/test/unit/sources/nijie_test.rb +++ b/test/unit/sources/nijie_test.rb @@ -305,6 +305,18 @@ module Sources end end + context "when the cached session cookie is invalid" do + should "clear the cached cookie after failing to fetch the data" do + site = Sources::Strategies.find("https://nijie.info/view.php?id=203688") + + Cache.put("nijie-session-cookie", HTTP::Cookie.new(name: "NIJIEIJIEID", value: "fake", domain: "nijie.info", path: "/")) + assert_equal("fake", site.cached_session_cookie.value) + + assert_equal([], site.image_urls) + assert_nil(Cache.get("nijie-session-cookie")) + end + end + context "a doujin post" do should "work" do image = "https://pic.nijie.net/01/dojin_main/dojin_sam/20120213044700%E3%82%B3%E3%83%94%E3%83%BC%20%EF%BD%9E%200011%E3%81%AE%E3%82%B3%E3%83%94%E3%83%BC.jpg"