Merge branch 'charlesmchen/blockOffer'

pull/1/head
Matthew Chen 7 years ago
commit 0115eb8475

@ -132,7 +132,7 @@ CHECKOUT OPTIONS:
:commit: 139bde37738ccb6ebcc68bf1b02c8a28400b6760
:git: https://github.com/WhisperSystems/SignalProtocolKit.git
SignalServiceKit:
:commit: adee71ba9b1fd955e3b4972233ab83548158f85b
:commit: 0ee09323f6052adb804af67dbd4330838477bb79
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf

@ -44,6 +44,11 @@ typedef void (^BlockActionCompletionBlock)(BOOL isBlocked);
contactsManager:(OWSContactsManager *)contactsManager
completionBlock:(nullable BlockActionCompletionBlock)completionBlock;
#pragma mark - UI Utils
+ (NSString *)formatDisplayNameForAlertTitle:(NSString *)displayName;
+ (NSString *)formatDisplayNameForAlertMessage:(NSString *)displayName;
@end
NS_ASSUME_NONNULL_END

@ -6,8 +6,8 @@
#import "AppDelegate.h"
#import "AttachmentSharing.h"
#import "BlockListUIUtils.h"
#import "DebugUITableViewController.h"
#import "BlockListViewController.h"
#import "DebugUITableViewController.h"
#import "Environment.h"
#import "FingerprintViewController.h"
#import "FullImageViewController.h"
@ -23,6 +23,7 @@
#import "OWSIncomingMessageCollectionViewCell.h"
#import "OWSMessagesBubblesSizeCalculator.h"
#import "OWSOutgoingMessageCollectionViewCell.h"
#import "OWSUnknownContactBlockOfferMessage.h"
#import "PropertyListPreferences.h"
#import "Signal-Swift.h"
#import "SignalKeyingStorage.h"
@ -383,6 +384,14 @@ typedef enum : NSUInteger {
self.senderDisplayName = ME_MESSAGE_IDENTIFIER;
[self initializeToolbars];
if ([self.thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)self.thread;
[ThreadUtil createBlockOfferIfNecessary:contactThread
storageManager:self.storageManager
contactsManager:self.contactsManager
blockingManager:self.blockingManager];
}
}
- (void)viewDidLayoutSubviews
@ -2003,6 +2012,8 @@ typedef enum : NSUInteger {
{
if ([message isKindOfClass:[TSInvalidIdentityKeyErrorMessage class]]) {
[self tappedInvalidIdentityKeyErrorMessage:(TSInvalidIdentityKeyErrorMessage *)message];
} else if ([message isKindOfClass:[OWSUnknownContactBlockOfferMessage class]]) {
[self tappedUnknownContactBlockOfferMessage:(OWSUnknownContactBlockOfferMessage *)message];
} else if (message.errorType == TSErrorMessageInvalidMessage) {
[self tappedCorruptedMessage:message];
} else {
@ -2050,48 +2061,83 @@ typedef enum : NSUInteger {
NSString *titleFormat = NSLocalizedString(@"SAFETY_NUMBERS_ACTIONSHEET_TITLE", @"Action sheet heading");
NSString *titleText = [NSString stringWithFormat:titleFormat, keyOwner];
UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:titleText
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:titleText
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
style:UIAlertActionStyleCancel
handler:nil];
[actionSheetController addAction:dismissAction];
UIAlertAction *showSafteyNumberAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"SHOW_SAFETY_NUMBER_ACTION", @"Action sheet item")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
DDLogInfo(@"%@ Remote Key Changed actions: Show fingerprint display", self.tag);
[self showFingerprintWithTheirIdentityKey:errorMessage.newIdentityKey
theirSignalId:errorMessage.theirSignalId];
}];
UIAlertAction *showSafteyNumberAction =
[UIAlertAction actionWithTitle:NSLocalizedString(@"SHOW_SAFETY_NUMBER_ACTION", @"Action sheet item")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ Remote Key Changed actions: Show fingerprint display", self.tag);
[self showFingerprintWithTheirIdentityKey:errorMessage.newIdentityKey
theirSignalId:errorMessage.theirSignalId];
}];
[actionSheetController addAction:showSafteyNumberAction];
UIAlertAction *acceptSafetyNumberAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"ACCEPT_NEW_IDENTITY_ACTION", @"Action sheet item")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {
DDLogInfo(@"%@ Remote Key Changed actions: Accepted new identity key", self.tag);
[errorMessage acceptNewIdentityKey];
if ([errorMessage isKindOfClass:[TSInvalidIdentityKeySendingErrorMessage class]]) {
[self.messageSender
resendMessageFromKeyError:(TSInvalidIdentityKeySendingErrorMessage *)
errorMessage
success:^{
DDLogDebug(@"%@ Successfully resent key-error message.", self.tag);
}
failure:^(NSError *_Nonnull error) {
DDLogError(@"%@ Failed to resend key-error message with error:%@",
self.tag,
error);
}];
}
}];
UIAlertAction *acceptSafetyNumberAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"ACCEPT_NEW_IDENTITY_ACTION", @"Action sheet item")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ Remote Key Changed actions: Accepted new identity key", self.tag);
[errorMessage acceptNewIdentityKey];
if ([errorMessage isKindOfClass:[TSInvalidIdentityKeySendingErrorMessage class]]) {
[self.messageSender
resendMessageFromKeyError:(TSInvalidIdentityKeySendingErrorMessage *)errorMessage
success:^{
DDLogDebug(@"%@ Successfully resent key-error message.", self.tag);
}
failure:^(NSError *_Nonnull error) {
DDLogError(@"%@ Failed to resend key-error message with error:%@", self.tag, error);
}];
}
}];
[actionSheetController addAction:acceptSafetyNumberAction];
[self presentViewController:actionSheetController animated:YES completion:nil];
}
- (void)tappedUnknownContactBlockOfferMessage:(OWSUnknownContactBlockOfferMessage *)errorMessage
{
NSString *displayName = [self.contactsManager displayNameForPhoneIdentifier:errorMessage.contactId];
NSString *title =
[NSString stringWithFormat:NSLocalizedString(@"BLOCK_OFFER_ACTIONSHEET_TITLE_FORMAT",
@"Title format for action sheet that offers to block an unknown user."
@"Embeds {{the unknown user's name or phone number}}."),
[BlockListUIUtils formatDisplayNameForAlertTitle:displayName]];
UIAlertController *actionSheetController =
[UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
style:UIAlertActionStyleCancel
handler:nil];
[actionSheetController addAction:dismissAction];
UIAlertAction *blockAction =
[UIAlertAction actionWithTitle:NSLocalizedString(@"BLOCK_OFFER_ACTIONSHEET_BLOCK_ACTION",
@"Action sheet that will block an unknown user.")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ Blocking an unknown user.", self.tag);
[self.blockingManager addBlockedPhoneNumber:errorMessage.contactId];
// Delete the block offer.
[self.storageManager.dbConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[errorMessage removeWithTransaction:transaction];
}];
}];
[actionSheetController addAction:blockAction];
[self presentViewController:actionSheetController animated:YES completion:nil];
}
#pragma mark - UIImagePickerController
/*

@ -5,6 +5,10 @@
@class TSThread;
@class OWSMessageSender;
@class SignalAttachment;
@class TSContactThread;
@class TSStorageManager;
@class OWSContactsManager;
@class OWSBlockingManager;
NS_ASSUME_NONNULL_BEGIN
@ -18,6 +22,11 @@ NS_ASSUME_NONNULL_BEGIN
inThread:(TSThread *)thread
messageSender:(OWSMessageSender *)messageSender;
+ (void)createBlockOfferIfNecessary:(TSContactThread *)contactThread
storageManager:(TSStorageManager *)storageManager
contactsManager:(OWSContactsManager *)contactsManager
blockingManager:(OWSBlockingManager *)blockingManager;
@end
NS_ASSUME_NONNULL_END

@ -3,10 +3,14 @@
//
#import "ThreadUtil.h"
#import "OWSContactsManager.h"
#import "Signal-Swift.h"
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSUnknownContactBlockOfferMessage.h>
#import <SignalServiceKit/TSDatabaseView.h>
#import <SignalServiceKit/TSOutgoingMessage.h>
#import <SignalServiceKit/TSThread.h>
@ -84,6 +88,111 @@ NS_ASSUME_NONNULL_BEGIN
}];
}
+ (void)createBlockOfferIfNecessary:(TSContactThread *)contactThread
storageManager:(TSStorageManager *)storageManager
contactsManager:(OWSContactsManager *)contactsManager
blockingManager:(OWSBlockingManager *)blockingManager
{
OWSAssert(contactThread);
OWSAssert(storageManager);
OWSAssert(contactsManager);
OWSAssert(blockingManager);
if ([[blockingManager blockedPhoneNumbers] containsObject:contactThread.contactIdentifier]) {
// Only create block offers for users which are not already blocked.
return;
}
Contact *contact = [contactsManager contactForPhoneIdentifier:contactThread.contactIdentifier];
if (contact) {
// Only create block offers for non-contacts.
return;
}
[storageManager.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
const int kMaxOutgoingMessageCount = 10;
__block TSIncomingMessage *firstIncomingMessage = nil;
__block TSOutgoingMessage *firstOutgoingMessage = nil;
__block long outgoingMessageCount = 0;
__block BOOL hasUnknownContactBlockOffer = NO;
[[transaction ext:TSMessageDatabaseViewExtensionName]
enumerateRowsInGroup:contactThread.uniqueId
usingBlock:^(
NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
if ([object isKindOfClass:[OWSUnknownContactBlockOfferMessage class]]) {
hasUnknownContactBlockOffer = YES;
// If there already is a block offer, abort.
*stop = YES;
} else if ([object isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)object;
if (!firstIncomingMessage) {
firstIncomingMessage = incomingMessage;
} else {
OWSAssert([[firstIncomingMessage receiptDateForSorting]
compare:[incomingMessage receiptDateForSorting]]
== NSOrderedAscending);
}
} else if ([object isKindOfClass:[TSOutgoingMessage class]]) {
TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)object;
if (!firstOutgoingMessage) {
firstOutgoingMessage = outgoingMessage;
} else {
OWSAssert([[firstOutgoingMessage receiptDateForSorting]
compare:[outgoingMessage receiptDateForSorting]]
== NSOrderedAscending);
}
outgoingMessageCount++;
if (outgoingMessageCount > kMaxOutgoingMessageCount) {
// If the user has sent more than N interactions, abort.
*stop = YES;
}
}
}];
if (!firstIncomingMessage && !firstOutgoingMessage) {
// If the thread has no interactions, abort.
return;
}
if (outgoingMessageCount > kMaxOutgoingMessageCount) {
// If the user has sent more than N messages, abort.
return;
}
if (hasUnknownContactBlockOffer) {
// If there already is a block offer, abort.
return;
}
BOOL hasOutgoingBeforeIncomingInteraction = (firstOutgoingMessage
&& (!firstIncomingMessage ||
[[firstOutgoingMessage receiptDateForSorting] compare:[firstIncomingMessage receiptDateForSorting]]
== NSOrderedAscending));
if (hasOutgoingBeforeIncomingInteraction) {
// If there is an outgoing message before an incoming message
// the local user initiated this conversation, abort.
return;
}
DDLogInfo(@"Creating block offer for unknown contact");
// We want the block offer to be the first interaction in their
// conversation's timeline, so we back-date it to slightly before
// the first incoming message (which we know is the first message).
TSIncomingMessage *firstMessage = firstIncomingMessage;
uint64_t blockOfferTimestamp = firstMessage.timestamp - 1;
TSErrorMessage *errorMessage =
[OWSUnknownContactBlockOfferMessage unknownContactBlockOfferMessage:blockOfferTimestamp
thread:contactThread
contactId:contactThread.contactIdentifier];
[errorMessage saveWithTransaction:transaction];
}];
}
#pragma mark - Logging
+ (NSString *)tag

@ -154,6 +154,12 @@
/* The title of the 'user unblocked' alert. */
"BLOCK_LIST_VIEW_UNBLOCKED_ALERT_TITLE" = "User Unblocked";
/* Action sheet that will block an unknown user. */
"BLOCK_OFFER_ACTIONSHEET_BLOCK_ACTION" = "Block";
/* Title format for action sheet that offers to block an unknown user.Embeds {{the unknown user's name or phone number}}. */
"BLOCK_OFFER_ACTIONSHEET_TITLE_FORMAT" = "Block %@?";
/* Accessibilty label for placing call button */
"CALL_LABEL" = "Call";
@ -1021,6 +1027,9 @@
/* In Inbox view, last message label for thread with corrupted attachment. */
"UNKNOWN_ATTACHMENT_LABEL" = "Unknown attachment";
/* No comment provided by engineer. */
"UNKNOWN_CONTACT_BLOCK_OFFER" = "User not in your contacts. Would you like to block this user?";
/* Displayed if for some reason we can't determine a contacts phone number *or* name */
"UNKNOWN_CONTACT_NAME" = "Unknown Contact";

Loading…
Cancel
Save