From 7b009cc893b314a0dec65792143aad97a2d6bf92 Mon Sep 17 00:00:00 2001 From: evazion Date: Tue, 22 Feb 2022 12:23:01 -0600 Subject: [PATCH] nicoseiga: fix inability to login to nicoseiga. NicoSeiga changed it so that on every login, you must enter a 2FA code sent by email. This broke the NicoSeiga strategy. The fix is to just use a static session cookie instead (and hope it doesn't expire, and isn't tied to an IP). The `nico_seiga_login` and `nico_seiga_password` config settings have been removed from config/danbooru_default_config.rb and replaced by `nico_seiga_user_session`. If you run your own Danbooru instance, you will have to update your config file manually. --- .github/workflows/test.yaml | 3 +- app/logical/nico_seiga_api_client.rb | 29 ++++++++++---------- app/logical/sources/strategies/nico_seiga.rb | 4 +-- config/danbooru_default_config.rb | 8 ++---- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3367655bd..69d4d8eaa 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -47,8 +47,7 @@ jobs: DANBOORU_PIXIV_PHPSESSID: ${{ secrets.DANBOORU_PIXIV_PHPSESSID }} DANBOORU_NIJIE_LOGIN: ${{ secrets.DANBOORU_NIJIE_LOGIN }} DANBOORU_NIJIE_PASSWORD: ${{ secrets.DANBOORU_NIJIE_PASSWORD }} - DANBOORU_NICO_SEIGA_LOGIN: ${{ secrets.DANBOORU_NICO_SEIGA_LOGIN }} - DANBOORU_NICO_SEIGA_PASSWORD: ${{ secrets.DANBOORU_NICO_SEIGA_PASSWORD }} + DANBOORU_NICO_SEIGA_USER_SESSION: ${{ secrets.DANBOORU_NICO_SEIGA_USER_SESSION }} DANBOORU_TUMBLR_CONSUMER_KEY: ${{ secrets.DANBOORU_TUMBLR_CONSUMER_KEY }} DANBOORU_DEVIANTART_CLIENT_ID: ${{ secrets.DANBOORU_DEVIANTART_CLIENT_ID }} DANBOORU_DEVIANTART_CLIENT_SECRET: ${{ secrets.DANBOORU_DEVIANTART_CLIENT_SECRET }} diff --git a/app/logical/nico_seiga_api_client.rb b/app/logical/nico_seiga_api_client.rb index 5d6996d22..d0b205ece 100644 --- a/app/logical/nico_seiga_api_client.rb +++ b/app/logical/nico_seiga_api_client.rb @@ -5,11 +5,12 @@ class NicoSeigaApiClient extend Memoist XML_API = "https://seiga.nicovideo.jp/api" - attr_reader :http + attr_reader :http, :user_session - def initialize(work_id:, type:, http: Danbooru::Http.new) + def initialize(work_id:, type:, user_session: Danbooru.config.nico_seiga_user_session, http: Danbooru::Http.new) @work_id = work_id @work_type = type + @user_session = user_session @http = http end @@ -60,7 +61,7 @@ class NicoSeigaApiClient api_response = JSON.parse(resp)["target_image"] when "manga" - resp = http.cache(1.minute).get("#{XML_API}/theme/info?id=#{@work_id}") + resp = get("#{XML_API}/theme/info?id=#{@work_id}") return {} if resp.blank? || resp.code.to_i == 404 api_response = Hash.from_xml(resp.to_s)["response"]["theme"] end @@ -79,26 +80,24 @@ class NicoSeigaApiClient end def user_api_response(user_id) - resp = http.cache(1.minute).get("#{XML_API}/user/info?id=#{user_id}") + resp = get("#{XML_API}/user/info?id=#{user_id}") return {} if resp.blank? || resp.code.to_i == 404 Hash.from_xml(resp.to_s)["response"]["user"] end - def login - form = { - mail_tel: Danbooru.config.nico_seiga_login, - password: Danbooru.config.nico_seiga_password + def cookies + { + skip_fetish_warning: "1", + user_session: user_session, } - - # XXX should fail gracefully instead of raising exception - resp = http.cache(1.hour).post("https://account.nicovideo.jp/login/redirector?site=seiga", form: form) - raise "NicoSeiga login failed (status=#{resp.status})" if resp.status != 200 - - http end def get(url) - login.cache(1.minute).get(url) + http.cookies(cookies).cache(1.minute).get(url) + end + + def head(url) + http.cookies(cookies).cache(1.minute).head(url) end memoize :api_response, :manga_api_response, :user_api_response diff --git a/app/logical/sources/strategies/nico_seiga.rb b/app/logical/sources/strategies/nico_seiga.rb index d35b1a8e7..4ccae57a1 100644 --- a/app/logical/sources/strategies/nico_seiga.rb +++ b/app/logical/sources/strategies/nico_seiga.rb @@ -53,7 +53,7 @@ module Sources PROFILE_PAGE = %r{\Ahttps?://seiga\.nicovideo\.jp/user/illust/(?\d+)}i def self.enabled? - Danbooru.config.nico_seiga_login.present? && Danbooru.config.nico_seiga_password.present? + Danbooru.config.nico_seiga_user_session.present? end def domains @@ -79,7 +79,7 @@ module Sources def image_url_for(url) return url if api_client.blank? - resp = api_client.login.head(url) + resp = api_client.head(url) if resp.uri.to_s =~ %r{https?://.+/(\w+/\d+/\d+)\z}i "https://lohas.nicoseiga.jp/priv/#{$1}" else diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index 4843ba3b4..1401b4ef6 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -265,11 +265,9 @@ module Danbooru nil end - def nico_seiga_login - nil - end - - def nico_seiga_password + # Your NicoSeiga "user_session" cookie. Login to NicoSeiga then use the + # devtools to find the "user_session" cookie. + def nico_seiga_user_session nil end