Skip to content

Commit 0df86b6

Browse files
Hocuriadbenitez
andauthored
fix: fixes for transport JsonRPC (#6680)
Follow-up to #6582 --------- Co-authored-by: adbenitez <asieldbenitez@gmail.com>
1 parent e951a69 commit 0df86b6

File tree

7 files changed

+183
-127
lines changed

7 files changed

+183
-127
lines changed

deltachat-jsonrpc/src/api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ impl CommandApi {
457457
///
458458
/// This function stops and starts IO as needed.
459459
///
460-
/// Usually it will be enough to only set `addr` and `imap.password`,
460+
/// Usually it will be enough to only set `addr` and `password`,
461461
/// and all the other settings will be autoconfigured.
462462
///
463463
/// During configuration, ConfigureProgress events are emitted;

deltachat-jsonrpc/src/api/types/login_param.rs

Lines changed: 84 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -4,83 +4,75 @@ use serde::Deserialize;
44
use serde::Serialize;
55
use yerpc::TypeDef;
66

7+
/// Login parameters entered by the user.
8+
79
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
810
#[serde(rename_all = "camelCase")]
9-
pub struct EnteredServerLoginParam {
10-
/// Server hostname or IP address.
11-
pub server: String,
11+
pub struct EnteredLoginParam {
12+
/// Email address.
13+
pub addr: String,
1214

13-
/// Server port.
14-
///
15-
/// 0 if not specified.
16-
pub port: u16,
15+
/// Password.
16+
pub password: String,
1717

18-
/// Socket security.
19-
pub security: Socket,
18+
/// Imap server hostname or IP address.
19+
pub imap_server: Option<String>,
2020

21-
/// Username.
22-
///
23-
/// Empty string if not specified.
24-
pub user: String,
21+
/// Imap server port.
22+
pub imap_port: Option<u16>,
2523

26-
/// Password.
27-
pub password: String,
28-
}
24+
/// Imap socket security.
25+
pub imap_security: Option<Socket>,
2926

30-
impl From<dc::EnteredServerLoginParam> for EnteredServerLoginParam {
31-
fn from(param: dc::EnteredServerLoginParam) -> Self {
32-
Self {
33-
server: param.server,
34-
port: param.port,
35-
security: param.security.into(),
36-
user: param.user,
37-
password: param.password,
38-
}
39-
}
40-
}
27+
/// Imap username.
28+
pub imap_user: Option<String>,
4129

42-
impl From<EnteredServerLoginParam> for dc::EnteredServerLoginParam {
43-
fn from(param: EnteredServerLoginParam) -> Self {
44-
Self {
45-
server: param.server,
46-
port: param.port,
47-
security: param.security.into(),
48-
user: param.user,
49-
password: param.password,
50-
}
51-
}
52-
}
30+
/// SMTP server hostname or IP address.
31+
pub smtp_server: Option<String>,
5332

54-
/// Login parameters entered by the user.
33+
/// SMTP server port.
34+
pub smtp_port: Option<u16>,
5535

56-
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
57-
#[serde(rename_all = "camelCase")]
58-
pub struct EnteredLoginParam {
59-
/// Email address.
60-
pub addr: String,
36+
/// SMTP socket security.
37+
pub smtp_security: Option<Socket>,
6138

62-
/// IMAP settings.
63-
pub imap: EnteredServerLoginParam,
39+
/// SMTP username.
40+
pub smtp_user: Option<String>,
6441

65-
/// SMTP settings.
66-
pub smtp: EnteredServerLoginParam,
42+
/// SMTP Password.
43+
///
44+
/// Only needs to be specified if different than IMAP password.
45+
pub smtp_password: Option<String>,
6746

6847
/// TLS options: whether to allow invalid certificates and/or
69-
/// invalid hostnames
70-
pub certificate_checks: EnteredCertificateChecks,
48+
/// invalid hostnames.
49+
/// Default: Automatic
50+
pub certificate_checks: Option<EnteredCertificateChecks>,
7151

72-
/// If true, login via OAUTH2 (not recommended anymore)
73-
pub oauth2: bool,
52+
/// If true, login via OAUTH2 (not recommended anymore).
53+
/// Default: false
54+
pub oauth2: Option<bool>,
7455
}
7556

7657
impl From<dc::EnteredLoginParam> for EnteredLoginParam {
7758
fn from(param: dc::EnteredLoginParam) -> Self {
59+
let imap_security: Socket = param.imap.security.into();
60+
let smtp_security: Socket = param.smtp.security.into();
61+
let certificate_checks: EnteredCertificateChecks = param.certificate_checks.into();
7862
Self {
7963
addr: param.addr,
80-
imap: param.imap.into(),
81-
smtp: param.smtp.into(),
82-
certificate_checks: param.certificate_checks.into(),
83-
oauth2: param.oauth2,
64+
password: param.imap.password,
65+
imap_server: param.imap.server.into_option(),
66+
imap_port: param.imap.port.into_option(),
67+
imap_security: imap_security.into_option(),
68+
imap_user: param.imap.user.into_option(),
69+
smtp_server: param.smtp.server.into_option(),
70+
smtp_port: param.smtp.port.into_option(),
71+
smtp_security: smtp_security.into_option(),
72+
smtp_user: param.smtp.user.into_option(),
73+
smtp_password: param.smtp.password.into_option(),
74+
certificate_checks: certificate_checks.into_option(),
75+
oauth2: param.oauth2.into_option(),
8476
}
8577
}
8678
}
@@ -91,18 +83,31 @@ impl TryFrom<EnteredLoginParam> for dc::EnteredLoginParam {
9183
fn try_from(param: EnteredLoginParam) -> Result<Self> {
9284
Ok(Self {
9385
addr: param.addr,
94-
imap: param.imap.into(),
95-
smtp: param.smtp.into(),
96-
certificate_checks: param.certificate_checks.into(),
97-
oauth2: param.oauth2,
86+
imap: dc::EnteredServerLoginParam {
87+
server: param.imap_server.unwrap_or_default(),
88+
port: param.imap_port.unwrap_or_default(),
89+
security: param.imap_security.unwrap_or_default().into(),
90+
user: param.imap_user.unwrap_or_default(),
91+
password: param.password,
92+
},
93+
smtp: dc::EnteredServerLoginParam {
94+
server: param.smtp_server.unwrap_or_default(),
95+
port: param.smtp_port.unwrap_or_default(),
96+
security: param.smtp_security.unwrap_or_default().into(),
97+
user: param.smtp_user.unwrap_or_default(),
98+
password: param.smtp_password.unwrap_or_default(),
99+
},
100+
certificate_checks: param.certificate_checks.unwrap_or_default().into(),
101+
oauth2: param.oauth2.unwrap_or_default(),
98102
})
99103
}
100104
}
101105

102-
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
106+
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema, Default, PartialEq)]
103107
#[serde(rename_all = "camelCase")]
104108
pub enum Socket {
105109
/// Unspecified socket security, select automatically.
110+
#[default]
106111
Automatic,
107112

108113
/// TLS connection.
@@ -137,12 +142,13 @@ impl From<Socket> for dc::Socket {
137142
}
138143
}
139144

140-
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
145+
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema, Default, PartialEq)]
141146
#[serde(rename_all = "camelCase")]
142147
pub enum EnteredCertificateChecks {
143148
/// `Automatic` means that provider database setting should be taken.
144149
/// If there is no provider database setting for certificate checks,
145150
/// check certificates strictly.
151+
#[default]
146152
Automatic,
147153

148154
/// Ensure that TLS certificate is valid for the server hostname.
@@ -177,3 +183,19 @@ impl From<EnteredCertificateChecks> for dc::EnteredCertificateChecks {
177183
}
178184
}
179185
}
186+
187+
trait IntoOption<T> {
188+
fn into_option(self) -> Option<T>;
189+
}
190+
impl<T> IntoOption<T> for T
191+
where
192+
T: Default + std::cmp::PartialEq,
193+
{
194+
fn into_option(self) -> Option<T> {
195+
if self == T::default() {
196+
None
197+
} else {
198+
Some(self)
199+
}
200+
}
201+
}

deltachat-rpc-client/src/deltachat_rpc_client/pytestplugin.py

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,6 @@
1212
from .rpc import Rpc
1313

1414

15-
def get_temp_credentials() -> dict:
16-
domain = os.getenv("CHATMAIL_DOMAIN")
17-
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
18-
password = f"{username}${username}"
19-
addr = f"{username}@{domain}"
20-
return {"email": addr, "password": password}
21-
22-
2315
class ACFactory:
2416
def __init__(self, deltachat: DeltaChat) -> None:
2517
self.deltachat = deltachat
@@ -32,26 +24,25 @@ def get_unconfigured_account(self) -> Account:
3224
def get_unconfigured_bot(self) -> Bot:
3325
return Bot(self.get_unconfigured_account())
3426

35-
def new_preconfigured_account(self) -> Account:
36-
"""Make a new account with configuration options set, but configuration not started."""
37-
credentials = get_temp_credentials()
38-
account = self.get_unconfigured_account()
39-
account.set_config("addr", credentials["email"])
40-
account.set_config("mail_pw", credentials["password"])
41-
assert not account.is_configured()
42-
return account
27+
def get_credentials(self) -> (str, str):
28+
domain = os.getenv("CHATMAIL_DOMAIN")
29+
username = "ci-" + "".join(random.choice("2345789acdefghjkmnpqrstuvwxyz") for i in range(6))
30+
return f"{username}@{domain}", f"{username}${username}"
4331

4432
@futuremethod
4533
def new_configured_account(self):
46-
account = self.new_preconfigured_account()
47-
yield account.configure.future()
34+
addr, password = self.get_credentials()
35+
account = self.get_unconfigured_account()
36+
params = {"addr": addr, "password": password}
37+
yield account._rpc.add_transport.future(account.id, params)
38+
4839
assert account.is_configured()
4940
return account
5041

5142
def new_configured_bot(self) -> Bot:
52-
credentials = get_temp_credentials()
43+
addr, password = self.get_credentials()
5344
bot = self.get_unconfigured_bot()
54-
bot.configure(credentials["email"], credentials["password"])
45+
bot.configure(addr, password)
5546
return bot
5647

5748
@futuremethod

deltachat-rpc-client/tests/test_account_events.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ def test_event_on_configuration(acfactory: ACFactory) -> None:
1313
Test if ACCOUNTS_ITEM_CHANGED event is emitted on configure
1414
"""
1515

16-
account = acfactory.new_preconfigured_account()
16+
addr, password = acfactory.get_credentials()
17+
account = acfactory.get_unconfigured_account()
1718
account.clear_all_events()
1819
assert not account.is_configured()
19-
future = account.configure.future()
20+
future = account._rpc.add_transport.future(account.id, {"addr": addr, "password": password})
2021
while True:
2122
event = account.wait_for_event()
2223
if event.kind == EventType.ACCOUNTS_ITEM_CHANGED:

deltachat-rpc-client/tests/test_securejoin.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,7 @@ def test_aeap_flow_verified(acfactory):
458458
"""Test that a new address is added to a contact when it changes its address."""
459459
ac1, ac2 = acfactory.get_online_accounts(2)
460460

461-
# ac1new is only used to get a new address.
462-
ac1new = acfactory.new_preconfigured_account()
461+
addr, password = acfactory.get_credentials()
463462

464463
logging.info("ac1: create verified-group QR, ac2 scans and joins")
465464
chat = ac1.create_group("hello", protect=True)
@@ -479,8 +478,8 @@ def test_aeap_flow_verified(acfactory):
479478
assert msg_in_1.text == msg_out.text
480479

481480
logging.info("changing email account")
482-
ac1.set_config("addr", ac1new.get_config("addr"))
483-
ac1.set_config("mail_pw", ac1new.get_config("mail_pw"))
481+
ac1.set_config("addr", addr)
482+
ac1.set_config("mail_pw", password)
484483
ac1.stop_io()
485484
ac1.configure()
486485
ac1.start_io()
@@ -493,11 +492,9 @@ def test_aeap_flow_verified(acfactory):
493492
msg_in_2_snapshot = msg_in_2.get_snapshot()
494493
assert msg_in_2_snapshot.text == msg_out.text
495494
assert msg_in_2_snapshot.chat.id == msg_in_1.chat.id
496-
assert msg_in_2.get_sender_contact().get_snapshot().address == ac1new.get_config("addr")
495+
assert msg_in_2.get_sender_contact().get_snapshot().address == addr
497496
assert len(msg_in_2_snapshot.chat.get_contacts()) == 2
498-
assert ac1new.get_config("addr") in [
499-
contact.get_snapshot().address for contact in msg_in_2_snapshot.chat.get_contacts()
500-
]
497+
assert addr in [contact.get_snapshot().address for contact in msg_in_2_snapshot.chat.get_contacts()]
501498

502499

503500
def test_gossip_verification(acfactory) -> None:

0 commit comments

Comments
 (0)