Export the key share trail in rageshake (opt-in)
This commit is contained in:
parent
41e3ff381f
commit
077bcb3f2a
@ -69,6 +69,9 @@ class BugReportActivity : VectorBaseActivity() {
|
|||||||
bug_report_button_include_crash_logs.isChecked = false
|
bug_report_button_include_crash_logs.isChecked = false
|
||||||
bug_report_button_include_crash_logs.isVisible = false
|
bug_report_button_include_crash_logs.isVisible = false
|
||||||
|
|
||||||
|
bug_report_button_include_key_share_history.isChecked = false
|
||||||
|
bug_report_button_include_key_share_history.isVisible = false
|
||||||
|
|
||||||
// Keep the screenshot
|
// Keep the screenshot
|
||||||
} else {
|
} else {
|
||||||
supportActionBar?.setTitle(R.string.title_activity_bug_report)
|
supportActionBar?.setTitle(R.string.title_activity_bug_report)
|
||||||
@ -121,6 +124,7 @@ class BugReportActivity : VectorBaseActivity() {
|
|||||||
forSuggestion,
|
forSuggestion,
|
||||||
bug_report_button_include_logs.isChecked,
|
bug_report_button_include_logs.isChecked,
|
||||||
bug_report_button_include_crash_logs.isChecked,
|
bug_report_button_include_crash_logs.isChecked,
|
||||||
|
bug_report_button_include_key_share_history.isChecked,
|
||||||
bug_report_button_include_screenshot.isChecked,
|
bug_report_button_include_screenshot.isChecked,
|
||||||
bug_report_edit_text.text.toString(),
|
bug_report_edit_text.text.toString(),
|
||||||
object : BugReporter.IMXBugReportListener {
|
object : BugReporter.IMXBugReportListener {
|
||||||
|
@ -33,6 +33,7 @@ import im.vector.app.core.extensions.getAllChildFragments
|
|||||||
import im.vector.app.core.extensions.toOnOff
|
import im.vector.app.core.extensions.toOnOff
|
||||||
import im.vector.app.features.settings.VectorLocale
|
import im.vector.app.features.settings.VectorLocale
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
|
import im.vector.app.features.settings.devtools.GossipingEventsSerializer
|
||||||
import im.vector.app.features.settings.locale.SystemLocaleProvider
|
import im.vector.app.features.settings.locale.SystemLocaleProvider
|
||||||
import im.vector.app.features.themes.ThemeUtils
|
import im.vector.app.features.themes.ThemeUtils
|
||||||
import im.vector.app.features.version.VersionProvider
|
import im.vector.app.features.version.VersionProvider
|
||||||
@ -74,6 +75,7 @@ class BugReporter @Inject constructor(
|
|||||||
private const val LOG_CAT_FILENAME = "logcat.log"
|
private const val LOG_CAT_FILENAME = "logcat.log"
|
||||||
private const val LOG_CAT_SCREENSHOT_FILENAME = "screenshot.png"
|
private const val LOG_CAT_SCREENSHOT_FILENAME = "screenshot.png"
|
||||||
private const val CRASH_FILENAME = "crash.log"
|
private const val CRASH_FILENAME = "crash.log"
|
||||||
|
private const val KEY_REQUESTS_FILENAME = "keyRequests.log"
|
||||||
|
|
||||||
private const val BUFFER_SIZE = 1024 * 1024 * 50
|
private const val BUFFER_SIZE = 1024 * 1024 * 50
|
||||||
}
|
}
|
||||||
@ -143,6 +145,7 @@ class BugReporter @Inject constructor(
|
|||||||
* @param forSuggestion true to send a suggestion
|
* @param forSuggestion true to send a suggestion
|
||||||
* @param withDevicesLogs true to include the device log
|
* @param withDevicesLogs true to include the device log
|
||||||
* @param withCrashLogs true to include the crash logs
|
* @param withCrashLogs true to include the crash logs
|
||||||
|
* @param withKeyRequestHistory true to include the crash logs
|
||||||
* @param withScreenshot true to include the screenshot
|
* @param withScreenshot true to include the screenshot
|
||||||
* @param theBugDescription the bug description
|
* @param theBugDescription the bug description
|
||||||
* @param listener the listener
|
* @param listener the listener
|
||||||
@ -152,6 +155,7 @@ class BugReporter @Inject constructor(
|
|||||||
forSuggestion: Boolean,
|
forSuggestion: Boolean,
|
||||||
withDevicesLogs: Boolean,
|
withDevicesLogs: Boolean,
|
||||||
withCrashLogs: Boolean,
|
withCrashLogs: Boolean,
|
||||||
|
withKeyRequestHistory: Boolean,
|
||||||
withScreenshot: Boolean,
|
withScreenshot: Boolean,
|
||||||
theBugDescription: String,
|
theBugDescription: String,
|
||||||
listener: IMXBugReportListener?) {
|
listener: IMXBugReportListener?) {
|
||||||
@ -207,6 +211,22 @@ class BugReporter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeSessionHolder.getSafeActiveSession()
|
||||||
|
?.takeIf { !mIsCancelled && withKeyRequestHistory }
|
||||||
|
?.cryptoService()
|
||||||
|
?.getGossipingEvents()
|
||||||
|
?.let { GossipingEventsSerializer().serialize(it) }
|
||||||
|
?.toByteArray()
|
||||||
|
?.let { rawByteArray ->
|
||||||
|
File(context.cacheDir.absolutePath, KEY_REQUESTS_FILENAME)
|
||||||
|
.also {
|
||||||
|
it.outputStream()
|
||||||
|
.use { os -> os.write(rawByteArray) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?.let { compressFile(it) }
|
||||||
|
?.let { gzippedFiles.add(it) }
|
||||||
|
|
||||||
var deviceId = "undefined"
|
var deviceId = "undefined"
|
||||||
var userId = "undefined"
|
var userId = "undefined"
|
||||||
var olmVersion = "undefined"
|
var olmVersion = "undefined"
|
||||||
|
@ -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.app.features.settings.devtools
|
||||||
|
|
||||||
|
import im.vector.app.core.resources.DateProvider
|
||||||
|
import me.gujun.android.span.span
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest
|
||||||
|
import org.threeten.bp.format.DateTimeFormatter
|
||||||
|
|
||||||
|
class GossipingEventsSerializer {
|
||||||
|
private val full24DateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
|
||||||
|
|
||||||
|
fun serialize(eventList: List<Event>): String {
|
||||||
|
return buildString {
|
||||||
|
eventList.forEach {
|
||||||
|
val clearType = it.getClearType()
|
||||||
|
append("[${getFormattedDate(it.ageLocalTs)}] $clearType from:${it.senderId} - ")
|
||||||
|
when (clearType) {
|
||||||
|
EventType.ROOM_KEY_REQUEST -> {
|
||||||
|
val content = it.getClearContent().toModel<RoomKeyShareRequest>()
|
||||||
|
append("reqId:${content?.requestId} action:${content?.action} ")
|
||||||
|
if (content?.action == GossipingToDeviceObject.ACTION_SHARE_REQUEST) {
|
||||||
|
append("sessionId: ${content.body?.sessionId} ")
|
||||||
|
}
|
||||||
|
append("requestedBy: ${content?.requestingDeviceId}")
|
||||||
|
}
|
||||||
|
EventType.FORWARDED_ROOM_KEY -> {
|
||||||
|
val encryptedContent = it.content.toModel<OlmEventContent>()
|
||||||
|
val content = it.getClearContent().toModel<ForwardedRoomKeyContent>()
|
||||||
|
|
||||||
|
append("sessionId:${content?.sessionId} From Device (sender key):${encryptedContent?.senderKey}")
|
||||||
|
span("\nFrom Device (sender key):") {
|
||||||
|
textStyle = "bold"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EventType.ROOM_KEY -> {
|
||||||
|
val content = it.getClearContent()
|
||||||
|
append("sessionId:${content?.get("session_id")} roomId:${content?.get("room_id")} dest:${content?.get("_dest") ?: "me"}")
|
||||||
|
}
|
||||||
|
EventType.SEND_SECRET -> {
|
||||||
|
val content = it.getClearContent().toModel<SecretSendEventContent>()
|
||||||
|
append("requestId:${content?.requestId} From Device:${it.mxDecryptionResult?.payload?.get("sender_device")}")
|
||||||
|
}
|
||||||
|
EventType.REQUEST_SECRET -> {
|
||||||
|
val content = it.getClearContent().toModel<SecretShareRequest>()
|
||||||
|
append("reqId:${content?.requestId} action:${content?.action} ")
|
||||||
|
if (content?.action == GossipingToDeviceObject.ACTION_SHARE_REQUEST) {
|
||||||
|
append("secretName:${content.secretName} ")
|
||||||
|
}
|
||||||
|
append("requestedBy:${content?.requestingDeviceId}")
|
||||||
|
}
|
||||||
|
EventType.ENCRYPTED -> {
|
||||||
|
append("Failed to Decrypt")
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
append("??")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
append("\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFormattedDate(ageLocalTs: Long?): String {
|
||||||
|
return ageLocalTs
|
||||||
|
?.let { DateProvider.toLocalDateTime(it) }
|
||||||
|
?.let { full24DateFormatter.format(it) }
|
||||||
|
?: "?"
|
||||||
|
}
|
||||||
|
}
|
@ -70,10 +70,6 @@ class KeyRequestViewModel @AssistedInject constructor(
|
|||||||
fun create(initialState: KeyRequestViewState): KeyRequestViewModel
|
fun create(initialState: KeyRequestViewState): KeyRequestViewModel
|
||||||
}
|
}
|
||||||
|
|
||||||
private val full24DateFormatter by lazy {
|
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object : MvRxViewModelFactory<KeyRequestViewModel, KeyRequestViewState> {
|
companion object : MvRxViewModelFactory<KeyRequestViewModel, KeyRequestViewState> {
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@ -98,54 +94,7 @@ class KeyRequestViewModel @AssistedInject constructor(
|
|||||||
// this can take long
|
// this can take long
|
||||||
val eventList = session.cryptoService().getGossipingEvents()
|
val eventList = session.cryptoService().getGossipingEvents()
|
||||||
// clean it a bit to
|
// clean it a bit to
|
||||||
val raw = buildString {
|
val raw = GossipingEventsSerializer().serialize(eventList)
|
||||||
eventList.forEach {
|
|
||||||
val clearType = it.getClearType()
|
|
||||||
append("[${getFormattedDate(it.ageLocalTs)}] $clearType from:${it.senderId} - ")
|
|
||||||
when (clearType) {
|
|
||||||
EventType.ROOM_KEY_REQUEST -> {
|
|
||||||
val content = it.getClearContent().toModel<RoomKeyShareRequest>()
|
|
||||||
append("reqId:${content?.requestId} action:${content?.action} ")
|
|
||||||
if (content?.action == GossipingToDeviceObject.ACTION_SHARE_REQUEST) {
|
|
||||||
append("sessionId: ${content.body?.sessionId} ")
|
|
||||||
}
|
|
||||||
append("requestedBy: ${content?.requestingDeviceId}")
|
|
||||||
}
|
|
||||||
EventType.FORWARDED_ROOM_KEY -> {
|
|
||||||
val encryptedContent = it.content.toModel<OlmEventContent>()
|
|
||||||
val content = it.getClearContent().toModel<ForwardedRoomKeyContent>()
|
|
||||||
|
|
||||||
append("sessionId:${content?.sessionId} From Device (sender key):${encryptedContent?.senderKey}")
|
|
||||||
span("\nFrom Device (sender key):") {
|
|
||||||
textStyle = "bold"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EventType.ROOM_KEY -> {
|
|
||||||
val content = it.getClearContent()
|
|
||||||
append("sessionId:${content?.get("session_id")} roomId:${content?.get("room_id")} dest:${content?.get("_dest") ?: "me"}")
|
|
||||||
}
|
|
||||||
EventType.SEND_SECRET -> {
|
|
||||||
val content = it.getClearContent().toModel<SecretSendEventContent>()
|
|
||||||
append("requestId:${content?.requestId} From Device:${it.mxDecryptionResult?.payload?.get("sender_device")}")
|
|
||||||
}
|
|
||||||
EventType.REQUEST_SECRET -> {
|
|
||||||
val content = it.getClearContent().toModel<SecretShareRequest>()
|
|
||||||
append("reqId:${content?.requestId} action:${content?.action} ")
|
|
||||||
if (content?.action == GossipingToDeviceObject.ACTION_SHARE_REQUEST) {
|
|
||||||
append("secretName:${content.secretName} ")
|
|
||||||
}
|
|
||||||
append("requestedBy:${content?.requestingDeviceId}")
|
|
||||||
}
|
|
||||||
EventType.ENCRYPTED -> {
|
|
||||||
append("Failed to Decrypt")
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
append("??")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
append("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setState {
|
setState {
|
||||||
copy(exporting = Success(Unit))
|
copy(exporting = Success(Unit))
|
||||||
}
|
}
|
||||||
@ -157,11 +106,4 @@ class KeyRequestViewModel @AssistedInject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFormattedDate(ageLocalTs: Long?): String {
|
|
||||||
return ageLocalTs
|
|
||||||
?.let { DateProvider.toLocalDateTime(it) }
|
|
||||||
?.let { full24DateFormatter.format(it) }
|
|
||||||
?: "?"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,15 @@
|
|||||||
android:checked="true"
|
android:checked="true"
|
||||||
android:text="@string/send_bug_report_include_crash_logs" />
|
android:text="@string/send_bug_report_include_crash_logs" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/bug_report_button_include_key_share_history"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginEnd="10dp"
|
||||||
|
android:checked="false"
|
||||||
|
android:text="@string/send_bug_report_include_key_share_history" />
|
||||||
|
|
||||||
<com.google.android.material.switchmaterial.SwitchMaterial
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
android:id="@+id/bug_report_button_include_screenshot"
|
android:id="@+id/bug_report_button_include_screenshot"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -192,6 +192,7 @@
|
|||||||
|
|
||||||
<string name="send_bug_report_include_logs">Send logs</string>
|
<string name="send_bug_report_include_logs">Send logs</string>
|
||||||
<string name="send_bug_report_include_crash_logs">Send crash logs</string>
|
<string name="send_bug_report_include_crash_logs">Send crash logs</string>
|
||||||
|
<string name="send_bug_report_include_key_share_history">Send key share requests history</string>
|
||||||
<string name="send_bug_report_include_screenshot">Send screenshot</string>
|
<string name="send_bug_report_include_screenshot">Send screenshot</string>
|
||||||
<string name="send_bug_report">Report bug</string>
|
<string name="send_bug_report">Report bug</string>
|
||||||
<string name="send_bug_report_description">Please describe the bug. What did you do? What did you expect to happen? What actually happened?</string>
|
<string name="send_bug_report_description">Please describe the bug. What did you do? What did you expect to happen? What actually happened?</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user