Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com
* 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 human@flowcrypt.com
* 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 human@flowcrypt.com
* 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 human@flowcrypt.com
* 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 human@flowcrypt.com
* 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