BaseActivity.kt 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Nextcloud Talk application
  3. *
  4. * @author Mario Danic
  5. * @author Marcel Hibbe
  6. * Copyright (C) 2023 Marcel Hibbe <dev@mhibbe.de>
  7. * Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. package com.nextcloud.talk.activities
  23. import android.annotation.SuppressLint
  24. import android.content.Context
  25. import android.os.Bundle
  26. import android.util.Log
  27. import android.view.View
  28. import android.view.WindowManager
  29. import android.webkit.SslErrorHandler
  30. import androidx.appcompat.app.AlertDialog
  31. import androidx.appcompat.app.AppCompatActivity
  32. import androidx.core.content.res.ResourcesCompat
  33. import autodagger.AutoInjector
  34. import com.google.android.material.dialog.MaterialAlertDialogBuilder
  35. import com.nextcloud.talk.R
  36. import com.nextcloud.talk.application.NextcloudTalkApplication
  37. import com.nextcloud.talk.events.CertificateEvent
  38. import com.nextcloud.talk.ui.theme.ViewThemeUtils
  39. import com.nextcloud.talk.utils.DisplayUtils
  40. import com.nextcloud.talk.utils.preferences.AppPreferences
  41. import com.nextcloud.talk.utils.ssl.TrustManager
  42. import org.greenrobot.eventbus.EventBus
  43. import org.greenrobot.eventbus.Subscribe
  44. import org.greenrobot.eventbus.ThreadMode
  45. import java.security.cert.CertificateParsingException
  46. import java.security.cert.X509Certificate
  47. import java.text.DateFormat
  48. import javax.inject.Inject
  49. @AutoInjector(NextcloudTalkApplication::class)
  50. open class BaseActivity : AppCompatActivity() {
  51. enum class AppBarLayoutType {
  52. TOOLBAR, SEARCH_BAR, EMPTY
  53. }
  54. @Inject
  55. lateinit var eventBus: EventBus
  56. @Inject
  57. lateinit var appPreferences: AppPreferences
  58. @Inject
  59. lateinit var viewThemeUtils: ViewThemeUtils
  60. @Inject
  61. lateinit var context: Context
  62. open val appBarLayoutType: AppBarLayoutType
  63. get() = AppBarLayoutType.TOOLBAR
  64. open val view: View?
  65. get() = null
  66. override fun onCreate(savedInstanceState: Bundle?) {
  67. NextcloudTalkApplication.sharedApplication!!.componentApplication.inject(this)
  68. super.onCreate(savedInstanceState)
  69. }
  70. public override fun onStart() {
  71. super.onStart()
  72. eventBus.register(this)
  73. }
  74. public override fun onResume() {
  75. super.onResume()
  76. if (appPreferences.isScreenSecured) {
  77. window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
  78. } else {
  79. window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
  80. }
  81. }
  82. public override fun onStop() {
  83. super.onStop()
  84. eventBus.unregister(this)
  85. }
  86. fun setupSystemColors() {
  87. colorizeStatusBar()
  88. colorizeNavigationBar()
  89. }
  90. open fun colorizeStatusBar() {
  91. if (resources != null) {
  92. if (appBarLayoutType == AppBarLayoutType.SEARCH_BAR) {
  93. viewThemeUtils.platform.resetStatusBar(this)
  94. } else {
  95. viewThemeUtils.platform.themeStatusBar(this)
  96. }
  97. }
  98. }
  99. fun colorizeNavigationBar() {
  100. if (resources != null) {
  101. DisplayUtils.applyColorToNavigationBar(
  102. this.window,
  103. ResourcesCompat.getColor(resources, R.color.bg_default, null)
  104. )
  105. }
  106. }
  107. fun showCertificateDialog(
  108. cert: X509Certificate,
  109. trustManager: TrustManager,
  110. sslErrorHandler: SslErrorHandler?
  111. ) {
  112. val formatter = DateFormat.getDateInstance(DateFormat.LONG)
  113. val validFrom = formatter.format(cert.notBefore)
  114. val validUntil = formatter.format(cert.notAfter)
  115. val issuedBy = cert.issuerDN.toString()
  116. val issuedFor: String
  117. try {
  118. if (cert.subjectAlternativeNames != null) {
  119. val stringBuilder = StringBuilder()
  120. for (o in cert.subjectAlternativeNames) {
  121. val list = o as List<*>
  122. val type = list[0] as Int
  123. if (type == 2) {
  124. val name = list[1] as String
  125. stringBuilder.append("[").append(type).append("]").append(name).append(" ")
  126. }
  127. }
  128. issuedFor = stringBuilder.toString()
  129. } else {
  130. issuedFor = cert.subjectDN.name
  131. }
  132. @SuppressLint("StringFormatMatches")
  133. val dialogText = String.format(
  134. resources.getString(R.string.nc_certificate_dialog_text),
  135. issuedBy,
  136. issuedFor,
  137. validFrom,
  138. validUntil
  139. )
  140. val dialogBuilder = MaterialAlertDialogBuilder(this)
  141. .setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_security_white_24dp))
  142. .setTitle(R.string.nc_certificate_dialog_title)
  143. .setMessage(dialogText)
  144. .setPositiveButton(R.string.nc_yes) { _, _ ->
  145. trustManager.addCertInTrustStore(cert)
  146. sslErrorHandler?.proceed()
  147. }
  148. .setNegativeButton(R.string.nc_no) { _, _ ->
  149. sslErrorHandler?.cancel()
  150. }
  151. viewThemeUtils.dialog.colorMaterialAlertDialogBackground(context, dialogBuilder)
  152. val dialog = dialogBuilder.show()
  153. viewThemeUtils.platform.colorTextButtons(
  154. dialog.getButton(AlertDialog.BUTTON_POSITIVE),
  155. dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
  156. )
  157. } catch (e: CertificateParsingException) {
  158. Log.d(TAG, "Failed to parse the certificate")
  159. }
  160. }
  161. @Subscribe(threadMode = ThreadMode.MAIN)
  162. fun onMessageEvent(event: CertificateEvent) {
  163. showCertificateDialog(event.x509Certificate, event.magicTrustManager, event.sslErrorHandler)
  164. }
  165. companion object {
  166. private val TAG = "BaseActivity"
  167. }
  168. }