diff --git a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java index cca835ad..8f6f16dc 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java +++ b/Clover/app/src/main/java/org/floens/chan/core/settings/ChanSettings.java @@ -161,7 +161,6 @@ public class ChanSettings { public static final BooleanSetting crashReporting; public static final BooleanSetting useNewCaptchaWindow; - public static final BooleanSetting useRealGoogleCookies; public static final StringSetting googleCookie; public static final LongSetting lastGoogleCookieUpdateTime; @@ -255,7 +254,6 @@ public class ChanSettings { crashReporting = new BooleanSetting(p, "preference_crash_reporting", true); useNewCaptchaWindow = new BooleanSetting(p, "use_new_captcha_window", true); - useRealGoogleCookies = new BooleanSetting(p, "use_real_google_cookies", false); googleCookie = new StringSetting(p, "google_cookie", ""); lastGoogleCookieUpdateTime = new LongSetting(p, "last_google_cookie_update_time", 0L); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java index 68e2af69..daa6179d 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java @@ -36,7 +36,6 @@ import android.widget.ScrollView; import android.widget.Toast; import org.floens.chan.R; -import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.core.site.Site; import org.floens.chan.core.site.SiteAuthentication; import org.floens.chan.ui.captcha.AuthenticationLayoutCallback; @@ -56,9 +55,6 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout private AppCompatButton captchaVerifyButton; private AppCompatButton useOldCaptchaButton; private AppCompatButton reloadCaptchaButton; - private AppCompatButton refreshCookiesButton; - private ConstraintLayout buttonsHolder; - private ScrollView background; private CaptchaNoJsV2Adapter adapter; private CaptchaNoJsPresenterV2 presenter; @@ -92,9 +88,8 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout captchaVerifyButton = view.findViewById(R.id.captcha_layout_v2_verify_button); useOldCaptchaButton = view.findViewById(R.id.captcha_layout_v2_use_old_captcha_button); reloadCaptchaButton = view.findViewById(R.id.captcha_layout_v2_reload_button); - refreshCookiesButton = view.findViewById(R.id.captcha_layout_v2_refresh_cookies); - buttonsHolder = view.findViewById(R.id.captcha_layout_v2_buttons_holder); - background = view.findViewById(R.id.captcha_layout_v2_background); + ConstraintLayout buttonsHolder = view.findViewById(R.id.captcha_layout_v2_buttons_holder); + ScrollView background = view.findViewById(R.id.captcha_layout_v2_background); background.setBackgroundColor(AndroidUtils.getAttrColor(getContext(), R.attr.backcolor)); buttonsHolder.setBackgroundColor(AndroidUtils.getAttrColor(getContext(), R.attr.backcolor_secondary)); @@ -103,17 +98,11 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout captchaVerifyButton.setTextColor(AndroidUtils.getAttrColor(getContext(), R.attr.text_color_primary)); useOldCaptchaButton.setTextColor(AndroidUtils.getAttrColor(getContext(), R.attr.text_color_primary)); reloadCaptchaButton.setTextColor(AndroidUtils.getAttrColor(getContext(), R.attr.text_color_primary)); - refreshCookiesButton.setTextColor(AndroidUtils.getAttrColor(getContext(), R.attr.text_color_primary)); captchaVerifyButton.setOnClickListener(this); useOldCaptchaButton.setOnClickListener(this); reloadCaptchaButton.setOnClickListener(this); - if (ChanSettings.useRealGoogleCookies.get()) { - refreshCookiesButton.setVisibility(View.VISIBLE); - refreshCookiesButton.setOnClickListener(this); - } - captchaVerifyButton.setEnabled(false); } @@ -183,26 +172,6 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout }); } - @Override - public void onGoogleCookiesRefreshed() { - // called on a background thread - - AndroidUtils.runOnUiThread(() -> { - showToast("Google cookies successfully refreshed"); - - // refresh the captcha as well - reset(); - }); - } - - // Called when we could not get google cookies - @Override - public void onGetGoogleCookieError(boolean shouldFallback, Throwable error) { - // called on a background thread - - handleError(shouldFallback, error); - } - // Called when we got response from re-captcha but could not parse some part of it @Override public void onCaptchaInfoParseError(Throwable error) { @@ -227,9 +196,7 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout } private void showToast(String message) { - AndroidUtils.runOnUiThread(() -> { - Toast.makeText(context, message, Toast.LENGTH_LONG).show(); - }); + AndroidUtils.runOnUiThread(() -> Toast.makeText(context, message, Toast.LENGTH_LONG).show()); } @Override @@ -240,8 +207,6 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout callback.onFallbackToV1CaptchaView(); } else if (v == reloadCaptchaButton) { reset(); - } else if (v == refreshCookiesButton) { - presenter.refreshCookies(); } } @@ -252,7 +217,7 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout captchaImagesGrid.setAdapter(null); captchaImagesGrid.setAdapter(adapter); - int columnsCount = 0; + int columnsCount; int imageSize = captchaImagesGrid.getWidth(); switch (captchaInfo.getCaptchaType()) { @@ -282,6 +247,10 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout } private void setCaptchaTitle(CaptchaInfo captchaInfo) { + if (captchaInfo.getCaptchaTitle() == null) { + return; + } + if (captchaInfo.getCaptchaTitle().hasBold()) { SpannableString spannableString = new SpannableString(captchaInfo.getCaptchaTitle().getTitle()); spannableString.setSpan( diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java index 256ca2c1..bf20c518 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java @@ -50,15 +50,12 @@ public class CaptchaNoJsPresenterV2 { private static final String acceptEncodingHeader = "deflate, br"; private static final String acceptLanguageHeader = "en-US"; private static final String recaptchaUrlBase = "https://www.google.com/recaptcha/api/fallback?k="; - private static final String googleBaseUrl = "https://www.google.com/"; private static final String encoding = "UTF-8"; private static final String mediaType = "application/x-www-form-urlencoded"; private static final String recaptchaChallengeString = "reCAPTCHA challenge"; private static final String verificationTokenString = "fbc-verification-token"; - private static final String setCookieHeaderName = "set-cookie"; private static final int SUCCESS_STATUS_CODE = 200; private static final long CAPTCHA_REQUEST_THROTTLE_MS = 3000L; - private static final long THREE_MONTHS = TimeUnit.DAYS.toMillis(90); // this cookie is taken from dashchan private static final String defaultGoogleCookies = "NID=87=gkOAkg09AKnvJosKq82kgnDnHj8Om2pLskKhdna02msog8HkdHDlasDf"; @@ -73,13 +70,9 @@ public class CaptchaNoJsPresenterV2 { private AuthenticationCallbacks callbacks; @Nullable private CaptchaInfo prevCaptchaInfo = null; - @NonNull - // either the default cookie or a real cookie - private volatile String googleCookie; private AtomicBoolean verificationInProgress = new AtomicBoolean(false); private AtomicBoolean captchaRequestInProgress = new AtomicBoolean(false); - private AtomicBoolean refreshCookiesRequestInProgress = new AtomicBoolean(false); private String siteKey; private String baseUrl; private long lastTimeCaptchaRequest = 0L; @@ -87,8 +80,6 @@ public class CaptchaNoJsPresenterV2 { public CaptchaNoJsPresenterV2(@Nullable AuthenticationCallbacks callbacks, Context context) { this.callbacks = callbacks; this.parser = new CaptchaNoJsHtmlParser(context, okHttpClient); - - this.googleCookie = ChanSettings.googleCookie.get(); } public void init(String siteKey, String baseUrl) { @@ -127,16 +118,12 @@ public class CaptchaNoJsPresenterV2 { throw new CaptchaNoJsV2Error("C parameter is null"); } - if (googleCookie.isEmpty()) { - throw new IllegalStateException("Google cookies are not supposed to be empty here"); - } - executor.submit(() -> { try { String recaptchaUrl = recaptchaUrlBase + siteKey; RequestBody body = createResponseBody(prevCaptchaInfo, selectedIds); - Logger.d(TAG, "Verify called. Current cookie = " + googleCookie); + Logger.d(TAG, "Verify called"); Request request = new Request.Builder() .url(recaptchaUrl) @@ -146,7 +133,7 @@ public class CaptchaNoJsPresenterV2 { .header("Accept", acceptHeader) .header("Accept-Encoding", acceptEncodingHeader) .header("Accept-Language", acceptLanguageHeader) - .header("Cookie", googleCookie) + .header("Cookie", defaultGoogleCookies) .build(); try (Response response = okHttpClient.newCall(request).execute()) { @@ -173,38 +160,6 @@ public class CaptchaNoJsPresenterV2 { } } - /** - * Manually refreshes the google cookie - * */ - public void refreshCookies() { - if (!refreshCookiesRequestInProgress.compareAndSet(false, true)) { - Logger.d(TAG, "Google cookie request is already in progress"); - return; - } - - if (executor.isShutdown()) { - refreshCookiesRequestInProgress.set(false); - Logger.d(TAG, "Cannot request google cookie, executor has been shut down"); - return; - } - - executor.submit(() -> { - try { - googleCookie = getGoogleCookies(true); - - if (callbacks != null) { - callbacks.onGoogleCookiesRefreshed(); - } - } catch (IOException e) { - if (callbacks != null) { - callbacks.onGetGoogleCookieError(false, e); - } - } finally { - refreshCookiesRequestInProgress.set(false); - } - }); - } - /** * Requests captcha data, parses it and then passes it to the render function */ @@ -232,16 +187,6 @@ public class CaptchaNoJsPresenterV2 { executor.submit(() -> { try { - try { - googleCookie = getGoogleCookies(false); - } catch (Throwable error) { - if (callbacks != null) { - callbacks.onGetGoogleCookieError(true, error); - } - - throw error; - } - try { prevCaptchaInfo = getCaptchaInfo(); } catch (Throwable error) { @@ -255,7 +200,6 @@ public class CaptchaNoJsPresenterV2 { Logger.e(TAG, "Error while executing captcha requests", error); prevCaptchaInfo = null; - googleCookie = defaultGoogleCookies; } finally { captchaRequestInProgress.set(false); } @@ -274,62 +218,12 @@ public class CaptchaNoJsPresenterV2 { } } - @NonNull - private String getGoogleCookies(boolean forced) throws IOException { - if (BackgroundUtils.isMainThread()) { - throw new RuntimeException("Must not be executed on the main thread"); - } - - if (!ChanSettings.useRealGoogleCookies.get()) { - Logger.d(TAG, "Google cookies request is disabled in the settings, using the default ones"); - return defaultGoogleCookies; - } - - boolean isItTimeToUpdateCookies = - ((System.currentTimeMillis() - ChanSettings.lastGoogleCookieUpdateTime.get()) > THREE_MONTHS); - - if (!forced && (!googleCookie.isEmpty() && !isItTimeToUpdateCookies)) { - Logger.d(TAG, "We already have google cookies"); - return googleCookie; - } - - Logger.d(TAG, "Time to update cookies: forced = " + forced + ", isCookieEmpty = " + - googleCookie.isEmpty() + ", last cookie expired = " + isItTimeToUpdateCookies); - - Request request = new Request.Builder() - .url(googleBaseUrl) - .header("User-Agent", userAgentHeader) - .header("Accept", acceptHeader) - .header("Accept-Encoding", acceptEncodingHeader) - .header("Accept-Language", acceptLanguageHeader) - .build(); - - try (Response response = okHttpClient.newCall(request).execute()) { - String newCookie = handleGetGoogleCookiesResponse(response); - if (!newCookie.equalsIgnoreCase(defaultGoogleCookies)) { - ChanSettings.googleCookie.set(newCookie); - ChanSettings.lastGoogleCookieUpdateTime.set(System.currentTimeMillis()); - - Logger.d(TAG, "Successfully refreshed google cookies, new cookie = " + newCookie); - } else { - Logger.d(TAG, "Could not successfully handle google cookie response, " + - "using the default google cookies until the next request"); - } - - return newCookie; - } - } - @Nullable private CaptchaInfo getCaptchaInfo() throws IOException { if (BackgroundUtils.isMainThread()) { throw new RuntimeException("Must not be executed on the main thread"); } - if (googleCookie.isEmpty()) { - throw new IllegalStateException("Google cookies are not supposed to be null here"); - } - String recaptchaUrl = recaptchaUrlBase + siteKey; Request request = new Request.Builder() @@ -339,7 +233,7 @@ public class CaptchaNoJsPresenterV2 { .header("Accept", acceptHeader) .header("Accept-Encoding", acceptEncodingHeader) .header("Accept-Language", acceptLanguageHeader) - .header("Cookie", googleCookie) + .header("Cookie", defaultGoogleCookies) .build(); try (Response response = okHttpClient.newCall(request).execute()) { @@ -378,33 +272,6 @@ public class CaptchaNoJsPresenterV2 { resultBody); } - @NonNull - private String handleGetGoogleCookiesResponse(Response response) { - if (response.code() != SUCCESS_STATUS_CODE) { - Logger.w(TAG, "Get google cookies request returned bad status code = " + response.code()); - return defaultGoogleCookies; - } - - Headers headers = response.headers(); - - for (String headerName : headers.names()) { - if (headerName.equalsIgnoreCase(setCookieHeaderName)) { - String setCookieHeader = headers.get(headerName); - if (setCookieHeader != null) { - String[] split = setCookieHeader.split(";"); - for (String splitPart : split) { - if (splitPart.startsWith("NID")) { - return splitPart; - } - } - } - } - } - - Logger.d(TAG, "Could not find the NID cookie in the headers"); - return defaultGoogleCookies; - } - @Nullable private CaptchaInfo handleGetRecaptchaResponse(Response response) { try { @@ -492,10 +359,6 @@ public class CaptchaNoJsPresenterV2 { } public interface AuthenticationCallbacks { - void onGetGoogleCookieError(boolean shouldFallback, Throwable error); - - void onGoogleCookiesRefreshed(); - void onCaptchaInfoParsed(CaptchaInfo captchaInfo); void onCaptchaInfoParseError(Throwable error); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/BehaviourSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/BehaviourSettingsController.java index e2f83be1..dabaf0ec 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/controller/BehaviourSettingsController.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/BehaviourSettingsController.java @@ -60,19 +60,6 @@ public class BehaviourSettingsController extends SettingsController { if (item == forceEnglishSetting) { Toast.makeText(context, R.string.setting_force_english_locale_toggle_notice, Toast.LENGTH_LONG).show(); - } else if (item == useNewCaptchaWindow) { - // when user disables the new captcha window also disable the usage of the google cookies - if (!ChanSettings.useNewCaptchaWindow.get()) { - ChanSettings.useRealGoogleCookies.set(false); - - // Reset the old google cookie - ChanSettings.googleCookie.set(""); - - // and cookie update time as well - ChanSettings.lastGoogleCookieUpdateTime.set(0L); - } - - rebuildPreferences(); } } @@ -181,13 +168,6 @@ public class BehaviourSettingsController extends SettingsController { R.string.settings_use_new_captcha_window, 0)); - if (ChanSettings.useNewCaptchaWindow.get()) { - captcha.add(new BooleanSettingView(this, - ChanSettings.useRealGoogleCookies, - R.string.settings_use_real_google_cookies, - R.string.settings_use_real_google_cookies_description)); - } - groups.add(captcha); } diff --git a/Clover/app/src/test/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParserTest.java b/Clover/app/src/test/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParserTest.java index 37a2f32a..62faa58b 100644 --- a/Clover/app/src/test/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParserTest.java +++ b/Clover/app/src/test/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParserTest.java @@ -2,6 +2,7 @@ package org.floens.chan.ui.captcha.v2; import android.content.Context; + import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; @@ -13,6 +14,7 @@ import okhttp3.OkHttpClient; import static org.junit.Assert.assertEquals; + public class CaptchaNoJsHtmlParserTest { private List inputDataList = new ArrayList<>(); private List> resultCheckboxList = new ArrayList<>();