Implemented checkCredentials()

This commit is contained in:
dankito 2024-11-30 21:05:59 +01:00
parent 1024346b5f
commit 51d9bdd617
4 changed files with 78 additions and 2 deletions

View File

@ -12,10 +12,14 @@ import net.codinux.invoicing.model.Invoice
import net.codinux.invoicing.pdf.PdfInvoiceData
import net.codinux.invoicing.pdf.PdfInvoiceDataExtractor
import net.codinux.invoicing.reader.EInvoiceReader
import net.codinux.invoicing.util.ExceptionHelper
import net.codinux.log.logger
import org.eclipse.angus.mail.imap.IMAPFolder
import org.eclipse.angus.mail.imap.IMAPMessage
import org.eclipse.angus.mail.util.MailConnectException
import java.io.File
import java.net.ConnectException
import java.net.UnknownHostException
import java.time.Instant
import java.util.*
import java.util.concurrent.Executors
@ -24,7 +28,8 @@ import kotlin.math.max
open class EmailsFetcher(
protected open val eInvoiceReader: EInvoiceReader = EInvoiceReader(),
protected open val pdfInvoiceDataExtractor: PdfInvoiceDataExtractor = PdfInvoiceDataExtractor(),
protected open val coroutineDispatcher: CoroutineDispatcher = Executors.newFixedThreadPool(max(24, Runtime.getRuntime().availableProcessors() * 4)).asCoroutineDispatcher()
protected open val coroutineDispatcher: CoroutineDispatcher = Executors.newFixedThreadPool(max(24, Runtime.getRuntime().availableProcessors() * 4)).asCoroutineDispatcher(),
protected open val exceptionHelper: ExceptionHelper = ExceptionHelper()
) {
protected data class MessagePart(
@ -43,6 +48,38 @@ open class EmailsFetcher(
protected val log by logger()
open fun checkCredentials(account: EmailAccount): CheckCredentialsResult {
try {
val status = connect(account, FetchEmailsOptions(showDebugOutputOnConsole = true))
close(status)
return CheckCredentialsResult.Ok
} catch (e: Throwable) {
log.info(e) { "Could not connect to account '$account'" }
return mapConnectResultError(e)
}
}
protected open fun mapConnectResultError(exception: Throwable): CheckCredentialsResult {
if (exception is AuthenticationFailedException) {
return CheckCredentialsResult.WrongUsername
} else if (exception is MailConnectException) {
val innerInnerException = exceptionHelper.getInnerException(exception, 1)
if (innerInnerException is UnknownHostException) {
return CheckCredentialsResult.InvalidImapServerAddress
} else if (innerInnerException is ConnectException) {
return CheckCredentialsResult.InvalidImapServerPort
}
} else if (exception is MessagingException) { // MessagingException is derived from MailConnectException, so place after MailConnectException
return CheckCredentialsResult.WrongPassword
}
return CheckCredentialsResult.UnknownError // fallback for cases i am not aware of
}
open fun listenForNewEmails(account: EmailAccount, options: ListenForNewMailsOptions) = runBlocking {
try {
val status = connect(account, options)
@ -336,6 +373,8 @@ open class EmailsFetcher(
val properties = mapAccountToJavaMailProperties(account, options)
val session = Session.getInstance(properties)
session.debug = options.showDebugOutputOnConsole
val store = session.getStore("imap")
store.connect(account.serverAddress, account.username, account.password)
@ -345,7 +384,7 @@ open class EmailsFetcher(
return FetchEmailsStatus(account, store, folder, options)
}
protected open fun mapAccountToJavaMailProperties(account: EmailAccount, options: FetchEmailsOptions) = Properties().apply {
protected open fun mapAccountToJavaMailProperties(account: EmailAccount, options: FetchEmailsOptions = FetchEmailsOptions()) = Properties().apply {
// the documentation of all properties can be found here: https://javaee.github.io/javamail/docs/api/com/sun/mail/imap/package-summary.html
put("mail.store.protocol", "imap")

View File

@ -29,6 +29,8 @@ open class FetchEmailsOptions(
val emailFolderName: String = "INBOX",
val connectTimeoutSeconds: Int = 5,
val showDebugOutputOnConsole: Boolean = false,
val onError: ((FetchEmailError) -> Unit)? = null,
val onEmailReceived: ((Email) -> Unit)? = null
) {

View File

@ -0,0 +1,18 @@
package net.codinux.invoicing.email.model
enum class CheckCredentialsResult {
Ok,
WrongUsername,
WrongPassword,
InvalidImapServerAddress,
InvalidImapServerPort,
UnknownError
}

View File

@ -0,0 +1,17 @@
package net.codinux.invoicing.util
open class ExceptionHelper {
open fun getInnerException(exception: Exception, maxDepth: Int = 3): Exception {
var innerException = exception
var depth = 0
while(innerException.cause is Exception && depth < maxDepth) {
innerException = innerException.cause as Exception
depth++
}
return innerException
}
}