Skip to content
Snippets Groups Projects
Commit 7bdec405 authored by Janne Mareike Koschinski's avatar Janne Mareike Koschinski
Browse files

Implement SSL whitelist UI

parent 0a91c68d
Branches
Tags
No related merge requests found
Pipeline #
Showing
with 209 additions and 64 deletions
......@@ -160,28 +160,34 @@
<!-- Client Settings -->
<activity
android:name=".ui.clientsettings.app.AppSettingsActivity"
android:name=".ui.clientsettings.client.ClientSettingsActivity"
android:exported="false"
android:label="@string/label_settings_client"
android:parentActivityName=".ui.chat.ChatActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.clientsettings.crash.CrashSettingsActivity"
android:name=".ui.clientsettings.crash.CrashActivity"
android:exported="false"
android:label="@string/label_crashes"
android:parentActivityName=".ui.clientsettings.app.AppSettingsActivity"
android:parentActivityName=".ui.clientsettings.client.ClientSettingsActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.clientsettings.about.AboutSettingsActivity"
android:name=".ui.clientsettings.whitelist.WhitelistActivity"
android:exported="false"
android:label="@string/label_certificates"
android:parentActivityName=".ui.clientsettings.client.ClientSettingsActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.clientsettings.about.AboutActivity"
android:exported="false"
android:label="@string/label_about"
android:parentActivityName=".ui.clientsettings.app.AppSettingsActivity"
android:parentActivityName=".ui.clientsettings.client.ClientSettingsActivity"
android:windowSoftInputMode="adjustResize" />
<activity
android:name=".ui.clientsettings.license.LicenseSettingsActivity"
android:name=".ui.clientsettings.license.LicenseActivity"
android:exported="false"
android:label="@string/label_license"
android:parentActivityName=".ui.clientsettings.about.AboutSettingsActivity"
android:parentActivityName=".ui.clientsettings.about.AboutActivity"
android:windowSoftInputMode="adjustResize" />
<!-- Client Setup Flow -->
......
......@@ -12,14 +12,16 @@ import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoActivity
import de.kuschku.quasseldroid.ui.chat.info.user.UserInfoFragmentProvider
import de.kuschku.quasseldroid.ui.chat.topic.TopicActivity
import de.kuschku.quasseldroid.ui.chat.topic.TopicFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.app.AppSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.app.AppSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.client.ClientSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.client.ClientSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashActivity
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseActivity
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseFragmentProvider
import de.kuschku.quasseldroid.ui.clientsettings.whitelist.WhitelistActivity
import de.kuschku.quasseldroid.ui.clientsettings.whitelist.WhitelistFragmentProvider
import de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity
import de.kuschku.quasseldroid.ui.coresettings.CoreSettingsFragmentProvider
import de.kuschku.quasseldroid.ui.coresettings.aliasitem.AliasItemActivity
......@@ -70,17 +72,20 @@ abstract class ActivityModule {
@ContributesAndroidInjector(modules = [TopicFragmentProvider::class])
abstract fun bindTopicActivity(): TopicActivity
@ContributesAndroidInjector(modules = [AppSettingsFragmentProvider::class])
abstract fun bindAppSettingsActivity(): AppSettingsActivity
@ContributesAndroidInjector(modules = [ClientSettingsFragmentProvider::class])
abstract fun bindClientSettingsActivity(): ClientSettingsActivity
@ContributesAndroidInjector(modules = [CrashSettingsFragmentProvider::class])
abstract fun bindCrashSettingsActivity(): CrashSettingsActivity
@ContributesAndroidInjector(modules = [WhitelistFragmentProvider::class])
abstract fun bindWhitelistActivity(): WhitelistActivity
@ContributesAndroidInjector(modules = [AboutSettingsFragmentProvider::class])
abstract fun bindAboutSettingsActivity(): AboutSettingsActivity
@ContributesAndroidInjector(modules = [CrashFragmentProvider::class])
abstract fun bindCrashActivity(): CrashActivity
@ContributesAndroidInjector(modules = [LicenseSettingsFragmentProvider::class])
abstract fun bindLicenseSettingsActivity(): LicenseSettingsActivity
@ContributesAndroidInjector(modules = [AboutFragmentProvider::class])
abstract fun bindAboutActivity(): AboutActivity
@ContributesAndroidInjector(modules = [LicenseFragmentProvider::class])
abstract fun bindLicenseActivity(): LicenseActivity
@ContributesAndroidInjector(modules = [CoreSettingsFragmentProvider::class])
abstract fun bindCoreSettingsActivity(): CoreSettingsActivity
......
......@@ -276,7 +276,8 @@ class QuasselService : DaggerLifecycleService(),
.throttleFirst(1, TimeUnit.SECONDS)
.toLiveData()
.observe(this, Observer {
if (wasEverConnected) sessionManager.reconnect(true)
if (wasEverConnected && !sessionManager.hasErrored)
sessionManager.reconnect(true)
})
sessionManager.state
......@@ -287,7 +288,8 @@ class QuasselService : DaggerLifecycleService(),
.observe(
this, Observer {
if (it == ConnectionState.DISCONNECTED || it == ConnectionState.CLOSED) {
if (wasEverConnected) sessionManager.reconnect()
if (wasEverConnected && !sessionManager.hasErrored)
sessionManager.reconnect()
} else {
wasEverConnected = true
}
......
......@@ -39,7 +39,7 @@ import de.kuschku.quasseldroid.settings.MessageSettings
import de.kuschku.quasseldroid.settings.Settings
import de.kuschku.quasseldroid.ui.chat.input.AutoCompleteAdapter
import de.kuschku.quasseldroid.ui.chat.input.ChatlineFragment
import de.kuschku.quasseldroid.ui.clientsettings.app.AppSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.client.ClientSettingsActivity
import de.kuschku.quasseldroid.ui.coresettings.CoreSettingsActivity
import de.kuschku.quasseldroid.util.helper.*
import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer
......@@ -162,7 +162,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
val dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
viewModel.errors.toLiveData().observe(this, Observer { error ->
error?.orNull()?.let {
error?.let {
when (it) {
is Error.HandshakeError -> it.message.let {
when (it) {
......@@ -567,7 +567,7 @@ class ChatActivity : ServiceBoundActivity(), SharedPreferences.OnSharedPreferenc
true
}
R.id.action_client_settings -> {
AppSettingsActivity.launch(this)
ClientSettingsActivity.launch(this)
true
}
R.id.action_disconnect -> {
......
......@@ -4,9 +4,9 @@ import android.content.Context
import android.content.Intent
import de.kuschku.quasseldroid.util.ui.SettingsActivity
class AboutSettingsActivity : SettingsActivity(AboutSettingsFragment()) {
class AboutActivity : SettingsActivity(AboutFragment()) {
companion object {
fun launch(context: Context) = context.startActivity(intent(context))
fun intent(context: Context) = Intent(context, AboutSettingsActivity::class.java)
fun intent(context: Context) = Intent(context, AboutActivity::class.java)
}
}
......@@ -18,7 +18,7 @@ import dagger.android.support.DaggerFragment
import de.kuschku.quasseldroid.BuildConfig
import de.kuschku.quasseldroid.R
class AboutSettingsFragment : DaggerFragment() {
class AboutFragment : DaggerFragment() {
@BindView(R.id.version)
lateinit var version: TextView
......@@ -40,7 +40,7 @@ class AboutSettingsFragment : DaggerFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_about, container, false)
val view = inflater.inflate(R.layout.preferences_about, container, false)
ButterKnife.bind(this, view)
version.text = BuildConfig.VERSION_NAME
......
......@@ -4,7 +4,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class AboutSettingsFragmentProvider {
abstract class AboutFragmentProvider {
@ContributesAndroidInjector
abstract fun bindAboutSettingsFragment(): AboutSettingsFragment
abstract fun bindAboutFragment(): AboutFragment
}
......@@ -8,7 +8,7 @@ import android.widget.TextView
import butterknife.BindView
import butterknife.ButterKnife
import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.license.LicenseActivity
import de.kuschku.quasseldroid.util.helper.visibleIf
class LibraryAdapter(private val libraries: List<Library>) :
......@@ -39,7 +39,7 @@ class LibraryAdapter(private val libraries: List<Library>) :
ButterKnife.bind(this, itemView)
itemView.setOnClickListener {
this.item?.run {
LicenseSettingsActivity.launch(itemView.context,
LicenseActivity.launch(itemView.context,
license_name = license.fullName,
license_text = license.text)
}
......
package de.kuschku.quasseldroid.ui.clientsettings.client
import android.content.Context
import android.content.Intent
import de.kuschku.quasseldroid.util.ui.SettingsActivity
class ClientSettingsActivity : SettingsActivity(ClientSettingsFragment()) {
companion object {
fun launch(context: Context) = context.startActivity(intent(context))
fun intent(context: Context) = Intent(context, ClientSettingsActivity::class.java)
}
}
package de.kuschku.quasseldroid.ui.clientsettings.app
package de.kuschku.quasseldroid.ui.clientsettings.client
import android.content.SharedPreferences
import android.os.Bundle
......@@ -11,12 +11,13 @@ import android.view.MenuItem
import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.settings.AppearanceSettings
import de.kuschku.quasseldroid.settings.Settings
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashSettingsActivity
import de.kuschku.quasseldroid.ui.clientsettings.about.AboutActivity
import de.kuschku.quasseldroid.ui.clientsettings.crash.CrashActivity
import de.kuschku.quasseldroid.ui.clientsettings.whitelist.WhitelistActivity
import de.kuschku.quasseldroid.util.backport.DaggerPreferenceFragmentCompat
import javax.inject.Inject
class AppSettingsFragment : DaggerPreferenceFragmentCompat(),
class ClientSettingsFragment : DaggerPreferenceFragmentCompat(),
SharedPreferences.OnSharedPreferenceChangeListener {
@Inject
lateinit var appearanceSettings: AppearanceSettings
......@@ -68,12 +69,16 @@ class AppSettingsFragment : DaggerPreferenceFragmentCompat(),
}
override fun onOptionsItemSelected(item: MenuItem?) = when (item?.itemId) {
R.id.action_about -> {
AboutSettingsActivity.launch(requireContext())
R.id.action_certificates -> {
WhitelistActivity.launch(requireContext())
true
}
R.id.action_crashes -> {
CrashSettingsActivity.launch(requireContext())
CrashActivity.launch(requireContext())
true
}
R.id.action_about -> {
AboutActivity.launch(requireContext())
true
}
else -> super.onOptionsItemSelected(item)
......
package de.kuschku.quasseldroid.ui.clientsettings.client
import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class ClientSettingsFragmentProvider {
@ContributesAndroidInjector
abstract fun bindClientSettingsFragment(): ClientSettingsFragment
}
......@@ -4,9 +4,9 @@ import android.content.Context
import android.content.Intent
import de.kuschku.quasseldroid.util.ui.SettingsActivity
class CrashSettingsActivity : SettingsActivity(CrashSettingsFragment()) {
class CrashActivity : SettingsActivity(CrashFragment()) {
companion object {
fun launch(context: Context) = context.startActivity(intent(context))
fun intent(context: Context) = Intent(context, CrashSettingsActivity::class.java)
fun intent(context: Context) = Intent(context, CrashActivity::class.java)
}
}
......@@ -18,7 +18,7 @@ import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.util.helper.fromJson
import java.io.File
class CrashSettingsFragment : DaggerFragment() {
class CrashFragment : DaggerFragment() {
@BindView(R.id.list)
lateinit var list: RecyclerView
......@@ -31,7 +31,7 @@ class CrashSettingsFragment : DaggerFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handlerThread = HandlerThread("CrashSettings")
handlerThread = HandlerThread("Crash")
handlerThread.start()
handler = Handler(handlerThread.looper)
}
......@@ -43,7 +43,7 @@ class CrashSettingsFragment : DaggerFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_crash, container, false)
val view = inflater.inflate(R.layout.preferences_crash, container, false)
ButterKnife.bind(this, view)
setHasOptionsMenu(true)
......
......@@ -4,7 +4,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class CrashSettingsFragmentProvider {
abstract class CrashFragmentProvider {
@ContributesAndroidInjector
abstract fun bindAppSettingsFragment(): CrashSettingsFragment
abstract fun bindClientSettingsFragment(): CrashFragment
}
......@@ -5,7 +5,7 @@ import android.content.Intent
import android.support.annotation.StringRes
import de.kuschku.quasseldroid.util.ui.SettingsActivity
class LicenseSettingsActivity : SettingsActivity(LicenseSettingsFragment()) {
class LicenseActivity : SettingsActivity(LicenseFragment()) {
companion object {
fun launch(
context: Context,
......@@ -17,7 +17,7 @@ class LicenseSettingsActivity : SettingsActivity(LicenseSettingsFragment()) {
context: Context,
license_name: String,
@StringRes license_text: Int
) = Intent(context, LicenseSettingsActivity::class.java).apply {
) = Intent(context, LicenseActivity::class.java).apply {
putExtra("license_name", license_name)
putExtra("license_text", license_text)
}
......
......@@ -11,13 +11,13 @@ import butterknife.ButterKnife
import dagger.android.support.DaggerFragment
import de.kuschku.quasseldroid.R
class LicenseSettingsFragment : DaggerFragment() {
class LicenseFragment : DaggerFragment() {
@BindView(R.id.text)
lateinit var text: TextView
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_license, container, false)
val view = inflater.inflate(R.layout.preferences_license, container, false)
ButterKnife.bind(this, view)
val textResource = arguments?.getInt("license_text", 0) ?: 0
......
......@@ -4,7 +4,7 @@ import dagger.Module
import dagger.android.ContributesAndroidInjector
@Module
abstract class LicenseSettingsFragmentProvider {
abstract class LicenseFragmentProvider {
@ContributesAndroidInjector
abstract fun bindLicenseSettingsFragment(): LicenseSettingsFragment
abstract fun bindLicenseFragment(): LicenseFragment
}
package de.kuschku.quasseldroid.ui.clientsettings.whitelist
import de.kuschku.quasseldroid.persistence.QuasselDatabase
data class Whitelist(
val certificates: List<QuasselDatabase.SslValidityWhitelistEntry>,
val hostnames: List<QuasselDatabase.SslHostnameWhitelistEntry>
)
package de.kuschku.quasseldroid.ui.clientsettings.app
package de.kuschku.quasseldroid.ui.clientsettings.whitelist
import android.content.Context
import android.content.Intent
import de.kuschku.quasseldroid.util.ui.SettingsActivity
class AppSettingsActivity : SettingsActivity(AppSettingsFragment()) {
class WhitelistActivity : SettingsActivity(WhitelistFragment()) {
companion object {
fun launch(context: Context) = context.startActivity(intent(context))
fun intent(context: Context) = Intent(context, AppSettingsActivity::class.java)
fun intent(context: Context) = Intent(context, WhitelistActivity::class.java)
}
}
package de.kuschku.quasseldroid.ui.clientsettings.whitelist
import android.support.v7.widget.AppCompatImageButton
import android.support.v7.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import butterknife.ButterKnife
import de.kuschku.quasseldroid.R
import de.kuschku.quasseldroid.persistence.QuasselDatabase
import de.kuschku.quasseldroid.util.helper.visibleIf
class WhitelistCertificateAdapter :
RecyclerView.Adapter<WhitelistCertificateAdapter.WhitelistItemViewHolder>() {
private var clickListener: ((QuasselDatabase.SslValidityWhitelistEntry) -> Unit)? = null
fun setOnClickListener(listener: ((QuasselDatabase.SslValidityWhitelistEntry) -> Unit)?) {
clickListener = listener
}
private val data = mutableListOf<QuasselDatabase.SslValidityWhitelistEntry>()
var list: List<QuasselDatabase.SslValidityWhitelistEntry>
get() = data
set(value) {
val length = data.size
data.clear()
notifyItemRangeRemoved(0, length)
data.addAll(value)
notifyItemRangeInserted(0, list.size)
}
fun add(item: QuasselDatabase.SslValidityWhitelistEntry) {
val index = data.size
data.add(item)
notifyItemInserted(index)
}
fun replace(index: Int, item: QuasselDatabase.SslValidityWhitelistEntry) {
data[index] = item
notifyItemChanged(index)
}
fun indexOf(item: QuasselDatabase.SslValidityWhitelistEntry) = data.indexOf(item)
fun remove(index: Int) {
data.removeAt(index)
notifyItemRemoved(index)
}
fun remove(item: QuasselDatabase.SslValidityWhitelistEntry) = remove(indexOf(item))
override fun getItemCount() = data.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = WhitelistItemViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.preferences_whitelist_certificate_item,
parent,
false),
::remove
)
override fun onBindViewHolder(holder: WhitelistItemViewHolder, position: Int) {
holder.bind(data[position])
}
class WhitelistItemViewHolder(
itemView: View,
clickListener: ((QuasselDatabase.SslValidityWhitelistEntry) -> Unit)?
) : RecyclerView.ViewHolder(itemView) {
@BindView(R.id.fingerprint)
lateinit var fingerprint: TextView
@BindView(R.id.ignore_date)
lateinit var ignoreDate: View
@BindView(R.id.action_delete)
lateinit var delete: AppCompatImageButton
private var item: QuasselDatabase.SslValidityWhitelistEntry? = null
init {
ButterKnife.bind(this, itemView)
delete.setOnClickListener {
item?.let {
clickListener?.invoke(it)
}
}
}
fun bind(item: QuasselDatabase.SslValidityWhitelistEntry) {
this.item = item
fingerprint.text = item.fingerprint
ignoreDate.visibleIf(item.ignoreDate)
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment