Migrate legacy ca cert in newer version
This commit is contained in:
@@ -6,6 +6,7 @@ import com.github.gotify.client.model.User
|
|||||||
|
|
||||||
internal class Settings(context: Context) {
|
internal class Settings(context: Context) {
|
||||||
private val sharedPreferences: SharedPreferences
|
private val sharedPreferences: SharedPreferences
|
||||||
|
val filesDir: String
|
||||||
var url: String
|
var url: String
|
||||||
get() = sharedPreferences.getString("url", "")!!
|
get() = sharedPreferences.getString("url", "")!!
|
||||||
set(value) = sharedPreferences.edit().putString("url", value).apply()
|
set(value) = sharedPreferences.edit().putString("url", value).apply()
|
||||||
@@ -26,6 +27,9 @@ internal class Settings(context: Context) {
|
|||||||
var serverVersion: String
|
var serverVersion: String
|
||||||
get() = sharedPreferences.getString("version", "UNKNOWN")!!
|
get() = sharedPreferences.getString("version", "UNKNOWN")!!
|
||||||
set(value) = sharedPreferences.edit().putString("version", value).apply()
|
set(value) = sharedPreferences.edit().putString("version", value).apply()
|
||||||
|
var legacyCert: String?
|
||||||
|
get() = sharedPreferences.getString("cert", null)
|
||||||
|
set(value) = sharedPreferences.edit().putString("cert", value).apply()
|
||||||
var caCertPath: String?
|
var caCertPath: String?
|
||||||
get() = sharedPreferences.getString("caCertPath", null)
|
get() = sharedPreferences.getString("caCertPath", null)
|
||||||
set(value) = sharedPreferences.edit().putString("caCertPath", value).apply()
|
set(value) = sharedPreferences.edit().putString("caCertPath", value).apply()
|
||||||
@@ -44,6 +48,7 @@ internal class Settings(context: Context) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
sharedPreferences = context.getSharedPreferences("gotify", Context.MODE_PRIVATE)
|
sharedPreferences = context.getSharedPreferences("gotify", Context.MODE_PRIVATE)
|
||||||
|
filesDir = context.filesDir.absolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tokenExists(): Boolean = !token.isNullOrEmpty()
|
fun tokenExists(): Boolean = !token.isNullOrEmpty()
|
||||||
@@ -52,6 +57,7 @@ internal class Settings(context: Context) {
|
|||||||
url = ""
|
url = ""
|
||||||
token = null
|
token = null
|
||||||
validateSSL = true
|
validateSSL = true
|
||||||
|
legacyCert = null
|
||||||
caCertPath = null
|
caCertPath = null
|
||||||
caCertCN = null
|
caCertCN = null
|
||||||
clientCertPath = null
|
clientCertPath = null
|
||||||
|
|||||||
@@ -7,57 +7,78 @@ import com.github.gotify.client.api.UserApi
|
|||||||
import com.github.gotify.client.api.VersionApi
|
import com.github.gotify.client.api.VersionApi
|
||||||
import com.github.gotify.client.auth.ApiKeyAuth
|
import com.github.gotify.client.auth.ApiKeyAuth
|
||||||
import com.github.gotify.client.auth.HttpBasicAuth
|
import com.github.gotify.client.auth.HttpBasicAuth
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileOutputStream
|
||||||
|
import java.io.IOException
|
||||||
|
import org.tinylog.kotlin.Logger
|
||||||
|
|
||||||
internal object ClientFactory {
|
internal object ClientFactory {
|
||||||
private fun unauthorized(baseUrl: String, sslSettings: SSLSettings): ApiClient {
|
private fun unauthorized(
|
||||||
return defaultClient(arrayOf(), "$baseUrl/", sslSettings)
|
settings: Settings,
|
||||||
|
sslSettings: SSLSettings,
|
||||||
|
baseUrl: String
|
||||||
|
): ApiClient {
|
||||||
|
return defaultClient(arrayOf(), settings, sslSettings, baseUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun basicAuth(
|
fun basicAuth(
|
||||||
baseUrl: String,
|
settings: Settings,
|
||||||
sslSettings: SSLSettings,
|
sslSettings: SSLSettings,
|
||||||
username: String,
|
username: String,
|
||||||
password: String
|
password: String
|
||||||
): ApiClient {
|
): ApiClient {
|
||||||
val client = defaultClient(
|
val client = defaultClient(arrayOf("basicAuth"), settings, sslSettings)
|
||||||
arrayOf("basicAuth"),
|
|
||||||
"$baseUrl/",
|
|
||||||
sslSettings
|
|
||||||
)
|
|
||||||
val auth = client.apiAuthorizations["basicAuth"] as HttpBasicAuth
|
val auth = client.apiAuthorizations["basicAuth"] as HttpBasicAuth
|
||||||
auth.username = username
|
auth.username = username
|
||||||
auth.password = password
|
auth.password = password
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clientToken(baseUrl: String, sslSettings: SSLSettings, token: String?): ApiClient {
|
fun clientToken(settings: Settings, token: String? = settings.token): ApiClient {
|
||||||
val client = defaultClient(
|
val client = defaultClient(arrayOf("clientTokenHeader"), settings)
|
||||||
arrayOf("clientTokenHeader"),
|
|
||||||
"$baseUrl/",
|
|
||||||
sslSettings
|
|
||||||
)
|
|
||||||
val tokenAuth = client.apiAuthorizations["clientTokenHeader"] as ApiKeyAuth
|
val tokenAuth = client.apiAuthorizations["clientTokenHeader"] as ApiKeyAuth
|
||||||
tokenAuth.apiKey = token
|
tokenAuth.apiKey = token
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
fun versionApi(baseUrl: String, sslSettings: SSLSettings): VersionApi {
|
fun versionApi(
|
||||||
return unauthorized(baseUrl, sslSettings).createService(VersionApi::class.java)
|
settings: Settings,
|
||||||
|
sslSettings: SSLSettings = settings.sslSettings(),
|
||||||
|
baseUrl: String = settings.url
|
||||||
|
): VersionApi {
|
||||||
|
return unauthorized(settings, sslSettings, baseUrl).createService(VersionApi::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun userApiWithToken(settings: Settings): UserApi {
|
fun userApiWithToken(settings: Settings): UserApi {
|
||||||
return clientToken(settings.url, settings.sslSettings(), settings.token)
|
return clientToken(settings).createService(UserApi::class.java)
|
||||||
.createService(UserApi::class.java)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun defaultClient(
|
private fun defaultClient(
|
||||||
authentications: Array<String>,
|
authentications: Array<String>,
|
||||||
baseUrl: String,
|
settings: Settings,
|
||||||
sslSettings: SSLSettings
|
sslSettings: SSLSettings = settings.sslSettings(),
|
||||||
|
baseUrl: String = settings.url
|
||||||
): ApiClient {
|
): ApiClient {
|
||||||
val client = ApiClient(authentications)
|
val client = ApiClient(authentications)
|
||||||
|
if (settings.legacyCert != null) {
|
||||||
|
Logger.info("Migrating legacy CA cert to new location")
|
||||||
|
var legacyCert: String? = null
|
||||||
|
try {
|
||||||
|
legacyCert = settings.legacyCert
|
||||||
|
settings.legacyCert = null
|
||||||
|
val caCertFile = File(settings.filesDir, CertUtils.CA_CERT_NAME)
|
||||||
|
FileOutputStream(caCertFile).use {
|
||||||
|
it.write(legacyCert?.encodeToByteArray())
|
||||||
|
}
|
||||||
|
settings.caCertPath = caCertFile.absolutePath
|
||||||
|
Logger.info("Migration of legacy CA cert succeeded")
|
||||||
|
} catch (e: IOException) {
|
||||||
|
Logger.error(e, "Migration of legacy CA cert failed")
|
||||||
|
if (legacyCert != null) settings.legacyCert = legacyCert
|
||||||
|
}
|
||||||
|
}
|
||||||
CertUtils.applySslSettings(client.okBuilder, sslSettings)
|
CertUtils.applySslSettings(client.okBuilder, sslSettings)
|
||||||
client.adapterBuilder.baseUrl(baseUrl)
|
client.adapterBuilder.baseUrl("$baseUrl/")
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ internal class InitializationActivity : AppCompatActivity() {
|
|||||||
callback: SuccessCallback<VersionInfo>,
|
callback: SuccessCallback<VersionInfo>,
|
||||||
errorCallback: Callback.ErrorCallback
|
errorCallback: Callback.ErrorCallback
|
||||||
) {
|
) {
|
||||||
ClientFactory.versionApi(settings.url, settings.sslSettings())
|
ClientFactory.versionApi(settings)
|
||||||
.version
|
.version
|
||||||
.enqueue(Callback.callInUI(this, callback, errorCallback))
|
.enqueue(Callback.callInUI(this, callback, errorCallback))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ internal class LoginActivity : AppCompatActivity() {
|
|||||||
binding.checkurl.visibility = View.GONE
|
binding.checkurl.visibility = View.GONE
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ClientFactory.versionApi(url, tempSslSettings())
|
ClientFactory.versionApi(settings, tempSslSettings(), url)
|
||||||
.version
|
.version
|
||||||
.enqueue(Callback.callInUI(this, onValidUrl(url), onInvalidUrl(url)))
|
.enqueue(Callback.callInUI(this, onValidUrl(url), onInvalidUrl(url)))
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -252,7 +252,7 @@ internal class LoginActivity : AppCompatActivity() {
|
|||||||
binding.login.visibility = View.GONE
|
binding.login.visibility = View.GONE
|
||||||
binding.loginProgress.visibility = View.VISIBLE
|
binding.loginProgress.visibility = View.VISIBLE
|
||||||
|
|
||||||
val client = ClientFactory.basicAuth(settings.url, tempSslSettings(), username, password)
|
val client = ClientFactory.basicAuth(settings, tempSslSettings(), username, password)
|
||||||
client.createService(UserApi::class.java)
|
client.createService(UserApi::class.java)
|
||||||
.currentUser()
|
.currentUser()
|
||||||
.enqueue(
|
.enqueue(
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ internal class MessagesActivity :
|
|||||||
|
|
||||||
private fun deleteApp(appId: Long) {
|
private fun deleteApp(appId: Long) {
|
||||||
val settings = viewModel.settings
|
val settings = viewModel.settings
|
||||||
val client = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
|
val client = ClientFactory.clientToken(settings)
|
||||||
client.createService(ApplicationApi::class.java)
|
client.createService(ApplicationApi::class.java)
|
||||||
.deleteApp(appId)
|
.deleteApp(appId)
|
||||||
.enqueue(
|
.enqueue(
|
||||||
@@ -597,8 +597,7 @@ internal class MessagesActivity :
|
|||||||
|
|
||||||
private fun deleteClientAndNavigateToLogin() {
|
private fun deleteClientAndNavigateToLogin() {
|
||||||
val settings = viewModel.settings
|
val settings = viewModel.settings
|
||||||
val api = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
|
val api = ClientFactory.clientToken(settings).createService(ClientApi::class.java)
|
||||||
.createService(ClientApi::class.java)
|
|
||||||
stopService(Intent(this@MessagesActivity, WebSocketService::class.java))
|
stopService(Intent(this@MessagesActivity, WebSocketService::class.java))
|
||||||
try {
|
try {
|
||||||
val clients = Api.execute(api.clients)
|
val clients = Api.execute(api.clients)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import com.squareup.picasso.Target
|
|||||||
internal class MessagesModel(parentView: Activity) : ViewModel() {
|
internal class MessagesModel(parentView: Activity) : ViewModel() {
|
||||||
val settings = Settings(parentView)
|
val settings = Settings(parentView)
|
||||||
val picassoHandler = PicassoHandler(parentView, settings)
|
val picassoHandler = PicassoHandler(parentView, settings)
|
||||||
val client = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
|
val client = ClientFactory.clientToken(settings)
|
||||||
val appsHolder = ApplicationHolder(parentView, client)
|
val appsHolder = ApplicationHolder(parentView, client)
|
||||||
val messages = MessageFacade(client.createService(MessageApi::class.java), appsHolder)
|
val messages = MessageFacade(client.createService(MessageApi::class.java), appsHolder)
|
||||||
|
|
||||||
|
|||||||
@@ -68,11 +68,7 @@ internal class WebSocketService : Service() {
|
|||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
settings = Settings(this)
|
settings = Settings(this)
|
||||||
val client = ClientFactory.clientToken(
|
val client = ClientFactory.clientToken(settings)
|
||||||
settings.url,
|
|
||||||
settings.sslSettings(),
|
|
||||||
settings.token
|
|
||||||
)
|
|
||||||
missingMessageUtil = MissedMessageUtil(client.createService(MessageApi::class.java))
|
missingMessageUtil = MissedMessageUtil(client.createService(MessageApi::class.java))
|
||||||
Logger.info("Create ${javaClass.simpleName}")
|
Logger.info("Create ${javaClass.simpleName}")
|
||||||
picassoHandler = PicassoHandler(this, settings)
|
picassoHandler = PicassoHandler(this, settings)
|
||||||
@@ -129,7 +125,7 @@ internal class WebSocketService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchApps() {
|
private fun fetchApps() {
|
||||||
ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
|
ClientFactory.clientToken(settings)
|
||||||
.createService(ApplicationApi::class.java)
|
.createService(ApplicationApi::class.java)
|
||||||
.apps
|
.apps
|
||||||
.enqueue(
|
.enqueue(
|
||||||
|
|||||||
@@ -61,11 +61,7 @@ internal class ShareActivity : AppCompatActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val client = ClientFactory.clientToken(
|
val client = ClientFactory.clientToken(settings)
|
||||||
settings.url,
|
|
||||||
settings.sslSettings(),
|
|
||||||
settings.token
|
|
||||||
)
|
|
||||||
appsHolder = ApplicationHolder(this, client)
|
appsHolder = ApplicationHolder(this, client)
|
||||||
appsHolder.onUpdate {
|
appsHolder.onUpdate {
|
||||||
val apps = appsHolder.get()
|
val apps = appsHolder.get()
|
||||||
@@ -136,11 +132,7 @@ internal class ShareActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun executeMessageCall(appIndex: Int, message: Message): Boolean {
|
private fun executeMessageCall(appIndex: Int, message: Message): Boolean {
|
||||||
val pushClient = ClientFactory.clientToken(
|
val pushClient = ClientFactory.clientToken(settings, appsHolder.get()[appIndex].token)
|
||||||
settings.url,
|
|
||||||
settings.sslSettings(),
|
|
||||||
appsHolder.get()[appIndex].token
|
|
||||||
)
|
|
||||||
return try {
|
return try {
|
||||||
val messageApi = pushClient.createService(MessageApi::class.java)
|
val messageApi = pushClient.createService(MessageApi::class.java)
|
||||||
Api.execute(messageApi.createMessage(message))
|
Api.execute(messageApi.createMessage(message))
|
||||||
|
|||||||
Reference in New Issue
Block a user