Login page now disallows visiting a domain other than the school's login page to prevent a successful login from another domain allowing access to the app's content

This commit is contained in:
Deniz Düzgören
2019-09-23 17:23:59 +02:00
parent 088aa90aa4
commit fd40115549
21 changed files with 328 additions and 295 deletions
@@ -18,7 +18,7 @@ import com.denizd.substitutionplan.R
import com.denizd.substitutionplan.database.SubstRepository
import com.denizd.substitutionplan.activities.Main
import com.denizd.substitutionplan.models.Food
import com.denizd.substitutionplan.models.Subst
import com.denizd.substitutionplan.models.Substitution
import com.google.android.material.snackbar.Snackbar
import org.jsoup.Jsoup
import java.lang.ref.WeakReference
@@ -57,7 +57,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
private val edit = prefs.edit()
private var currentTime = ""
private var currentFoodTime = ""
private var substUrl = "https://djd4rkn355.github.io/subst.html"
private var substUrl = "https://djd4rkn355.github.io/avh_substitutions.html"
private var foodUrl = "https://djd4rkn355.github.io/food.html"
override fun doInBackground(vararg params: Void?): Void? {
@@ -149,7 +149,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
if (currentTime != prefs.getString("timeNew", "")) {
val rows = doc.select("tr")
val paragraphs = doc.select("p")
val substArray = ArrayList<Subst>()
val substArray = ArrayList<Substitution>()
val coursePreference = prefs.getString("courses", "") ?: ""
val classPreference = prefs.getString("classes", "") ?: ""
@@ -169,7 +169,7 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
val row = rows[i]
val cols = row.select("th")
val subst = Subst(
val subst = Substitution(
group = cols[0].text(),
date = cols[1].text(),
time = cols[2].text(),
@@ -237,11 +237,12 @@ internal class DataFetcher(isPlan: Boolean, isMenu: Boolean, isJobService: Boole
val notification = NotificationCompat.Builder(context, HelperFunctions.notificationChannelId)
.setStyle(NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(notificationLayout)
.setSmallIcon(R.drawable.ic_avhlogo)
.setContentIntent(openAppPending)
.setAutoCancel(true)
.setColor(ContextCompat.getColor(context, R.color.colorAccent))
notification.setSmallIcon(if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) R.drawable.ic_avh else R.drawable.ic_avhlogo)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
val sound = if ((prefs.getString("ringtoneUri", "") ?: "").isNotEmpty()) {
Uri.parse(prefs.getString("ringtoneUri", "") ?: "")
@@ -20,7 +20,7 @@ import androidx.core.content.ContextCompat
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.fragment.app.FragmentActivity
import com.denizd.substitutionplan.R
import com.denizd.substitutionplan.models.Subst
import com.denizd.substitutionplan.models.Substitution
import java.util.*
import java.io.File
import java.io.FileOutputStream
@@ -45,6 +45,12 @@ internal object HelperFunctions {
"brown", "grey", "pureWhite", "salmon", "tangerine", "banana", "flora", "spindrift", "sky", "orchid",
"lavender", "carnation", "brown2", "pureBlack")
/**
* A list of all phrases used to describe that a course has been cancelled. Expand this
* if necessary. No further code changes required if this is expanded
*/
val cancellations = arrayOf("eigenverantwortliches arbeiten", "entfall", "entfällt", "fällt aus", "freisetzung", "vtr. ohne lehrer")
private val colourIntegers = intArrayOf(
0,
R.color.bgRed,
@@ -135,6 +141,60 @@ internal object HelperFunctions {
}
}
/**
* This function returns a string that is used to get the colour set for a specific course
* from Shared Preferences
*
* @param course the course abbreviation as a string
*
* @return the string used to store the course's colour in Shared Preferences
*/
fun getColourString(course: String): String {
var colorCheck: String
return try {
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 3)
when (colorCheck) {
"deu", "dep", "daz", "fda" -> "German"
"mat", "map" -> "Maths"
"eng", "enp", "ena" -> "English"
"spo", "spp", "spth" -> "PhysEd"
"pol", "pop" -> "Politics"
"dar", "dap" -> "Theatre"
"phy", "php" -> "Physics"
"bio", "bip", "nw1", "nw2", "nw3", "nw4" -> "Biology"
"che", "chp" -> "Chemistry"
"phi", "psp" -> "Philosophy"
"laa", "laf", "lat" -> "Latin"
"spa", "spf" -> "Spanish"
"fra", "frf", "frz" -> "French"
"inf" -> "CompSci"
"ges" -> "History"
"rel" -> "Religion"
"geg" -> "Geography"
"kun" -> "Arts"
"mus" -> "Music"
"tue" -> "Turkish"
"chi" -> "Chinese"
"gll" -> "GLL"
"wat" -> "WAT"
"för" -> "Forder"
"met", "wpb" -> "WP"
else -> ""
}
} catch (e: StringIndexOutOfBoundsException) {
try {
colorCheck = course.toLowerCase(Locale.ROOT).substring(0, 2)
when (colorCheck) {
"nw" -> "Biology"
"wp" -> "WP"
else -> ""
}
} catch (e2: StringIndexOutOfBoundsException) {
""
}
}
}
/**
* This function served as a way to transfer a deprecated method of storing user-defined
* course colours to a new method. It is not required otherwise, but still remains in
@@ -163,17 +223,17 @@ internal object HelperFunctions {
* This function serves for checking whether a course on the substitution plan is relevant to
* the user and should be shown on their personal plan as well as in their notifications
*
* @param subst the substitution item
* @param substitution the substitution item
* @param coursePreference a string that represents the courses the user is enrolled in
* @param classPreference a string that represents the group the user is in
* @param psa decide whether or not any PSA items should be included in the filter
*
* @return true if the substitution is relevant to the user, false otherwise
*/
fun checkPersonalSubstitutions(subst: Subst, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
val group = subst.group
val course = subst.course
if (psa && subst.date.isNotEmpty() && subst.date.substring(0, 3) == "psa") {
fun checkPersonalSubstitutions(substitution: Substitution, coursePreference: String, classPreference: String, psa: Boolean): Boolean {
val group = substitution.group
val course = substitution.course
if (psa && substitution.date.isNotEmpty() && substitution.date.substring(0, 3) == "psa") {
return true
}
if (coursePreference.isEmpty() && classPreference.isNotEmpty()) {
@@ -1,8 +1,11 @@
package com.denizd.substitutionplan.data
import android.graphics.Bitmap
import android.util.Log
import android.webkit.CookieManager
import android.webkit.WebView
import android.webkit.WebViewClient
import java.lang.IllegalStateException
/**
* Class that extends WebViewClient to provide a function that checks the webpage's cookies to
@@ -10,27 +13,40 @@ import android.webkit.WebViewClient
*
* @param successListener a reference to the OnLoginSuccessListener implemented in an activity
*/
internal class LoginWebViewClient(successListener: OnLoginSuccessListener) : WebViewClient() {
internal class LoginWebViewClient(private val successListener: OnLoginSuccessListener) : WebViewClient() {
private val mSuccessListener = successListener
/**
* onPageStarted has been overridden to prevent users from reaching a domain different from
* the school's login page
*/
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
if (url != "https://307.joomla.schule.bremen.de/index.php/component/users/profile?Itemid=171"
&& url != "https://307.joomla.schule.bremen.de/index.php/component/users/#top") {
reloadLoginPage(webView = view)
}
}
/**
* OnPageFinished has been overridden to check if the cookie "joomla_user_state=logged_in"
* exists, and returns true to the OnLoginSuccessListener
*
* @param view a reference to the WebView
* @param url a reference to the url of the WebView
*/
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
view?.scrollY = -4000
view?.scrollY = -10_000
val cookies = CookieManager.getInstance().getCookie(url)
if (cookies.contains("joomla_user_state=logged_in")) {
mSuccessListener.onLoginSucceeded(true)
successListener.onLoginSucceeded(true)
}
}
private fun reloadLoginPage(webView: WebView?) {
webView?.loadUrl("https://307.joomla.schule.bremen.de/index.php/component/users/#top")
}
/**
* The interface that provides onLoginSucceeded to the activity or fragment that implements it
*/