Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Device Manager] Unverified and inactive sessions list (PSG-698, PSG-696) #7171

Merged
merged 10 commits into from
Sep 23, 2022

Conversation

onurays
Copy link
Contributor

@onurays onurays commented Sep 19, 2022

Type of change

  • Feature
  • Bugfix
  • Technical
  • Other :

Content

From the main session management screen, clicking view all button of Security Recommendations section navigates to standalone session list screen with the correct filter applied by default.

Motivation and context

Fixes #7170.

Screenshots / GIFs

Unverified sessions Inactive sessions
unverified_sessions inactive_sessions

Tests

  • Enable VectorFeatures.isNewDeviceManagementEnabled
  • Navigate to Settings > Security & Privacy > Show All Sessions (V2, WIP)
  • Click on View All button under the Security Recommendations section
  • See the list of all sessions with the correct filter applied by default

Tested devices

  • Physical
  • Emulator
  • OS version(s):

Checklist

@onurays onurays requested review from a team, fedrunov and mnaturel and removed request for a team September 19, 2022 13:53
@onurays onurays marked this pull request as ready for review September 19, 2022 13:54
@@ -125,6 +128,29 @@ class VectorSettingsDevicesFragment :
views.deviceListOtherSessions.callback = this
}

private fun initSecurityRecommendationsView() {
views.deviceListUnverifiedSessionsRecommendation.callback = object : SecurityRecommendationView.Callback {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should clean up the callback when the fragment is destroyed or when the SecurityRecommendationView is detached.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -71,7 +71,7 @@ class DevicesViewModel @AssistedInject constructor(
.execute { async ->
if (async is Success) {
val deviceFullInfoList = async.invoke()
val unverifiedSessionsCount = deviceFullInfoList.count { !it.cryptoDeviceInfo?.isVerified.orFalse() }
val unverifiedSessionsCount = deviceFullInfoList.count { !it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be consistent, I am wondering if we should update the GetEncryptionTrustLevelForDeviceUseCase logic instead and rely on the RoomEncryptionTrustLevel of DeviceFullInfo for the verification status of a session. This field is used for example in SessionInfoView or in OtherSessionItem to render the verification status. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely talk to crypto team (@BillCarsonFr) to be clear about trust levels.

@@ -31,8 +31,8 @@ class FilterDevicesUseCase @Inject constructor() {
.filter {
when (filterType) {
DeviceManagerFilterType.ALL_SESSIONS -> true
DeviceManagerFilterType.VERIFIED -> it.cryptoDeviceInfo?.isVerified.orFalse()
DeviceManagerFilterType.UNVERIFIED -> !it.cryptoDeviceInfo?.isVerified.orFalse()
DeviceManagerFilterType.VERIFIED -> it.cryptoDeviceInfo?.trustLevel?.isCrossSigningVerified().orFalse()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark as a previous one, maybe we should rely on the RoomEncryptionTrustLevel field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will create a dedicated PR to refactor after talking to crypto team.

stringProvider([email protected])
clickListener { device.deviceInfo.deviceId?.let { host.callback?.onItemClicked(it) } }
}
}
}
}

private fun calculateDescription(device: DeviceFullInfo, formattedLastActivityDate: String): String {
return if (device.isInactive) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it may be easier to read with a when {} pattern, what do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, better, done.

return Intent(context, OtherSessionsActivity::class.java)
fun newIntent(
context: Context,
titleResourceId: Int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may annotate this second argument with @StringRes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


@Parcelize
data class OtherSessionsArgs(
val titleResourceId: Int,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark, @StringRes annotation can be added here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -57,6 +59,7 @@ class OtherSessionsFragment :

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
views.otherSessionsToolbar.title = getString(args.titleResourceId)
setupToolbar(views.otherSessionsToolbar).allowBack()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can call setTitle(args.titleResourceId) instead just right after setupToolbar() to configure the toolbar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, done.

@@ -55,7 +55,7 @@ class OtherSessionsViewModel @AssistedInject constructor(
observeDevicesJob?.cancel()
observeDevicesJob = getDeviceFullInfoListUseCase.execute(
filterType = currentFilter,
excludeCurrentDevice = true
excludeCurrentDevice = !initialState.includeCurrentSession
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should always use the same pattern everywhere for this argument for consistency and to avoid errors? Either excludeCurrentDevice or includeCurrentDevice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense, done.

@@ -57,6 +63,17 @@ class DevicesViewModelTest {
)
}

@Before
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this mock on SystemClock?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is somehow failing on my machine. I didn't see a harm to mock it.

@@ -164,20 +181,24 @@ class DevicesViewModelTest {
private fun givenDeviceFullInfoList(): List<DeviceFullInfo> {
val verifiedCryptoDeviceInfo = mockk<CryptoDeviceInfo>()
every { verifiedCryptoDeviceInfo.isVerified } returns true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should remove the isVerified mocks since we use trustLevel instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, done.

Copy link
Contributor

@mnaturel mnaturel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added some comments to improve readability and maintainability. I have tested it and it is working well.

Is it confirmed we can show the filter option when navigating from security recommendation views?

@onurays
Copy link
Contributor Author

onurays commented Sep 21, 2022

I have added some comments to improve readability and maintainability. I have tested it and it is working well.

Is it confirmed we can show the filter option when navigating from security recommendation views?

Thank you for your quick review. No answer yet about the filter icon.

@sonarcloud
Copy link

sonarcloud bot commented Sep 23, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

30.0% 30.0% Coverage
0.0% 0.0% Duplication

@onurays onurays merged commit 6c79aae into develop Sep 23, 2022
@onurays onurays deleted the feature/ons/device_manager_security_sessions branch September 23, 2022 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Device Manager] Unverified and inactive sessions list
2 participants