Skip to content

Commit

Permalink
issue #1223 a port of Mime.processDecoded() (#1267)
Browse files Browse the repository at this point in the history
* issue #1223 a port of Mime.processDecoded()

* Fixed JUnit tests that relate to Android side.| #1267

* Fixed MsgBlockFactory.| #1267

* Fixes after code review

* Fix javadoc comment

Co-authored-by: Ivan Pizhenko <[email protected]>
Co-authored-by: DenBond7 <[email protected]>
  • Loading branch information
3 people authored May 31, 2021
1 parent e336f06 commit 8266be3
Show file tree
Hide file tree
Showing 25 changed files with 1,549 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact [email protected]
* Contributors:
* Ivan Pizhenko
*/

package com.flowcrypt.email.api.retrofit.response.model.node

import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.Expose

data class EncryptedAttMsgBlock(@Expose override val content: String?,
@Expose val attMeta: AttMeta) : MsgBlock {

var fileUri: Uri? = null

@Expose
override val complete: Boolean = true
@Expose
override val type: MsgBlock.Type = MsgBlock.Type.ENCRYPTED_ATT

constructor(source: Parcel) : this(
source.readString(),
source.readParcelable<AttMeta>(AttMeta::class.java.classLoader)!!
) {
fileUri = source.readParcelable<Uri>(Uri::class.java.classLoader)
}

override fun describeContents(): Int {
return 0
}

override fun writeToParcel(dest: Parcel, flags: Int) =
with(dest) {
writeParcelable(type, flags)
writeString(content)
writeParcelable(attMeta, flags)
writeParcelable(fileUri, flags)
}

companion object {
@JvmField
val CREATOR: Parcelable.Creator<EncryptedAttMsgBlock> = object : Parcelable.Creator<EncryptedAttMsgBlock> {
override fun createFromParcel(source: Parcel): EncryptedAttMsgBlock {
source.readParcelable<MsgBlock.Type>(MsgBlock.Type::class.java.classLoader)
return EncryptedAttMsgBlock(source)
}

override fun newArray(size: Int): Array<EncryptedAttMsgBlock?> = arrayOfNulls(size)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ data class GenericMsgBlock(
@Expose override val complete: Boolean
) : MsgBlock {

constructor(source: Parcel, type: MsgBlock.Type) : this(
constructor(type: MsgBlock.Type, source: Parcel) : this(
type,
source.readString(),
1 == source.readInt()
Expand All @@ -38,7 +38,7 @@ data class GenericMsgBlock(
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeParcelable(type, flags)
writeString(content)
writeInt((if (complete) 1 else 0))
writeInt(if (complete) 1 else 0)
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package com.flowcrypt.email.api.retrofit.response.model.node
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import java.lang.IllegalArgumentException

interface MsgBlock : Parcelable {
val type: Type
Expand Down Expand Up @@ -69,7 +70,13 @@ interface MsgBlock : Parcelable {
CERTIFICATE,

@SerializedName("signature")
SIGNATURE;
SIGNATURE,

@SerializedName("signedText")
SIGNED_TEXT,

@SerializedName("signedHtml")
SIGNED_HTML;

override fun describeContents(): Int {
return 0
Expand All @@ -87,12 +94,25 @@ interface MsgBlock : Parcelable {
}

val keyBlockTypes = setOf(PUBLIC_KEY, PRIVATE_KEY)

val replaceableBlockTypes = setOf(
PUBLIC_KEY, PRIVATE_KEY, SIGNED_MSG, ENCRYPTED_MSG, ENCRYPTED_MSG_LINK
)

val wellKnownBlockTypes = setOf(
PUBLIC_KEY, PRIVATE_KEY, SIGNED_MSG, ENCRYPTED_MSG
)

val signedBlocks = setOf(SIGNED_TEXT, SIGNED_HTML, SIGNED_MSG)

fun ofSerializedName(serializedName: String): Type {
for (v in values()) {
val field = Type::class.java.getField(v.name)
val annotation = field.getAnnotation(SerializedName::class.java)
if (annotation != null && annotation.value == serializedName) return v
}
throw IllegalArgumentException("Unknown block type serialized name '$serializedName'")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ object MsgBlockFactory {
val supportedMsgBlockTypes = listOf(
MsgBlock.Type.PUBLIC_KEY,
MsgBlock.Type.DECRYPT_ERROR,
MsgBlock.Type.DECRYPTED_ATT
MsgBlock.Type.DECRYPTED_ATT,
MsgBlock.Type.ENCRYPTED_ATT,
MsgBlock.Type.SIGNED_HTML,
MsgBlock.Type.SIGNED_TEXT
)

@JvmStatic
Expand All @@ -21,24 +24,41 @@ object MsgBlockFactory {
MsgBlock.Type.PUBLIC_KEY -> PublicKeyMsgBlock(source)
MsgBlock.Type.DECRYPT_ERROR -> DecryptErrorMsgBlock(source)
MsgBlock.Type.DECRYPTED_ATT -> DecryptedAttMsgBlock(source)
else -> GenericMsgBlock(source, type)
MsgBlock.Type.ENCRYPTED_ATT -> EncryptedAttMsgBlock(source)
MsgBlock.Type.SIGNED_TEXT, MsgBlock.Type.SIGNED_HTML, MsgBlock.Type.SIGNED_MSG -> {
SignedBlock(source)
}
else -> GenericMsgBlock(type, source)
}
}

@JvmStatic
fun fromContent(type: MsgBlock.Type, content: String, missingEnd: Boolean = false): MsgBlock {
fun fromContent(
type: MsgBlock.Type,
content: String?,
missingEnd: Boolean = false,
signature: String? = null
): MsgBlock {
val complete = !missingEnd
return when (type) {
MsgBlock.Type.PUBLIC_KEY -> PublicKeyMsgBlock(content, complete, null)
MsgBlock.Type.DECRYPT_ERROR -> DecryptErrorMsgBlock(content, complete, null)
MsgBlock.Type.SIGNED_TEXT -> {
SignedBlock(SignedBlock.Type.SIGNED_TEXT, content, complete, signature)
}
MsgBlock.Type.SIGNED_HTML -> {
SignedBlock(SignedBlock.Type.SIGNED_HTML, content, complete, signature)
}
else -> GenericMsgBlock(type, content, complete)
}
}

@JvmStatic
fun fromAttachment(type: MsgBlock.Type, content: String, attMeta: AttMeta): MsgBlock {
fun fromAttachment(type: MsgBlock.Type, content: String?, attMeta: AttMeta): MsgBlock {
return when (type) {
MsgBlock.Type.DECRYPTED_ATT -> DecryptedAttMsgBlock(content, true, attMeta, null)
MsgBlock.Type.ENCRYPTED_ATT -> EncryptedAttMsgBlock(content, attMeta)
MsgBlock.Type.PLAIN_ATT -> PlainAttMsgBlock(content, attMeta)
else ->
throw IllegalArgumentException("Can't create block of type ${type.name} from attachment")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact [email protected]
* Contributors:
* Ivan Pizhenko
*/

package com.flowcrypt.email.api.retrofit.response.model.node

import android.net.Uri
import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.Expose

data class PlainAttMsgBlock(
@Expose override val content: String?,
@Expose val attMeta: AttMeta
) : MsgBlock {

var fileUri: Uri? = null

@Expose
override val complete: Boolean = true

@Expose
override val type: MsgBlock.Type = MsgBlock.Type.PLAIN_ATT

constructor(source: Parcel) : this(
source.readString(),
source.readParcelable<AttMeta>(AttMeta::class.java.classLoader)!!
) {
fileUri = source.readParcelable(Uri::class.java.classLoader)
}

override fun describeContents(): Int {
return 0
}

override fun writeToParcel(dest: Parcel, flags: Int) =
with(dest) {
writeParcelable(type, flags)
writeString(content)
writeParcelable(attMeta, flags)
writeParcelable(fileUri, flags)
}

companion object {
@JvmField
val CREATOR: Parcelable.Creator<PlainAttMsgBlock> = object : Parcelable.Creator<PlainAttMsgBlock> {
override fun createFromParcel(source: Parcel): PlainAttMsgBlock {
source.readParcelable<MsgBlock.Type>(MsgBlock.Type::class.java.classLoader)
return PlainAttMsgBlock(source)
}

override fun newArray(size: Int): Array<PlainAttMsgBlock?> = arrayOfNulls(size)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact [email protected]
* Contributors:
* Ivan Pizhenko
*/

package com.flowcrypt.email.api.retrofit.response.model.node

import android.os.Parcel
import android.os.Parcelable
import com.google.gson.annotations.Expose

/**
* Message block which represents content with a signature.
*/
data class SignedBlock(
@Expose val signedType: Type,
@Expose override val content: String?,
@Expose override val complete: Boolean,
@Expose val signature: String?
) : MsgBlock {

@Expose
override val type: MsgBlock.Type = when (signedType) {
Type.SIGNED_MSG -> MsgBlock.Type.SIGNED_MSG
Type.SIGNED_TEXT -> MsgBlock.Type.SIGNED_TEXT
Type.SIGNED_HTML -> MsgBlock.Type.SIGNED_HTML
}

constructor(source: Parcel) : this(
source.readParcelable<Type>(Type::class.java.classLoader)
?: throw IllegalArgumentException("Undefined type"),
source.readString(),
1 == source.readInt(),
source.readString()
)

override fun describeContents() = 0

override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeParcelable(type, flags)
writeParcelable(signedType, flags)
writeString(content)
writeInt(if (complete) 1 else 0)
writeString(signature)
}

enum class Type : Parcelable {
SIGNED_MSG,
SIGNED_TEXT,
SIGNED_HTML;

override fun describeContents(): Int {
return 0
}

override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeInt(ordinal)
}

companion object {
@JvmField
val CREATOR: Parcelable.Creator<Type> = object : Parcelable.Creator<Type> {
override fun createFromParcel(source: Parcel): Type = values()[source.readInt()]
override fun newArray(size: Int): Array<Type?> = arrayOfNulls(size)
}
}
}

companion object {
@JvmField
val CREATOR: Parcelable.Creator<MsgBlock> = object : Parcelable.Creator<MsgBlock> {
override fun createFromParcel(source: Parcel): MsgBlock {
val partType = source.readParcelable<MsgBlock.Type>(MsgBlock.Type::class.java.classLoader)!!
return MsgBlockFactory.fromParcel(partType, source)
}

override fun newArray(size: Int): Array<MsgBlock?> = arrayOfNulls(size)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact [email protected]
* Contributors:
* Ivan Pizhenko
*/

package com.flowcrypt.email.extensions.javax.mail

import javax.mail.BodyPart
import javax.mail.MessagingException

fun BodyPart.hasFileName(): Boolean {
return try {
this.fileName != null
} catch (ex: MessagingException) {
false
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact [email protected]
* Contributors:
* Ivan Pizhenko
*/

package com.flowcrypt.email.extensions.javax.mail

import java.util.Locale
import javax.mail.Part

fun Part.isInline(): Boolean {
return (this.disposition?.toLowerCase(Locale.getDefault()) ?: "") == Part.INLINE
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,11 @@ fun String.countOfMatchesZeroOneOrMore(needle: String): Int {
}
return result
}

fun String.normalizeEol(): String {
return this.replace("\r\n", "\n").replace('\r', '\n')
}

fun String.removeUtf8Bom(): String {
return if (this.startsWith("\uFEFF")) this.substring(1) else this
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,19 @@ object PgpArmor {
}

private val lineSeparatorBytes = Strings.lineSeparator().toByteArray()

@JvmStatic
fun clip(text: String): String? {
val unknown = ARMOR_HEADER_DICT[MsgBlock.Type.UNKNOWN]!!
if (text.contains(unknown.begin) && text.contains(unknown.end)) {
val match = blockRegex.find(text)
if (match != null) return text.substring(match.range)
}
return null
}

private val blockRegex = Regex(
"(-----BEGIN PGP (MESSAGE|SIGNED MESSAGE|SIGNATURE|PUBLIC KEY BLOCK)-----[\\s\\S]+" +
"-----END PGP (MESSAGE|SIGNATURE|PUBLIC KEY BLOCK)-----)"
)
}
Loading

0 comments on commit 8266be3

Please sign in to comment.