Support Basic and Digest authentication

This commit is contained in:
Syer10
2021-07-13 14:18:15 -04:00
parent 7ca5104c5c
commit 71b05d1f32
7 changed files with 95 additions and 2 deletions

View File

@@ -61,6 +61,7 @@ dependencies {
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
implementation("io.ktor:ktor-client-websockets:$ktorVersion")
implementation("io.ktor:ktor-client-auth:$ktorVersion")
// Logging
val slf4jVersion = "1.7.31"

View File

@@ -7,11 +7,16 @@
package ca.gosyer.data.server
import ca.gosyer.BuildConfig
import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy
import io.ktor.client.HttpClient
import io.ktor.client.engine.ProxyBuilder
import io.ktor.client.engine.ProxyConfig
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.features.auth.providers.BasicAuthCredentials
import io.ktor.client.features.auth.providers.DigestAuthCredentials
import io.ktor.client.features.auth.providers.basic
import io.ktor.client.features.auth.providers.digest
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
import io.ktor.client.features.logging.LogLevel
@@ -21,6 +26,7 @@ import io.ktor.http.URLBuilder
import kotlinx.serialization.json.Json
import javax.inject.Inject
import javax.inject.Provider
import io.ktor.client.features.auth.Auth as AuthFeature
typealias Http = HttpClient
@@ -44,6 +50,29 @@ internal class HttpProvider @Inject constructor(
)
}
}
when (serverPreferences.auth().get()) {
Auth.NONE -> Unit
Auth.BASIC -> install(AuthFeature) {
basic {
credentials {
BasicAuthCredentials(
serverPreferences.authUsername().get(),
serverPreferences.authPassword().get()
)
}
}
}
Auth.DIGEST -> install(AuthFeature) {
digest {
credentials {
DigestAuthCredentials(
serverPreferences.authUsername().get(),
serverPreferences.authPassword().get()
)
}
}
}
}
install(JsonFeature) {
serializer = KotlinxSerializer(
Json {

View File

@@ -8,6 +8,7 @@ package ca.gosyer.data.server
import ca.gosyer.common.prefs.Preference
import ca.gosyer.common.prefs.PreferenceStore
import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy
class ServerPreferences(private val preferenceStore: PreferenceStore) {
@@ -47,4 +48,15 @@ class ServerPreferences(private val preferenceStore: PreferenceStore) {
fun proxySocksPort(): Preference<Int> {
return preferenceStore.getInt("proxy_socks_port")
}
fun auth(): Preference<Auth> {
return preferenceStore.getJsonObject("auth", Auth.NONE, Auth.serializer())
}
fun authUsername(): Preference<String> {
return preferenceStore.getString("auth_username")
}
fun authPassword(): Preference<String> {
return preferenceStore.getString("auth_password")
}
}

View File

@@ -0,0 +1,16 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package ca.gosyer.data.server.model
import kotlinx.serialization.Serializable
@Serializable
enum class Auth {
NONE,
BASIC,
DIGEST
}

View File

@@ -62,6 +62,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.takeOrElse
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
@@ -160,7 +161,8 @@ fun EditTextPreference(
title: String,
subtitle: String? = null,
icon: ImageVector? = null,
enabled: Boolean = true
enabled: Boolean = true,
visualTransformation: VisualTransformation = VisualTransformation.None
) {
var editText by remember { mutableStateOf(TextFieldValue(preference.value)) }
PreferenceRow(
@@ -178,7 +180,8 @@ fun EditTextPreference(
editText,
onValueChange = {
editText = it
}
},
visualTransformation = visualTransformation
)
}
},

View File

@@ -11,7 +11,9 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.text.input.PasswordVisualTransformation
import ca.gosyer.data.server.ServerPreferences
import ca.gosyer.data.server.model.Auth
import ca.gosyer.data.server.model.Proxy
import ca.gosyer.ui.base.components.Toolbar
import ca.gosyer.ui.base.prefs.ChoicePreference
@@ -46,12 +48,24 @@ class SettingsServerViewModel @Inject constructor(
val httpPort = serverPreferences.proxyHttpPort().asStringStateIn(scope)
val socksHost = serverPreferences.proxySocksHost().asStateIn(scope)
val socksPort = serverPreferences.proxySocksPort().asStringStateIn(scope)
val auth = serverPreferences.auth().asStateIn(scope)
@Composable
fun getAuthChoices() = mapOf(
Auth.NONE to stringResource("no_auth"),
Auth.BASIC to stringResource("basic_auth"),
Auth.DIGEST to stringResource("digest_auth")
)
val authUsername = serverPreferences.authUsername().asStateIn(scope)
val authPassword = serverPreferences.authPassword().asStateIn(scope)
}
@Composable
fun SettingsServerScreen(navController: BackStack<Route>) {
val vm = viewModel<SettingsServerViewModel>()
val proxy by vm.proxy.collectAsState()
val auth by vm.auth.collectAsState()
Column {
Toolbar(stringResource("settings_server_screen"), navController, true)
SwitchPreference(preference = vm.host, title = stringResource("host_server"))
@@ -62,6 +76,7 @@ fun SettingsServerScreen(navController: BackStack<Route>) {
item {
EditTextPreference(vm.port, stringResource("server_port"), subtitle = vm.port.collectAsState().value)
}
item {
ChoicePreference(vm.proxy, vm.getProxyChoices(), stringResource("server_proxy"))
}
@@ -84,6 +99,17 @@ fun SettingsServerScreen(navController: BackStack<Route>) {
}
}
}
item {
ChoicePreference(vm.auth, vm.getAuthChoices(), stringResource("authentication"))
}
if (auth != Auth.NONE) {
item {
EditTextPreference(vm.authUsername, stringResource("auth_username"))
}
item {
EditTextPreference(vm.authPassword, stringResource("auth_password"), visualTransformation = PasswordVisualTransformation())
}
}
}
}
}

View File

@@ -176,4 +176,10 @@
<string name="server_proxy">Proxy access to the server</string>
<string name="http_port">HTTP PORT</string>
<string name="socks_port">SOCKS PORT</string>
<string name="authentication">Server authentication</string>
<string name="no_auth">No auth</string>
<string name="basic_auth">Basic auth</string>
<string name="digest_auth">Digest auth</string>
<string name="auth_username">Auth username</string>
<string name="auth_password">Auth password</string>
</resources>