commit 32db64f848835201a32bfa4570434782a80c0a8c
parent 0811cefca0af60456f082f3fcbd49734bc4e1d7a
Author: MTRNord <mtrnord1@gmail.com>
Date: Wed, 22 Feb 2023 12:20:19 +0100
add thunderbird autoconfig parsing, add basic login_view and login, add basic imap state, add color_eyre
Diffstat:
6 files changed, 1012 insertions(+), 186 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3,6 +3,21 @@
version = 3
[[package]]
+name = "Inflector"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
+
+[[package]]
+name = "addr2line"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
name = "adler"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -18,13 +33,10 @@ dependencies = [
]
[[package]]
-name = "android_system_properties"
-version = "0.1.5"
+name = "aliasable"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
+checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
[[package]]
name = "anyhow"
@@ -33,12 +45,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
[[package]]
-name = "arrayvec"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
-
-[[package]]
name = "ascii-canvas"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,12 +82,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
+name = "backtrace"
+version = "0.3.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
+name = "base64"
+version = "0.21.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
+
+[[package]]
name = "bindgen"
version = "0.63.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -234,7 +261,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
- "nom 7.1.3",
+ "nom",
]
[[package]]
@@ -258,13 +285,10 @@ version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
dependencies = [
- "iana-time-zone",
"js-sys",
"num-integer",
"num-traits",
- "time 0.1.45",
"wasm-bindgen",
- "winapi",
]
[[package]]
@@ -279,13 +303,30 @@ dependencies = [
]
[[package]]
-name = "codespan-reporting"
-version = "0.11.1"
+name = "color-eyre"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
+dependencies = [
+ "backtrace",
+ "color-spantrace",
+ "eyre",
+ "indenter",
+ "once_cell",
+ "owo-colors",
+ "tracing-error",
+]
+
+[[package]]
+name = "color-spantrace"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+checksum = "1ba75b3d9449ecdccb27ecbc479fdc0b87fa2dd43d2f8298f9bf0e59aacc8dce"
dependencies = [
- "termcolor",
- "unicode-width",
+ "once_cell",
+ "owo-colors",
+ "tracing-core",
+ "tracing-error",
]
[[package]]
@@ -295,6 +336,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
name = "core-foundation-sys"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -359,50 +410,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
-name = "cxx"
-version = "1.0.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62"
-dependencies = [
- "cc",
- "cxxbridge-flags",
- "cxxbridge-macro",
- "link-cplusplus",
-]
-
-[[package]]
-name = "cxx-build"
-version = "1.0.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690"
-dependencies = [
- "cc",
- "codespan-reporting",
- "once_cell",
- "proc-macro2",
- "quote",
- "scratch",
- "syn",
-]
-
-[[package]]
-name = "cxxbridge-flags"
-version = "1.0.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf"
-
-[[package]]
-name = "cxxbridge-macro"
-version = "1.0.91"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
name = "dbus"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -471,6 +478,15 @@ dependencies = [
]
[[package]]
+name = "encoding_rs"
+version = "0.8.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
name = "exr"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -487,6 +503,16 @@ dependencies = [
]
[[package]]
+name = "eyre"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb"
+dependencies = [
+ "indenter",
+ "once_cell",
+]
+
+[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -531,7 +557,22 @@ dependencies = [
"futures-sink",
"nanorand",
"pin-project",
- "spin",
+ "spin 0.9.5",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+dependencies = [
+ "percent-encoding",
]
[[package]]
@@ -736,6 +777,12 @@ dependencies = [
]
[[package]]
+name = "gimli"
+version = "0.27.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
+
+[[package]]
name = "gio"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -951,6 +998,25 @@ dependencies = [
]
[[package]]
+name = "h2"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
+dependencies = [
+ "bytes",
+ "fnv",
+ "futures-core",
+ "futures-sink",
+ "futures-util",
+ "http",
+ "indexmap",
+ "slab",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
+[[package]]
name = "half"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -999,27 +1065,74 @@ dependencies = [
]
[[package]]
-name = "iana-time-zone"
-version = "0.1.53"
+name = "http"
+version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "wasm-bindgen",
- "winapi",
+ "bytes",
+ "fnv",
+ "itoa",
]
[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.1"
+name = "http-body"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
+dependencies = [
+ "bytes",
+ "http",
+ "pin-project-lite",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "httpdate"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
+
+[[package]]
+name = "hyper"
+version = "0.14.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c"
+dependencies = [
+ "bytes",
+ "futures-channel",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "httparse",
+ "httpdate",
+ "itoa",
+ "pin-project-lite",
+ "socket2",
+ "tokio",
+ "tower-service",
+ "tracing",
+ "want",
+]
+
+[[package]]
+name = "hyper-rustls"
+version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c"
dependencies = [
- "cxx",
- "cxx-build",
+ "http",
+ "hyper",
+ "rustls",
+ "tokio",
+ "tokio-rustls",
]
[[package]]
@@ -1053,29 +1166,36 @@ dependencies = [
[[package]]
name = "imap"
-version = "2.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c617c55def8c42129e0dd503f11d7ee39d73f5c7e01eff55768b3879ff1d107d"
+version = "3.0.0-alpha.10"
+source = "git+https://github.com/erooster-mail/rust-imap.git?branch=MTRNord/clippy#38abe294b7332a4fde7095b52e838f3a55ebf1da"
dependencies = [
- "base64",
+ "base64 0.21.0",
"bufstream",
"chrono",
"imap-proto",
"lazy_static",
- "nom 5.1.2",
+ "nom",
+ "ouroboros",
"regex",
+ "rustls-connector",
]
[[package]]
name = "imap-proto"
-version = "0.10.2"
+version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "16a6def1d5ac8975d70b3fd101d57953fe3278ef2ee5d7816cba54b1d1dfc22f"
+checksum = "f73b1b63179418b20aa81002d616c5f21b4ba257da9bca6989ea64dc573933e0"
dependencies = [
- "nom 5.1.2",
+ "nom",
]
[[package]]
+name = "indenter"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
+
+[[package]]
name = "indexmap"
version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1095,6 +1215,12 @@ dependencies = [
]
[[package]]
+name = "ipnet"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146"
+
+[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1104,6 +1230,12 @@ dependencies = [
]
[[package]]
+name = "itoa"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+
+[[package]]
name = "jpeg-decoder"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1168,19 +1300,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
-name = "lexical-core"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe"
-dependencies = [
- "arrayvec",
- "bitflags",
- "cfg-if",
- "ryu",
- "static_assertions",
-]
-
-[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1206,15 +1325,6 @@ dependencies = [
]
[[package]]
-name = "link-cplusplus"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
-dependencies = [
- "cc",
-]
-
-[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1243,21 +1353,27 @@ dependencies = [
"dirs-next",
"objc-foundation",
"objc_id",
- "time 0.3.19",
+ "time",
]
[[package]]
name = "mail-client"
version = "0.1.0"
dependencies = [
+ "color-eyre",
"glib-build-tools",
"gtk4",
"imap",
"notify-rust",
+ "once_cell",
+ "quick-xml 0.27.1",
"relm4",
"relm4-components",
"relm4-macros",
+ "reqwest",
+ "rustls-connector",
"sequoia-openpgp",
+ "serde",
"tokio",
"tracing",
"tracing-subscriber",
@@ -1303,6 +1419,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ac78937f19a0c7807e45a931eac41f766f210173ec664ec046d58e6d388a5cb"
[[package]]
+name = "mime"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
+
+[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1372,17 +1494,6 @@ checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "nom"
-version = "5.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
-dependencies = [
- "lexical-core",
- "memchr",
- "version_check",
-]
-
-[[package]]
-name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
@@ -1494,18 +1605,62 @@ dependencies = [
]
[[package]]
+name = "object"
+version = "0.30.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
+name = "openssl-probe"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
+
+[[package]]
+name = "ouroboros"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db"
+dependencies = [
+ "aliasable",
+ "ouroboros_macro",
+]
+
+[[package]]
+name = "ouroboros_macro"
+version = "0.15.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7"
+dependencies = [
+ "Inflector",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
+name = "owo-colors"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
+
+[[package]]
name = "pango"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1561,6 +1716,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
+name = "percent-encoding"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+
+[[package]]
name = "pest"
version = "2.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1704,6 +1865,16 @@ dependencies = [
]
[[package]]
+name = "quick-xml"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffc053f057dd768a56f62cd7e434c42c831d296968997e9ac1f76ea7c2d14c41"
+dependencies = [
+ "memchr",
+ "serde",
+]
+
+[[package]]
name = "quote"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1861,6 +2032,66 @@ dependencies = [
]
[[package]]
+name = "reqwest"
+version = "0.11.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9"
+dependencies = [
+ "base64 0.21.0",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "hyper",
+ "hyper-rustls",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "rustls",
+ "rustls-pemfile",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+ "tokio-rustls",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "webpki-roots",
+ "winreg",
+]
+
+[[package]]
+name = "ring"
+version = "0.16.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
+dependencies = [
+ "cc",
+ "libc",
+ "once_cell",
+ "spin 0.5.2",
+ "untrusted",
+ "web-sys",
+ "winapi",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
+
+[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1876,6 +2107,51 @@ dependencies = [
]
[[package]]
+name = "rustls"
+version = "0.20.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
+dependencies = [
+ "log",
+ "ring",
+ "sct",
+ "webpki",
+]
+
+[[package]]
+name = "rustls-connector"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c6a18f8d10f71bce9bca6eaeb80429460e652f3bcf0381f0c5f8954abf7b3b8"
+dependencies = [
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "webpki",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b"
+dependencies = [
+ "base64 0.21.0",
+]
+
+[[package]]
name = "rustversion"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1888,6 +2164,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
[[package]]
+name = "schannel"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
+dependencies = [
+ "windows-sys 0.42.0",
+]
+
+[[package]]
name = "scoped_threadpool"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1900,10 +2185,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
-name = "scratch"
-version = "1.0.3"
+name = "sct"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "security-framework"
+version = "2.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
+checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
[[package]]
name = "semver"
@@ -1930,7 +2242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70af2f594bf5261eb87be5060db1e40d6445686d2bb3ec41c014cf53701130a2"
dependencies = [
"anyhow",
- "base64",
+ "base64 0.13.1",
"buffered-reader",
"bzip2",
"chrono",
@@ -1957,6 +2269,43 @@ name = "serde"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.152"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.93"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "serde_urlencoded"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
+dependencies = [
+ "form_urlencoded",
+ "itoa",
+ "ryu",
+ "serde",
+]
[[package]]
name = "sha1collisiondetection"
@@ -2031,6 +2380,12 @@ dependencies = [
[[package]]
name = "spin"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
+
+[[package]]
+name = "spin"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc"
@@ -2039,12 +2394,6 @@ dependencies = [
]
[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
-[[package]]
name = "string_cache"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2108,7 +2457,7 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c58de036c4d2e20717024de2a3c4bf56c301f07b21bc8ef9b57189fce06f1f3b"
dependencies = [
- "quick-xml",
+ "quick-xml 0.23.1",
"strum",
"windows",
]
@@ -2139,15 +2488,6 @@ dependencies = [
]
[[package]]
-name = "termcolor"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
-dependencies = [
- "winapi-util",
-]
-
-[[package]]
name = "thiserror"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2199,17 +2539,6 @@ dependencies = [
[[package]]
name = "time"
-version = "0.1.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
-dependencies = [
- "libc",
- "wasi 0.10.0+wasi-snapshot-preview1",
- "winapi",
-]
-
-[[package]]
-name = "time"
version = "0.3.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53250a3b3fed8ff8fd988587d8925d26a83ac3845d9e03b220b37f34c2b8d6c2"
@@ -2280,6 +2609,31 @@ dependencies = [
]
[[package]]
+name = "tokio-rustls"
+version = "0.23.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
+dependencies = [
+ "rustls",
+ "tokio",
+ "webpki",
+]
+
+[[package]]
+name = "tokio-util"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
+dependencies = [
+ "bytes",
+ "futures-core",
+ "futures-sink",
+ "pin-project-lite",
+ "tokio",
+ "tracing",
+]
+
+[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2306,6 +2660,12 @@ dependencies = [
]
[[package]]
+name = "tower-service"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
+
+[[package]]
name = "tracing"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2339,6 +2699,16 @@ dependencies = [
]
[[package]]
+name = "tracing-error"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
+dependencies = [
+ "tracing",
+ "tracing-subscriber",
+]
+
+[[package]]
name = "tracing-log"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2384,6 +2754,12 @@ dependencies = [
]
[[package]]
+name = "try-lock"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
+
+[[package]]
name = "typenum"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2423,18 +2799,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
[[package]]
-name = "unicode-width"
-version = "0.1.10"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
-
-[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
+name = "untrusted"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
+
+[[package]]
+name = "url"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2459,16 +2846,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
-name = "wasi"
-version = "0.9.0+wasi-snapshot-preview1"
+name = "want"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
+checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
+dependencies = [
+ "log",
+ "try-lock",
+]
[[package]]
name = "wasi"
-version = "0.10.0+wasi-snapshot-preview1"
+version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
@@ -2502,6 +2893,18 @@ dependencies = [
]
[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
name = "wasm-bindgen-macro"
version = "0.2.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2531,6 +2934,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d"
[[package]]
+name = "web-sys"
+version = "0.3.61"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webpki"
+version = "0.22.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
+dependencies = [
+ "ring",
+ "untrusted",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "0.22.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
+dependencies = [
+ "webpki",
+]
+
+[[package]]
name = "weezl"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2553,15 +2985,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
-name = "winapi-util"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
-dependencies = [
- "winapi",
-]
-
-[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2692,6 +3115,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
[[package]]
+name = "winreg"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "xxhash-rust"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -15,10 +15,20 @@ tracing = "0.1.37"
tokio = { version = "1.25.0", features = ["full"] }
sequoia-openpgp = "1.13.0"
notify-rust = { version = "4.7.1", default-features = false, features = ["d", "images"] }
+# Needs to be in sync with imap crate version
+rustls-connector = { version = "0.16.1"}
+color-eyre = "0.6.2"
+reqwest = { version = "0.11.14", features = ["rustls", "rustls-tls"], default-features = false }
+quick-xml = { version = "0.27.1", features = ["serde", "serialize"] }
+serde = { version = "1.0.152", features = ["derive"] }
+once_cell = "1.17.1"
[dependencies.imap]
-version = "2.4.1"
+version = "3.0.0-alpha.10"
+git = "https://github.com/erooster-mail/rust-imap.git"
+branch = "MTRNord/clippy"
default-features = false
+features = ["rustls-tls"]
[build-dependencies]
glib-build-tools = "0.17"
diff --git a/build-aux/de.nordgedanken.Email.Devel.yaml b/build-aux/de.nordgedanken.Email.Devel.yaml
@@ -12,8 +12,7 @@ finish-args:
- --device=dri
- --share=network
- --socket=session-bus
- - --env=GTK_DEBUG=interactive
- - --env=RUST_LOG=mail_client=debug
+ #- --env=GTK_DEBUG=interactive
- --env=G_MESSAGES_DEBUG=none
- --env=RUST_BACKTRACE=1
build-options:
@@ -33,4 +32,4 @@ modules:
- -Dprofile=development
sources:
- type: dir
- path: ../
-\ No newline at end of file
+ path: ../
diff --git a/src/imap_state.rs b/src/imap_state.rs
@@ -0,0 +1,18 @@
+use imap::Session;
+use relm4::SharedState;
+use rustls_connector::TlsStream;
+use std::net::TcpStream;
+
+pub enum ImapSession {
+ TLS(Session<TlsStream<TcpStream>>),
+ TCP(Session<TcpStream>),
+ None,
+}
+
+impl Default for ImapSession {
+ fn default() -> Self {
+ Self::None
+ }
+}
+
+pub static IMAP_SESSION: SharedState<ImapSession> = SharedState::new();
diff --git a/src/login_view.rs b/src/login_view.rs
@@ -0,0 +1,323 @@
+use crate::imap_state::ImapSession;
+use crate::imap_state::IMAP_SESSION;
+use crate::AppMsg;
+use color_eyre::{eyre::bail, Result};
+use gtk::prelude::*;
+use once_cell::sync::Lazy;
+use quick_xml::de::from_str;
+use relm4::component::AsyncComponent;
+use relm4::component::AsyncComponentParts;
+use relm4::loading_widgets::LoadingWidgets;
+use relm4::prelude::*;
+use relm4::AsyncComponentSender;
+use relm4::{view, Worker, WorkerController};
+use reqwest::StatusCode;
+use serde::Deserialize;
+use std::convert::identity;
+use tokio::runtime::Runtime;
+
+static RUNTIME: Lazy<Runtime> = Lazy::new(|| Runtime::new().unwrap());
+
+pub struct LoginView {
+ // stores entered values
+ email: gtk::EntryBuffer,
+ password: gtk::PasswordEntryBuffer,
+ login_worker: WorkerController<AsyncLoginHandler>,
+}
+
+#[derive(Debug)]
+pub enum LoginMsg {
+ Finished,
+ StartLogin,
+}
+
+#[relm4::component(async, pub)]
+impl AsyncComponent for LoginView {
+ type Init = ();
+ type Input = LoginMsg;
+ type Output = AppMsg;
+ type CommandOutput = LoginMsg;
+
+ view! {
+ gtk::Box {
+ set_orientation: gtk::Orientation::Vertical,
+ set_halign: gtk::Align::Fill,
+ set_valign: gtk::Align::Fill,
+ set_hexpand: true,
+ set_vexpand: true,
+
+ gtk::Box {
+ set_orientation: gtk::Orientation::Vertical,
+ set_margin_all: 8,
+ set_spacing: 8,
+ set_halign: gtk::Align::Center,
+ set_valign: gtk::Align::Center,
+
+ gtk::Entry {
+ set_tooltip_text: Some("Username"),
+ set_buffer: &model.email,
+ },
+ gtk::Entry {
+ set_tooltip_text: Some("Password"),
+ set_buffer: &model.password,
+ set_visibility: false,
+ },
+ gtk::Button {
+ set_label: "Login",
+ connect_clicked => LoginMsg::StartLogin,
+ },
+ }
+ }
+ }
+
+ fn init_loading_widgets(root: &mut Self::Root) -> Option<LoadingWidgets> {
+ view! {
+ #[local_ref]
+ root {
+ // This will be removed automatically by
+ // LoadingWidgets when the full view has loaded
+ #[name(spinner)]
+ gtk::Spinner {
+ start: (),
+ set_halign: gtk::Align::Center,
+ }
+ }
+ }
+ Some(LoadingWidgets::new(root, spinner))
+ }
+
+ async fn init(
+ _: Self::Init,
+ root: Self::Root,
+ sender: AsyncComponentSender<Self>,
+ ) -> AsyncComponentParts<Self> {
+ // TODO: Check if logged in and exit early if needed
+ let model = LoginView {
+ email: gtk::EntryBuffer::new(None::<String>),
+ password: gtk::PasswordEntryBuffer::new(),
+ login_worker: AsyncLoginHandler::builder()
+ .detach_worker(())
+ .forward(sender.input_sender(), identity),
+ };
+
+ // Insert the code generation of the view! macro here
+ let widgets = view_output!();
+
+ AsyncComponentParts { model, widgets }
+ }
+
+ async fn update(
+ &mut self,
+ msg: Self::Input,
+ sender: AsyncComponentSender<Self>,
+ _root: &Self::Root,
+ ) {
+ tracing::info!("Got msg1: {:?}", msg);
+ match msg {
+ LoginMsg::StartLogin => {
+ tracing::info!("Starting login");
+ self.login_worker
+ .sender()
+ .send(AsyncLoginHandlerMsg::StartLogin(
+ self.email.text().to_string(),
+ self.password.text().to_string(),
+ ))
+ .unwrap();
+ }
+ LoginMsg::Finished => {
+ tracing::info!("Login finished");
+ sender.output(AppMsg::ToMainView).unwrap();
+ }
+ _ => {}
+ }
+ }
+}
+
+#[derive(Debug)]
+enum AsyncLoginHandlerMsg {
+ StartLogin(String, String),
+}
+
+struct AsyncLoginHandler;
+
+impl Worker for AsyncLoginHandler {
+ type Init = ();
+ type Input = AsyncLoginHandlerMsg;
+ type Output = LoginMsg;
+
+ fn init(_init: Self::Init, _sender: ComponentSender<Self>) -> Self {
+ Self
+ }
+
+ fn update(&mut self, msg: AsyncLoginHandlerMsg, sender: ComponentSender<Self>) {
+ tracing::info!("Got msg: {:?}", msg);
+ match msg {
+ AsyncLoginHandlerMsg::StartLogin(email, password) => {
+ RUNTIME.block_on(async move {
+ tracing::info!("Starting login inner");
+ let server_url = email.split('@').last().unwrap().to_string();
+ let config = get_autoconfig(server_url, email.clone()).await;
+ match config {
+ Ok(config) => {
+ tracing::info!("Got config: {:?}", config);
+
+ let incoming_server = config
+ .email_provider
+ .incoming_servers
+ .iter()
+ .find(|d| d.socket_type == "SSL")
+ .unwrap();
+
+ let client = imap::ClientBuilder::new(
+ incoming_server.hostname.clone(),
+ incoming_server.port.parse::<u16>().unwrap(),
+ )
+ .rustls()
+ .unwrap();
+
+ // TODO: Use OAUth2 if https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat#OAuth2 is set
+
+ let auth_data = match incoming_server.username.as_str() {
+ "%EMAILADDRESS%" => PlainAuth { email, password },
+ "%EMAILLOCALPART%" => {
+ let email = email.split('@').next().unwrap().to_string();
+ PlainAuth { email, password }
+ }
+ "%EMAILDOMAIN%" => {
+ let email = email.split('@').last().unwrap().to_string();
+ PlainAuth { email, password }
+ }
+ _ => {
+ tracing::error!("Username type not supported");
+ return;
+ }
+ };
+
+ // the client we have here is unauthenticated.
+ // to do anything useful with the e-mails, we need to log in
+ // FIXME: Use correct authentication method
+ let imap_session = client
+ .authenticate("PLAIN", &auth_data)
+ .map_err(|e| e.0)
+ .unwrap();
+
+ *IMAP_SESSION.write() = ImapSession::TLS(imap_session);
+ sender.output(LoginMsg::Finished).unwrap();
+ }
+ Err(e) => {
+ tracing::warn!("Unable to get config: {:?}", e);
+ }
+ }
+ });
+ }
+ };
+ }
+}
+
+struct PlainAuth {
+ email: String,
+ password: String,
+}
+
+impl imap::Authenticator for PlainAuth {
+ type Response = String;
+ fn process(&self, _: &[u8]) -> Self::Response {
+ format!("\0{}\0{}", self.email, self.password)
+ }
+}
+
+async fn get_autoconfig(server_url: String, email: String) -> Result<AutoconfigXML> {
+ // First check subdomain with email
+ // TODO: Parse xml
+ let resp = reqwest::get(format!(
+ "https://autoconfig.{server_url}/mail/config-v1.1.xml?emailaddress={email}"
+ ))
+ .await;
+
+ match resp {
+ Ok(resp) => {
+ if resp.status() != StatusCode::OK {
+ tracing::info!("Not found. Trying well-known");
+ return get_autoconfig_wellknown(server_url).await;
+ }
+
+ let xml_text = resp.text().await?;
+ let parsed_xml: AutoconfigXML = from_str(&xml_text)?;
+
+ Ok(parsed_xml)
+ }
+ Err(_) => {
+ tracing::info!("Not found. Trying well-known");
+ get_autoconfig_wellknown(server_url).await
+ }
+ }
+}
+
+async fn get_autoconfig_wellknown(server_url: String) -> Result<AutoconfigXML> {
+ let resp = reqwest::get(format!(
+ "https://{server_url}/.well-known/autoconfig/mail/config-v1.1.xml"
+ ))
+ .await?;
+
+ if resp.status() != StatusCode::OK {
+ // TODO: Check DNS
+ bail!("Unable to find server autoconfig");
+ }
+
+ let xml_text = resp.text().await?;
+ let parsed_xml: AutoconfigXML = from_str(&xml_text)?;
+ Ok(parsed_xml)
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+struct AutoconfigXML {
+ #[serde(rename = "@version")]
+ version: String,
+ email_provider: EmailProviderXML,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+struct EmailProviderXML {
+ #[serde(rename = "@id")]
+ id: String,
+ #[serde(rename = "domain", default)]
+ domains: Vec<String>,
+ display_name: String,
+ display_short_name: String,
+ documentation: Option<DocumentationXML>,
+ #[serde(rename = "incomingServer", default)]
+ incoming_servers: Vec<IncomingServerXML>,
+ #[serde(rename = "outgoingServer", default)]
+ outgoing_servers: Vec<OutgoingServerXML>,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct DocumentationXML {
+ url: String,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+struct IncomingServerXML {
+ #[serde(rename = "@type", default)]
+ servertype: String,
+ hostname: String,
+ port: String,
+ socket_type: String,
+ authentication: String,
+ username: String,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(rename_all = "camelCase")]
+struct OutgoingServerXML {
+ #[serde(rename = "@type", default)]
+ servertype: String,
+ hostname: String,
+ port: String,
+ socket_type: String,
+ authentication: String,
+ username: String,
+}
diff --git a/src/main.rs b/src/main.rs
@@ -1,5 +1,10 @@
+use color_eyre::Result;
use gtk::{gdk::Display, gio, prelude::*, Application};
+use login_view::LoginView;
use main_view::MainView;
+use relm4::component::AsyncComponent;
+use relm4::component::AsyncComponentController;
+use relm4::component::AsyncController;
use relm4::prelude::*;
use std::convert::identity;
@@ -7,29 +12,56 @@ use std::convert::identity;
mod config;
mod folder_view;
+mod imap_state;
+mod login_view;
mod main_view;
struct App {
main_view: Controller<MainView>,
+ login_view: AsyncController<LoginView>,
+ active_child: Child,
}
#[derive(Debug)]
-enum Msg {}
+pub enum AppMsg {
+ ToMainView,
+}
+
+#[derive(Debug)]
+enum Child {
+ LoginView,
+ MainView,
+}
#[relm4::component]
-impl Component for App {
+impl SimpleComponent for App {
type Init = ();
- type Input = ();
+ type Input = AppMsg;
type Output = ();
- type CommandOutput = Msg;
view! {
#[root]
- main_window = gtk::ApplicationWindow {
+ #[name(main_window)]
+ gtk::ApplicationWindow {
set_title: Some("Email"),
set_default_size: (1280, 720),
- model.main_view.widget(),
+ match model.active_child {
+ Child::LoginView => {
+ gtk::Box {
+ set_halign: gtk::Align::Fill,
+ set_valign: gtk::Align::Fill,
+ model.login_view.widget(),
+ }
+ },
+ Child::MainView => {
+ gtk::Box {
+ set_halign: gtk::Align::Fill,
+ set_valign: gtk::Align::Fill,
+ model.main_view.widget(),
+ }
+ }
+ },
}
}
@@ -38,17 +70,29 @@ impl Component for App {
root: &Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
+ // TODO: Check if we are logged in and if not go to login
+ // FIXME: Remove Placeholder
let model = App {
- main_view: MainView::builder()
+ active_child: Child::LoginView,
+ main_view: MainView::builder().launch(()).detach(),
+ login_view: LoginView::builder()
.launch(())
.forward(sender.input_sender(), identity),
};
let widgets = view_output!();
ComponentParts { model, widgets }
}
+
+ fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>) {
+ match msg {
+ AppMsg::ToMainView => self.active_child = Child::MainView,
+ }
+ }
}
-fn main() {
+fn main() -> Result<()> {
+ color_eyre::install()?;
+
// Show traces to find potential performance bottlenecks, for example
tracing_subscriber::fmt()
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::FULL)
@@ -73,6 +117,7 @@ fn main() {
app.connect_startup(|_| load_css());
let app = RelmApp::with_app(app);
app.run::<App>(());
+ Ok(())
}
fn load_css() {