Skip to content

Commit 7e08542

Browse files
committed
Shift to webView based authentication
1 parent 016c63b commit 7e08542

File tree

10 files changed

+126
-375
lines changed

10 files changed

+126
-375
lines changed

.idea/gradle.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ android {
1212
applicationId "com.blockgeeks.iitj_auth"
1313
minSdk 23
1414
targetSdk 31
15-
versionCode 10
16-
versionName "1.4.2"
15+
versionCode 11
16+
versionName "2.0.0"
1717

1818
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1919
}

app/release/app-release.apk

-220 KB
Binary file not shown.

app/release/output-metadata.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
"type": "SINGLE",
1212
"filters": [],
1313
"attributes": [],
14-
"versionCode": 9,
15-
"versionName": "1.4.1",
14+
"versionCode": 11,
15+
"versionName": "2.0.0",
1616
"outputFile": "app-release.apk"
1717
}
1818
],

app/src/main/java/com/blockgeeks/iitj_auth/services/ForegroundService.kt

Lines changed: 119 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.blockgeeks.iitj_auth.services
22

3+
import android.annotation.SuppressLint
34
import android.app.*
45
import android.content.Context
56
import android.content.Intent
@@ -9,26 +10,26 @@ import android.net.Network
910
import android.net.NetworkCapabilities
1011
import android.net.NetworkRequest
1112
import android.os.Build
12-
import android.os.Bundle
13+
import android.os.Handler
1314
import android.os.IBinder
1415
import android.util.Log
16+
import android.webkit.WebResourceError
17+
import android.webkit.WebResourceRequest
18+
import android.webkit.WebView
19+
import android.webkit.WebViewClient
1520
import android.widget.Toast
1621
import androidx.core.app.NotificationCompat
1722
import androidx.core.app.NotificationManagerCompat
1823
import androidx.security.crypto.EncryptedSharedPreferences
19-
import androidx.work.ExistingPeriodicWorkPolicy
20-
import androidx.work.PeriodicWorkRequest
2124
import androidx.work.WorkManager
2225
import com.blockgeeks.iitj_auth.R
2326
import com.blockgeeks.iitj_auth.activities.MainActivity
24-
import com.blockgeeks.iitj_auth.utils.authenticate
2527
import com.blockgeeks.iitj_auth.utils.getMasterKey
26-
import com.blockgeeks.iitj_auth.workers.LoginInitiatorWorker
27-
import com.google.firebase.analytics.FirebaseAnalytics
2828
import io.sentry.Sentry
29-
import java.util.concurrent.TimeUnit
29+
import java.util.*
3030

3131

32+
const val loginUrl = "http://www.gstatic.com/generate_204"
3233
const val TAG = "ForegroundService"
3334

3435
class MyForegroundService : Service() {
@@ -65,70 +66,125 @@ class MyForegroundService : Service() {
6566
connectivityManager.bindProcessToNetwork(network)
6667
Log.i(TAG, "Captive Portal detected")
6768
Toast.makeText(applicationContext, "Logging in..", Toast.LENGTH_LONG).show()
68-
val response = authenticate(applicationContext, username!!, password!!)
69-
if (response == "Success") {
70-
// Dismiss the captive portal using the Captive portal API
71-
Log.i(TAG, "Connected!")
72-
updateNotification("Login Successful! ✅")
73-
Toast.makeText(applicationContext, "Connected!", Toast.LENGTH_LONG).show()
74-
75-
// First cancel all work
76-
WorkManager.getInstance(applicationContext)
77-
.cancelUniqueWork("periodicLoginWorkName")
78-
79-
// Use WorkManager to schedule work
80-
val periodicLoginWork = PeriodicWorkRequest.Builder(
81-
LoginInitiatorWorker::class.java,
82-
60,
83-
TimeUnit.MINUTES,
84-
5,
85-
TimeUnit.MINUTES
86-
).build()
87-
WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
88-
"periodicLoginWorkName",
89-
ExistingPeriodicWorkPolicy.REPLACE,
90-
periodicLoginWork
91-
)
92-
93-
} else if (response == "Already Connected") {
94-
// Already Authenticated
95-
Log.i(TAG, "Already Connected!")
96-
} else if (response == "Failed") {
97-
Log.i(TAG, "Authentication Failed!")
98-
updateNotification(
99-
"Login Failed! ❌",
100-
"Please check if your username and password are correct."
101-
)
102-
Toast.makeText(applicationContext, "Authentication failed!", Toast.LENGTH_LONG)
103-
.show()
104-
} else if (response == "Unknown") {
105-
Log.i(TAG, "Authentication Failed!")
106-
updateNotification("Authentication Failed! ❌")
107-
} else {
108-
// res = null states
109-
val parameters = Bundle().apply {
110-
this.putString("level_name", "message")
111-
this.putInt("level_difficulty", 4)
112-
}
113-
FirebaseAnalytics.getInstance(applicationContext)
114-
.logEvent("Auth_failed", parameters)
115-
116-
Log.i(TAG, "Authentication Failed! , response null")
117-
updateNotification(
118-
"Authentication Failed! ❌",
119-
"Try toggling the Wifi on/off once."
120-
)
121-
}
122-
69+
loginViaWebView(applicationContext, username!!, password!!)
12370
}
124-
12571
}
12672

12773
override fun onLost(network: Network) {
12874
Log.e(TAG, "Lost network")
12975
}
13076
}
13177

78+
@SuppressLint("SetJavaScriptEnabled")
79+
fun loginViaWebView(context: Context, username: String, password: String) {
80+
val webView = WebView(context)
81+
webView.settings.javaScriptEnabled = true
82+
webView.loadUrl(loginUrl)
83+
var response: String? = null
84+
85+
webView.webViewClient = object : WebViewClient() {
86+
override fun onReceivedError(
87+
view: WebView,
88+
request: WebResourceRequest,
89+
error: WebResourceError
90+
) {
91+
super.onReceivedError(view, request, error)
92+
Log.e(TAG, "$error")
93+
view.destroy()
94+
}
95+
96+
override fun onPageFinished(view: WebView, url: String) {
97+
view.evaluateJavascript(
98+
"(" +
99+
"function(){ " +
100+
"var user = document.getElementById('ft_un');" +
101+
"user.value = '" + username + "';" +
102+
"var pwd = document.getElementById('ft_pd');" +
103+
"pwd.value = '" + password + "';" +
104+
"var inputSubmit = document.querySelector(\"input[type='submit']\");" +
105+
"if (inputSubmit) {" +
106+
"inputSubmit.click();" +
107+
"}" +
108+
"var inputButton = document.querySelector(\"button[type='submit']\");" +
109+
"if (inputButton) {" +
110+
"inputButton.click();" +
111+
"}" +
112+
"return document.body.innerHTML;" +
113+
"}" +
114+
")()", null
115+
)
116+
117+
view.webViewClient = object : WebViewClient() {
118+
override fun onPageFinished(view: WebView, url: String) {
119+
Log.e(TAG, "onPageFinished: " + "login done")
120+
view.evaluateJavascript(
121+
"(function(){ return document.body.innerHTML; })()"
122+
) { htmlDocumentString ->
123+
if (htmlDocumentString != null) {
124+
if (htmlDocumentString.lowercase(Locale.getDefault())
125+
.contains("Keepalive".lowercase(Locale.getDefault()))
126+
) {
127+
Log.i(TAG, "Connected!")
128+
updateNotification("Login Successful! ✅")
129+
Toast.makeText(
130+
applicationContext,
131+
"Connected!",
132+
Toast.LENGTH_LONG
133+
).show()
134+
135+
} else if (htmlDocumentString.lowercase(Locale.getDefault())
136+
.contains("over limit".lowercase(Locale.getDefault()))
137+
) {
138+
updateNotification(
139+
"Over Limit! ⚠️",
140+
)
141+
Toast.makeText(
142+
applicationContext,
143+
"Authentication failed!",
144+
Toast.LENGTH_LONG
145+
)
146+
.show()
147+
Log.i(TAG, "Over Limit!")
148+
} else if (htmlDocumentString.lowercase(Locale.getDefault())
149+
.contains("Authentication Failed".lowercase(Locale.getDefault()))
150+
) {
151+
Log.i(TAG, "Authentication Failed!")
152+
updateNotification(
153+
"Login Failed! ❌",
154+
"Please recheck if your username and password are correct."
155+
)
156+
Toast.makeText(
157+
applicationContext,
158+
"Authentication failed!",
159+
Toast.LENGTH_LONG
160+
)
161+
.show()
162+
} else {
163+
Log.i(
164+
TAG,
165+
"onReceiveValue: Unknown"
166+
)
167+
Log.i(TAG, "Authentication Failed!")
168+
updateNotification("Authentication Failed! ❌")
169+
}
170+
}
171+
}
172+
destroyWebViewAfterDelay(view)
173+
}
174+
}
175+
}
176+
}
177+
}
178+
179+
private fun destroyWebViewAfterDelay(view: WebView?) {
180+
val handler = Handler()
181+
handler.postDelayed(Runnable {
182+
Log.e(TAG, "run: " + "webView destroyed")
183+
view?.destroy()
184+
}, 5000)
185+
}
186+
187+
132188
override fun onCreate() {
133189
val pendingIntent: PendingIntent =
134190
Intent(this, MainActivity::class.java).let { notificationIntent ->

0 commit comments

Comments
 (0)