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

RoomVC: Update encryption decoration with shields #2937

Merged
merged 8 commits into from
Jan 24, 2020
7 changes: 7 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Changes in 0.10.5 (2020-xx-xx)
===============================================

Improvements:
* ON/OFF Cross-signing development in a Lab setting (#2855).
* RoomVC: Update encryption decoration with shields (#2934, #2930, #2906).

Changes in 0.10.4 (2019-12-11)
===============================================

Expand Down
23 changes: 23 additions & 0 deletions Riot/Modules/Room/DataSources/RoomDataSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@

#import "WidgetManager.h"

/**
RoomEncryptionTrustLevel represents the room members trust level in an encrypted room.
*/
typedef NS_ENUM(NSUInteger, RoomEncryptionTrustLevel) {
RoomEncryptionTrustLevelTrusted,
RoomEncryptionTrustLevelWarning,
RoomEncryptionTrustLevelNormal,
RoomEncryptionTrustLevelUnknown
};

@protocol RoomDataSourceDelegate;

/**
The data source for `RoomViewController` in Vector.
*/
Expand All @@ -39,6 +51,11 @@
*/
@property(nonatomic) BOOL showBubbleDateTimeOnSelection;

/**
Current room members trust level for an encrypted room.
*/
@property(nonatomic, readonly) RoomEncryptionTrustLevel encryptionTrustLevel;

/**
Check if there is an active jitsi widget in the room and return it.

Expand Down Expand Up @@ -85,3 +102,9 @@
failure:(void(^)(NSError*))failure;

@end

@protocol RoomDataSourceDelegate <MXKDataSourceDelegate>

- (void)roomDataSource:(RoomDataSource*)roomDataSource didUpdateEncryptionTrustLevel:(RoomEncryptionTrustLevel)roomEncryptionTrustLevel;

@end
104 changes: 104 additions & 0 deletions Riot/Modules/Room/DataSources/RoomDataSource.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ @interface RoomDataSource() <BubbleReactionsViewModelDelegate>
// Timer used to debounce cells refresh
@property (nonatomic, strong) NSTimer *refreshCellsTimer;

@property (nonatomic, readonly) id<RoomDataSourceDelegate> roomDataSourceDelegate;

@property(nonatomic, readwrite) RoomEncryptionTrustLevel encryptionTrustLevel;

@end

@implementation RoomDataSource
Expand Down Expand Up @@ -83,6 +87,9 @@ - (instancetype)initWithRoomId:(NSString *)roomId andMatrixSession:(MXSession *)

[self registerKeyVerificationRequestNotification];
[self registerDeviceVerificationTransactionNotification];
[self registerTrustLevelDidChangeNotifications];

self.encryptionTrustLevel = RoomEncryptionTrustLevelUnknown;
}
return self;
}
Expand All @@ -105,6 +112,21 @@ - (void)finalizeInitialization
NSLog(@"[MXKRoomDataSource] finalizeRoomDataSource: Cannot retrieve all room members");
}];
}

if (self.room.summary.isEncrypted)
{
[self fetchEncryptionTrustedLevel];
}
}

- (id<RoomDataSourceDelegate>)roomDataSourceDelegate
{
if (!self.delegate || ![self.delegate conformsToProtocol:@protocol(RoomDataSourceDelegate)])
{
return nil;
}

return ((id<RoomDataSourceDelegate>)(self.delegate));
}

- (void)updateEventFormatter
Expand Down Expand Up @@ -167,6 +189,88 @@ - (void)setNeedsUpdateAdditionalContentHeightForCellData:(id<MXKRoomBubbleCellDa
}
}

#pragma mark Encryption trust level

- (void)registerTrustLevelDidChangeNotifications
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceInfoTrustLevelDidChange:) name:MXDeviceInfoTrustLevelDidChangeNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(crossSigningInfoTrustLevelDidChange:) name:MXCrossSigningInfoTrustLevelDidChangeNotification object:nil];
}

- (void)deviceInfoTrustLevelDidChange:(NSNotification*)notification
{
MXDeviceInfo *deviceInfo = notification.object;

NSString *userId = deviceInfo.userId;

if (userId)
{
[self encryptionTrustLevelDidChangeRelatedToUserId:userId];
}
}

- (void)crossSigningInfoTrustLevelDidChange:(NSNotification*)notification
{
MXCrossSigningInfo *crossSigningInfo = notification.object;

NSString *userId = crossSigningInfo.userId;

if (userId)
{
[self encryptionTrustLevelDidChangeRelatedToUserId:userId];
}
}

- (void)fetchEncryptionTrustedLevel
{
[self encryptionTrustLevelDidChangeRelatedToUserId:self.mxSession.myUser.userId];
}

- (void)encryptionTrustLevelDidChangeRelatedToUserId:(NSString*)userId
{
if (!self.room.summary.isEncrypted)
{
return;
}

[self.room members:^(MXRoomMembers *roomMembers) {
MXRoomMember *roomMember = [roomMembers memberWithUserId:userId];

// If user belongs to the room refresh the trust level
if (roomMember)
{
[self.room trustedMembersProgressWithSuccess:^(NSProgress *trustedMembersProgress) {
Copy link
Member

Choose a reason for hiding this comment

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

We should check percentage of trusted devices.


RoomEncryptionTrustLevel roomEncryptionTrustLevel;

double trustedMembersPercentage = trustedMembersProgress.fractionCompleted;

if (trustedMembersPercentage >= 1.0)
{
roomEncryptionTrustLevel = RoomEncryptionTrustLevelTrusted;
}
else if (trustedMembersPercentage == 0.0)
{
roomEncryptionTrustLevel = RoomEncryptionTrustLevelNormal;
}
else
{
roomEncryptionTrustLevel = RoomEncryptionTrustLevelWarning;
}

self.encryptionTrustLevel = roomEncryptionTrustLevel;
[self.roomDataSourceDelegate roomDataSource:self didUpdateEncryptionTrustLevel:roomEncryptionTrustLevel];

} failure:^(NSError *error) {
NSLog(@"[RoomDataSource] trustLevelDidChangeRelatedToUserId fails to retrieve room members trusted progress");
}];
}

} failure:^(NSError *error) {
NSLog(@"[RoomDataSource] trustLevelDidChangeRelatedToUserId fails to retrieve room members");
}];
}

#pragma mark -

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
Expand Down
85 changes: 77 additions & 8 deletions Riot/Modules/Room/RoomViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@

@interface RoomViewController () <UISearchBarDelegate, UIGestureRecognizerDelegate, UIScrollViewAccessibilityDelegate, RoomTitleViewTapGestureDelegate, RoomParticipantsViewControllerDelegate, MXKRoomMemberDetailsViewControllerDelegate, ContactsTableViewControllerDelegate, MXServerNoticesDelegate, RoomContextualMenuViewControllerDelegate,
ReactionsMenuViewModelCoordinatorDelegate, EditHistoryCoordinatorBridgePresenterDelegate, MXKDocumentPickerPresenterDelegate, EmojiPickerCoordinatorBridgePresenterDelegate,
ReactionHistoryCoordinatorBridgePresenterDelegate, CameraPresenterDelegate, MediaPickerCoordinatorBridgePresenterDelegate>
ReactionHistoryCoordinatorBridgePresenterDelegate, CameraPresenterDelegate, MediaPickerCoordinatorBridgePresenterDelegate,
RoomDataSourceDelegate>
{
// The expanded header
ExpandedRoomTitleView *expandedHeader;
Expand Down Expand Up @@ -1421,6 +1422,11 @@ - (BOOL)isRoomPreview
return NO;
}

- (BOOL)isEncryptionEnabled
{
return self.roomDataSource.room.summary.isEncrypted && self.mainSession.crypto != nil;
}

- (void)refreshRoomTitle
{
if (rightBarButtonItems && !self.navigationItem.rightBarButtonItems)
Expand Down Expand Up @@ -1541,12 +1547,8 @@ - (void)refreshRoomInputToolbar
roomInputToolbarView.supportCallOption &= ([[AppDelegate theDelegate] callStatusBarWindow] == nil);
}

// Check whether the encryption is enabled in the room
if (self.roomDataSource.room.summary.isEncrypted)
{
// Encrypt the user's messages as soon as the user supports the encryption?
roomInputToolbarView.isEncryptionEnabled = (self.mainSession.crypto != nil);
}
// Update encryption decoration if needed
[self updateEncryptionDecorationForRoomInputToolbar:roomInputToolbarView];
}
else if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:DisabledRoomInputToolbarView.class])
{
Expand Down Expand Up @@ -1626,6 +1628,61 @@ - (void)updateInputToolBarViewHeight
[UIView setAnimationsEnabled:YES];
}

- (UIImage*)roomEncryptionBadgeImage
{
NSString *encryptionIconName;
UIImage *encryptionIcon;

if (self.isEncryptionEnabled)
{
RoomEncryptionTrustLevel roomEncryptionTrustLevel = ((RoomDataSource*)self.roomDataSource).encryptionTrustLevel;

switch (roomEncryptionTrustLevel) {
case RoomEncryptionTrustLevelWarning:
encryptionIconName = @"encryption_warning";
break;
case RoomEncryptionTrustLevelNormal:
encryptionIconName = @"encryption_normal";
break;
case RoomEncryptionTrustLevelTrusted:
encryptionIconName = @"encryption_trusted";
break;
default:
break;
}
}

if (encryptionIconName)
{
encryptionIcon = [UIImage imageNamed:encryptionIconName];
}

return encryptionIcon;
}

- (void)updateInputToolbarEncryptionDecoration
{
if (self.inputToolbarView && [self.inputToolbarView isKindOfClass:RoomInputToolbarView.class])
{
RoomInputToolbarView *roomInputToolbarView = (RoomInputToolbarView*)self.inputToolbarView;
[self updateEncryptionDecorationForRoomInputToolbar:roomInputToolbarView];
}
}

- (void)updateExpandedHeaderEncryptionDecoration
{
if (self->expandedHeader)
{
self->expandedHeader.roomAvatarBadgeImageView.image = self.roomEncryptionBadgeImage;
}
}

- (void)updateEncryptionDecorationForRoomInputToolbar:(RoomInputToolbarView*)roomInputToolbarView
{
roomInputToolbarView.isEncryptionEnabled = self.isEncryptionEnabled;
roomInputToolbarView.encryptedRoomIcon.image = self.roomEncryptionBadgeImage;
}

- (void)handleLongPressFromCell:(id<MXKCellRendering>)cell withTappedEvent:(MXEvent*)event
{
if (event && !customizedRoomDataSource.selectedEventId)
Expand Down Expand Up @@ -1725,9 +1782,12 @@ - (void)showExpandedHeader:(BOOL)isVisible
// Note the avatar title view does not define tap gesture.

expandedHeader.roomAvatar.alpha = 0.0;
expandedHeader.roomAvatarBadgeImageView.alpha = 0.0;

shadowImage = [[UIImage alloc] init];

[self updateExpandedHeaderEncryptionDecoration];

// Dismiss the keyboard when header is expanded.
[self.inputToolbarView dismissKeyboard];
}
Expand Down Expand Up @@ -1758,7 +1818,8 @@ - (void)showExpandedHeader:(BOOL)isVisible
self.bubblesTableViewTopConstraint.constant = (isVisible ? self.expandedHeaderContainerHeightConstraint.constant - self.bubblesTableView.mxk_adjustedContentInset.top : 0);
self.jumpToLastUnreadBannerContainerTopConstraint.constant = (isVisible ? self.expandedHeaderContainerHeightConstraint.constant : self.bubblesTableView.mxk_adjustedContentInset.top);

expandedHeader.roomAvatar.alpha = 1;
self->expandedHeader.roomAvatar.alpha = 1;
self->expandedHeader.roomAvatarBadgeImageView.alpha = 1;

// Force to render the view
[self forceLayoutRefresh];
Expand Down Expand Up @@ -3193,6 +3254,14 @@ - (RoomInputToolbarView*)inputToolbarViewAsRoomInputToolbarView
return roomInputToolbarView;
}

#pragma mark - RoomDataSourceDelegate

- (void)roomDataSource:(RoomDataSource *)roomDataSource didUpdateEncryptionTrustLevel:(RoomEncryptionTrustLevel)roomEncryptionTrustLevel
{
[self updateInputToolbarEncryptionDecoration];
[self updateExpandedHeaderEncryptionDecoration];
}

#pragma mark - Segues

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
Expand Down
Loading