Add Message.flags

MAILAND-2830
This commit is contained in:
Davide Farella 2022-04-06 08:56:31 +02:00
parent 680daabf0c
commit 205aa715ce
10 changed files with 113 additions and 115 deletions

View File

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 15,
"identityHash": "62f56b04811fed2faf791d36b634e176",
"identityHash": "129e6d8c1a51ba4e86fbbecb7be4622d",
"entities": [
{
"tableName": "attachmentv3",
@ -208,7 +208,7 @@
},
{
"tableName": "messagev3",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`ID` TEXT, `ConversationID` TEXT, `Subject` TEXT, `Unread` INTEGER NOT NULL, `Type` INTEGER NOT NULL, `Time` INTEGER NOT NULL, `Size` INTEGER NOT NULL, `Location` INTEGER NOT NULL, `FolderLocation` TEXT, `Starred` INTEGER, `NumAttachments` INTEGER NOT NULL, `IsEncrypted` INTEGER NOT NULL, `ExpirationTime` INTEGER NOT NULL, `IsReplied` INTEGER, `IsRepliedAll` INTEGER, `IsForwarded` INTEGER, `Body` TEXT, `IsDownloaded` INTEGER NOT NULL, `AddressID` TEXT, `InlineResponse` INTEGER NOT NULL, `NewServerId` TEXT, `MIMEType` TEXT, `SpamScore` INTEGER NOT NULL, `AccessTime` INTEGER NOT NULL, `Header` TEXT, `ParsedHeaders` TEXT, `LabelIDs` TEXT NOT NULL, `ToList` TEXT NOT NULL, `ReplyTos` TEXT NOT NULL, `CCList` TEXT NOT NULL, `BCCList` TEXT NOT NULL, `_id` INTEGER PRIMARY KEY AUTOINCREMENT, `Sender_SenderName` TEXT, `Sender_SenderSerialized` TEXT)",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`ID` TEXT, `ConversationID` TEXT, `Subject` TEXT, `Unread` INTEGER NOT NULL, `Type` INTEGER NOT NULL, `Time` INTEGER NOT NULL, `Size` INTEGER NOT NULL, `Location` INTEGER NOT NULL, `FolderLocation` TEXT, `Starred` INTEGER, `NumAttachments` INTEGER NOT NULL, `IsEncrypted` INTEGER NOT NULL, `ExpirationTime` INTEGER NOT NULL, `IsReplied` INTEGER, `IsRepliedAll` INTEGER, `IsForwarded` INTEGER, `Body` TEXT, `IsDownloaded` INTEGER NOT NULL, `AddressID` TEXT, `InlineResponse` INTEGER NOT NULL, `NewServerId` TEXT, `MIMEType` TEXT, `SpamScore` INTEGER NOT NULL, `AccessTime` INTEGER NOT NULL, `Header` TEXT, `ParsedHeaders` TEXT, `LabelIDs` TEXT NOT NULL, `ToList` TEXT NOT NULL, `ReplyTos` TEXT NOT NULL, `CCList` TEXT NOT NULL, `BCCList` TEXT NOT NULL, `Flags` INTEGER NOT NULL, `_id` INTEGER PRIMARY KEY AUTOINCREMENT, `Sender_SenderName` TEXT, `Sender_SenderSerialized` TEXT)",
"fields": [
{
"fieldPath": "messageId",
@ -396,6 +396,12 @@
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "flags",
"columnName": "Flags",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "dbId",
"columnName": "_id",
@ -525,7 +531,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '62f56b04811fed2faf791d36b634e176')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '129e6d8c1a51ba4e86fbbecb7be4622d')"
]
}
}

View File

@ -1,82 +0,0 @@
/*
* Copyright (c) 2020 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonMail is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.enumerations;
/**
* This enum represent some of the possible values that are contained in the
* `Message.Flags` bitmap of message flags.
* Here is a list of all the possible values such flags can assume.
* Mapping between the Flag's bitmap and this enum is performed in `MessageFlagsToEncryptionMapper`.
* <p>
* Received = 1 (2^0)
* Sent = 2 (2^1)
* Internal = 4 (2^2)
* E2E = 8 (2^3)
* Auto = 16 (2^4)
* Replied = 32 (2^5)
* RepliedAll = 64 (2^6)
* Forwarded = 128 (2^7)
* Auto replied = 256 (2^8)
* Imported = 512 (2^9)
* Opened = 1024 (2^10)
* Receipt Sent = 2048 (2^11)
* Notified = 4096 (2^12)
* Touched = 8192 (2^13)
* Receipt = 16384 (2^14)
* Proton = 32768 (2^15)
* Receipt request = 65536 (2^16)
* Public key = 131072 (2^17)
* Sign = 262144 (2^18)
* Unsubscribed = 524288 (2^19)
* SPF fail = 16777216 (2^24)
* DKIM fail = 33554432 (2^25)
* DMARC fail = 67108864 (2^26)
* Ham manual = 134217728 (2^27)
* Spam auto = 268435456 (2^28)
* Spam manual = 536870912 (2^29)
* Phishing auto = 1073741824 (2^30)
* Phishing manual = 2147483648 (2^31)
*/
public enum MessageFlag {
RECEIVED(1L), // whether a message is received
SENT(2L), // whether a message is sent
INTERNAL(4L), // whether the message is between ProtonMail recipients
E2E(8L), // whether the message is end-to-end encrypted
AUTO(16L), // whether the message is an autoresponse
REPLIED(32L), // whether the message is replied to
REPLIED_ALL(64L), // whether the message is replied all to
FORWARDED(128L), // whether the message is forwarded
AUTO_REPLIED(256L), // whether the message has been responded to with an autoresponse
IMPORTED(512L), // whether the message is an import
OPENED(1024L), // whether the message has ever been opened by the user
RECEIPT_SENT(2048L), // whether a read receipt has been sent in response to the message
RECEIPT_REQUEST(65536L), // whether to request a read receipt for the message
PUBLIC_KEY(131072L), // whether to attach the public key
SIGN(262144L); // whether to sign the message
private final Long value;
MessageFlag(Long value) {
this.value = value;
}
public Long getValue() {
return value;
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
* ProtonMail is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonMail is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonMail. If not, see https://www.gnu.org/licenses/.
*/
package ch.protonmail.android.api.models.enumerations
/**
* @see ~/Slim-API/mail/#operation/get_mail-v4-messages-{enc_id}
*/
enum class MessageFlag(val flagValue: Long) {
RECEIVED(flagValue = 1),
SENT(flagValue = 2),
/**
* Message is between ProtonMail recipients
*/
INTERNAL(flagValue = 4),
E2E(flagValue = 8),
/**
* Message is an auto-response
*/
AUTO(flagValue = 16),
REPLIED(flagValue = 32),
REPLIED_ALL(flagValue = 64),
FORWARDED(flagValue = 128),
/**
* Message has been responded to with an auto-response
*/
AUTO_REPLIED(flagValue = 256),
IMPORTED(flagValue = 512),
OPENED(flagValue = 1_024),
/**
* Read receipt has been sent in response to the message
*/
RECEIPT_SENT(flagValue = 2_048),
/**
* Request a read receipt for the message
*/
RECEIPT_REQUEST(flagValue = 65_536),
/**
* Attach the public key
*/
PUBLIC_KEY(flagValue = 131_072),
SIGN(flagValue = 262_144),
PHISHING_AUTO(flagValue = 1_073_741_824),
PHISHING_MANUAL(flagValue = 2_147_483_648);
}
operator fun Long.contains(flag: MessageFlag) =
this and flag.flagValue == flag.flagValue

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
@ -44,7 +44,7 @@ class MessageFactory @Inject constructor(
conversationId = serverMessage.ConversationID,
subject = serverMessage.Subject,
Unread = serverMessage.Unread.parseBoolean("Unread"),
Type = MessageUtils.calculateType(serverMessage.Flags),
Type = MessageUtils.calculateType(serverMessage.flags),
sender = messageSenderFactory.createMessageSender(requireNotNull(serverMessage.Sender)),
time = serverMessage.time.checkIfSet("Time"),
@ -60,11 +60,11 @@ class MessageFactory @Inject constructor(
.contains(Constants.MessageLocationType.STARRED),
folderLocation = serverMessage.FolderLocation,
numAttachments = serverMessage.NumAttachments,
messageEncryption = messageFlagsToEncryptionMapper.flagsToMessageEncryption(serverMessage.Flags),
messageEncryption = messageFlagsToEncryptionMapper.flagsToMessageEncryption(serverMessage.flags),
expirationTime = serverMessage.ExpirationTime,
isReplied = serverMessage.Flags and MessageFlag.REPLIED.value == MessageFlag.REPLIED.value,
isRepliedAll = serverMessage.Flags and MessageFlag.REPLIED_ALL.value == MessageFlag.REPLIED_ALL.value,
isForwarded = serverMessage.Flags and MessageFlag.FORWARDED.value == MessageFlag.FORWARDED.value,
isReplied = serverMessage.flags and MessageFlag.REPLIED.flagValue == MessageFlag.REPLIED.flagValue,
isRepliedAll = serverMessage.flags and MessageFlag.REPLIED_ALL.flagValue == MessageFlag.REPLIED_ALL.flagValue,
isForwarded = serverMessage.flags and MessageFlag.FORWARDED.flagValue == MessageFlag.FORWARDED.flagValue,
isDownloaded = serverMessage.Body != null,
spamScore = serverMessage.SpamScore,
addressID = serverMessage.AddressID,
@ -76,7 +76,8 @@ class MessageFactory @Inject constructor(
bccList = serverMessage.BCCList?.toList() ?: listOf(),
replyTos = serverMessage.ReplyTos?.toList() ?: listOf(),
header = serverMessage.Header,
parsedHeaders = serverMessage.parsedHeaders
parsedHeaders = serverMessage.parsedHeaders,
flags = serverMessage.flags
).apply {
attachments = serverMessage.Attachments?.map(attachmentFactory::createAttachment) ?: emptyList()
embeddedImageIds = serverMessage.embeddedImagesArray?.toList() ?: emptyList()

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
@ -22,9 +22,10 @@ import ch.protonmail.android.api.models.MessageRecipient
import ch.protonmail.android.api.models.messages.ParsedHeaders
import com.google.gson.annotations.SerializedName
private const val FIELD_FLAGS = "Flags"
private const val FIELD_ID = "ID"
private const val FIELD_LABEL_IDS_REMOVED = "LabelIDsRemoved"
private const val FIELD_LABEL_IDS_ADDED = "LabelIDsAdded"
private const val FIELD_LABEL_IDS_REMOVED = "LabelIDsRemoved"
private const val FIELD_PARSED_HEADERS = "ParsedHeaders"
private const val FIELD_TIME = "Time"
@ -37,7 +38,8 @@ data class ServerMessage(
val Unread: Int = -1,
val Type: Int = -1, // 0 = INBOX, 1 = DRAFT, 2 = SENT, 3 = INBOX_AND_SENT
val Sender: ServerMessageSender? = null,
val Flags: Long = 0,
@SerializedName(FIELD_FLAGS)
val flags: Long = 0,
@SerializedName(FIELD_TIME)
val time: Long = -1,
val Size: Long = -1,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
@ -34,7 +34,6 @@ import ch.protonmail.android.core.Constants
import ch.protonmail.android.core.UserManager
import ch.protonmail.android.data.local.ContactDao
import ch.protonmail.android.data.local.MessageDao
import ch.protonmail.android.pendingaction.data.PendingActionDao
import ch.protonmail.android.data.local.model.ContactData
import ch.protonmail.android.data.local.model.Message
import ch.protonmail.android.data.local.model.MessageSender
@ -54,6 +53,7 @@ import ch.protonmail.android.mailbox.data.local.model.UnreadCounterEntity.Type
import ch.protonmail.android.mailbox.data.mapper.ApiToDatabaseUnreadCounterMapper
import ch.protonmail.android.mailbox.data.remote.model.CountsApiModel
import ch.protonmail.android.mailbox.domain.HandleChangeToConversations
import ch.protonmail.android.pendingaction.data.PendingActionDao
import ch.protonmail.android.prefs.SecureSharedPreferences
import ch.protonmail.android.usecase.fetch.LaunchInitialDataFetch
import ch.protonmail.android.utils.MessageUtils
@ -406,14 +406,14 @@ class EventHandler @AssistedInject constructor(
expired = true
}
}
if (newMessage.Flags > 0) {
message.isReplied = newMessage.Flags and MessageFlag.REPLIED.value == MessageFlag.REPLIED.value
if (newMessage.flags > 0) {
message.isReplied = newMessage.flags and MessageFlag.REPLIED.flagValue == MessageFlag.REPLIED.flagValue
message.isRepliedAll =
newMessage.Flags and MessageFlag.REPLIED_ALL.value == MessageFlag.REPLIED_ALL.value
message.isForwarded = newMessage.Flags and MessageFlag.FORWARDED.value == MessageFlag.FORWARDED.value
newMessage.flags and MessageFlag.REPLIED_ALL.flagValue == MessageFlag.REPLIED_ALL.flagValue
message.isForwarded = newMessage.flags and MessageFlag.FORWARDED.flagValue == MessageFlag.FORWARDED.flagValue
message.Type = MessageUtils.calculateType(newMessage.Flags)
message.messageEncryption = messageFlagsToEncryptionMapper.flagsToMessageEncryption(newMessage.Flags)
message.Type = MessageUtils.calculateType(newMessage.flags)
message.messageEncryption = messageFlagsToEncryptionMapper.flagsToMessageEncryption(newMessage.flags)
}
if (newMessage.AddressID != null) {
message.addressID = newMessage.AddressID

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*

View File

@ -33,6 +33,8 @@ import ch.protonmail.android.api.models.MessagePayload
import ch.protonmail.android.api.models.MessageRecipient
import ch.protonmail.android.api.models.RecipientType
import ch.protonmail.android.api.models.enumerations.MessageEncryption
import ch.protonmail.android.api.models.enumerations.MessageFlag
import ch.protonmail.android.api.models.enumerations.contains
import ch.protonmail.android.api.models.messages.ParsedHeaders
import ch.protonmail.android.api.models.messages.receive.MessageLocationResolver
import ch.protonmail.android.api.models.messages.receive.ServerMessageSender
@ -72,6 +74,7 @@ const val COLUMN_MESSAGE_BCC_LIST = "BCCList"
const val COLUMN_MESSAGE_BODY = "Body"
const val COLUMN_MESSAGE_CC_LIST = "CCList"
const val COLUMN_MESSAGE_EXPIRATION_TIME = "ExpirationTime"
const val COLUMN_MESSAGE_FLAGS = "Flags"
const val COLUMN_MESSAGE_FOLDER_LOCATION = "FolderLocation"
const val COLUMN_MESSAGE_HEADER = "Header"
const val COLUMN_MESSAGE_ID = "ID"
@ -205,7 +208,10 @@ data class Message @JvmOverloads constructor(
var bccList: List<MessageRecipient> = emptyList(),
@Embedded(prefix = COLUMN_MESSAGE_PREFIX_SENDER)
var sender: MessageSender? = MessageSender(null, null)
var sender: MessageSender? = MessageSender(null, null),
@ColumnInfo(name = COLUMN_MESSAGE_FLAGS)
val flags: Long = 0
) : Serializable {
@ -578,7 +584,8 @@ data class Message @JvmOverloads constructor(
)
}
fun isPhishing() = false
fun isPhishing(): Boolean =
MessageFlag.PHISHING_AUTO in flags || MessageFlag.PHISHING_MANUAL in flags
enum class MessageType {
INBOX, DRAFT, SENT, INBOX_AND_SENT

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
@ -44,11 +44,11 @@ import javax.inject.Inject
class MessageFlagsToEncryptionMapper @Inject constructor() : Mapper<Long, MessageEncryption> {
fun flagsToMessageEncryption(messageFlags: Long): MessageEncryption {
val internal = messageFlags and MessageFlag.INTERNAL.value == MessageFlag.INTERNAL.value
val e2e = messageFlags and MessageFlag.E2E.value == MessageFlag.E2E.value
val received = messageFlags and MessageFlag.RECEIVED.value == MessageFlag.RECEIVED.value
val sent = messageFlags and MessageFlag.SENT.value == MessageFlag.SENT.value
val auto = messageFlags and MessageFlag.AUTO.value == MessageFlag.AUTO.value
val internal = messageFlags and MessageFlag.INTERNAL.flagValue == MessageFlag.INTERNAL.flagValue
val e2e = messageFlags and MessageFlag.E2E.flagValue == MessageFlag.E2E.flagValue
val received = messageFlags and MessageFlag.RECEIVED.flagValue == MessageFlag.RECEIVED.flagValue
val sent = messageFlags and MessageFlag.SENT.flagValue == MessageFlag.SENT.flagValue
val auto = messageFlags and MessageFlag.AUTO.flagValue == MessageFlag.AUTO.flagValue
return when {
internal -> handleInternalMessage(e2e, received, sent, auto)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 Proton Technologies AG
* Copyright (c) 2022 Proton Technologies AG
*
* This file is part of ProtonMail.
*
@ -212,8 +212,8 @@ object MessageUtils {
}
fun calculateType(flags: Long): Message.MessageType {
val received = flags and MessageFlag.RECEIVED.value == MessageFlag.RECEIVED.value
val sent = flags and MessageFlag.SENT.value == MessageFlag.SENT.value
val received = flags and MessageFlag.RECEIVED.flagValue == MessageFlag.RECEIVED.flagValue
val sent = flags and MessageFlag.SENT.flagValue == MessageFlag.SENT.flagValue
return if (received && sent) {
Message.MessageType.INBOX_AND_SENT
} else if (received) {