Skip to content

Commit

Permalink
Migrate legacy ca cert in newer version
Browse files Browse the repository at this point in the history
  • Loading branch information
cyb3rko committed Apr 23, 2024
1 parent 60946e4 commit a3dd80c
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 44 deletions.
6 changes: 6 additions & 0 deletions app/src/main/kotlin/com/github/gotify/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.github.gotify.client.model.User

internal class Settings(context: Context) {
private val sharedPreferences: SharedPreferences
val filesDir: String
var url: String
get() = sharedPreferences.getString("url", "")!!
set(value) = sharedPreferences.edit().putString("url", value).apply()
Expand All @@ -26,6 +27,9 @@ internal class Settings(context: Context) {
var serverVersion: String
get() = sharedPreferences.getString("version", "UNKNOWN")!!
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?
get() = sharedPreferences.getString("caCertPath", null)
set(value) = sharedPreferences.edit().putString("caCertPath", value).apply()
Expand All @@ -44,6 +48,7 @@ internal class Settings(context: Context) {

init {
sharedPreferences = context.getSharedPreferences("gotify", Context.MODE_PRIVATE)
filesDir = context.filesDir.absolutePath
}

fun tokenExists(): Boolean = !token.isNullOrEmpty()
Expand All @@ -52,6 +57,7 @@ internal class Settings(context: Context) {
url = ""
token = null
validateSSL = true
legacyCert = null
caCertPath = null
caCertCN = null
clientCertPath = null
Expand Down
63 changes: 42 additions & 21 deletions app/src/main/kotlin/com/github/gotify/api/ClientFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,78 @@ import com.github.gotify.client.api.UserApi
import com.github.gotify.client.api.VersionApi
import com.github.gotify.client.auth.ApiKeyAuth
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 {
private fun unauthorized(baseUrl: String, sslSettings: SSLSettings): ApiClient {
return defaultClient(arrayOf(), "$baseUrl/", sslSettings)
private fun unauthorized(
settings: Settings,
sslSettings: SSLSettings,
baseUrl: String
): ApiClient {
return defaultClient(arrayOf(), settings, sslSettings, baseUrl)
}

fun basicAuth(
baseUrl: String,
settings: Settings,
sslSettings: SSLSettings,
username: String,
password: String
): ApiClient {
val client = defaultClient(
arrayOf("basicAuth"),
"$baseUrl/",
sslSettings
)
val client = defaultClient(arrayOf("basicAuth"), settings, sslSettings)
val auth = client.apiAuthorizations["basicAuth"] as HttpBasicAuth
auth.username = username
auth.password = password
return client
}

fun clientToken(baseUrl: String, sslSettings: SSLSettings, token: String?): ApiClient {
val client = defaultClient(
arrayOf("clientTokenHeader"),
"$baseUrl/",
sslSettings
)
fun clientToken(settings: Settings, token: String? = settings.token): ApiClient {
val client = defaultClient(arrayOf("clientTokenHeader"), settings)
val tokenAuth = client.apiAuthorizations["clientTokenHeader"] as ApiKeyAuth
tokenAuth.apiKey = token
return client
}

fun versionApi(baseUrl: String, sslSettings: SSLSettings): VersionApi {
return unauthorized(baseUrl, sslSettings).createService(VersionApi::class.java)
fun versionApi(
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 {
return clientToken(settings.url, settings.sslSettings(), settings.token)
.createService(UserApi::class.java)
return clientToken(settings).createService(UserApi::class.java)
}

private fun defaultClient(
authentications: Array<String>,
baseUrl: String,
sslSettings: SSLSettings
settings: Settings,
sslSettings: SSLSettings = settings.sslSettings(),
baseUrl: String = settings.url
): ApiClient {
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)
client.adapterBuilder.baseUrl(baseUrl)
client.adapterBuilder.baseUrl("$baseUrl/")
return client
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ internal class InitializationActivity : AppCompatActivity() {
callback: SuccessCallback<VersionInfo>,
errorCallback: Callback.ErrorCallback
) {
ClientFactory.versionApi(settings.url, settings.sslSettings())
ClientFactory.versionApi(settings)
.version
.enqueue(Callback.callInUI(this, callback, errorCallback))
}
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/kotlin/com/github/gotify/login/LoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ internal class LoginActivity : AppCompatActivity() {
binding.checkurl.visibility = View.GONE

try {
ClientFactory.versionApi(url, tempSslSettings())
ClientFactory.versionApi(settings, tempSslSettings(), url)
.version
.enqueue(Callback.callInUI(this, onValidUrl(url), onInvalidUrl(url)))
} catch (e: Exception) {
Expand Down Expand Up @@ -252,7 +252,7 @@ internal class LoginActivity : AppCompatActivity() {
binding.login.visibility = View.GONE
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)
.currentUser()
.enqueue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ internal class MessagesActivity :

private fun deleteApp(appId: Long) {
val settings = viewModel.settings
val client = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
val client = ClientFactory.clientToken(settings)
client.createService(ApplicationApi::class.java)
.deleteApp(appId)
.enqueue(
Expand Down Expand Up @@ -597,8 +597,7 @@ internal class MessagesActivity :

private fun deleteClientAndNavigateToLogin() {
val settings = viewModel.settings
val api = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
.createService(ClientApi::class.java)
val api = ClientFactory.clientToken(settings).createService(ClientApi::class.java)
stopService(Intent(this@MessagesActivity, WebSocketService::class.java))
try {
val clients = Api.execute(api.clients)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import com.squareup.picasso.Target
internal class MessagesModel(parentView: Activity) : ViewModel() {
val settings = Settings(parentView)
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 messages = MessageFacade(client.createService(MessageApi::class.java), appsHolder)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,7 @@ internal class WebSocketService : Service() {
override fun onCreate() {
super.onCreate()
settings = Settings(this)
val client = ClientFactory.clientToken(
settings.url,
settings.sslSettings(),
settings.token
)
val client = ClientFactory.clientToken(settings)
missingMessageUtil = MissedMessageUtil(client.createService(MessageApi::class.java))
Logger.info("Create ${javaClass.simpleName}")
picassoHandler = PicassoHandler(this, settings)
Expand Down Expand Up @@ -129,7 +125,7 @@ internal class WebSocketService : Service() {
}

private fun fetchApps() {
ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
ClientFactory.clientToken(settings)
.createService(ApplicationApi::class.java)
.apps
.enqueue(
Expand Down
12 changes: 2 additions & 10 deletions app/src/main/kotlin/com/github/gotify/sharing/ShareActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ internal class ShareActivity : AppCompatActivity() {
return
}

val client = ClientFactory.clientToken(
settings.url,
settings.sslSettings(),
settings.token
)
val client = ClientFactory.clientToken(settings)
appsHolder = ApplicationHolder(this, client)
appsHolder.onUpdate {
val apps = appsHolder.get()
Expand Down Expand Up @@ -136,11 +132,7 @@ internal class ShareActivity : AppCompatActivity() {
}

private fun executeMessageCall(appIndex: Int, message: Message): Boolean {
val pushClient = ClientFactory.clientToken(
settings.url,
settings.sslSettings(),
appsHolder.get()[appIndex].token
)
val pushClient = ClientFactory.clientToken(settings, appsHolder.get()[appIndex].token)
return try {
val messageApi = pushClient.createService(MessageApi::class.java)
Api.execute(messageApi.createMessage(message))
Expand Down

0 comments on commit a3dd80c

Please sign in to comment.