Added fake implem for Account.isEndToEndEncryptionMandatory() + possibility to change mode

This commit is contained in:
Sylvain Berfini 2024-04-29 15:50:17 +02:00
parent 7633af198a
commit cf7dbb7f61
14 changed files with 137 additions and 53 deletions

View file

@ -138,17 +138,8 @@ class ContactsManager @UiThread constructor() {
@WorkerThread
override fun onDefaultAccountChanged(core: Core, account: Account?) {
Log.i("$TAG Default account changed, update all contact models showTrust value")
val showTrust = account?.isEndToEndEncryptionMandatory()
knownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
unknownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
conferenceAvatarMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
Log.i("$TAG Default account changed, update all contacts' model showTrust value")
updateContactsModelDependingOnDefaultAccountMode()
}
}
@ -212,6 +203,7 @@ class ContactsManager @UiThread constructor() {
coreContext.contactsManager.notifyContactsListChanged()
}
@WorkerThread
fun contactRemoved(friend: Friend) {
for (sipAddress in friend.addresses) {
val sipUri = sipAddress.asStringUriOnly()
@ -611,6 +603,24 @@ class ContactsManager @UiThread constructor() {
return personBuilder.build()
}
@WorkerThread
fun updateContactsModelDependingOnDefaultAccountMode() {
val account = coreContext.core.defaultAccount
val showTrust = account?.isEndToEndEncryptionMandatory() == true
Log.i(
"$TAG Default account mode is [${if (showTrust) "end-to-end encryption mandatory" else "interoperable"}], update all contact models showTrust value"
)
knownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
unknownContactsAvatarsMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
conferenceAvatarMap.forEach { (_, contactAvatarModel) ->
contactAvatarModel.showTrust.postValue(showTrust)
}
}
@WorkerThread
private fun getAvatarModelFromCache(key: String): ContactAvatarModel? {
return knownContactsAvatarsMap[key] ?: unknownContactsAvatarsMap[key]

View file

@ -64,6 +64,7 @@ class ProfileModeFragment : Fragment() {
}
binding.setContinueClickListener {
viewModel.applySelectedMode()
requireActivity().finish()
}

View file

@ -35,6 +35,8 @@ import org.linphone.core.Factory
import org.linphone.core.Reason
import org.linphone.core.RegistrationState
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.setEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setInteroperabilityMode
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
@ -221,6 +223,27 @@ open class AccountLoginViewModel @UiThread constructor() : ViewModel() {
isCurrentlySelectedModeSecure.value = false
}
@UiThread
fun applySelectedMode() {
coreContext.postOnCoreThread { core ->
if (::newlyCreatedAccount.isInitialized) {
if (isCurrentlySelectedModeSecure.value == true) {
Log.i(
"$TAG Selected mode is end-to-end encrypted, forcing media & im encryption to mandatory and setting media encryption to ZRTP"
)
newlyCreatedAccount.setEndToEndEncryptionMandatory()
} else {
Log.i(
"$TAG Selected mode is interoperable, not forcing media & im encryption to mandatory and setting media encryption to SRTP"
)
newlyCreatedAccount.setInteroperabilityMode()
}
} else {
Log.e("$TAG Failed to find newlyCreatedAccount!")
}
}
}
@UiThread
private fun isLoginButtonEnabled(): Boolean {
return sipIdentity.value.orEmpty().trim().isNotEmpty() && password.value.orEmpty().isNotEmpty()

View file

@ -39,10 +39,7 @@ import org.linphone.utils.LinphoneUtils
import org.linphone.utils.ShortcutUtils
import org.linphone.utils.TimestampUtils
class ConversationModel @WorkerThread constructor(
val chatRoom: ChatRoom,
val isDisabledBecauseNotSecured: Boolean = false
) {
class ConversationModel @WorkerThread constructor(val chatRoom: ChatRoom) {
companion object {
private const val TAG = "[Conversation Model]"
}
@ -57,6 +54,8 @@ class ConversationModel @WorkerThread constructor(
Capabilities.Conference.toInt()
)
val isEncrypted = chatRoom.hasCapability(Capabilities.Encrypted.toInt())
val isReadOnly = chatRoom.isReadOnly
val subject = MutableLiveData<String>()

View file

@ -27,12 +27,10 @@ import org.linphone.R
import org.linphone.contacts.ContactsManager
import org.linphone.core.ChatMessage
import org.linphone.core.ChatRoom
import org.linphone.core.ChatRoom.Capabilities
import org.linphone.core.Core
import org.linphone.core.CoreListenerStub
import org.linphone.core.tools.Log
import org.linphone.ui.main.chat.model.ConversationModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.ui.main.viewmodel.AbstractMainViewModel
import org.linphone.utils.AppUtils
import org.linphone.utils.Event
@ -147,11 +145,8 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
val account = LinphoneUtils.getDefaultAccount()
val chatRooms = account?.chatRooms ?: coreContext.core.chatRooms
for (chatRoom in chatRooms) {
val disabledBecauseNotSecured = account?.isEndToEndEncryptionMandatory() == true && !chatRoom.hasCapability(
Capabilities.Encrypted.toInt()
)
if (filter.isEmpty()) {
val model = ConversationModel(chatRoom, disabledBecauseNotSecured)
val model = ConversationModel(chatRoom)
list.add(model)
count += 1
} else {
@ -173,7 +168,7 @@ class ConversationsListViewModel @UiThread constructor() : AbstractMainViewModel
chatRoom.peerAddress.asStringUriOnly().contains(filter, ignoreCase = true) ||
chatRoom.subject.orEmpty().contains(filter, ignoreCase = true)
) {
val model = ConversationModel(chatRoom, disabledBecauseNotSecured)
val model = ConversationModel(chatRoom)
list.add(model)
count += 1
}

View file

@ -24,6 +24,7 @@ import androidx.annotation.UiThread
import androidx.annotation.WorkerThread
import androidx.lifecycle.MutableLiveData
import org.linphone.LinphoneApplication.Companion.coreContext
import org.linphone.LinphoneApplication.Companion.corePreferences
import org.linphone.R
import org.linphone.contacts.AbstractAvatarModel
import org.linphone.core.Account
@ -113,8 +114,6 @@ class AccountModel @WorkerThread constructor(
account.addListener(accountListener)
coreContext.core.addListener(coreListener)
trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
showTrust.postValue(account.isEndToEndEncryptionMandatory())
presenceStatus.postValue(ConsolidatedPresence.Offline)
update()
@ -166,6 +165,9 @@ class AccountModel @WorkerThread constructor(
"$TAG Refreshing info for account [${account.params.identityAddress?.asStringUriOnly()}]"
)
trust.postValue(SecurityLevel.EndToEndEncryptedAndVerified)
showTrust.postValue(account.isEndToEndEncryptionMandatory())
val name = LinphoneUtils.getDisplayName(account.params.identityAddress)
displayName.postValue(name)
@ -233,7 +235,47 @@ class AccountModel @WorkerThread constructor(
}
}
@WorkerThread
fun Account.isEndToEndEncryptionMandatory(): Boolean {
// TODO FIXME: use real API when available
return params.identityAddress?.domain == "sip.linphone.org"
val defaultDomain = params.identityAddress?.domain == corePreferences.defaultDomain
// TODO FIXME: use API when available
// val encryption = params.mediaEncryption == MediaEncryption.ZRTP && params.mediaEncryptionMandatory && params.instantMessagingEncryptionMandatory
val encryption = corePreferences.config.getBool("test", "account_e2e_mode", false)
return defaultDomain && encryption
}
@WorkerThread
fun Account.setEndToEndEncryptionMandatory() {
/*
TODO FIXME: use API when available
val clone = params.clone()
clone.mediaEncryption = MediaEncryption.ZRTP
clone.mediaEncryptionMandatory = true
clone.instantMessagingEncryptionMandatory = true
params = clone
*/
corePreferences.config.setBool("test", "account_e2e_mode", true)
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i("[Account] End-to-end encryption set mandatory on account")
}
@WorkerThread
fun Account.setInteroperabilityMode() {
/*
TODO FIXME: use API when available
val clone = params.clone()
clone.mediaEncryption = MediaEncryption.SRTP
clone.mediaEncryptionMandatory = false
clone.instantMessagingEncryptionMandatory = false
params = clone
*/
corePreferences.config.setBool("test", "account_e2e_mode", false)
if (this == core.defaultAccount) {
coreContext.contactsManager.updateContactsModelDependingOnDefaultAccountMode()
}
Log.i("[Account] Account configured in interoperable mode")
}

View file

@ -30,6 +30,8 @@ import org.linphone.core.Factory
import org.linphone.core.tools.Log
import org.linphone.ui.main.model.AccountModel
import org.linphone.ui.main.model.isEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setEndToEndEncryptionMandatory
import org.linphone.ui.main.model.setInteroperabilityMode
import org.linphone.ui.main.settings.model.AccountDeviceModel
import org.linphone.utils.Event
@ -299,6 +301,18 @@ class AccountProfileViewModel @UiThread constructor() : ViewModel() {
@UiThread
fun applySelectedMode() {
// TODO
coreContext.postOnCoreThread { core ->
if (isCurrentlySelectedModeSecure.value == true) {
Log.i(
"$TAG Selected mode is end-to-end encrypted, forcing media & im encryption to mandatory and setting media encryption to ZRTP"
)
account.setEndToEndEncryptionMandatory()
} else {
Log.i(
"$TAG Selected mode is interoperable, not forcing media & im encryption to mandatory and setting media encryption to SRTP"
)
account.setInteroperabilityMode()
}
}
}
}

View file

@ -415,7 +415,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:text="@{viewModel.isCurrentlySelectedModeSecure ? @string/manage_account_secure_mode_default_title : @string/manage_account_secure_mode_interoperable_title, default=@string/manage_account_secure_mode_default_title}"
android:text="@{viewModel.isCurrentlySelectedModeSecure ? @string/manage_account_e2e_encrypted_mode_default_title : @string/manage_account_e2e_encrypted_mode_interoperable_title, default=@string/manage_account_e2e_encrypted_mode_default_title}"
app:layout_constraintTop_toTopOf="@id/mode_background"
app:layout_constraintStart_toStartOf="@id/mode_background"
app:layout_constraintBottom_toBottomOf="@id/mode_background"/>

View file

@ -85,7 +85,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="@string/manage_account_secure_mode_default_title"
android:text="@string/manage_account_e2e_encrypted_mode_default_title"
android:textSize="16sp"
android:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@ -119,7 +119,7 @@
android:paddingBottom="10dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_default_summary"
android:text="@string/manage_account_e2e_encrypted_mode_default_summary"
android:textSize="14sp"
android:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo"
@ -146,7 +146,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="20dp"
android:text="@string/manage_account_secure_mode_interoperable_title"
android:text="@string/manage_account_e2e_encrypted_mode_interoperable_title"
android:textSize="16sp"
android:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@ -180,7 +180,7 @@
android:paddingBottom="20dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_interoperable_summary"
android:text="@string/manage_account_e2e_encrypted_mode_interoperable_summary"
android:textSize="14sp"
android:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo"

View file

@ -92,7 +92,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="16dp"
android:text="@string/manage_account_secure_mode_default_title"
android:text="@string/manage_account_e2e_encrypted_mode_default_title"
android:textSize="16sp"
android:textColor="?attr/color_main2_900"
android:checked="@{viewModel.isCurrentlySelectedModeSecure}"
@ -127,7 +127,7 @@
android:paddingBottom="20dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_default_summary"
android:text="@string/manage_account_e2e_encrypted_mode_default_summary"
android:textSize="14sp"
android:gravity="start"
android:drawableEnd="@drawable/profile_secure_logo"
@ -144,7 +144,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginStart="16dp"
android:text="@string/manage_account_secure_mode_interoperable_title"
android:text="@string/manage_account_e2e_encrypted_mode_interoperable_title"
android:textSize="16sp"
android:textColor="?attr/color_main2_900"
android:checked="@{!viewModel.isCurrentlySelectedModeSecure}"
@ -179,7 +179,7 @@
android:paddingBottom="20dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:text="@string/manage_account_secure_mode_interoperable_summary"
android:text="@string/manage_account_e2e_encrypted_mode_interoperable_summary"
android:textSize="14sp"
android:gravity="start"
android:drawableEnd="@drawable/profile_interop_logo"

View file

@ -57,7 +57,7 @@
android:layout_height="wrap_content"
app:barrierDirection="start"
app:barrierMargin="-5dp"
app:constraint_referenced_ids="notifications_count, warning_disabled_not_secured, ephemeral, muted, date_time, last_sent_message_status" />
app:constraint_referenced_ids="notifications_count, warning_not_secured, ephemeral, muted, date_time, last_sent_message_status" />
<androidx.appcompat.widget.AppCompatTextView
style="@style/default_text_style"
@ -161,13 +161,13 @@
app:tint="?attr/color_main2_400" />
<ImageView
android:id="@+id/warning_disabled_not_secured"
android:id="@+id/warning_not_secured"
android:layout_width="@dimen/small_icon_size"
android:layout_height="@dimen/small_icon_size"
android:layout_marginStart="5dp"
android:layout_marginEnd="10dp"
android:src="@drawable/lock_simple_open_bold"
android:visibility="@{model.isDisabledBecauseNotSecured ? View.VISIBLE : View.GONE}"
android:visibility="@{model.isEncrypted ? View.GONE : View.VISIBLE}"
app:layout_constraintTop_toBottomOf="@id/date_time"
app:layout_constraintBottom_toTopOf="@id/separator"
app:layout_constraintEnd_toStartOf="@id/ephemeral"

View file

@ -39,7 +39,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:paddingTop="@dimen/dialog_top_bottom_margin"
android:text="@{defaultMode ? @string/manage_account_secure_mode_default_title : @string/manage_account_secure_mode_interoperable_title, default=@string/manage_account_secure_mode_default_title}"
android:text="@{defaultMode ? @string/manage_account_e2e_encrypted_mode_default_title : @string/manage_account_e2e_encrypted_mode_interoperable_title, default=@string/manage_account_e2e_encrypted_mode_default_title}"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@id/message"
app:layout_constraintStart_toStartOf="@id/dialog_background"
@ -54,7 +54,7 @@
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:layout_marginTop="10dp"
android:text="@{defaultMode ? @string/manage_account_dialog_secure_mode_default_message : @string/manage_account_dialog_secure_mode_interoperable_message, default=@string/manage_account_dialog_secure_mode_default_message}"
android:text="@{defaultMode ? @string/manage_account_dialog_e2e_encrypted_mode_default_message : @string/manage_account_dialog_e2e_encrypted_mode_interoperable_message, default=@string/manage_account_dialog_e2e_encrypted_mode_default_message}"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@id/confirm"
app:layout_constraintStart_toStartOf="@id/dialog_background"

View file

@ -292,14 +292,14 @@
<string name="manage_account_delete">Supprimer le compte</string>
<string name="manage_account_choose_mode_title">Choisir le mode</string>
<string name="manage_account_choose_mode_apply_label">Appliquer</string>
<string name="manage_account_secure_mode_default_title">Chiffré de bout en bout</string>
<string name="manage_account_secure_mode_interoperable_title">Intéropérable</string>
<string name="manage_account_secure_mode_default_summary">Ce mode vous garantit la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges.</string>
<string name="manage_account_secure_mode_interoperable_summary">Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec nimporte quelle autre service SIP.</string>
<string name="manage_account_e2e_encrypted_mode_default_title">Chiffré de bout en bout</string>
<string name="manage_account_e2e_encrypted_mode_interoperable_title">Intéropérable</string>
<string name="manage_account_e2e_encrypted_mode_default_summary">Ce mode vous garantit la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges.</string>
<string name="manage_account_e2e_encrypted_mode_interoperable_summary">Ce mode vous permet de profiter de toutes les fonctionnalités de &appName; tout en restant interopérable avec nimporte quelle autre service SIP.</string>
<string name="manage_account_device_remove">Supprimer</string>
<string name="manage_account_device_last_connection">Dernière connexion :</string>
<string name="manage_account_dialog_secure_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_secure_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_e2e_encrypted_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_e2e_encrypted_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_remove_account_title">Supprimer %s ?</string>
<string name="manage_account_dialog_remove_account_message">Vous pouvez vous reconnecter à tout moment en cliquant sur "Ajouter un compte".Cependant toutes les informations stockées sur ce périphérique seront supprimées.</string>

View file

@ -327,14 +327,14 @@
<string name="manage_account_delete">Delete account</string>
<string name="manage_account_choose_mode_title">Choose account mode</string>
<string name="manage_account_choose_mode_apply_label">Apply</string>
<string name="manage_account_secure_mode_default_title">Default mode</string>
<string name="manage_account_secure_mode_interoperable_title">Interoperable mode</string>
<string name="manage_account_secure_mode_default_summary">This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.</string>
<string name="manage_account_secure_mode_interoperable_summary">This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.</string>
<string name="manage_account_e2e_encrypted_mode_default_title">End-to-end encrypted mode</string>
<string name="manage_account_e2e_encrypted_mode_interoperable_title">Interoperable mode</string>
<string name="manage_account_e2e_encrypted_mode_default_summary">This mode guarantee your data confidentiality. Our end-to-end encryption technology provide the highest level or security for your communications.</string>
<string name="manage_account_e2e_encrypted_mode_interoperable_summary">This mode allows you to enjoy all &appName; features while staying interoperable with any SIP service through point-to-point encryption.</string>
<string name="manage_account_device_remove">Remove</string>
<string name="manage_account_device_last_connection">Last connection:</string>
<string name="manage_account_dialog_secure_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_secure_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_e2e_encrypted_mode_default_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_e2e_encrypted_mode_interoperable_message">Blah</string> <!-- TODO -->
<string name="manage_account_dialog_remove_account_title">Delete %s?</string>
<string name="manage_account_dialog_remove_account_message">You can reconnect at any time by clicking “Add an account”. However, all data on this phone will be deleted.</string>