Implement banning
This commit is contained in:
parent
3e5baca72d
commit
18c646987a
|
@ -1528,15 +1528,17 @@ typedef enum : NSUInteger {
|
||||||
[self showDetailViewForViewItem:conversationViewItem];
|
[self showDetailViewForViewItem:conversationViewItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)report:(id<ConversationViewItem>)conversationViewItem
|
- (void)banUser:(id<ConversationViewItem>)conversationViewItem
|
||||||
{
|
{
|
||||||
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Report?" message:@"If the message is found to violate the Session Public Chat code of conduct it will be removed." preferredStyle:UIAlertControllerStyleAlert];
|
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Ban This User?" message:nil preferredStyle:UIAlertControllerStyleAlert];
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
|
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
|
||||||
uint64_t messageID = 0;
|
NSString* publicKey;
|
||||||
if ([conversationViewItem.interaction isKindOfClass:TSMessage.class]) {
|
if ([conversationViewItem.interaction isKindOfClass:TSIncomingMessage.class]) {
|
||||||
messageID = ((TSMessage *)conversationViewItem.interaction).openGroupServerMessageID;
|
publicKey = ((TSIncomingMessage *)conversationViewItem.interaction).authorId;
|
||||||
}
|
}
|
||||||
[SNOpenGroupAPI reportMessageWithID:messageID inChannel:1 onServer:@"https://chat.getsession.org"];
|
SNOpenGroup *openGroup = [LKStorage.shared getOpenGroupForThreadID:self.thread.uniqueId];
|
||||||
|
if (openGroup == nil) return;
|
||||||
|
[[SNOpenGroupAPI banPublicKey:publicKey fromServer:openGroup.server] retainUntilComplete];
|
||||||
}]];
|
}]];
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]];
|
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]];
|
||||||
[self presentViewController:alert animated:YES completion:nil];
|
[self presentViewController:alert animated:YES completion:nil];
|
||||||
|
|
|
@ -67,6 +67,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
|
||||||
|
|
||||||
@property (nonatomic, readonly) BOOL isGroupThread;
|
@property (nonatomic, readonly) BOOL isGroupThread;
|
||||||
@property (nonatomic, readonly) BOOL userCanDeleteGroupMessage;
|
@property (nonatomic, readonly) BOOL userCanDeleteGroupMessage;
|
||||||
|
@property (nonatomic, readonly) BOOL userHasModerationPermission;
|
||||||
|
|
||||||
@property (nonatomic, readonly) BOOL hasBodyText;
|
@property (nonatomic, readonly) BOOL hasBodyText;
|
||||||
|
|
||||||
|
|
|
@ -1184,6 +1184,23 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL)userHasModerationPermission
|
||||||
|
{
|
||||||
|
if (!self.isGroupThread) return false;
|
||||||
|
TSGroupThread *groupThread = (TSGroupThread *)self.interaction.thread;
|
||||||
|
|
||||||
|
// Make sure it's an open group message
|
||||||
|
TSMessage *message = (TSMessage *)self.interaction;
|
||||||
|
if (!message.isOpenGroupMessage) return false;
|
||||||
|
|
||||||
|
// Ensure we have the details needed to contact the server
|
||||||
|
SNOpenGroup *openGroup = [LKStorage.shared getOpenGroupForThreadID:groupThread.uniqueId];
|
||||||
|
if (openGroup == nil) return false;
|
||||||
|
|
||||||
|
// Check that we're a moderator
|
||||||
|
return [SNOpenGroupAPI isUserModerator:[SNGeneralUtilities getUserPublicKey] forChannel:openGroup.channel onServer:openGroup.server];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Foundation
|
||||||
|
|
||||||
@objc
|
@objc
|
||||||
protocol MessageActionsDelegate: class {
|
protocol MessageActionsDelegate: class {
|
||||||
func report(_ conversationViewItem: ConversationViewItem)
|
func banUser(_ conversationViewItem: ConversationViewItem)
|
||||||
func messageActionsShowDetailsForItem(_ conversationViewItem: ConversationViewItem)
|
func messageActionsShowDetailsForItem(_ conversationViewItem: ConversationViewItem)
|
||||||
func messageActionsReplyToItem(_ conversationViewItem: ConversationViewItem)
|
func messageActionsReplyToItem(_ conversationViewItem: ConversationViewItem)
|
||||||
func copyPublicKey(for conversationViewItem: ConversationViewItem)
|
func copyPublicKey(for conversationViewItem: ConversationViewItem)
|
||||||
|
@ -45,14 +45,6 @@ struct MessageActionBuilder {
|
||||||
block: { [weak delegate] _ in delegate?.messageActionsShowDetailsForItem(conversationViewItem) }
|
block: { [weak delegate] _ in delegate?.messageActionsShowDetailsForItem(conversationViewItem) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func report(_ conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
|
||||||
return MenuAction(image: #imageLiteral(resourceName: "Flag"),
|
|
||||||
title: NSLocalizedString("Report", comment: ""),
|
|
||||||
subtitle: nil,
|
|
||||||
block: { [weak delegate] _ in delegate?.report(conversationViewItem) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func deleteMessage(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
static func deleteMessage(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
||||||
return MenuAction(image: #imageLiteral(resourceName: "ic_trash"),
|
return MenuAction(image: #imageLiteral(resourceName: "ic_trash"),
|
||||||
|
@ -61,6 +53,14 @@ struct MessageActionBuilder {
|
||||||
block: { _ in conversationViewItem.deleteAction() }
|
block: { _ in conversationViewItem.deleteAction() }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func banUser(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
||||||
|
return MenuAction(image: #imageLiteral(resourceName: "ic_block"),
|
||||||
|
title: "Ban User",
|
||||||
|
subtitle: nil,
|
||||||
|
block: { [weak delegate] _ in delegate?.banUser(conversationViewItem) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
static func copyMedia(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
static func copyMedia(conversationViewItem: ConversationViewItem, delegate: MessageActionsDelegate) -> MenuAction {
|
||||||
return MenuAction(image: #imageLiteral(resourceName: "ic_copy"),
|
return MenuAction(image: #imageLiteral(resourceName: "ic_copy"),
|
||||||
|
@ -108,10 +108,9 @@ class ConversationViewItemActions: NSObject {
|
||||||
actions.append(deleteAction)
|
actions.append(deleteAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat"
|
if isGroup && conversationViewItem.interaction is TSIncomingMessage && conversationViewItem.userHasModerationPermission {
|
||||||
|| conversationViewItem.interaction.thread.name() == "Session Public Chat" {
|
let banAction = MessageActionBuilder.banUser(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate)
|
actions.append(banAction)
|
||||||
actions.append(reportAction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
|
@ -152,10 +151,9 @@ class ConversationViewItemActions: NSObject {
|
||||||
actions.append(deleteAction)
|
actions.append(deleteAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat"
|
if isGroup && conversationViewItem.interaction is TSIncomingMessage && conversationViewItem.userHasModerationPermission {
|
||||||
|| conversationViewItem.interaction.thread.name() == "Session Public Chat" {
|
let banAction = MessageActionBuilder.banUser(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate)
|
actions.append(banAction)
|
||||||
actions.append(reportAction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
|
@ -185,10 +183,9 @@ class ConversationViewItemActions: NSObject {
|
||||||
actions.append(deleteAction)
|
actions.append(deleteAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isGroup && conversationViewItem.interaction.thread.name() == "Loki Public Chat"
|
if isGroup && conversationViewItem.interaction is TSIncomingMessage && conversationViewItem.userHasModerationPermission {
|
||||||
|| conversationViewItem.interaction.thread.name() == "Session Public Chat" {
|
let banAction = MessageActionBuilder.banUser(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
let reportAction = MessageActionBuilder.report(conversationViewItem, delegate: delegate)
|
actions.append(banAction)
|
||||||
actions.append(reportAction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
|
|
|
@ -205,7 +205,7 @@ public final class OpenGroupAPI : DotNetAPI {
|
||||||
}
|
}
|
||||||
let lastDeletionServerID = storage.getLastDeletionServerID(for: channel, on: server)
|
let lastDeletionServerID = storage.getLastDeletionServerID(for: channel, on: server)
|
||||||
if serverID > (lastDeletionServerID ?? 0) {
|
if serverID > (lastDeletionServerID ?? 0) {
|
||||||
storage.write { transaction in
|
storage.writeSync { transaction in
|
||||||
storage.setLastDeletionServerID(for: channel, on: server, to: serverID, using: transaction)
|
storage.setLastDeletionServerID(for: channel, on: server, to: serverID, using: transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,6 +238,33 @@ public final class OpenGroupAPI : DotNetAPI {
|
||||||
}.handlingInvalidAuthTokenIfNeeded(for: server)
|
}.handlingInvalidAuthTokenIfNeeded(for: server)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Banning
|
||||||
|
@objc(banPublicKey:fromServer:)
|
||||||
|
public static func objc_ban(_ publicKey: String, from server: String) -> AnyPromise {
|
||||||
|
return AnyPromise.from(ban(publicKey, from: server))
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func ban(_ publicKey: String, from server: String) -> Promise<Void> {
|
||||||
|
SNLog("Banning user with ID: \(publicKey) from server: \(server).")
|
||||||
|
return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global(qos: .default)) {
|
||||||
|
getOpenGroupServerPublicKey(for: server).then(on: DispatchQueue.global(qos: .default)) { serverPublicKey in
|
||||||
|
getAuthToken(for: server).then(on: DispatchQueue.global(qos: .default)) { token -> Promise<Void> in
|
||||||
|
let url = URL(string: "\(server)/loki/v1/moderation/blacklist/@\(publicKey)")!
|
||||||
|
let request = TSRequest(url: url, method: "POST", parameters: [:])
|
||||||
|
request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ]
|
||||||
|
let promise = OnionRequestAPI.sendOnionRequest(request, to: server, using: serverPublicKey, isJSONRequired: false)
|
||||||
|
promise.done(on: DispatchQueue.global(qos: .default)) { _ -> Void in
|
||||||
|
SNLog("Banned user with ID: \(publicKey) from server: \(server).")
|
||||||
|
}
|
||||||
|
promise.catch(on: DispatchQueue.main) { error in
|
||||||
|
print(error)
|
||||||
|
}
|
||||||
|
return promise.map { _ in }
|
||||||
|
}
|
||||||
|
}.handlingInvalidAuthTokenIfNeeded(for: server)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: Display Name & Profile Picture
|
// MARK: Display Name & Profile Picture
|
||||||
public static func getDisplayNames(for channel: UInt64, on server: String) -> Promise<Void> {
|
public static func getDisplayNames(for channel: UInt64, on server: String) -> Promise<Void> {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public final class OpenGroupPoller : NSObject {
|
||||||
|
|
||||||
// MARK: Settings
|
// MARK: Settings
|
||||||
private let pollForNewMessagesInterval: TimeInterval = 4
|
private let pollForNewMessagesInterval: TimeInterval = 4
|
||||||
private let pollForDeletedMessagesInterval: TimeInterval = 60
|
private let pollForDeletedMessagesInterval: TimeInterval = 30
|
||||||
private let pollForModeratorsInterval: TimeInterval = 10 * 60
|
private let pollForModeratorsInterval: TimeInterval = 10 * 60
|
||||||
|
|
||||||
// MARK: Lifecycle
|
// MARK: Lifecycle
|
||||||
|
|
Loading…
Reference in New Issue