Skip to content
This repository has been archived by the owner on Sep 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #244 from admin-ch/feature/dev-debug-certpinning
Browse files Browse the repository at this point in the history
Add debug option to disable/enable certificate pinning on DEV builds
  • Loading branch information
benz-ubique authored Sep 7, 2021
2 parents c2c7716 + b8a18ae commit 1f82fb3
Show file tree
Hide file tree
Showing 15 changed files with 236 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.admin.bag.covidcertificate.common.debug
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/

import android.content.Context
import androidx.fragment.app.Fragment

open class DebugFragment : Fragment() {

companion object {
fun newInstance(): DebugFragment = DebugFragment()

const val EXISTS = false

fun initDebug(context: Context) {}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package ch.admin.bag.covidcertificate.common.debug
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import ch.admin.bag.covidcertificate.common.databinding.FragmentDebugBinding
import ch.admin.bag.covidcertificate.sdk.android.net.CertificatePinning

open class DebugFragment : Fragment() {

companion object {
fun newInstance(): DebugFragment = DebugFragment()

const val EXISTS = true

fun initDebug(context: Context) {
CertificatePinning.enabled = DebugSecureStorage.getInstance(context).isCertPinningEnabled
}
}

private var _binding: FragmentDebugBinding? = null
protected val binding get() = _binding!!

private lateinit var debugSecureStorage: DebugSecureStorage

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
debugSecureStorage = DebugSecureStorage.getInstance(requireContext())
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentDebugBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
binding.toolbar.setNavigationOnClickListener {
parentFragmentManager.popBackStack()
}

binding.buttonToggleCertificatePinning.apply {
isChecked = debugSecureStorage.isCertPinningEnabled

setOnCheckedChangeListener { _, isChecked ->
debugSecureStorage.isCertPinningEnabled = isChecked
CertificatePinning.enabled = isChecked
}
}
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/

package ch.admin.bag.covidcertificate.common.debug

import android.content.Context
import ch.admin.bag.covidcertificate.sdk.android.net.CertificatePinning
import ch.admin.bag.covidcertificate.sdk.android.utils.EncryptedSharedPreferencesUtil
import ch.admin.bag.covidcertificate.sdk.android.utils.SingletonHolder

class DebugSecureStorage private constructor(context: Context) {

companion object : SingletonHolder<DebugSecureStorage, Context>(::DebugSecureStorage) {
private const val PREFERENCES = "DebugSecureStorage"
private const val KEY_CERT_PINNING_ENABLED = "KEY_CERT_PINNING_ENABLED"
}

private val prefs = EncryptedSharedPreferencesUtil.initializeSharedPreferences(context, PREFERENCES)

var isCertPinningEnabled: Boolean
get() = prefs.getBoolean(KEY_CERT_PINNING_ENABLED, CertificatePinning.enabled)
set(value) = prefs.edit().putBoolean(KEY_CERT_PINNING_ENABLED, value).apply()

}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@
app:titleTextAppearance="@style/CovidCertificate.ToolbarTitle"
app:titleTextColor="@color/grey" />

<CheckBox
android:id="@+id/button_toggle_certificate_pinning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
android:text="Certificate Pinning enabled (needs a restart)" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/certificates_recycler_view"
android:layout_width="match_parent"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package ch.admin.bag.covidcertificate.common.debug
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/

import android.content.Context
import androidx.fragment.app.Fragment

open class DebugFragment : Fragment() {

companion object {
fun newInstance(): DebugFragment = DebugFragment()

const val EXISTS = false

fun initDebug(context: Context) {}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import androidx.fragment.app.activityViewModels
import ch.admin.bag.covidcertificate.common.config.ConfigViewModel
import ch.admin.bag.covidcertificate.common.config.InfoBoxModel
import ch.admin.bag.covidcertificate.common.data.ConfigSecureStorage
import ch.admin.bag.covidcertificate.common.debug.DebugFragment
import ch.admin.bag.covidcertificate.common.dialog.InfoDialogFragment
import ch.admin.bag.covidcertificate.common.html.BuildInfo
import ch.admin.bag.covidcertificate.common.html.ImprintFragment
import ch.admin.bag.covidcertificate.common.util.AssetUtil
import ch.admin.bag.covidcertificate.verifier.databinding.FragmentHomeBinding
import ch.admin.bag.covidcertificate.verifier.faq.VerifierFaqFragment
import ch.admin.bag.covidcertificate.verifier.pager.HomescreenPageAdapter
import ch.admin.bag.covidcertificate.verifier.pager.HomescreenPagerFragment
import ch.admin.bag.covidcertificate.verifier.qr.VerifierQrScanFragment
import com.google.android.material.tabs.TabLayoutMediator
import java.util.concurrent.atomic.AtomicLong

class HomeFragment : Fragment() {

Expand Down Expand Up @@ -74,6 +75,10 @@ class HomeFragment : Fragment() {
//Some implementation
}.attach()

if (DebugFragment.EXISTS) {
setupDebugFragment()
}

binding.homescreenHeader.headerImpressum.setOnClickListener {
val buildInfo = BuildInfo(
getString(R.string.verifier_app_title),
Expand Down Expand Up @@ -103,6 +108,24 @@ class HomeFragment : Fragment() {
_binding = null
}

private fun setupDebugFragment() {
val lastClick = AtomicLong(0)
val debugButtonClickListener = View.OnClickListener {
val now = System.currentTimeMillis()
if (lastClick.get() > now - 1000L) {
lastClick.set(0)
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_enter, R.anim.slide_exit, R.anim.slide_pop_enter, R.anim.slide_pop_exit)
.replace(R.id.fragment_container, DebugFragment.newInstance())
.addToBackStack(DebugFragment::class.java.canonicalName)
.commit()
} else {
lastClick.set(now)
}
}
binding.homescreenHeader.schwiizerchruez.setOnClickListener(debugButtonClickListener)
}

private fun setupInfoBox() {
configViewModel.configLiveData.observe(viewLifecycleOwner) { config ->
val notificationButton = binding.homescreenHeader.headerNotification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ch.admin.bag.covidcertificate.verifier
import android.app.Application
import android.os.Build
import ch.admin.bag.covidcertificate.common.data.ConfigSecureStorage
import ch.admin.bag.covidcertificate.common.debug.DebugFragment
import ch.admin.bag.covidcertificate.common.util.EnvironmentUtil
import ch.admin.bag.covidcertificate.sdk.android.CovidCertificateSdk
import ch.admin.bag.covidcertificate.sdk.android.data.Config
Expand All @@ -13,6 +14,11 @@ class MainApplication : Application() {

override fun onCreate() {
super.onCreate()

if (DebugFragment.EXISTS) {
DebugFragment.initDebug(this)
}

// If this is a fresh install, don't show the certificate light updateboarding
val isFreshInstall = ConfigSecureStorage.getInstance(this).getConfig() == null
if (isFreshInstall) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ch.admin.bag.covidcertificate.wallet.debug
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/

import ch.admin.bag.covidcertificate.common.debug.DebugFragment

class WalletDebugFragment : DebugFragment() {
companion object {
fun newInstance(): DebugFragment = DebugFragment()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,25 @@ package ch.admin.bag.covidcertificate.wallet.debug

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import ch.admin.bag.covidcertificate.wallet.BuildConfig
import ch.admin.bag.covidcertificate.common.debug.DebugFragment
import ch.admin.bag.covidcertificate.wallet.CertificatesViewModel
import ch.admin.bag.covidcertificate.wallet.databinding.FragmentDebugBinding

class DebugFragment : Fragment() {
class WalletDebugFragment : DebugFragment() {

companion object {
fun newInstance(): DebugFragment = DebugFragment()

const val EXISTS = BuildConfig.FLAVOR == "abn" || BuildConfig.FLAVOR == "dev"
}

private val certificatesViewModel by activityViewModels<CertificatesViewModel>()

private var _binding: FragmentDebugBinding? = null
private val binding get() = _binding!!

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentDebugBinding.inflate(inflater, container, false)
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// Have additional self-control to not be shown in PROD
if (!EXISTS) {
parentFragmentManager.popBackStack()
}
super.onViewCreated(view, savedInstanceState)

binding.toolbar.setNavigationOnClickListener {
parentFragmentManager.popBackStack()
}
setupRecyclerView()
}

override fun onDestroyView() {
super.onDestroyView()
_binding = null
}

private fun setupRecyclerView() {
val recyclerView = binding.certificatesRecyclerView

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import ch.admin.bag.covidcertificate.common.debug.DebugFragment
import ch.admin.bag.covidcertificate.common.net.ConfigRepository
import ch.admin.bag.covidcertificate.common.util.EnvironmentUtil
import ch.admin.bag.covidcertificate.sdk.android.CovidCertificateSdk
import ch.admin.bag.covidcertificate.sdk.android.data.Config
import ch.admin.bag.covidcertificate.sdk.android.net.interceptor.UserAgentInterceptor
import ch.admin.bag.covidcertificate.sdk.android.CovidCertificateSdk
import ch.admin.bag.covidcertificate.wallet.data.CertificateStorage
import ch.admin.bag.covidcertificate.wallet.data.WalletDataItem
import ch.admin.bag.covidcertificate.wallet.data.WalletDataSecureStorage
Expand All @@ -22,6 +23,11 @@ class MainApplication : Application() {

override fun onCreate() {
super.onCreate()

if (DebugFragment.EXISTS) {
DebugFragment.initDebug(this)
}

Config.appToken = BuildConfig.SDK_APP_TOKEN
Config.userAgent =
UserAgentInterceptor.UserAgentGenerator { "${this.packageName};${BuildConfig.VERSION_NAME};${BuildConfig.BUILD_TIME};Android;${Build.VERSION.SDK_INT}" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ import androidx.viewpager2.widget.ViewPager2
import ch.admin.bag.covidcertificate.common.config.ConfigViewModel
import ch.admin.bag.covidcertificate.common.config.InfoBoxModel
import ch.admin.bag.covidcertificate.common.data.ConfigSecureStorage
import ch.admin.bag.covidcertificate.common.debug.DebugFragment
import ch.admin.bag.covidcertificate.common.dialog.InfoDialogFragment
import ch.admin.bag.covidcertificate.common.html.BuildInfo
import ch.admin.bag.covidcertificate.common.html.ImprintFragment
import ch.admin.bag.covidcertificate.common.util.AssetUtil
import ch.admin.bag.covidcertificate.common.util.HorizontalMarginItemDecoration
import ch.admin.bag.covidcertificate.common.views.hideAnimated
import ch.admin.bag.covidcertificate.common.views.rotate
Expand All @@ -46,7 +46,7 @@ import ch.admin.bag.covidcertificate.wallet.DeeplinkViewModel
import ch.admin.bag.covidcertificate.wallet.R
import ch.admin.bag.covidcertificate.wallet.add.CertificateAddFragment
import ch.admin.bag.covidcertificate.wallet.databinding.FragmentHomeBinding
import ch.admin.bag.covidcertificate.wallet.debug.DebugFragment
import ch.admin.bag.covidcertificate.wallet.debug.WalletDebugFragment
import ch.admin.bag.covidcertificate.wallet.detail.CertificateDetailFragment
import ch.admin.bag.covidcertificate.wallet.faq.WalletFaqFragment
import ch.admin.bag.covidcertificate.wallet.homescreen.pager.CertificatesPagerAdapter
Expand Down Expand Up @@ -161,10 +161,8 @@ class HomeFragment : Fragment() {
lastClick.set(0)
parentFragmentManager.beginTransaction()
.setCustomAnimations(R.anim.slide_enter, R.anim.slide_exit, R.anim.slide_pop_enter, R.anim.slide_pop_exit)
.replace(
R.id.fragment_container, DebugFragment.newInstance()
)
.addToBackStack(DebugFragment::class.java.canonicalName)
.replace(R.id.fragment_container, WalletDebugFragment.newInstance())
.addToBackStack(WalletDebugFragment::class.java.canonicalName)
.commit()
} else {
lastClick.set(now)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ch.admin.bag.covidcertificate.wallet.debug
/*
* Copyright (c) 2021 Ubique Innovation AG <https://www.ubique.ch>
*
* 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/.
*
* SPDX-License-Identifier: MPL-2.0
*/


import ch.admin.bag.covidcertificate.common.debug.DebugFragment

class WalletDebugFragment : DebugFragment() {
companion object {
fun newInstance(): DebugFragment = DebugFragment()
}
}

0 comments on commit 1f82fb3

Please sign in to comment.