import CocoaLumberjackSwift
import Foundation
import ThreemaMacros
public final class MessagePermission: NSObject {
public enum MessagePermissionError: Error {
case conversationNotFound(for: String)
}
let myIdentityStore: MyIdentityStoreProtocol
let userSettings: UserSettingsProtocol
let groupManager: GroupManagerProtocol
let entityManager: EntityManager
@objc public required init(
myIdentityStore: MyIdentityStoreProtocol,
userSettings: UserSettingsProtocol,
groupManager: GroupManagerProtocolObjc,
entityManager: EntityManager
) {
self.myIdentityStore = myIdentityStore
self.userSettings = userSettings
self.groupManager = groupManager as! GroupManagerProtocol
self.entityManager = entityManager
}
/// Check can send message to contact.
/// - Parameters:
/// - to: Receiver identity of the message
/// - Returns: Is not isAllowed than reason is set to inform user
public func canSend(to identity: String) -> (isAllowed: Bool, reason: String?) {
var result: (isAllowed: Bool, reason: String?) = (false, nil)
entityManager.performAndWait {
if let conversation = self.entityManager.entityFetcher.conversationEntity(for: identity) {
result = self.canSend(to: conversation)
}
// Check for blacklisted contact
else if let contact = self.entityManager.entityFetcher.contactEntity(for: identity),
self.userSettings.blacklist.contains(contact.identity) {
DDLogError("Cannot send a message to this contact \(identity) because it is blocked")
result = (false, #localize("contact_blocked_cannot_send"))
}
// Check for invalid contact
else if let contact = self.entityManager.entityFetcher.contactEntity(for: identity),
contact.contactState == .invalid {
DDLogError("Cannot send a message to this contact (\(contact.identity) because it is invalid")
result = (false, #localize("contact_invalid_cannot_send"))
}
else {
result = (true, nil)
}
}
return result
}
/// Check can send message to group.
/// - Parameters:
/// - groupID: Group ID
/// - groupCreator: Group creator
/// - Returns: Is not isAllowed than reason is set to inform user
public func canSend(
groudID: Data,
groupCreatorIdentity: String
) -> (isAllowed: Bool, reason: String?) {
var result: (isAllowed: Bool, reason: String?) = (false, nil)
entityManager.performAndWait {
guard let conversation = self.groupManager.getGroup(groudID, creator: groupCreatorIdentity)?.conversation
else {
result = (
false,
"Conversation for group (id \(groudID.hexString) / group creator \(groupCreatorIdentity)) not found."
)
return
}
result = self.canSend(to: conversation)
}
return result
}
@objc func canSend(to identity: String, reason: UnsafeMutablePointer<NSString?>?) -> Bool {
let result = canSend(to: identity)
if let r = result.reason, let reason {
reason.pointee = r as NSString
}
return result.isAllowed
}
@objc func canSend(
groupID: Data,
groupCreatorIdentity: String,
reason: UnsafeMutablePointer<NSString?>?
) -> Bool {
let result = canSend(groudID: groupID, groupCreatorIdentity: groupCreatorIdentity)
if let r = result.reason, let reason {
reason.pointee = r as NSString
}
return result.isAllowed
}
private func canSend(to conversation: ConversationEntity) -> (isAllowed: Bool, reason: String?) {
// Check for blacklisted contact
if let identity = conversation.contact?.identity,
conversation.groupID == nil,
userSettings.blacklist.contains(identity) {
DDLogError("Cannot send a message to this contact \(identity) because it is blocked")
return (false, #localize("contact_blocked_cannot_send"))
}
// Check that the group was started while we were using the same identity as now
if let groupMyIdentity = conversation.groupMyIdentity,
!groupMyIdentity.elementsEqual(myIdentityStore.identity) {
DDLogError(
"Cannot send a message to this group. This group was created while user were using a different Threema ID. Cannot send any messages to it with your current ID"
)
return (
false,
String.localizedStringWithFormat(
#localize("group_different_identity"),
TargetManager.localizedAppName
)
)
}
// Check for invalid contact
if conversation.groupID == nil,
let contact = conversation.contact,
contact.contactState == .invalid {
DDLogError("Cannot send a message to this contact (\(contact.identity) because it is invalid")
return (false, #localize("contact_invalid_cannot_send"))
}
// Check group state
if let group = groupManager.getGroup(conversation: conversation) {
// Not allowed for empty groups, exept i'm group creator because is a note group
if group.allMemberIdentities.filter({ $0 != myIdentityStore.identity }).isEmpty,
!group.isOwnGroup {
DDLogError("Cannot send a message because there are no more members in this group")
return (false, #localize("no_more_members"))
}
if group.didLeave || group.didForcedLeave {
DDLogError("Cannot send a message to this group because i left the group, i'm not a member anymore")
return (false, #localize("group_is_not_member"))
}
}
return (true, nil)
}
}
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland