mirror of
https://github.com/chatmail/core.git
synced 2026-04-03 22:12:11 +03:00
Compare commits
16 Commits
fix/setupc
...
split_qr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf692b5739 | ||
|
|
030aec7373 | ||
|
|
6a351de4f9 | ||
|
|
bbff1c9c3e | ||
|
|
bbb8144129 | ||
|
|
83f3e23297 | ||
|
|
4f880932ae | ||
|
|
62e8c2497c | ||
|
|
37f854be3e | ||
|
|
e0e82e1877 | ||
|
|
95d8665dbe | ||
|
|
8667de994e | ||
|
|
cee0e22ce7 | ||
|
|
dc8a2f54e5 | ||
|
|
b3bc5b2520 | ||
|
|
00e929afac |
@@ -12,7 +12,7 @@ restore-workspace: &restore-workspace
|
||||
restore-cache: &restore-cache
|
||||
restore_cache:
|
||||
keys:
|
||||
- cargo-v1-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
- cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
- repo-source-{{ .Branch }}-{{ .Revision }}
|
||||
|
||||
commands:
|
||||
@@ -23,20 +23,9 @@ commands:
|
||||
steps:
|
||||
- *restore-workspace
|
||||
- *restore-cache
|
||||
- setup_remote_docker:
|
||||
docker_layer_caching: true
|
||||
# TODO: move into image
|
||||
- run:
|
||||
name: Install Docker client
|
||||
command: |
|
||||
set -x
|
||||
VER="18.09.2"
|
||||
curl -L -o /tmp/docker-$VER.tgz https://download.docker.com/linux/static/stable/x86_64/docker-$VER.tgz
|
||||
tar -xz -C /tmp -f /tmp/docker-$VER.tgz
|
||||
mv /tmp/docker/* /usr/bin
|
||||
- run:
|
||||
name: Test (<< parameters.target >>)
|
||||
command: TARGET=<< parameters.target >> ci/run.sh
|
||||
command: TARGET=<< parameters.target >> ci_scripts/run-rust-test.sh
|
||||
no_output_timeout: 15m
|
||||
|
||||
jobs:
|
||||
@@ -52,7 +41,7 @@ jobs:
|
||||
command: cargo generate-lockfile
|
||||
- restore_cache:
|
||||
keys:
|
||||
- cargo-v1-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
- cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
- run: rustup install $(cat rust-toolchain)
|
||||
- run: rustup default $(cat rust-toolchain)
|
||||
- run: rustup component add --toolchain $(cat rust-toolchain) rustfmt
|
||||
@@ -61,13 +50,14 @@ jobs:
|
||||
- run: cargo fetch
|
||||
- run: rustc +stable --version
|
||||
- run: rustc +$(cat rust-toolchain) --version
|
||||
- run: rm -rf .git
|
||||
# make sure this git repo doesn't grow too big
|
||||
- run: git gc
|
||||
- persist_to_workspace:
|
||||
root: /mnt
|
||||
paths:
|
||||
- crate
|
||||
- save_cache:
|
||||
key: cargo-v1-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
key: cargo-v2-{{ checksum "rust-toolchain" }}-{{ checksum "Cargo.toml" }}-{{ checksum "Cargo.lock" }}-{{ arch }}
|
||||
paths:
|
||||
- "~/.cargo"
|
||||
- "~/.rustup"
|
||||
@@ -102,7 +92,7 @@ jobs:
|
||||
- run: cargo fetch
|
||||
- run:
|
||||
name: Test
|
||||
command: TARGET=x86_64-apple-darwin ci/run.sh
|
||||
command: TARGET=x86_64-apple-darwin ci_scripts/run-rust-test.sh
|
||||
|
||||
test_x86_64-unknown-linux-gnu:
|
||||
executor: default
|
||||
@@ -124,18 +114,18 @@ jobs:
|
||||
|
||||
|
||||
build_test_docs_wheel:
|
||||
machine: True
|
||||
steps:
|
||||
- checkout
|
||||
# - run: docker pull deltachat/doxygen
|
||||
- run: docker pull deltachat/coredeps
|
||||
- run:
|
||||
name: build docs, run tests and build wheels
|
||||
command: ci_scripts/ci_run.sh
|
||||
environment:
|
||||
docker:
|
||||
- image: deltachat/coredeps
|
||||
environment:
|
||||
TESTS: 1
|
||||
DOCS: 1
|
||||
|
||||
working_directory: /mnt/crate
|
||||
steps:
|
||||
- *restore-workspace
|
||||
- *restore-cache
|
||||
- run:
|
||||
name: build docs, run tests and build wheels
|
||||
command: ci_scripts/run-python.sh
|
||||
- run:
|
||||
name: copying docs and wheels to workspace
|
||||
command: |
|
||||
@@ -143,7 +133,6 @@ jobs:
|
||||
# cp -av docs workspace/c-docs
|
||||
cp -av python/.docker-tox/wheelhouse workspace/
|
||||
cp -av python/doc/_build/ workspace/py-docs
|
||||
|
||||
- persist_to_workspace:
|
||||
root: workspace
|
||||
paths:
|
||||
@@ -176,15 +165,16 @@ workflows:
|
||||
|
||||
test:
|
||||
jobs:
|
||||
- build_test_docs_wheel
|
||||
- cargo_fetch
|
||||
- build_test_docs_wheel:
|
||||
requires:
|
||||
- cargo_fetch
|
||||
- upload_docs_wheels:
|
||||
requires:
|
||||
- build_test_docs_wheel
|
||||
- cargo_fetch
|
||||
- rustfmt:
|
||||
requires:
|
||||
- cargo_fetch
|
||||
|
||||
- clippy:
|
||||
requires:
|
||||
- cargo_fetch
|
||||
|
||||
95
Cargo.lock
generated
95
Cargo.lock
generated
@@ -2,7 +2,7 @@
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "adler32"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
@@ -245,8 +245,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -285,7 +285,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -344,7 +344,7 @@ dependencies = [
|
||||
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"publicsuffix 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"try_from 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -520,7 +520,7 @@ dependencies = [
|
||||
"reqwest 0.9.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rusqlite 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustyline 4.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -530,6 +530,18 @@ dependencies = [
|
||||
"thread-local-object 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-provider-overview"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/deltachat/provider-overview?rev=366b41a7503973e4ffac3aa5173b419f2f03c211#366b41a7503973e4ffac3aa5173b419f2f03c211"
|
||||
dependencies = [
|
||||
"glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deltachat_derive"
|
||||
version = "0.1.0"
|
||||
@@ -543,6 +555,7 @@ name = "deltachat_ffi"
|
||||
version = "1.0.0-alpha.4"
|
||||
dependencies = [
|
||||
"deltachat 1.0.0-alpha.4",
|
||||
"deltachat-provider-overview 0.1.0 (git+https://github.com/deltachat/provider-overview?rev=366b41a7503973e4ffac3aa5173b419f2f03c211)",
|
||||
"human-panic 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -639,7 +652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.19"
|
||||
version = "0.8.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -814,6 +827,11 @@ name = "glob"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.1.26"
|
||||
@@ -887,8 +905,8 @@ dependencies = [
|
||||
"backtrace 0.3.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"os_type 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"toml 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1065,8 +1083,8 @@ dependencies = [
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -1207,7 +1225,7 @@ name = "miniz_oxide"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1263,7 +1281,7 @@ dependencies = [
|
||||
"openssl 0.10.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.9.49 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1601,7 +1619,7 @@ version = "0.7.24"
|
||||
source = "git+https://github.com/sfackler/rust-phf?rev=0d00821#0d0082178568036736bb6d51cb91f95ca5a616c3"
|
||||
dependencies = [
|
||||
"phf_shared 0.7.24 (git+https://github.com/sfackler/rust-phf?rev=0d00821)",
|
||||
"rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1732,7 +1750,7 @@ version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1811,7 +1829,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.1"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -1991,7 +2009,7 @@ dependencies = [
|
||||
"bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cookie_store 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"http 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2001,7 +2019,7 @@ dependencies = [
|
||||
"mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"mime_guess 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2126,7 +2144,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2176,7 +2194,7 @@ version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2186,15 +2204,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.100"
|
||||
version = "1.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2209,7 +2227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2219,7 +2237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@@ -2424,7 +2442,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
@@ -2600,7 +2618,7 @@ name = "toml"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2872,6 +2890,14 @@ dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "0.6.0"
|
||||
@@ -2891,7 +2917,7 @@ dependencies = [
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
|
||||
"checksum adler32 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
|
||||
"checksum aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "54eb1d8fe354e5fc611daf4f2ea97dd45a765f4f1e4512306ec183ae2e8f20c9"
|
||||
"checksum aes-soft 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cfd7e7ae3f9a1fb5c03b389fc6bb9a51400d0c13053f0dca698c832bfd893a0d"
|
||||
"checksum aesni 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2f70a6b5f971e473091ab7cfb5ffac6cde81666c4556751d8d5620ead8abf100"
|
||||
@@ -2949,6 +2975,7 @@ dependencies = [
|
||||
"checksum darling_core 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6afc018370c3bff3eb51f89256a6bdb18b4fdcda72d577982a14954a7a0b402c"
|
||||
"checksum darling_macro 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c6d8dac1c6f1d29a41c4712b4400f878cb4fcc4c7628f298dd75038e024998d1"
|
||||
"checksum debug_stub_derive 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "496b7f8a2f853313c3ca370641d7ff3e42c32974fdccda8f0684599ed0a3ff6b"
|
||||
"checksum deltachat-provider-overview 0.1.0 (git+https://github.com/deltachat/provider-overview?rev=366b41a7503973e4ffac3aa5173b419f2f03c211)" = "<none>"
|
||||
"checksum derive_builder 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ac53fa6a3cda160df823a9346442525dcaf1e171999a1cf23e67067e4fd64d4"
|
||||
"checksum derive_builder_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0288a23da9333c246bb18c143426074a6ae96747995c5819d2947b64cd942b37"
|
||||
"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839"
|
||||
@@ -2959,7 +2986,7 @@ dependencies = [
|
||||
"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e"
|
||||
"checksum ed25519-dalek 1.0.0-pre.1 (registry+https://github.com/rust-lang/crates.io-index)" = "81956bcf7ef761fb4e1d88de3fa181358a0d26cbcb9755b587a08f9119824b86"
|
||||
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
|
||||
"checksum encoding_rs 0.8.19 (registry+https://github.com/rust-lang/crates.io-index)" = "79906e1ad1f7f8bc48864fcc6ffd58336fb5992e627bf61928099cb25fdf4314"
|
||||
"checksum encoding_rs 0.8.20 (registry+https://github.com/rust-lang/crates.io-index)" = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9"
|
||||
"checksum entities 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca"
|
||||
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
|
||||
"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3"
|
||||
@@ -2983,6 +3010,7 @@ dependencies = [
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "473a1265acc8ff1e808cd0a1af8cee3c2ee5200916058a2ca113c29f2d903571"
|
||||
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
|
||||
"checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
"checksum h2 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462"
|
||||
"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
@@ -3084,7 +3112,7 @@ dependencies = [
|
||||
"checksum r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "806e268035ce9e5a604bf617ac8a073ef28b59ef2e48e8338db0baf530caef33"
|
||||
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59cea0d944b32347a1863e95942fd6ebdb486afb4f038119494f2860380c1d51"
|
||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
@@ -3116,7 +3144,7 @@ dependencies = [
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum safemem 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d2b08423011dae9a5ca23f07cf57dac3857f5c885d352b76f6d95f4aea9434d0"
|
||||
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
|
||||
"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
|
||||
"checksum schannel 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "87f550b06b6cba9c8b8be3ee73f391990116bf527450d2556e9b9ce263b9a021"
|
||||
"checksum scheduled-thread-pool 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd07742e081ff6c077f5f6b283f12f32b9e7cc765b316160d66289b74546fbb3"
|
||||
"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
@@ -3124,8 +3152,8 @@ dependencies = [
|
||||
"checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "f4473e8506b213730ff2061073b48fa51dcc66349219e2e7c5608f0296a1d95a"
|
||||
"checksum serde_derive 1.0.100 (registry+https://github.com/rust-lang/crates.io-index)" = "11e410fde43e157d789fc290d26bc940778ad0fdd47836426fbac36573710dbb"
|
||||
"checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd"
|
||||
"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
|
||||
"checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
|
||||
@@ -3206,5 +3234,6 @@ dependencies = [
|
||||
"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e"
|
||||
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
"checksum x25519-dalek 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7ee1585dc1484373cbc1cee7aafda26634665cf449436fd6e24bfd1fad230538"
|
||||
"checksum yaml-rust 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
|
||||
"checksum zeroize 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e68403b858b6af538b11614e62dfe9ab2facba9f13a0cafb974855cfb495ec95"
|
||||
"checksum zeroize_derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3f07490820219949839d0027b965ffdd659d75be9220c00798762e36c6cd281"
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
# perform CI jobs on PRs and after merges to master.
|
||||
# triggered from .circleci/config.yml
|
||||
|
||||
set -e -x
|
||||
|
||||
export BRANCH=${CIRCLE_BRANCH:-test7}
|
||||
|
||||
# run doxygen on c-source (needed by later doc-generation steps).
|
||||
# XXX modifies the host filesystem docs/xml and docs/html directories
|
||||
# XXX which you can then only remove with sudo as they belong to root
|
||||
|
||||
# XXX we don't do doxygen doc generation with Rust anymore, needs to be
|
||||
# substituted with rust-docs
|
||||
#if [ -n "$DOCS" ] ; then
|
||||
# docker run --rm -it -v $PWD:/mnt -w /mnt/docs deltachat/doxygen doxygen
|
||||
#fi
|
||||
|
||||
# run everything else inside docker (TESTS, DOCS, WHEELS)
|
||||
docker run -e DCC_PY_LIVECONFIG -e BRANCH -e TESTS -e DOCS \
|
||||
--rm -it -v $(pwd):/mnt -w /mnt \
|
||||
deltachat/coredeps ci_scripts/run_all.sh
|
||||
|
||||
@@ -36,20 +36,25 @@ if [ -n "$TESTS" ]; then
|
||||
rm -rf src/deltachat/__pycache__
|
||||
export PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
# run tox
|
||||
# XXX we don't run liveconfig tests because they hang sometimes
|
||||
# see https://github.com/deltachat/deltachat-core-rust/issues/331
|
||||
# unset DCC_PY_LIVECONFIG
|
||||
|
||||
tox --workdir "$TOXWORKDIR" -e lint,py35,py36,py37,auditwheels -- -k "not qr"
|
||||
tox --workdir "$TOXWORKDIR" -e py35,py36,py37 -- -k "qr"
|
||||
# run tox. The circle-ci project env-var-setting DCC_PY_LIVECONFIG
|
||||
# allows running of "liveconfig" tests but for speed reasons
|
||||
# we run them only for the highest python version we support
|
||||
|
||||
# we split out qr-tests run to minimize likelyness of flaky tests
|
||||
# (some qr tests are pretty heavy in terms of send/received
|
||||
# messages and rust's imap code likely has concurrency problems)
|
||||
tox --workdir "$TOXWORKDIR" -e py37 -- -k "not qr"
|
||||
tox --workdir "$TOXWORKDIR" -e py37 -- -k "qr"
|
||||
unset DCC_PY_LIVECONFIG
|
||||
tox --workdir "$TOXWORKDIR" -p4 -e lint,py35,py36,doc
|
||||
tox --workdir "$TOXWORKDIR" -e auditwheels
|
||||
popd
|
||||
fi
|
||||
|
||||
|
||||
if [ -n "$DOCS" ]; then
|
||||
echo -----------------------
|
||||
echo generating python docs
|
||||
echo -----------------------
|
||||
(cd python && tox --workdir "$TOXWORKDIR" -e doc)
|
||||
fi
|
||||
# if [ -n "$DOCS" ]; then
|
||||
# echo -----------------------
|
||||
# echo generating python docs
|
||||
# echo -----------------------
|
||||
# (cd python && tox --workdir "$TOXWORKDIR" -e doc)
|
||||
# fi
|
||||
@@ -39,8 +39,4 @@ fi
|
||||
|
||||
# Run all the test configurations:
|
||||
$CARGO_CMD $CARGO_SUBCMD $OPT
|
||||
$CARGO_CMD $CARGO_SUBCMD $OPT_RELEASE
|
||||
$CARGO_CMD $CARGO_SUBCMD $OPT_RELEASE_IGNORED
|
||||
|
||||
# Build the ffi lib
|
||||
$CARGO_CMD $CARGO_SUBCMD $OPT_FFI_RELEASE
|
||||
@@ -16,6 +16,7 @@ crate-type = ["cdylib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
deltachat = { path = "../", default-features = false }
|
||||
deltachat-provider-overview = { git = "https://github.com/deltachat/provider-overview", rev = "366b41a7503973e4ffac3aa5173b419f2f03c211" }
|
||||
libc = "0.2"
|
||||
human-panic = "1.0.1"
|
||||
num-traits = "0.2.6"
|
||||
|
||||
@@ -11,6 +11,16 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct _dc_context dc_context_t;
|
||||
typedef struct _dc_array dc_array_t;
|
||||
typedef struct _dc_chatlist dc_chatlist_t;
|
||||
typedef struct _dc_chat dc_chat_t;
|
||||
typedef struct _dc_msg dc_msg_t;
|
||||
typedef struct _dc_contact dc_contact_t;
|
||||
typedef struct _dc_lot dc_lot_t;
|
||||
typedef struct _dc_provider dc_provider_t;
|
||||
|
||||
|
||||
/**
|
||||
* @mainpage Getting started
|
||||
*
|
||||
@@ -189,13 +199,6 @@ extern "C" {
|
||||
* SQLite database for offline functionality and for account-related
|
||||
* settings.
|
||||
*/
|
||||
typedef struct _dc_context dc_context_t;
|
||||
typedef struct _dc_array dc_array_t;
|
||||
typedef struct _dc_chatlist dc_chatlist_t;
|
||||
typedef struct _dc_chat dc_chat_t;
|
||||
typedef struct _dc_msg dc_msg_t;
|
||||
typedef struct _dc_contact dc_contact_t;
|
||||
typedef struct _dc_lot dc_lot_t;
|
||||
|
||||
|
||||
/**
|
||||
@@ -443,7 +446,6 @@ char* dc_get_info (dc_context_t* context);
|
||||
char* dc_get_oauth2_url (dc_context_t* context, const char* addr, const char* redirect_uri);
|
||||
|
||||
|
||||
|
||||
// connect
|
||||
|
||||
/**
|
||||
@@ -3419,6 +3421,110 @@ int dc_contact_is_blocked (const dc_contact_t* contact);
|
||||
int dc_contact_is_verified (dc_contact_t* contact);
|
||||
|
||||
|
||||
/**
|
||||
* @class dc_provider_t
|
||||
*
|
||||
* Opaque object containing information about one single email provider.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Create a provider struct for the given domain.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param domain The domain to get provider info for.
|
||||
* @return a dc_provider_t struct which can be used with the dc_provider_get_*
|
||||
* accessor functions. If no provider info is found, NULL will be
|
||||
* returned.
|
||||
*/
|
||||
dc_provider_t* dc_provider_new_from_domain (char* domain);
|
||||
|
||||
|
||||
/**
|
||||
* Create a provider struct for the given email address.
|
||||
*
|
||||
* The provider is extracted from the email address and it's information is returned.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param email The user's email address to extract the provider info form.
|
||||
* @return a dc_provider_t struct which can be used with the dc_provider_get_*
|
||||
* accessor functions. If no provider info is found, NULL will be
|
||||
* returned.
|
||||
*/
|
||||
dc_provider_t* dc_provider_new_from_email (char* email);
|
||||
|
||||
|
||||
/**
|
||||
* URL of the overview page.
|
||||
*
|
||||
* This URL allows linking to the providers page on providers.delta.chat.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
* @return A string which must be free()d.
|
||||
*/
|
||||
char* dc_provider_get_overview_page (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* The provider's name.
|
||||
*
|
||||
* The name of the provider, e.g. "POSTEO".
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
* @return A string which must be free()d.
|
||||
*/
|
||||
char* dc_provider_get_name (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* The markdown content of the providers page.
|
||||
*
|
||||
* This contains the preparation steps or additional information if the status
|
||||
* is @ref DC_PROVIDER_STATUS_BROKEN.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
* @return A string which must be free()d.
|
||||
*/
|
||||
char* dc_provider_get_markdown (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* Date of when the state was last checked/updated.
|
||||
*
|
||||
* This is returned as a string.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
* @return A string which must be free()d.
|
||||
*/
|
||||
char* dc_provider_get_status_date (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* Whether DC works with this provider.
|
||||
*
|
||||
* Can be one of @ref DC_PROVIDER_STATUS_OK, @ref
|
||||
* DC_PROVIDER_STATUS_PREPARATION and @ref DC_PROVIDER_STATUS_BROKEN.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
* @return The status as a constant number.
|
||||
*/
|
||||
int dc_provider_get_status (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* Free the provider info struct.
|
||||
*
|
||||
* @memberof dc_provider_t
|
||||
* @param provider The dc_provider_t struct.
|
||||
*/
|
||||
void dc_provider_unref (const dc_provider_t* provider);
|
||||
|
||||
|
||||
/**
|
||||
* @class dc_lot_t
|
||||
*
|
||||
@@ -4026,6 +4132,41 @@ void dc_array_add_id (dc_array_t*, uint32_t); // depreca
|
||||
#define DC_SHOW_EMAILS_ALL 2
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup DC_PROVIDER_STATUS DC_PROVIDER_STATUS
|
||||
*
|
||||
* These constants are used as return values for dc_provider_get_status().
|
||||
*
|
||||
* @addtogroup DC_PROVIDER_STATUS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provider status returned by dc_provider_get_status().
|
||||
*
|
||||
* Works right out of the box without any preperation steps needed
|
||||
*/
|
||||
#define DC_PROVIDER_STATUS_OK 1
|
||||
|
||||
/**
|
||||
* Provider status returned by dc_provider_get_status().
|
||||
*
|
||||
* Works, but preparation steps are needed
|
||||
*/
|
||||
#define DC_PROVIDER_STATUS_PREPARATION 2
|
||||
|
||||
/**
|
||||
* Provider status returned by dc_provider_get_status().
|
||||
*
|
||||
* Doesn't work (too unstable to use falls also in this category)
|
||||
*/
|
||||
#define DC_PROVIDER_STATUS_BROKEN 3
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* TODO: Strings need some doumentation about used placeholders.
|
||||
*
|
||||
|
||||
@@ -233,7 +233,7 @@ pub unsafe extern "C" fn dc_open(
|
||||
let ffi_context = &*context;
|
||||
let rust_cb = move |_ctx: &Context, evt: Event| ffi_context.translate_cb(evt);
|
||||
|
||||
let ctx = if blobdir.is_null() {
|
||||
let ctx = if blobdir.is_null() || *blobdir == 0 {
|
||||
Context::new(
|
||||
Box::new(rust_cb),
|
||||
ffi_context.os_name.clone(),
|
||||
@@ -2813,6 +2813,8 @@ fn as_opt_str<'a>(s: *const libc::c_char) -> Option<&'a str> {
|
||||
Some(dc_tools::as_str(s))
|
||||
}
|
||||
|
||||
pub mod providers;
|
||||
|
||||
pub trait ResultExt<T> {
|
||||
fn unwrap_or_log_default(self, context: &context::Context, message: &str) -> T;
|
||||
fn log_err(&self, context: &context::Context, message: &str);
|
||||
|
||||
92
deltachat-ffi/src/providers.rs
Normal file
92
deltachat-ffi/src/providers.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
extern crate deltachat_provider_overview;
|
||||
|
||||
use std::ptr;
|
||||
|
||||
use deltachat::dc_tools::{as_str, StrExt};
|
||||
use deltachat_provider_overview::StatusState;
|
||||
|
||||
#[no_mangle]
|
||||
pub type dc_provider_t = deltachat_provider_overview::Provider;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_new_from_domain(
|
||||
domain: *const libc::c_char,
|
||||
) -> *const dc_provider_t {
|
||||
match deltachat_provider_overview::get_provider_info(as_str(domain)) {
|
||||
Some(provider) => provider,
|
||||
None => ptr::null(),
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_new_from_email(
|
||||
email: *const libc::c_char,
|
||||
) -> *const dc_provider_t {
|
||||
let domain = deltachat_provider_overview::get_domain_from_email(as_str(email));
|
||||
match deltachat_provider_overview::get_provider_info(domain) {
|
||||
Some(provider) => provider,
|
||||
None => ptr::null(),
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! null_guard {
|
||||
($context:tt) => {
|
||||
if $context.is_null() {
|
||||
return ptr::null_mut() as *mut libc::c_char;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_get_overview_page(
|
||||
provider: *const dc_provider_t,
|
||||
) -> *mut libc::c_char {
|
||||
null_guard!(provider);
|
||||
format!(
|
||||
"{}/{}",
|
||||
deltachat_provider_overview::PROVIDER_OVERVIEW_URL,
|
||||
(*provider).overview_page
|
||||
)
|
||||
.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_get_name(provider: *const dc_provider_t) -> *mut libc::c_char {
|
||||
null_guard!(provider);
|
||||
(*provider).name.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_get_markdown(
|
||||
provider: *const dc_provider_t,
|
||||
) -> *mut libc::c_char {
|
||||
null_guard!(provider);
|
||||
(*provider).markdown.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_get_status_date(
|
||||
provider: *const dc_provider_t,
|
||||
) -> *mut libc::c_char {
|
||||
null_guard!(provider);
|
||||
(*provider).status.date.strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_get_status(provider: *const dc_provider_t) -> u32 {
|
||||
if provider.is_null() {
|
||||
return 0;
|
||||
}
|
||||
match (*provider).status.state {
|
||||
StatusState::OK => 1,
|
||||
StatusState::PREPARATION => 2,
|
||||
StatusState::BROKEN => 3,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_provider_unref(_provider: *const dc_provider_t) {
|
||||
()
|
||||
}
|
||||
|
||||
// TODO expose general provider overview url?
|
||||
@@ -8,6 +8,9 @@ from os.path import join as joinpath
|
||||
# this works well when you in a git-checkout
|
||||
# run "python deltachat/const.py" to regenerate events
|
||||
# begin const generated
|
||||
DC_PROVIDER_STATUS_OK = 1
|
||||
DC_PROVIDER_STATUS_PREPARATION = 2
|
||||
DC_PROVIDER_STATUS_BROKEN = 3
|
||||
DC_GCL_ARCHIVED_ONLY = 0x01
|
||||
DC_GCL_NO_SPECIALS = 0x02
|
||||
DC_GCL_ADD_ALLDONE_HINT = 0x04
|
||||
@@ -84,7 +87,8 @@ DC_EVENT_IS_OFFLINE = 2081
|
||||
|
||||
|
||||
def read_event_defines(f):
|
||||
rex = re.compile(r'#define\s+((?:DC_EVENT_|DC_QR|DC_MSG|DC_STATE_|DC_CONTACT_ID_|DC_GCL|DC_CHAT)\S+)\s+([x\d]+).*')
|
||||
rex = re.compile(r'#define\s+((?:DC_EVENT_|DC_QR|DC_MSG|DC_STATE_|'
|
||||
r'DC_CONTACT_ID_|DC_GCL|DC_CHAT|DC_PROVIDER)\S+)\s+([x\d]+).*')
|
||||
for line in f:
|
||||
m = rex.match(line)
|
||||
if m:
|
||||
|
||||
67
python/src/deltachat/provider.py
Normal file
67
python/src/deltachat/provider.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""Provider info class."""
|
||||
|
||||
from .capi import ffi, lib
|
||||
from .cutil import as_dc_charpointer, from_dc_charpointer
|
||||
|
||||
|
||||
class ProviderNotFoundError(Exception):
|
||||
"""The provider information was not found."""
|
||||
|
||||
|
||||
class Provider(object):
|
||||
"""Provider information.
|
||||
|
||||
:param domain: The domain to get the provider info for, this is
|
||||
normally the part following the `@` of the domain.
|
||||
"""
|
||||
|
||||
def __init__(self, domain):
|
||||
provider = ffi.gc(
|
||||
lib.dc_provider_new_from_domain(as_dc_charpointer(domain)),
|
||||
lib.dc_provider_unref,
|
||||
)
|
||||
if provider == ffi.NULL:
|
||||
raise ProviderNotFoundError("Provider not found")
|
||||
self._provider = provider
|
||||
|
||||
@classmethod
|
||||
def from_email(cls, email):
|
||||
"""Create provider info from an email address.
|
||||
|
||||
:param email: Email address to get provider info for.
|
||||
"""
|
||||
return cls(email.split('@')[-1])
|
||||
|
||||
@property
|
||||
def overview_page(self):
|
||||
"""URL to the overview page of the provider on providers.delta.chat."""
|
||||
return from_dc_charpointer(
|
||||
lib.dc_provider_get_overview_page(self._provider))
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""The name of the provider."""
|
||||
return from_dc_charpointer(lib.dc_provider_get_name(self._provider))
|
||||
|
||||
@property
|
||||
def markdown(self):
|
||||
"""Content of the information page, formatted as markdown."""
|
||||
return from_dc_charpointer(
|
||||
lib.dc_provider_get_markdown(self._provider))
|
||||
|
||||
@property
|
||||
def status_date(self):
|
||||
"""The date the provider info was last updated, as a string."""
|
||||
return from_dc_charpointer(
|
||||
lib.dc_provider_get_status_date(self._provider))
|
||||
|
||||
@property
|
||||
def status(self):
|
||||
"""The status of the provider information.
|
||||
|
||||
This is one of the
|
||||
:attr:`deltachat.const.DC_PROVIDER_STATUS_OK`,
|
||||
:attr:`deltachat.const.DC_PROVIDER_STATUS_PREPARATION` or
|
||||
:attr:`deltachat.const.DC_PROVIDER_STATUS_BROKEN` constants.
|
||||
"""
|
||||
return lib.dc_provider_get_status(self._provider)
|
||||
@@ -4,7 +4,7 @@ from deltachat import const
|
||||
from conftest import wait_configuration_progress, wait_msgs_changed
|
||||
|
||||
|
||||
class TestInCreation:
|
||||
class TestOnlineInCreation:
|
||||
def test_forward_increation(self, acfactory, data, lp):
|
||||
ac1 = acfactory.get_online_configuring_account()
|
||||
ac2 = acfactory.get_online_configuring_account()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from __future__ import print_function
|
||||
from deltachat import capi, const, set_context_callback, clear_context_callback
|
||||
from deltachat import capi, cutil, const, set_context_callback, clear_context_callback
|
||||
from deltachat.capi import ffi
|
||||
from deltachat.capi import lib
|
||||
from deltachat.account import EventLogger
|
||||
@@ -83,3 +83,18 @@ def test_markseen_invalid_message_ids(acfactory):
|
||||
msg_ids = [9]
|
||||
lib.dc_markseen_msgs(ac1._dc_context, msg_ids, len(msg_ids))
|
||||
ac1._evlogger.ensure_event_not_queued("DC_EVENT_WARNING|DC_EVENT_ERROR")
|
||||
|
||||
|
||||
def test_provider_info():
|
||||
provider = lib.dc_provider_new_from_email(cutil.as_dc_charpointer("ex@example.com"))
|
||||
assert cutil.from_dc_charpointer(
|
||||
lib.dc_provider_get_overview_page(provider)
|
||||
) == "https://providers.delta.chat/example.com"
|
||||
assert cutil.from_dc_charpointer(lib.dc_provider_get_name(provider)) == "Example"
|
||||
assert cutil.from_dc_charpointer(lib.dc_provider_get_markdown(provider)) == "\n..."
|
||||
assert cutil.from_dc_charpointer(lib.dc_provider_get_status_date(provider)) == "2018-09"
|
||||
assert lib.dc_provider_get_status(provider) == const.DC_PROVIDER_STATUS_PREPARATION
|
||||
|
||||
|
||||
def test_provider_info_none():
|
||||
assert lib.dc_provider_new_from_email(cutil.as_dc_charpointer("email@unexistent.no")) == ffi.NULL
|
||||
|
||||
27
python/tests/test_provider_info.py
Normal file
27
python/tests/test_provider_info.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import pytest
|
||||
|
||||
from deltachat import const
|
||||
from deltachat import provider
|
||||
|
||||
|
||||
def test_provider_info_from_email():
|
||||
example = provider.Provider.from_email("email@example.com")
|
||||
assert example.overview_page == "https://providers.delta.chat/example.com"
|
||||
assert example.name == "Example"
|
||||
assert example.markdown == "\n..."
|
||||
assert example.status_date == "2018-09"
|
||||
assert example.status == const.DC_PROVIDER_STATUS_PREPARATION
|
||||
|
||||
|
||||
def test_provider_info_from_domain():
|
||||
example = provider.Provider("example.com")
|
||||
assert example.overview_page == "https://providers.delta.chat/example.com"
|
||||
assert example.name == "Example"
|
||||
assert example.markdown == "\n..."
|
||||
assert example.status_date == "2018-09"
|
||||
assert example.status == const.DC_PROVIDER_STATUS_PREPARATION
|
||||
|
||||
|
||||
def test_provider_info_none():
|
||||
with pytest.raises(provider.ProviderNotFoundError):
|
||||
provider.Provider.from_email("email@unexistent.no")
|
||||
@@ -19,12 +19,12 @@ deps =
|
||||
pytest-rerunfailures
|
||||
pytest-timeout
|
||||
pytest-xdist
|
||||
auditwheel
|
||||
pdbpp
|
||||
requests
|
||||
|
||||
[testenv:auditwheels]
|
||||
skipsdist = True
|
||||
deps = auditwheel
|
||||
commands =
|
||||
python tests/auditwheels.py {toxworkdir}/wheelhouse
|
||||
|
||||
@@ -45,7 +45,7 @@ commands =
|
||||
[testenv:doc]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
sphinx==2.0.1
|
||||
sphinx==2.2.0
|
||||
breathe
|
||||
|
||||
changedir = doc
|
||||
|
||||
180
spec.md
180
spec.md
@@ -2,7 +2,9 @@
|
||||
|
||||
Version 0.19.0
|
||||
|
||||
This document describes how emails can be used to implement typical messenger functions while staying compatible to existing MUAs.
|
||||
This document describes how emails can be used
|
||||
to implement typical messenger functions
|
||||
while staying compatible to existing MUAs.
|
||||
|
||||
- [Encryption](#encryption)
|
||||
- [Outgoing messages](#outgoing-messages)
|
||||
@@ -20,10 +22,14 @@ This document describes how emails can be used to implement typical messenger fu
|
||||
|
||||
# Encryption
|
||||
|
||||
Messages SHOULD be encrypted by the [Autocrypt](https://autocrypt.org/level1.html) standard; `prefer-encrypt=mutual` MAY be set by default.
|
||||
Messages SHOULD be encrypted by the
|
||||
[Autocrypt](https://autocrypt.org/level1.html) standard;
|
||||
`prefer-encrypt=mutual` MAY be set by default.
|
||||
|
||||
Meta data (at least the subject and all chat-headers) SHOULD be encrypted by the [Memoryhole](https://github.com/autocrypt/memoryhole) standard.
|
||||
If Memoryhole is not used, the subject of encrypted messages SHOULD be replaced by the string
|
||||
Meta data (at least the subject and all chat-headers) SHOULD be encrypted
|
||||
by the [Memoryhole](https://github.com/autocrypt/memoryhole) standard.
|
||||
If Memoryhole is not used,
|
||||
the subject of encrypted messages SHOULD be replaced by the string
|
||||
`Chat: Encrypted message` where the part after the colon MAY be localized.
|
||||
|
||||
|
||||
@@ -31,7 +37,8 @@ If Memoryhole is not used, the subject of encrypted messages SHOULD be replaced
|
||||
|
||||
Messengers MUST add a `Chat-Version: 1.0` header to outgoing messages.
|
||||
For filtering and smart appearance of the messages in normal MUAs,
|
||||
the `Subject` header SHOULD start with the characters `Chat:` and SHOULD be an excerpt of the message.
|
||||
the `Subject` header SHOULD start with the characters `Chat:`
|
||||
and SHOULD be an excerpt of the message.
|
||||
Replies to messages MAY follow the typical `Re:`-format.
|
||||
|
||||
The body MAY contain text which MUST have the content type `text/plain`
|
||||
@@ -41,8 +48,8 @@ The text MAY be divided into a user-text-part and a footer-part using the
|
||||
line `-- ` (minus, minus, space, lineend).
|
||||
|
||||
The user-text-part MUST contain only user generated content.
|
||||
User generated content are eg. texts a user has actually typed or pasted or
|
||||
forwarded from another user.
|
||||
User generated content are eg. texts a user has actually typed
|
||||
or pasted or forwarded from another user.
|
||||
Full quotes, footers or sth. like that MUST NOT go to the user-text-part.
|
||||
|
||||
From: sender@domain
|
||||
@@ -56,14 +63,19 @@ Full quotes, footers or sth. like that MUST NOT go to the user-text-part.
|
||||
|
||||
# Incoming messages
|
||||
|
||||
The `Chat-Version` header MAY be used to detect if a messages comes from a compatible messenger.
|
||||
The `Chat-Version` header MAY be used
|
||||
to detect if a messages comes from a compatible messenger.
|
||||
|
||||
The `Subject` header MUST NOT be used to detect compatible messengers, groups or whatever.
|
||||
The `Subject` header MUST NOT be used
|
||||
to detect compatible messengers, groups or whatever.
|
||||
|
||||
Messenger SHOULD show the `Subject` if the message comes from a normal MUA together with the email-body.
|
||||
The email-body SHOULD be converted to plain text, full-quotes and similar regions SHOULD be cut.
|
||||
Messenger SHOULD show the `Subject`
|
||||
if the message comes from a normal MUA together with the email-body.
|
||||
The email-body SHOULD be converted
|
||||
to plain text, full-quotes and similar regions SHOULD be cut.
|
||||
|
||||
Attachments SHOULD be shown where possible. If an attachment cannot be shown, a non-distracting warning SHOULD be printed.
|
||||
Attachments SHOULD be shown where possible.
|
||||
If an attachment cannot be shown, a non-distracting warning SHOULD be printed.
|
||||
|
||||
|
||||
# Forwarded messages
|
||||
@@ -90,21 +102,25 @@ which SHOULD be anonymized or just a placeholder.
|
||||
Hello world!
|
||||
|
||||
Incoming forwarded messages are detected by the header.
|
||||
The messenger SHOULD mark these messages in a way that it becomes obvious
|
||||
that the message is not created by the sender.
|
||||
Note that most messengers do not show the original sender with forwarded messages
|
||||
The messenger SHOULD mark these messages in a way that
|
||||
it becomes obvious that the message is not created by the sender.
|
||||
Note that most messengers do not show the original sender of forwarded messages
|
||||
but MUAs typically expose the sender in the UI.
|
||||
|
||||
|
||||
# Groups
|
||||
|
||||
Groups are chats with usually more than one recipient, each defined by an email-address.
|
||||
Groups are chats with usually more than one recipient,
|
||||
each defined by an email-address.
|
||||
The sender plus the recipients are the group members.
|
||||
|
||||
To allow different groups with the same members, groups are identified by a group-id.
|
||||
The group-id MUST be created only from the characters `0`-`9`, `A`-`Z`, `a`-`z` `_` and `-`.
|
||||
To allow different groups with the same members,
|
||||
groups are identified by a group-id.
|
||||
The group-id MUST be created only from the characters
|
||||
`0`-`9`, `A`-`Z`, `a`-`z` `_` and `-`.
|
||||
|
||||
Groups MUST have a group-name. The group-name is any non-zero-length UTF-8 string.
|
||||
Groups MUST have a group-name.
|
||||
The group-name is any non-zero-length UTF-8 string.
|
||||
|
||||
Groups MAY have a group-image.
|
||||
|
||||
@@ -113,13 +129,17 @@ Groups MAY have a group-image.
|
||||
|
||||
All group members MUST be added to the `From`/`To` headers.
|
||||
The group-id MUST be written to the `Chat-Group-ID` header.
|
||||
The group-name MUST be written to `Chat-Group-Name` header (the forced presence of this header makes it easier to join a group chat on a second device any time).
|
||||
The group-name MUST be written to `Chat-Group-Name` header
|
||||
(the forced presence of this header makes it easier
|
||||
to join a group chat on a second device any time).
|
||||
|
||||
The `Subject` header of outgoing group messages SHOULD start with the characters `Chat:` followed by the group-name and a colon followed by an excerpt of the message.
|
||||
The `Subject` header of outgoing group messages
|
||||
SHOULD start with the characters `Chat:`
|
||||
followed by the group-name and a colon followed by an excerpt of the message.
|
||||
|
||||
To identify the group-id on replies from normal MUAs, the group-id MUST also be added to
|
||||
the message-id of outgoing messages. The message-id MUST have the
|
||||
format `Gr.<group-id>.<unique data>`.
|
||||
To identify the group-id on replies from normal MUAs,
|
||||
the group-id MUST also be added to the message-id of outgoing messages.
|
||||
The message-id MUST have the format `Gr.<group-id>.<unique data>`.
|
||||
|
||||
From: member1@domain
|
||||
To: member2@domain, member3@domain
|
||||
@@ -131,30 +151,46 @@ format `Gr.<group-id>.<unique data>`.
|
||||
|
||||
Hello group - this group contains three members
|
||||
|
||||
Messengers adding the member list in the form `Name <email-address>` MUST take care only to spread the names authorized by the contacts themselves.
|
||||
Otherwise, names as _Daddy_ or _Honey_ may be spread (this issue is also true for normal MUAs, however, for more contact- and chat-centralized apps
|
||||
Messengers adding the member list in the form `Name <email-address>`
|
||||
MUST take care only to spread the names authorized by the contacts themselves.
|
||||
Otherwise, names as _Daddy_ or _Honey_ may be spread
|
||||
(this issue is also true for normal MUAs, however,
|
||||
for more contact- and chat-centralized apps
|
||||
such situations happen more frequently).
|
||||
|
||||
|
||||
## Incoming group messages
|
||||
|
||||
The messenger MUST search incoming messages for the group-id in the following headers: `Chat-Group-ID`,
|
||||
The messenger MUST search incoming messages for the group-id
|
||||
in the following headers: `Chat-Group-ID`,
|
||||
`Message-ID`, `In-Reply-To` and `References` (in this order).
|
||||
|
||||
If the messenger finds a valid and existent group-id, the message SHOULD be assigned to the given group.
|
||||
If the messenger finds a valid but not existent group-id, the messenger MAY create a new group.
|
||||
If no group-id is found, the message MAY be assigned to a normal single-user chat with the email-address given in `From`.
|
||||
If the messenger finds a valid and existent group-id,
|
||||
the message SHOULD be assigned to the given group.
|
||||
If the messenger finds a valid but not existent group-id,
|
||||
the messenger MAY create a new group.
|
||||
If no group-id is found,
|
||||
the message MAY be assigned
|
||||
to a normal single-user chat with the email-address given in `From`.
|
||||
|
||||
|
||||
## Add and remove members
|
||||
|
||||
Messenger clients MUST construct the member list from the `From`/`To` headers only on the first group message or if they see a `Chat-Group-Member-Added` or `Chat-Group-Member-Removed` action header.
|
||||
Both headers MUST have the email-address of the added or removed member as the value.
|
||||
Messenger clients MUST NOT construct the member list on other group messages (this is to avoid accidentally altered To-lists in normal MUAs; the user
|
||||
does not expect adding a user to a _message_ will also add him to the _group_ "forever").
|
||||
Messenger clients MUST construct the member list
|
||||
from the `From`/`To` headers only on the first group message
|
||||
or if they see a `Chat-Group-Member-Added`
|
||||
or `Chat-Group-Member-Removed` action header.
|
||||
Both headers MUST have the email-address
|
||||
of the added or removed member as the value.
|
||||
Messenger clients MUST NOT construct the member list
|
||||
on other group messages
|
||||
(this is to avoid accidentally altered To-lists in normal MUAs;
|
||||
the user does not expect adding a user to a _message_
|
||||
will also add him to the _group_ "forever").
|
||||
|
||||
The messenger SHOULD send an explicit mail for each added or removed member.
|
||||
The body of the message SHOULD contain a localized description about what happened
|
||||
The body of the message SHOULD contain
|
||||
a localized description about what happened
|
||||
and the message SHOULD appear as a message or action from the sender.
|
||||
|
||||
From: member1@domain
|
||||
@@ -190,7 +226,8 @@ with the value set to the old group name to all group members.
|
||||
The new group name goes to the header `Chat-Group-Name`.
|
||||
|
||||
The messenger SHOULD send an explicit mail for each name change.
|
||||
The body of the message SHOULD contain a localized description about what happened
|
||||
The body of the message SHOULD contain
|
||||
a localized description about what happened
|
||||
and the message SHOULD appear as a message or action from the sender.
|
||||
|
||||
From: member1@domain
|
||||
@@ -208,13 +245,17 @@ and the message SHOULD appear as a message or action from the sender.
|
||||
## Set group image
|
||||
|
||||
A group MAY have a group-image.
|
||||
To change or set the group-image, the messenger MUST attach an image file to a message and MUST add the header `Chat-Group-Image` with the
|
||||
value set to the image name.
|
||||
To change or set the group-image,
|
||||
the messenger MUST attach an image file to a message
|
||||
and MUST add the header `Chat-Group-Image`
|
||||
with the value set to the image name.
|
||||
|
||||
To remove the group-image, the messenger MUST add the header `Chat-Group-Image: 0`.
|
||||
To remove the group-image,
|
||||
the messenger MUST add the header `Chat-Group-Image: 0`.
|
||||
|
||||
The messenger SHOULD send an explicit mail for each group image change.
|
||||
The body of the message SHOULD contain a localized description about what happened
|
||||
The body of the message SHOULD contain
|
||||
a localized description about what happened
|
||||
and the message SHOULD appear as a message or action from the sender.
|
||||
|
||||
|
||||
@@ -239,20 +280,29 @@ and the message SHOULD appear as a message or action from the sender.
|
||||
/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBw ...
|
||||
--==break==--
|
||||
|
||||
The image format SHOULD be image/jpeg or image/png. To save data, it is RECOMMENDED to add a `Chat-Group-Image` only on image changes.
|
||||
The image format SHOULD be image/jpeg or image/png.
|
||||
To save data, it is RECOMMENDED
|
||||
to add a `Chat-Group-Image` only on image changes.
|
||||
|
||||
|
||||
# Set profile image
|
||||
|
||||
A user MAY have a profile-image that MAY be spread to his contacts.
|
||||
To change or set the profile-image, the messenger MUST attach an image file to a message and MUST add the header `Chat-Profile-Image` with the
|
||||
value set to the image name.
|
||||
To change or set the profile-image,
|
||||
the messenger MUST attach an image file to a message
|
||||
and MUST add the header `Chat-Profile-Image`
|
||||
with the value set to the image name.
|
||||
|
||||
To remove the profile-image, the messenger MUST add the header `Chat-Profile-Image: 0`.
|
||||
To remove the profile-image,
|
||||
the messenger MUST add the header `Chat-Profile-Image: 0`.
|
||||
|
||||
To spread the image, the messenger MAY send the profile image together with the next mail to a given contact
|
||||
(to do this only once, the messenger has to keep a `profile_image_update_state` somewhere).
|
||||
Alternatively, the messenger MAY send an explicit mail for each profile-image change to all contacts using a compatible messenger.
|
||||
To spread the image,
|
||||
the messenger MAY send the profile image
|
||||
together with the next mail to a given contact
|
||||
(to do this only once,
|
||||
the messenger has to keep a `profile_image_update_state` somewhere).
|
||||
Alternatively, the messenger MAY send an explicit mail
|
||||
for each profile-image change to all contacts using a compatible messenger.
|
||||
The messenger SHOULD NOT send an explicit mail to normal MUAs.
|
||||
|
||||
From: sender@domain
|
||||
@@ -273,18 +323,25 @@ The messenger SHOULD NOT send an explicit mail to normal MUAs.
|
||||
AKCgkJi3j4l5kjoldfUAKCgkJi3j4lldfHjgWICwgIEBQYFBA ...
|
||||
--==break==--
|
||||
|
||||
The image format SHOULD be image/jpeg or image/png. Note that `Chat-Profile-Image` may appear together with all other headers, eg. there may be a
|
||||
`Chat-Profile-Image` and a `Chat-Group-Image` header in the same message. To save data, it is RECOMMENDED to add a `Chat-Profile-Image` header only on image changes.
|
||||
The image format SHOULD be image/jpeg or image/png.
|
||||
Note that `Chat-Profile-Image` may appear together with all other headers,
|
||||
eg. there may be a `Chat-Profile-Image` and a `Chat-Group-Image` header
|
||||
in the same message.
|
||||
To save data, it is RECOMMENDED to add a `Chat-Profile-Image` header
|
||||
only on image changes.
|
||||
|
||||
|
||||
# Miscellaneous
|
||||
|
||||
Messengers SHOULD use the header `Chat-Predecessor` instead of `In-Reply-To` as
|
||||
the latter one results in infinite threads on typical MUAs.
|
||||
Messengers SHOULD use the header `Chat-Predecessor`
|
||||
instead of `In-Reply-To` as the latter one results
|
||||
in infinite threads on typical MUAs.
|
||||
|
||||
Messengers SHOULD add a `Chat-Voice-message: 1` header if an attached audio file is a voice message.
|
||||
Messengers SHOULD add a `Chat-Voice-message: 1` header
|
||||
if an attached audio file is a voice message.
|
||||
|
||||
Messengers MAY add a `Chat-Duration` header to specify the duration of attached audio or video files.
|
||||
Messengers MAY add a `Chat-Duration` header
|
||||
to specify the duration of attached audio or video files.
|
||||
The value MUST be the duration in milliseconds.
|
||||
This allows the receiver to show the time without knowing the file format.
|
||||
|
||||
@@ -292,16 +349,23 @@ This allows the receiver to show the time without knowing the file format.
|
||||
Chat-Voice-Message: 1
|
||||
Chat-Duration: 10000
|
||||
|
||||
Messengers MAY send and receive Message Disposition Notifications (MDNs, [RFC 8098](https://tools.ietf.org/html/rfc8098), [RFC 3503](https://tools.ietf.org/html/rfc3503))
|
||||
using the `Chat-Disposition-Notification-To` header instead of the `Disposition-Notification-To` (which unfortunately forces many other MUAs to send weird mails not following any
|
||||
standard).
|
||||
Messengers MAY send and receive Message Disposition Notifications
|
||||
(MDNs, [RFC 8098](https://tools.ietf.org/html/rfc8098),
|
||||
[RFC 3503](https://tools.ietf.org/html/rfc3503))
|
||||
using the `Chat-Disposition-Notification-To` header
|
||||
instead of the `Disposition-Notification-To`
|
||||
(which unfortunately forces many other MUAs
|
||||
to send weird mails not following any standard).
|
||||
|
||||
|
||||
## Sync messages
|
||||
|
||||
If some action is required by a message header, the action should only be performed if the _effective date_ is newer than the date the last action was performed.
|
||||
If some action is required by a message header,
|
||||
the action should only be performed if the _effective date_ is newer
|
||||
than the date the last action was performed.
|
||||
|
||||
We define the effective date of a message as the sending time of the message as indicated by its Date header,
|
||||
We define the effective date of a message
|
||||
as the sending time of the message as indicated by its Date header,
|
||||
or the time of first receipt if that date is in the future or unavailable.
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use auto_mozilla::moz_autoconfigure;
|
||||
macro_rules! progress {
|
||||
($context:tt, $progress:expr) => {
|
||||
assert!(
|
||||
$progress > 0 && $progress <= 1000,
|
||||
$progress <= 1000,
|
||||
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
|
||||
);
|
||||
$context.call_cb($crate::events::Event::ConfigureProgress($progress));
|
||||
@@ -660,3 +660,36 @@ pub fn read_autoconf_file(context: &Context, url: &str) -> *mut libc::c_char {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use crate::config::*;
|
||||
use crate::configure::dc_job_do_DC_JOB_CONFIGURE_IMAP;
|
||||
use crate::job::*;
|
||||
use crate::param::*;
|
||||
use crate::test_utils::*;
|
||||
|
||||
#[test]
|
||||
fn test_no_panic_on_bad_credentials() {
|
||||
let t = dummy_context();
|
||||
t.ctx
|
||||
.set_config(Config::Addr, Some("probably@unexistant.addr"))
|
||||
.unwrap();
|
||||
t.ctx.set_config(Config::MailPw, Some("123456")).unwrap();
|
||||
let job = Job {
|
||||
job_id: 1,
|
||||
action: Action::ConfigureImap,
|
||||
foreign_id: 0,
|
||||
desired_timestamp: 0,
|
||||
added_timestamp: 0,
|
||||
tries: 0,
|
||||
param: Params::new(),
|
||||
try_again: 0,
|
||||
pending_error: None,
|
||||
};
|
||||
unsafe {
|
||||
dc_job_do_DC_JOB_CONFIGURE_IMAP(&t.ctx, &job);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,6 +475,15 @@ mod tests {
|
||||
assert!(dbfile2.is_file());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_empty_blobdir() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let dbfile = tmp.path().join("db.sqlite");
|
||||
let blobdir = PathBuf::new();
|
||||
let res = Context::with_blobdir(Box::new(|_, _| 0), "FakeOS".into(), dbfile, blobdir);
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_with_blobdir_not_exists() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
|
||||
@@ -196,8 +196,8 @@ pub fn dc_render_setup_file(context: &Context, passphrase: &str) -> Result<Strin
|
||||
_ => Some(("Autocrypt-Prefer-Encrypt", "mutual")),
|
||||
};
|
||||
let private_key_asc = private_key.to_asc(ac_headers);
|
||||
let encr = dc_pgp_symm_encrypt(&passphrase, private_key_asc.as_bytes())
|
||||
.ok_or(format_err!("Failed to encrypt private key."))?;
|
||||
let encr = dc_pgp_symm_encrypt(&passphrase, private_key_asc.as_bytes())?;
|
||||
|
||||
let replacement = format!(
|
||||
concat!(
|
||||
"-----BEGIN PGP MESSAGE-----\r\n",
|
||||
@@ -385,7 +385,7 @@ fn set_self_key(
|
||||
}
|
||||
|
||||
pub unsafe fn dc_decrypt_setup_file(
|
||||
_context: &Context,
|
||||
context: &Context,
|
||||
passphrase: *const libc::c_char,
|
||||
filecontent: *const libc::c_char,
|
||||
) -> *mut libc::c_char {
|
||||
@@ -424,12 +424,17 @@ pub unsafe fn dc_decrypt_setup_file(
|
||||
|| binary_bytes == 0)
|
||||
{
|
||||
/* decrypt symmetrically */
|
||||
if let Some(plain) = dc_pgp_symm_decrypt(
|
||||
match dc_pgp_symm_decrypt(
|
||||
as_str(passphrase),
|
||||
std::slice::from_raw_parts(binary as *const u8, binary_bytes),
|
||||
) {
|
||||
let payload_c = CString::new(plain).unwrap();
|
||||
payload = strdup(payload_c.as_ptr());
|
||||
Ok(plain) => {
|
||||
let payload_c = CString::new(plain).unwrap();
|
||||
payload = strdup(payload_c.as_ptr());
|
||||
}
|
||||
Err(err) => {
|
||||
error!(context, "Failed to decrypt message: {:?}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,10 +598,7 @@ unsafe fn add_parts(
|
||||
|
||||
// if the mime-headers should be saved, find out its size
|
||||
// (the mime-header ends with an empty line)
|
||||
let save_mime_headers = context
|
||||
.sql
|
||||
.get_config_int(context, "save_mime_headers")
|
||||
.unwrap_or_default();
|
||||
let save_mime_headers = context.sql.get_config_bool(context, "save_mime_headers");
|
||||
if let Some(field) = mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) {
|
||||
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
@@ -688,14 +685,11 @@ unsafe fn add_parts(
|
||||
part.param.to_string(),
|
||||
part.bytes,
|
||||
*hidden,
|
||||
if 0 != save_mime_headers {
|
||||
let body_string = std::str::from_utf8(std::slice::from_raw_parts(
|
||||
if save_mime_headers {
|
||||
Some(String::from_utf8_lossy(std::slice::from_raw_parts(
|
||||
imf_raw_not_terminated as *const u8,
|
||||
imf_raw_bytes,
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
Some(body_string)
|
||||
)))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
|
||||
@@ -296,7 +296,7 @@ impl E2eeHelper {
|
||||
if (*plain).str_0.is_null() || (*plain).len <= 0 {
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
if let Some(ctext_v) = dc_pgp_pk_encrypt(
|
||||
if let Ok(ctext_v) = dc_pgp_pk_encrypt(
|
||||
std::slice::from_raw_parts(
|
||||
(*plain).str_0 as *const u8,
|
||||
(*plain).len,
|
||||
@@ -908,7 +908,7 @@ unsafe fn decrypt_part(
|
||||
};
|
||||
|
||||
/*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */
|
||||
if let Some(plain) = dc_pgp_pk_decrypt(
|
||||
if let Ok(plain) = dc_pgp_pk_decrypt(
|
||||
std::slice::from_raw_parts(decoded_data as *const u8, decoded_data_bytes),
|
||||
&private_keyring,
|
||||
&public_keyring_for_validate,
|
||||
|
||||
@@ -24,6 +24,8 @@ pub enum Error {
|
||||
Utf8(std::str::Utf8Error),
|
||||
#[fail(display = "{:?}", _0)]
|
||||
CStringError(crate::dc_tools::CStringError),
|
||||
#[fail(display = "PGP: {:?}", _0)]
|
||||
Pgp(pgp::errors::Error),
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
@@ -70,6 +72,12 @@ impl From<crate::dc_tools::CStringError> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<pgp::errors::Error> for Error {
|
||||
fn from(err: pgp::errors::Error) -> Error {
|
||||
Error::Pgp(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! bail {
|
||||
($e:expr) => {
|
||||
|
||||
@@ -20,7 +20,6 @@ use crate::oauth2::dc_get_oauth2_access_token;
|
||||
use crate::param::Params;
|
||||
|
||||
const DC_IMAP_SEEN: usize = 0x0001;
|
||||
const DC_REGENERATE: usize = 0x01;
|
||||
|
||||
const DC_SUCCESS: usize = 3;
|
||||
const DC_ALREADY_DONE: usize = 2;
|
||||
@@ -418,9 +417,7 @@ impl Imap {
|
||||
if (server_flags & DC_LP_AUTH_OAUTH2) != 0 {
|
||||
let addr: &str = config.addr.as_ref();
|
||||
|
||||
if let Some(token) =
|
||||
dc_get_oauth2_access_token(context, addr, imap_pw, DC_REGENERATE as usize)
|
||||
{
|
||||
if let Some(token) = dc_get_oauth2_access_token(context, addr, imap_pw, true) {
|
||||
let auth = OAuth2 {
|
||||
user: imap_user.into(),
|
||||
access_token: token,
|
||||
|
||||
@@ -74,14 +74,14 @@ pub fn dc_get_oauth2_access_token(
|
||||
context: &Context,
|
||||
addr: impl AsRef<str>,
|
||||
code: impl AsRef<str>,
|
||||
flags: usize,
|
||||
regenerate: bool,
|
||||
) -> Option<String> {
|
||||
if let Some(oauth2) = Oauth2::from_address(addr) {
|
||||
let lock = context.oauth2_critical.clone();
|
||||
let _l = lock.lock().unwrap();
|
||||
|
||||
// read generated token
|
||||
if 0 == flags & 0x1 && !is_expired(context) {
|
||||
if !regenerate && !is_expired(context) {
|
||||
let access_token = context.sql.get_config(context, "oauth2_access_token");
|
||||
if access_token.is_some() {
|
||||
// success
|
||||
@@ -216,12 +216,13 @@ pub fn dc_get_oauth2_addr(
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(access_token) = dc_get_oauth2_access_token(context, addr.as_ref(), code.as_ref(), 0)
|
||||
if let Some(access_token) =
|
||||
dc_get_oauth2_access_token(context, addr.as_ref(), code.as_ref(), false)
|
||||
{
|
||||
let addr_out = oauth2.get_addr(context, access_token);
|
||||
if addr_out.is_none() {
|
||||
// regenerate
|
||||
if let Some(access_token) = dc_get_oauth2_access_token(context, addr, code, 0x1) {
|
||||
if let Some(access_token) = dc_get_oauth2_access_token(context, addr, code, true) {
|
||||
oauth2.get_addr(context, access_token)
|
||||
} else {
|
||||
None
|
||||
|
||||
123
src/pgp.rs
123
src/pgp.rs
@@ -12,6 +12,7 @@ use pgp::types::{CompressionAlgorithm, KeyTrait, SecretKeyTrait, StringToKey};
|
||||
use rand::thread_rng;
|
||||
|
||||
use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use crate::key::*;
|
||||
use crate::keyring::*;
|
||||
use crate::x::*;
|
||||
@@ -189,7 +190,7 @@ pub fn dc_pgp_pk_encrypt(
|
||||
plain: &[u8],
|
||||
public_keys_for_encryption: &Keyring,
|
||||
private_key_for_signing: Option<&Key>,
|
||||
) -> Option<String> {
|
||||
) -> Result<String, Error> {
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
let pkeys: Vec<&SignedPublicKey> = public_keys_for_encryption
|
||||
.keys()
|
||||
@@ -203,9 +204,10 @@ pub fn dc_pgp_pk_encrypt(
|
||||
let mut rng = thread_rng();
|
||||
|
||||
// TODO: measure time
|
||||
// TODO: better error handling
|
||||
let encrypted_msg = if let Some(private_key) = private_key_for_signing {
|
||||
let skey: &SignedSecretKey = private_key.try_into().unwrap();
|
||||
let skey: &SignedSecretKey = private_key
|
||||
.try_into()
|
||||
.map_err(|_| format_err!("Invalid private key"))?;
|
||||
|
||||
lit_msg
|
||||
.sign(skey, || "".into(), Default::default())
|
||||
@@ -215,9 +217,10 @@ pub fn dc_pgp_pk_encrypt(
|
||||
lit_msg.encrypt_to_keys(&mut rng, Default::default(), &pkeys)
|
||||
};
|
||||
|
||||
encrypted_msg
|
||||
.and_then(|msg| msg.to_armored_string(None))
|
||||
.ok()
|
||||
let msg = encrypted_msg?;
|
||||
let encoded_msg = msg.to_armored_string(None)?;
|
||||
|
||||
Ok(encoded_msg)
|
||||
}
|
||||
|
||||
pub fn dc_pgp_pk_decrypt(
|
||||
@@ -225,77 +228,73 @@ pub fn dc_pgp_pk_decrypt(
|
||||
private_keys_for_decryption: &Keyring,
|
||||
public_keys_for_validation: &Keyring,
|
||||
ret_signature_fingerprints: Option<&mut HashSet<String>>,
|
||||
) -> Option<Vec<u8>> {
|
||||
// TODO: proper error handling
|
||||
if let Ok((msg, _)) = Message::from_armor_single(Cursor::new(ctext)) {
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
let k: &Key = &key;
|
||||
k.try_into().ok()
|
||||
})
|
||||
.collect();
|
||||
) -> Result<Vec<u8>, Error> {
|
||||
let (msg, _) = Message::from_armor_single(Cursor::new(ctext))?;
|
||||
let skeys: Vec<&SignedSecretKey> = private_keys_for_decryption
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
let k: &Key = &key;
|
||||
k.try_into().ok()
|
||||
})
|
||||
.collect();
|
||||
|
||||
msg.decrypt(|| "".into(), || "".into(), &skeys[..])
|
||||
.and_then(|(mut decryptor, _)| {
|
||||
// TODO: how to handle the case when we detect multiple messages?
|
||||
decryptor.next().expect("no message")
|
||||
})
|
||||
.and_then(|dec_msg| {
|
||||
if let Some(ret_signature_fingerprints) = ret_signature_fingerprints {
|
||||
if !public_keys_for_validation.keys().is_empty() {
|
||||
let pkeys: Vec<&SignedPublicKey> = public_keys_for_validation
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
let k: &Key = &key;
|
||||
k.try_into().ok()
|
||||
})
|
||||
.collect();
|
||||
let (decryptor, _) = msg.decrypt(|| "".into(), || "".into(), &skeys[..])?;
|
||||
let msgs = decryptor.collect::<Result<Vec<_>, _>>()?;
|
||||
ensure!(!msgs.is_empty(), "No valid messages found");
|
||||
|
||||
for pkey in &pkeys {
|
||||
if dec_msg.verify(&pkey.primary_key).is_ok() {
|
||||
let fp = hex::encode_upper(pkey.fingerprint());
|
||||
ret_signature_fingerprints.insert(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
let dec_msg = &msgs[0];
|
||||
|
||||
if let Some(ret_signature_fingerprints) = ret_signature_fingerprints {
|
||||
if !public_keys_for_validation.keys().is_empty() {
|
||||
let pkeys: Vec<&SignedPublicKey> = public_keys_for_validation
|
||||
.keys()
|
||||
.iter()
|
||||
.filter_map(|key| {
|
||||
let k: &Key = &key;
|
||||
k.try_into().ok()
|
||||
})
|
||||
.collect();
|
||||
|
||||
for pkey in &pkeys {
|
||||
if dec_msg.verify(&pkey.primary_key).is_ok() {
|
||||
let fp = hex::encode_upper(pkey.fingerprint());
|
||||
ret_signature_fingerprints.insert(fp);
|
||||
}
|
||||
dec_msg.get_content()
|
||||
})
|
||||
.ok()
|
||||
.and_then(|content| content)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match dec_msg.get_content()? {
|
||||
Some(content) => Ok(content),
|
||||
None => bail!("Decrypted message is empty"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Symmetric encryption.
|
||||
pub fn dc_pgp_symm_encrypt(passphrase: &str, plain: &[u8]) -> Option<String> {
|
||||
pub fn dc_pgp_symm_encrypt(passphrase: &str, plain: &[u8]) -> Result<String, Error> {
|
||||
let mut rng = thread_rng();
|
||||
let lit_msg = Message::new_literal_bytes("", plain);
|
||||
|
||||
let s2k = StringToKey::new_default(&mut rng);
|
||||
let msg =
|
||||
lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || passphrase.into());
|
||||
lit_msg.encrypt_with_password(&mut rng, s2k, Default::default(), || passphrase.into())?;
|
||||
|
||||
msg.and_then(|msg| msg.to_armored_string(None)).ok()
|
||||
let encoded_msg = msg.to_armored_string(None)?;
|
||||
|
||||
Ok(encoded_msg)
|
||||
}
|
||||
|
||||
/// Symmetric decryption.
|
||||
pub fn dc_pgp_symm_decrypt(passphrase: &str, ctext: &[u8]) -> Option<Vec<u8>> {
|
||||
let enc_msg = Message::from_bytes(Cursor::new(ctext));
|
||||
pub fn dc_pgp_symm_decrypt(passphrase: &str, ctext: &[u8]) -> Result<Vec<u8>, Error> {
|
||||
let enc_msg = Message::from_bytes(Cursor::new(ctext))?;
|
||||
let decryptor = enc_msg.decrypt_with_password(|| passphrase.into())?;
|
||||
|
||||
enc_msg
|
||||
.and_then(|msg| {
|
||||
let mut decryptor = msg.decrypt_with_password(|| passphrase.into())?;
|
||||
match decryptor.next() {
|
||||
Some(x) => x,
|
||||
None => Err(pgp::errors::Error::InvalidInput),
|
||||
}
|
||||
})
|
||||
.and_then(|msg| msg.get_content())
|
||||
.ok()
|
||||
.and_then(|content| content)
|
||||
let msgs = decryptor.collect::<Result<Vec<_>, _>>()?;
|
||||
ensure!(!msgs.is_empty(), "No valid messages found");
|
||||
|
||||
match msgs[0].get_content()? {
|
||||
Some(content) => Ok(content),
|
||||
None => bail!("Decrypted message is empty"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ impl Smtp {
|
||||
// oauth2
|
||||
let addr = &lp.addr;
|
||||
let send_pw = &lp.send_pw;
|
||||
let access_token = dc_get_oauth2_access_token(context, addr, send_pw, 0);
|
||||
let access_token = dc_get_oauth2_access_token(context, addr, send_pw, false);
|
||||
if access_token.is_none() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -68,94 +68,11 @@ pub fn configure_alice_keypair(ctx: &Context) -> String {
|
||||
// .unwrap();
|
||||
// println!("{}", public.to_base64(64));
|
||||
// println!("{}", private.to_base64(64));
|
||||
let public = key::Key::from_base64(
|
||||
concat!(
|
||||
"xsBNBF086ewBCACmJKuoxIO6T87yi4Q3MyNpMch3Y8KrtHDQyUszU36eqM3Pmd1l",
|
||||
"FrbcCd8ZWo2pq6OJSwsM/jjRGn1zo2YOaQeJRRrC+KrKGqSUtRSYQBPrPjE2YjSX",
|
||||
"AMbu8jBI6VVUhHeghriBkK79PY9O/oRhIJC0p14IJe6CQ6OI2fTmTUHF9i/nJ3G4",
|
||||
"Wb3/K1bU3yVfyPZjTZQPYPvvh03vxHULKurtYkX5DTEMSWsF4qzLMps+l87VuLV9",
|
||||
"iQnbN7YMRLHHx2KkX5Ivi7JCefhCa54M0K3bDCCxuVWAM5wjQwNZjzR+WL+dYchw",
|
||||
"oFvuF8NrlzjM9dSv+2rn+J7f99ijSXarzPC7ABEBAAHNEzxhbGljZUBleGFtcGxl",
|
||||
"LmNvbT7CwIkEEAEIADMCGQEFAl086fgCGwMECwkIBwYVCAkKCwIDFgIBFiEE+iai",
|
||||
"x4d0doj87Q0ek6DcNkbrcegACgkQk6DcNkbrcei3ogf/cruUmQ+th52TFHTHdkw9",
|
||||
"OHUl3MrXtZ7QmHyOAFvbXE/6n5Eeh+eZoF8MWWV72m14Wbs+vTcNQkFVTdOPptkK",
|
||||
"A8e4cJqwDOHsyAnvQXZ7WNje9+BMzcoipIUawHP4ORFaPDsKLZQ0b4wBbKn8ziea",
|
||||
"6zjGF0/qljTdoxTtsYpv5wXYuhwbYklrLOqgSa5M7LXUe7E3g9mbg+9iX1GuB8m6",
|
||||
"GkquJN814Y+xny4xhZzGOfue6SeP12jJMNSjSP7416dRq7794VGnkkW9V/7oFEUK",
|
||||
"u5wO9FFbgDySOSlEjByGejSGuBmho0iJSjcPjZ7EY/j3M3orq4dpza5C82OeSvxD",
|
||||
"Fc7ATQRdPOnsAQgA5oLxXRLnyugzOmNCy7dxV3JrDZscA6JNlJlDWIShT0YSs+zG",
|
||||
"9JzDeQql+sYXgUSxOoIayItuXtnFn7tstwGoOnYvadm/e5/7V5fKAQRtCtdN51av",
|
||||
"62n18Venlm0yNKpROPcZ6M/sc4m6uU6YRZ/a1idal8VGY0wLKlghjIBuIiBoVQ/R",
|
||||
"noW+/fhmwIg08dQ5m8hQe3GEOZEeLrTWL/9awPlXK7Y+DmJOoR4qbHWEcRfbzS6q",
|
||||
"4zW8vk2ztB8ngwbnqYy8zrN1DCICN1gYdlU++uVw6Bb1XfY8Cdldh1VLKpF35mAm",
|
||||
"jxLZfVDcoObFH3Cv2GB7BEYxv86KC2Y6T74Q/wARAQABwsB2BBgBCAAgBQJdPOn4",
|
||||
"AhsMFiEE+iaix4d0doj87Q0ek6DcNkbrcegACgkQk6DcNkbrcegLxwf/dXshJnoW",
|
||||
"qEnRsf6rVb9/Mc66ti+NVQLfNd275dybh/QIJdK3NmSxdnTPIEJRVspJywJoupwX",
|
||||
"FNrnHG2Ff6QPvHqI+/oNu986r9d7Z1oQibbLHKt8t6kpOfg/xGxotagJuiCQvR9m",
|
||||
"MjD1DqsdB37SjDxGupZOOJSXWi6KX60IE+uM+QOBfeOZziQwuFmA5wV6RDXIeYJf",
|
||||
"qrcbeXeR1d0nfNpPHQR1gBiqmxNb6KBbdXD2+EXW60axC7D2b1APmzMlammDliPw",
|
||||
"sK9U1rc9nuquEBvGDOJf4K+Dzn+mDCqRpP6uAuQ7RKHyim4uyN0wwKObzPqgJCGw",
|
||||
"jTglkixw+aSTXw=="
|
||||
),
|
||||
KeyType::Public,
|
||||
)
|
||||
.unwrap();
|
||||
let public =
|
||||
key::Key::from_base64(include_str!("../test-data/key/public.asc"), KeyType::Public)
|
||||
.unwrap();
|
||||
let private = key::Key::from_base64(
|
||||
concat!(
|
||||
"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",
|
||||
"zPqgJCGwjTglkixw+aSTXw=="
|
||||
),
|
||||
include_str!("../test-data/key/private.asc"),
|
||||
KeyType::Private,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
1
test-data/key/private.asc
Normal file
1
test-data/key/private.asc
Normal file
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -573,7 +573,7 @@ fn test_dc_get_oauth2_token() {
|
||||
let ctx = create_test_context();
|
||||
let addr = "dignifiedquire@gmail.com";
|
||||
let code = "fail";
|
||||
let res = dc_get_oauth2_access_token(&ctx.ctx, addr, code, 0);
|
||||
let res = dc_get_oauth2_access_token(&ctx.ctx, addr, code, false);
|
||||
// this should fail as it is an invalid password
|
||||
assert_eq!(res, None);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user