[Login/Librus] Add Librus captcha activity/dialog.

This commit is contained in:
Kuba Szczodrzyński 2019-11-05 21:42:16 +01:00
parent 14cd548dff
commit 39c8a743bb
5 changed files with 180 additions and 31 deletions

View File

@ -15,10 +15,14 @@
android:theme="@style/SplashTheme"
android:usesCleartextTraffic="true"
tools:ignore="UnusedAttribute">
<activity
android:name=".ui.modules.login.LoginLibrusCaptchaActivity"
android:theme="@android:style/Theme.Dialog"
android:excludeFromRecents="true"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/SplashTheme">
<intent-filter>
@ -29,7 +33,7 @@
</intent-filter>
</activity>
<activity
android:name="pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeActivity"
android:name=".ui.modules.messages.MessagesComposeActivity"
android:configChanges="orientation|screenSize"
android:label="@string/messages_compose_title"
android:theme="@style/AppTheme.Black" />
@ -39,7 +43,7 @@
android:label="@string/app_name"
android:theme="@style/AppTheme" />
<activity
android:name="pl.szczodrzynski.edziennik.ui.modules.login.LoginActivity"
android:name=".ui.modules.login.LoginActivity"
android:configChanges="orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/AppTheme.Light" />
@ -101,22 +105,18 @@
android:excludeFromRecents="true"
android:noHistory="true"
android:theme="@style/AppTheme.NoDisplay" />
<activity
android:name=".ui.modules.settings.SettingsLicenseActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme" />
<activity
android:name="com.theartofdev.edmodo.cropper.CropImageActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/Base.Theme.AppCompat" />
<activity
android:name=".ui.modules.webpush.WebPushConfigActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="@style/AppTheme.Dark" />
<activity
android:name=".ui.modules.home.CounterActivity"
android:theme="@style/AppTheme.Black" />
@ -169,7 +169,6 @@
android:name="android.appwidget.provider"
android:resource="@xml/widget_notifications_info" />
</receiver>
<receiver
android:name=".widgets.luckynumber.WidgetLuckyNumber"
android:label="@string/widget_lucky_number_title">
@ -188,7 +187,6 @@
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
@ -196,14 +194,7 @@
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service
android:name=".sync.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<receiver
android:name=".sync.FirebaseBroadcastReceiver"
android:exported="true"
@ -212,6 +203,23 @@
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>
<receiver
android:name=".receivers.SzkolnyReceiver"
android:exported="true">
<intent-filter>
<action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" />
</intent-filter>
</receiver>
<service
android:name=".sync.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service
android:name=".widgets.timetable.WidgetTimetableService"
android:permission="android.permission.BIND_REMOTEVIEWS" />
@ -222,14 +230,6 @@
<service android:name=".Notifier$GetDataRetryService" />
<receiver
android:name=".receivers.SzkolnyReceiver"
android:exported="true">
<intent-filter>
<action android:name="pl.szczodrzynski.edziennik.SZKOLNY_MAIN" />
</intent-filter>
</receiver>
<service android:name=".api.v2.ApiService" />
</application>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
@ -244,4 +244,4 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
</manifest>
</manifest>

View File

@ -30,6 +30,7 @@ import androidx.fragment.app.Fragment;
import androidx.work.WorkManager;
import com.afollestad.materialdialogs.MaterialDialog;
import com.chuckerteam.chucker.api.Chucker;
import com.mikepenz.iconics.IconicsColor;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.IconicsSize;
@ -50,6 +51,7 @@ import pl.szczodrzynski.edziennik.databinding.CardLuckyNumberBinding;
import pl.szczodrzynski.edziennik.databinding.CardUpdateBinding;
import pl.szczodrzynski.edziennik.databinding.FragmentHomeBinding;
import pl.szczodrzynski.edziennik.receivers.BootReceiver;
import pl.szczodrzynski.edziennik.ui.modules.login.LoginLibrusCaptchaActivity;
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesComposeActivity;
import pl.szczodrzynski.edziennik.utils.Colors;
import pl.szczodrzynski.edziennik.utils.Themes;
@ -104,6 +106,14 @@ public class HomeFragment extends Fragment {
b.pruneWorkButton.setOnClickListener((v -> WorkManager.getInstance(app).pruneWork()));
b.runChucker.setOnClickListener((v -> {
startActivity(Chucker.getLaunchIntent(activity, Chucker.SCREEN_HTTP));
}));
b.librusCaptchaButton.setOnClickListener((v -> {
startActivity(new Intent(activity, LoginLibrusCaptchaActivity.class));
}));
//((TextView)v.findViewById(R.id.nextSync)).setText(getString(R.string.next_sync_format,Time.fromMillis(app.appJobs.syncJobTime).getStringHMS()));

View File

@ -0,0 +1,116 @@
package pl.szczodrzynski.edziennik.ui.modules.login
import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.util.Base64
import android.webkit.JavascriptInterface
import android.webkit.WebView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.api.v2.LIBRUS_USER_AGENT
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.edziennik.utils.Utils.hexFromColorInt
import java.nio.charset.Charset
class LoginLibrusCaptchaActivity : AppCompatActivity() {
companion object {
private const val TAG = "LoginLibrusCaptchaActivity"
}
private lateinit var webView: WebView
private lateinit var dialog: AlertDialog
private lateinit var jsInterface: CaptchaCallbackInterface
@SuppressLint("AddJavascriptInterface", "SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setTheme(Themes.appThemeNoDisplay)
setFinishOnTouchOutside(false)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true)
}
val base64Content = """
PCFET0NUWVBFIGh0bWw+PGh0bWw+PGhlYWQ+PHNjcmlwdCBzcmM9Imh0dHBzOi8vd3d3Lmdvb2ds
ZS5jb20vcmVjYXB0Y2hhL2FwaS5qcz9vbmxvYWQ9cmVhZHkmcmVuZGVyPWV4cGxpY2l0Ij48L3Nj
cmlwdD48L2hlYWQ+PGJvZHk+PGJyPjxjZW50ZXIgaWQ9ImdyIj48L2NlbnRlcj48YnI+PHNjcmlw
dD5mdW5jdGlvbiByZWFkeSgpe2dyZWNhcHRjaGEucmVuZGVyKCdncicse3NpdGVrZXk6JzZMZjQ4
bW9VQUFBQUFCOUNsaGR2SHI0NmdSV1ItQ04zMUNYUVBHMlUnLHRoZW1lOidUSEVNRScsY2FsbGJh
Y2s6ZnVuY3Rpb24oZSl7d2luZG93LmlmLmNhbGxiYWNrKGUpO30sImV4cGlyZWQtY2FsbGJhY2si
OmZ1bmN0aW9uKCl7d2luZG93LmlmLmV4cGlyZWRDYWxsYmFjayhlKTt9LCJlcnJvci1jYWxsYmFj
ayI6ZnVuY3Rpb24oKXt3aW5kb3cuaWYuZXJyb3JDYWxsYmFjayhlKTt9fSk7fTwvc2NyaXB0Pjwv
Ym9keT48L2h0bWw+"""
val backgroundColor = if (Themes.isDark) 0x424242 else 0xffffff
val backgroundColorString = hexFromColorInt(backgroundColor)
val htmlContent = Base64.decode(base64Content, Base64.DEFAULT)
.toString(Charset.defaultCharset())
.replace("COLOR", backgroundColorString, true)
.replace("THEME", if (Themes.isDark) "dark" else "light")
jsInterface = object : CaptchaCallbackInterface {
@JavascriptInterface
override fun callback(recaptchaResponse: String) {
MaterialDialog.Builder(this@LoginLibrusCaptchaActivity)
.title("Captcha checked")
.content("Response: $recaptchaResponse")
.positiveText("OK")
.show()
}
@JavascriptInterface
override fun expiredCallback() {
MaterialDialog.Builder(this@LoginLibrusCaptchaActivity)
.title("Captcha expired")
.content("Captcha expired")
.positiveText("OK")
.show()
}
@JavascriptInterface
override fun errorCallback() {
MaterialDialog.Builder(this@LoginLibrusCaptchaActivity)
.title("Captcha error")
.content("Captcha error")
.positiveText("OK")
.show()
}
}
webView = WebView(this).apply {
//setBackgroundColor((backgroundColor.toLong() or 0xff000000).toInt())
setBackgroundColor(Color.TRANSPARENT)
settings.javaScriptEnabled = true
settings.userAgentString = LIBRUS_USER_AGENT
addJavascriptInterface(jsInterface, "if")
loadDataWithBaseURL("https://portal.librus.pl/rodzina/login/", htmlContent, "text/html", "UTF-8", null)
setLayerType(WebView.LAYER_TYPE_SOFTWARE, null)
}
dialog = MaterialAlertDialogBuilder(this)
.setTitle(R.string.login_librus_captcha_title)
.setView(webView)
.setNegativeButton(R.string.cancel) { dialog, _ ->
dialog.dismiss()
finish()
}
.setCancelable(false)
.show()
}
interface CaptchaCallbackInterface {
@JavascriptInterface
fun callback(recaptchaResponse: String)
@JavascriptInterface
fun expiredCallback()
@JavascriptInterface
fun errorCallback()
}
}

View File

@ -36,24 +36,46 @@
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical"
tools:visibility="visible">
tools:visibility="visible"
tools:ignore="HardcodedText">
<com.google.android.material.button.MaterialButton
android:id="@+id/librusCaptchaButton"
style="@style/Widget.MaterialComponents.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Librus Captcha" />
<com.google.android.material.button.MaterialButton
android:id="@+id/runChucker"
style="@style/Widget.MaterialComponents.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="Launch Chucker" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:gravity="center">
<com.google.android.material.button.MaterialButton
android:id="@+id/mobidziennikMessagesSwitch"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_margin="8dp"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:text="Zmień moduł wiadomości" />
<com.google.android.material.button.MaterialButton
android:id="@+id/composeButton"
style="@style/Widget.MaterialComponents.Button"
android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_weight="1"
android:text="Compose" />
</LinearLayout>

View File

@ -984,4 +984,5 @@
<string name="dont_ask_again">Nie pytaj ponownie</string>
<string name="app_manager_open_failed">Nie udało się otworzyć ustawień</string>
<string name="edziennik_notification_api_notify_title">Tworzenie powiadomień</string>
<string name="login_librus_captcha_title">Librus - logowanie</string>
</resources>