mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-18 04:08:44 +03:00
Key Req Dev tool initial commit
This commit is contained in:
parent
06fc5c2dd9
commit
757e90986e
13 changed files with 356 additions and 1 deletions
|
@ -28,6 +28,7 @@ import im.vector.matrix.android.api.session.events.model.Content
|
|||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.internal.crypto.MXEventDecryptionResult
|
||||
import im.vector.matrix.android.internal.crypto.NewSessionListener
|
||||
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
|
||||
import im.vector.matrix.android.internal.crypto.crosssigning.DeviceTrustLevel
|
||||
import im.vector.matrix.android.internal.crypto.model.CryptoDeviceInfo
|
||||
import im.vector.matrix.android.internal.crypto.model.ImportRoomKeysResult
|
||||
|
@ -129,4 +130,6 @@ interface CryptoService {
|
|||
fun addNewSessionListener(newSessionListener: NewSessionListener)
|
||||
|
||||
fun removeSessionListener(listener: NewSessionListener)
|
||||
|
||||
fun getOutgoingRoomKeyRequest(): List<OutgoingRoomKeyRequest>
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
|
||||
// the crypto store
|
||||
private val cryptoStore: IMXCryptoStore,
|
||||
|
||||
// Olm device
|
||||
private val olmDevice: MXOlmDevice,
|
||||
// Set of parameters used to configure/customize the end-to-end crypto.
|
||||
|
@ -1091,4 +1092,8 @@ internal class DefaultCryptoService @Inject constructor(
|
|||
override fun toString(): String {
|
||||
return "DefaultCryptoService of " + credentials.userId + " (" + credentials.deviceId + ")"
|
||||
}
|
||||
|
||||
override fun getOutgoingRoomKeyRequest(): List<OutgoingRoomKeyRequest> {
|
||||
return cryptoStore.getOutgoingRoomKeyRequests()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import im.vector.matrix.android.api.util.Optional
|
|||
import im.vector.matrix.android.internal.crypto.DeviceListManager
|
||||
import im.vector.matrix.android.internal.crypto.MXOlmDevice
|
||||
import im.vector.matrix.android.internal.crypto.MyDeviceInfoHolder
|
||||
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequestManager
|
||||
import im.vector.matrix.android.internal.crypto.model.CryptoCrossSigningKey
|
||||
import im.vector.matrix.android.internal.crypto.model.KeyUsage
|
||||
import im.vector.matrix.android.internal.crypto.model.rest.UploadSignatureQueryBuilder
|
||||
|
@ -61,6 +62,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||
private val taskExecutor: TaskExecutor,
|
||||
private val coroutineDispatchers: MatrixCoroutineDispatchers,
|
||||
private val cryptoCoroutineScope: CoroutineScope,
|
||||
private val outgoingRoomKeyRequestManager: OutgoingRoomKeyRequestManager,
|
||||
private val eventBus: EventBus) : CrossSigningService, DeviceListManager.UserDevicesUpdateListener {
|
||||
|
||||
private var olmUtility: OlmUtility? = null
|
||||
|
@ -736,6 +738,7 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||
// If it's me, recheck trust of all users and devices?
|
||||
val users = ArrayList<String>()
|
||||
if (otherUserId == userId && currentTrust != trusted) {
|
||||
reRequestAllPendingRoomKeyRequest()
|
||||
cryptoStore.updateUsersTrust {
|
||||
users.add(it)
|
||||
checkUserTrust(it).isVerified()
|
||||
|
@ -751,4 +754,18 @@ internal class DefaultCrossSigningService @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reRequestAllPendingRoomKeyRequest() {
|
||||
Timber.d("## CrossSigning - reRequest pending outgoing room key requests")
|
||||
cryptoStore.getOutgoingRoomKeyRequests().forEach {
|
||||
it.requestBody?.let {requestBody ->
|
||||
if (cryptoStore.getInboundGroupSession(requestBody.sessionId ?: "", requestBody.senderKey ?: "") == null) {
|
||||
outgoingRoomKeyRequestManager.resendRoomKeyRequest(requestBody)
|
||||
} else {
|
||||
outgoingRoomKeyRequestManager.cancelRoomKeyRequest(requestBody)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -424,4 +424,8 @@ internal interface IMXCryptoStore {
|
|||
fun clearOtherUserTrust()
|
||||
|
||||
fun updateUsersTrust(check: (String) -> Boolean)
|
||||
|
||||
// Dev tools
|
||||
|
||||
fun getOutgoingRoomKeyRequests() : List<OutgoingRoomKeyRequest>
|
||||
}
|
||||
|
|
|
@ -1024,6 +1024,14 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getOutgoingRoomKeyRequests(): List<OutgoingRoomKeyRequest> {
|
||||
return monarchy.fetchAllMappedSync( { realm ->
|
||||
realm.where(OutgoingRoomKeyRequestEntity::class.java)
|
||||
}, {
|
||||
it.toOutgoingRoomKeyRequest()
|
||||
})
|
||||
}
|
||||
|
||||
override fun getCrossSigningInfo(userId: String): MXCrossSigningInfo? {
|
||||
return doRealmQueryAndCopy(realmConfiguration) { realm ->
|
||||
realm.where(CrossSigningInfoEntity::class.java)
|
||||
|
|
|
@ -74,6 +74,8 @@ import im.vector.riotx.features.settings.VectorSettingsSecurityPrivacyFragment
|
|||
import im.vector.riotx.features.settings.crosssigning.CrossSigningSettingsFragment
|
||||
import im.vector.riotx.features.settings.devices.VectorSettingsDevicesFragment
|
||||
import im.vector.riotx.features.settings.devtools.AccountDataFragment
|
||||
import im.vector.riotx.features.settings.devtools.KeyRequestListFragment
|
||||
import im.vector.riotx.features.settings.devtools.KeyRequestsFragment
|
||||
import im.vector.riotx.features.settings.ignored.VectorSettingsIgnoredUsersFragment
|
||||
import im.vector.riotx.features.settings.push.PushGatewaysFragment
|
||||
import im.vector.riotx.features.share.IncomingShareFragment
|
||||
|
@ -366,4 +368,14 @@ interface FragmentModule {
|
|||
@IntoMap
|
||||
@FragmentKey(AccountDataFragment::class)
|
||||
fun bindAccountDataFragment(fragment: AccountDataFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(KeyRequestListFragment::class)
|
||||
fun bindKeyRequestListFragment(fragment: KeyRequestListFragment): Fragment
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@FragmentKey(KeyRequestsFragment::class)
|
||||
fun bindKeyRequestsFragment(fragment: KeyRequestsFragment): Fragment
|
||||
}
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.settings.devtools
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.epoxy.loadingItem
|
||||
import im.vector.riotx.core.extensions.exhaustive
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.core.ui.list.genericItem
|
||||
import im.vector.riotx.core.ui.list.genericItemHeader
|
||||
import me.gujun.android.span.span
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeyRequestEpoxyController @Inject constructor(
|
||||
private val stringProvider: StringProvider
|
||||
) : TypedEpoxyController<KeyRequestListViewState>() {
|
||||
|
||||
interface InteractionListener {
|
||||
//fun didTap(data: UserAccountData)
|
||||
}
|
||||
|
||||
var interactionListener: InteractionListener? = null
|
||||
|
||||
override fun buildModels(data: KeyRequestListViewState?) {
|
||||
data?.outgoingRoomKeyRequest?.let { async ->
|
||||
when (async) {
|
||||
is Uninitialized,
|
||||
is Loading -> {
|
||||
loadingItem {
|
||||
id("loadingOutgoing")
|
||||
loadingText(stringProvider.getString(R.string.loading))
|
||||
}
|
||||
}
|
||||
is Fail -> {
|
||||
genericItem {
|
||||
id("failOutgoing")
|
||||
title(async.error.localizedMessage)
|
||||
}
|
||||
}
|
||||
is Success -> {
|
||||
val requestList = async.invoke().groupBy { it.roomId }
|
||||
|
||||
requestList.forEach {
|
||||
|
||||
genericItemHeader {
|
||||
id(it.key)
|
||||
text("roomId: ${it.key}")
|
||||
}
|
||||
it.value.forEach { roomKeyRequest ->
|
||||
genericItem {
|
||||
id(roomKeyRequest.requestId)
|
||||
title(roomKeyRequest.requestId)
|
||||
description(
|
||||
span {
|
||||
span("sessionId:") {
|
||||
textStyle = "bold"
|
||||
}
|
||||
+"${roomKeyRequest.sessionId}"
|
||||
span("\nstate:") {
|
||||
textStyle = "bold"
|
||||
}
|
||||
+"\n${roomKeyRequest.state.name}"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}.exhaustive
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.settings.devtools
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.cleanup
|
||||
import im.vector.riotx.core.extensions.configureWith
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import im.vector.riotx.core.resources.ColorProvider
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeyRequestListFragment @Inject constructor(
|
||||
val viewModelFactory: KeyRequestListViewModel.Factory,
|
||||
private val epoxyController: KeyRequestEpoxyController,
|
||||
private val colorProvider: ColorProvider
|
||||
) : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId() = R.layout.fragment_generic_recycler
|
||||
|
||||
private val viewModel: KeyRequestListViewModel by fragmentViewModel(KeyRequestListViewModel::class)
|
||||
|
||||
override fun invalidate() = withState(viewModel) { state ->
|
||||
epoxyController.setData(state)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
recyclerView.configureWith(epoxyController, showDivider = true)
|
||||
// epoxyController.interactionListener = this
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
recyclerView.cleanup()
|
||||
// epoxyController.interactionListener = null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.settings.devtools
|
||||
|
||||
import com.airbnb.mvrx.Async
|
||||
import com.airbnb.mvrx.FragmentViewModelContext
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.internal.crypto.IncomingRoomKeyRequest
|
||||
import im.vector.matrix.android.internal.crypto.OutgoingRoomKeyRequest
|
||||
import im.vector.riotx.core.platform.EmptyAction
|
||||
import im.vector.riotx.core.platform.EmptyViewEvents
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
||||
data class KeyRequestListViewState(
|
||||
val incomingRequests: Async<List<IncomingRoomKeyRequest>> = Uninitialized,
|
||||
val outgoingRoomKeyRequest: Async<List<OutgoingRoomKeyRequest>> = Uninitialized
|
||||
) : MvRxState
|
||||
|
||||
class KeyRequestListViewModel @AssistedInject constructor(@Assisted initialState: KeyRequestListViewState,
|
||||
private val session: Session)
|
||||
: VectorViewModel<KeyRequestListViewState, EmptyAction, EmptyViewEvents>(initialState) {
|
||||
|
||||
init {
|
||||
session.cryptoService().getOutgoingRoomKeyRequest().let {
|
||||
setState {
|
||||
copy(
|
||||
outgoingRoomKeyRequest = Success(it)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun handle(action: EmptyAction) {}
|
||||
|
||||
@AssistedInject.Factory
|
||||
interface Factory {
|
||||
fun create(initialState: KeyRequestListViewState): KeyRequestListViewModel
|
||||
}
|
||||
|
||||
companion object : MvRxViewModelFactory<KeyRequestListViewModel, KeyRequestListViewState> {
|
||||
|
||||
@JvmStatic
|
||||
override fun create(viewModelContext: ViewModelContext, state: KeyRequestListViewState): KeyRequestListViewModel? {
|
||||
val fragment: KeyRequestListFragment = (viewModelContext as FragmentViewModelContext).fragment()
|
||||
return fragment.viewModelFactory.create(state)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2020 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.riotx.features.settings.devtools
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.platform.VectorBaseActivity
|
||||
import im.vector.riotx.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_devtool_keyrequests.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class KeyRequestsFragment @Inject constructor() : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId(): Int = R.layout.fragment_devtool_keyrequests
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.key_share_request)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
devToolKeyRequestPager.adapter = KeyReqPagerAdapter(requireActivity())
|
||||
|
||||
TabLayoutMediator(devToolKeyRequestTabs, devToolKeyRequestPager) { tab, _ ->
|
||||
tab.text = "Outgoing"
|
||||
}.attach()
|
||||
|
||||
}
|
||||
|
||||
private inner class KeyReqPagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return childFragmentManager.fragmentFactory.instantiate(requireContext().classLoader, KeyRequestListFragment::class.java.name)
|
||||
}
|
||||
}
|
||||
}
|
22
vector/src/main/res/layout/fragment_devtool_keyrequests.xml
Normal file
22
vector/src/main/res/layout/fragment_devtool_keyrequests.xml
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:background="#FFFFFF">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/devToolKeyRequestTabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:tabMode="scrollable" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/devToolKeyRequestPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
</LinearLayout>
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
<!-- BEGIN Strings added by Valere -->
|
||||
|
||||
|
||||
<string name="settings_key_requests">Key Requests</string>
|
||||
<!-- END Strings added by Valere -->
|
||||
|
||||
|
||||
|
|
|
@ -65,13 +65,20 @@
|
|||
app:fragment="im.vector.riotx.features.settings.push.PushRulesFragment" />
|
||||
</im.vector.riotx.core.preference.VectorPreferenceCategory>
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreferenceCategory android:title="@string/settings_dev_tools">
|
||||
<im.vector.riotx.core.preference.VectorPreferenceCategory
|
||||
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
|
||||
android:title="@string/settings_dev_tools">
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:persistent="false"
|
||||
android:title="@string/settings_account_data"
|
||||
app:fragment="im.vector.riotx.features.settings.devtools.AccountDataFragment" />
|
||||
|
||||
<im.vector.riotx.core.preference.VectorPreference
|
||||
android:persistent="false"
|
||||
android:title="@string/settings_key_requests"
|
||||
app:fragment="im.vector.riotx.features.settings.devtools.KeyRequestsFragment" />
|
||||
|
||||
</im.vector.riotx.core.preference.VectorPreferenceCategory>
|
||||
|
||||
</androidx.preference.PreferenceScreen>
|
Loading…
Add table
Reference in a new issue