Integrate SslManager into the ValidationExecutor

This commit is contained in:
Aidan Follestad 2019-01-11 18:12:51 -08:00
parent 55ea6674e6
commit 909e5420ad
9 changed files with 63 additions and 14 deletions

View file

@ -20,12 +20,12 @@ import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.browser.customtabs.CustomTabsIntent
import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
import androidx.core.text.HtmlCompat.fromHtml
import com.afollestad.materialdialogs.utils.MDUtil.resolveColor
import com.afollestad.nocknock.utilities.ext.toUri
import com.afollestad.nocknock.utilities.ui.toast
typealias ActivityLifeChange = (activity: Activity, resumed: Boolean) -> Unit
@ -57,8 +57,6 @@ fun Application.onActivityLifeChange(cb: ActivityLifeChange) {
fun String.toHtml() = fromHtml(this, FROM_HTML_MODE_LEGACY)
fun String.toUri() = Uri.parse(this)!!
fun Activity.viewUrl(url: String) {
val customTabsIntent = CustomTabsIntent.Builder()
.apply {

View file

@ -25,6 +25,7 @@ import com.afollestad.nocknock.data.AppDatabase
import com.afollestad.nocknock.data.Database1to2Migration
import com.afollestad.nocknock.data.Database2to3Migration
import com.afollestad.nocknock.data.Database3to4Migration
import com.afollestad.nocknock.data.Database4to5Migration
import com.afollestad.nocknock.notifications.Qualifiers.MAIN_ACTIVITY_CLASS
import com.afollestad.nocknock.ui.main.MainActivity
import com.afollestad.nocknock.utilities.ext.systemService
@ -43,7 +44,8 @@ val mainModule = module {
.addMigrations(
Database1to2Migration(),
Database2to3Migration(),
Database3to4Migration()
Database3to4Migration(),
Database4to5Migration()
)
.build()
}

View file

@ -0,0 +1,20 @@
/**
* Designed and developed by Aidan Follestad (@afollestad)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.afollestad.nocknock.utilities.ext
import android.net.Uri
fun String.toUri() = Uri.parse(this)!!

View file

@ -34,7 +34,7 @@ import com.afollestad.nocknock.data.model.ValidationResult
SiteSettings::class,
Site::class
],
version = 4,
version = 5,
exportSchema = false
)
@TypeConverters(Converters::class)

View file

@ -57,3 +57,15 @@ class Database3to4Migration : Migration(3, 4) {
)
}
}
/**
* Migrates the database from version 4 to 5.
*
* @author Aidan Follestad (@afollestad)
*/
class Database4to5Migration : Migration(4, 5) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `site_settings` ADD COLUMN certificatePath TEXT")
}
}

View file

@ -40,8 +40,10 @@ data class SiteSettings(
/** Whether or not the [Site] is enabled for automatic periodic checks. */
var disabled: Boolean,
/** The network response timeout for validation attempts. */
var networkTimeout: Int
var networkTimeout: Int,
/** The Uri to a self signed certificate. */
var certificate: String?
) : Serializable {
constructor() : this(0, 0, STATUS_CODE, null, false, 0)
constructor() : this(0, 0, STATUS_CODE, null, false, 0, null)
}

View file

@ -25,7 +25,7 @@ import org.koin.dsl.module.module
val engineModule = module {
single {
RealValidationExecutor(get(), get(), get(), get(), get(), get())
RealValidationExecutor(get(), get(), get(), get(), get(), get(), get())
} bind ValidationExecutor::class
factory { RealSslManager(get()) } bind SslManager::class

View file

@ -23,13 +23,16 @@ import com.afollestad.nocknock.data.model.Site
import com.afollestad.nocknock.data.model.Status.ERROR
import com.afollestad.nocknock.data.model.Status.OK
import com.afollestad.nocknock.engine.R
import com.afollestad.nocknock.engine.ssl.SslManager
import com.afollestad.nocknock.engine.validation.ValidationJob.Companion.KEY_SITE_ID
import com.afollestad.nocknock.utilities.ext.toUri
import com.afollestad.nocknock.utilities.providers.BundleProvider
import com.afollestad.nocknock.utilities.providers.JobInfoProvider
import com.afollestad.nocknock.utilities.providers.StringProvider
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.jetbrains.annotations.TestOnly
import java.net.SocketTimeoutException
import java.util.concurrent.TimeUnit.MILLISECONDS
import timber.log.Timber.d as log
@ -66,7 +69,8 @@ class RealValidationExecutor(
private val stringProvider: StringProvider,
private val bundleProvider: BundleProvider,
private val jobInfoProvider: JobInfoProvider,
private val database: AppDatabase
private val database: AppDatabase,
private val sslManager: SslManager
) : ValidationExecutor {
private var clientTimeoutChanger: ClientTimeoutChanger = { client, timeout ->
@ -161,7 +165,16 @@ class RealValidationExecutor(
.build()
return try {
val client = clientTimeoutChanger(okHttpClient, siteSettings.networkTimeout)
val clientWithTimeout = clientTimeoutChanger(okHttpClient, siteSettings.networkTimeout)
val client = if (!siteSettings.certificate.isNullOrEmpty()) {
sslManager.clientForCertificate(
certUri = siteSettings.certificate!!.toUri(),
host = site.url.toUri().host ?: "",
client = clientWithTimeout
)
} else {
clientWithTimeout
}
val response = client.newCall(request)
.execute()
@ -199,7 +212,9 @@ class RealValidationExecutor(
jobScheduler.allPendingJobs
.firstOrNull { job -> job.id == site.id.toInt() }
// @TestOnly fun setClientTimeoutChanger(changer: ClientTimeoutChanger) {
// this.clientTimeoutChanger = changer
// }
@Suppress("unused")
@TestOnly
fun setClientTimeoutChanger(changer: ClientTimeoutChanger) {
this.clientTimeoutChanger = changer
}
}

View file

@ -45,7 +45,7 @@ import okhttp3.ResponseBody
import org.junit.Test
import java.net.SocketTimeoutException
class CheckStatusManagerTest {
class ValidationExecutorTest {
private val timeoutError = "Oh no, a timeout"