mirror of
https://github.com/chatmail/core.git
synced 2026-04-20 23:16:30 +03:00
api: Sketch add_transport_from_qr(), add_transport(), list_transports(), delete_transport() APIs (#6589)
Four new APIs `add_transport_from_qr()`, `add_transport()`, `list_transports()`, `delete_transport()`, as described in the draft at "API". The `add_tranport*()` APIs automatically stops and starts I/O; for `configure()` the stopping and starting is done in the JsonRPC bindings, which is not where things like this should be done I think, the bindings should just translate the APIs. This also completely disables AEAP for now. I won't be available for a week, but if you want to merge this already, feel free to just commit all review suggestions and squash-merge.
This commit is contained in:
@@ -39,6 +39,7 @@ use deltachat::{imex, info};
|
||||
use sanitize_filename::is_sanitized;
|
||||
use tokio::fs;
|
||||
use tokio::sync::{watch, Mutex, RwLock};
|
||||
use types::login_param::EnteredLoginParam;
|
||||
use walkdir::WalkDir;
|
||||
use yerpc::rpc;
|
||||
|
||||
@@ -431,6 +432,9 @@ impl CommandApi {
|
||||
|
||||
/// Configures this account with the currently set parameters.
|
||||
/// Setup the credential config before calling this.
|
||||
///
|
||||
/// Deprecated as of 2025-02; use `add_transport_from_qr()`
|
||||
/// or `add_transport()` instead.
|
||||
async fn configure(&self, account_id: u32) -> Result<()> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
ctx.stop_io().await;
|
||||
@@ -445,6 +449,69 @@ impl CommandApi {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Configures a new email account using the provided parameters
|
||||
/// and adds it as a transport.
|
||||
///
|
||||
/// If the email address is the same as an existing transport,
|
||||
/// then this existing account will be reconfigured instead of a new one being added.
|
||||
///
|
||||
/// This function stops and starts IO as needed.
|
||||
///
|
||||
/// Usually it will be enough to only set `addr` and `imap.password`,
|
||||
/// and all the other settings will be autoconfigured.
|
||||
///
|
||||
/// During configuration, ConfigureProgress events are emitted;
|
||||
/// they indicate a successful configuration as well as errors
|
||||
/// and may be used to create a progress bar.
|
||||
/// This function will return after configuration is finished.
|
||||
///
|
||||
/// If configuration is successful,
|
||||
/// the working server parameters will be saved
|
||||
/// and used for connecting to the server.
|
||||
/// The parameters entered by the user will be saved separately
|
||||
/// so that they can be prefilled when the user opens the server-configuration screen again.
|
||||
///
|
||||
/// See also:
|
||||
/// - [Self::is_configured()] to check whether there is
|
||||
/// at least one working transport.
|
||||
/// - [Self::add_transport_from_qr()] to add a transport
|
||||
/// from a server encoded in a QR code.
|
||||
/// - [Self::list_transports()] to get a list of all configured transports.
|
||||
/// - [Self::delete_transport()] to remove a transport.
|
||||
async fn add_transport(&self, account_id: u32, param: EnteredLoginParam) -> Result<()> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
ctx.add_transport(¶m.try_into()?).await
|
||||
}
|
||||
|
||||
/// Adds a new email account as a transport
|
||||
/// using the server encoded in the QR code.
|
||||
/// See [Self::add_transport].
|
||||
async fn add_transport_from_qr(&self, account_id: u32, qr: String) -> Result<()> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
ctx.add_transport_from_qr(&qr).await
|
||||
}
|
||||
|
||||
/// Returns the list of all email accounts that are used as a transport in the current profile.
|
||||
/// Use [Self::add_transport()] to add or change a transport
|
||||
/// and [Self::delete_transport()] to delete a transport.
|
||||
async fn list_transports(&self, account_id: u32) -> Result<Vec<EnteredLoginParam>> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
let res = ctx
|
||||
.list_transports()
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|t| t.into())
|
||||
.collect();
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
/// Removes the transport with the specified email address
|
||||
/// (i.e. [EnteredLoginParam::addr]).
|
||||
async fn delete_transport(&self, account_id: u32, addr: String) -> Result<()> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
ctx.delete_transport(&addr).await
|
||||
}
|
||||
|
||||
/// Signal an ongoing process to stop.
|
||||
async fn stop_ongoing_process(&self, account_id: u32) -> Result<()> {
|
||||
let ctx = self.get_context(account_id).await?;
|
||||
|
||||
179
deltachat-jsonrpc/src/api/types/login_param.rs
Normal file
179
deltachat-jsonrpc/src/api/types/login_param.rs
Normal file
@@ -0,0 +1,179 @@
|
||||
use anyhow::Result;
|
||||
use deltachat::login_param as dc;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use yerpc::TypeDef;
|
||||
|
||||
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EnteredServerLoginParam {
|
||||
/// Server hostname or IP address.
|
||||
pub server: String,
|
||||
|
||||
/// Server port.
|
||||
///
|
||||
/// 0 if not specified.
|
||||
pub port: u16,
|
||||
|
||||
/// Socket security.
|
||||
pub security: Socket,
|
||||
|
||||
/// Username.
|
||||
///
|
||||
/// Empty string if not specified.
|
||||
pub user: String,
|
||||
|
||||
/// Password.
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl From<dc::EnteredServerLoginParam> for EnteredServerLoginParam {
|
||||
fn from(param: dc::EnteredServerLoginParam) -> Self {
|
||||
Self {
|
||||
server: param.server,
|
||||
port: param.port,
|
||||
security: param.security.into(),
|
||||
user: param.user,
|
||||
password: param.password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EnteredServerLoginParam> for dc::EnteredServerLoginParam {
|
||||
fn from(param: EnteredServerLoginParam) -> Self {
|
||||
Self {
|
||||
server: param.server,
|
||||
port: param.port,
|
||||
security: param.security.into(),
|
||||
user: param.user,
|
||||
password: param.password,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Login parameters entered by the user.
|
||||
|
||||
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct EnteredLoginParam {
|
||||
/// Email address.
|
||||
pub addr: String,
|
||||
|
||||
/// IMAP settings.
|
||||
pub imap: EnteredServerLoginParam,
|
||||
|
||||
/// SMTP settings.
|
||||
pub smtp: EnteredServerLoginParam,
|
||||
|
||||
/// TLS options: whether to allow invalid certificates and/or
|
||||
/// invalid hostnames
|
||||
pub certificate_checks: EnteredCertificateChecks,
|
||||
|
||||
/// If true, login via OAUTH2 (not recommended anymore)
|
||||
pub oauth2: bool,
|
||||
}
|
||||
|
||||
impl From<dc::EnteredLoginParam> for EnteredLoginParam {
|
||||
fn from(param: dc::EnteredLoginParam) -> Self {
|
||||
Self {
|
||||
addr: param.addr,
|
||||
imap: param.imap.into(),
|
||||
smtp: param.smtp.into(),
|
||||
certificate_checks: param.certificate_checks.into(),
|
||||
oauth2: param.oauth2,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<EnteredLoginParam> for dc::EnteredLoginParam {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(param: EnteredLoginParam) -> Result<Self> {
|
||||
Ok(Self {
|
||||
addr: param.addr,
|
||||
imap: param.imap.into(),
|
||||
smtp: param.smtp.into(),
|
||||
certificate_checks: param.certificate_checks.into(),
|
||||
oauth2: param.oauth2,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum Socket {
|
||||
/// Unspecified socket security, select automatically.
|
||||
Automatic,
|
||||
|
||||
/// TLS connection.
|
||||
Ssl,
|
||||
|
||||
/// STARTTLS connection.
|
||||
Starttls,
|
||||
|
||||
/// No TLS, plaintext connection.
|
||||
Plain,
|
||||
}
|
||||
|
||||
impl From<dc::Socket> for Socket {
|
||||
fn from(value: dc::Socket) -> Self {
|
||||
match value {
|
||||
dc::Socket::Automatic => Self::Automatic,
|
||||
dc::Socket::Ssl => Self::Ssl,
|
||||
dc::Socket::Starttls => Self::Starttls,
|
||||
dc::Socket::Plain => Self::Plain,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Socket> for dc::Socket {
|
||||
fn from(value: Socket) -> Self {
|
||||
match value {
|
||||
Socket::Automatic => Self::Automatic,
|
||||
Socket::Ssl => Self::Ssl,
|
||||
Socket::Starttls => Self::Starttls,
|
||||
Socket::Plain => Self::Plain,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, TypeDef, schemars::JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum EnteredCertificateChecks {
|
||||
/// `Automatic` means that provider database setting should be taken.
|
||||
/// If there is no provider database setting for certificate checks,
|
||||
/// check certificates strictly.
|
||||
Automatic,
|
||||
|
||||
/// Ensure that TLS certificate is valid for the server hostname.
|
||||
Strict,
|
||||
|
||||
/// Accept certificates that are expired, self-signed
|
||||
/// or otherwise not valid for the server hostname.
|
||||
AcceptInvalidCertificates,
|
||||
}
|
||||
|
||||
impl From<dc::EnteredCertificateChecks> for EnteredCertificateChecks {
|
||||
fn from(value: dc::EnteredCertificateChecks) -> Self {
|
||||
match value {
|
||||
dc::EnteredCertificateChecks::Automatic => Self::Automatic,
|
||||
dc::EnteredCertificateChecks::Strict => Self::Strict,
|
||||
dc::EnteredCertificateChecks::AcceptInvalidCertificates => {
|
||||
Self::AcceptInvalidCertificates
|
||||
}
|
||||
dc::EnteredCertificateChecks::AcceptInvalidCertificates2 => {
|
||||
Self::AcceptInvalidCertificates
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EnteredCertificateChecks> for dc::EnteredCertificateChecks {
|
||||
fn from(value: EnteredCertificateChecks) -> Self {
|
||||
match value {
|
||||
EnteredCertificateChecks::Automatic => Self::Automatic,
|
||||
EnteredCertificateChecks::Strict => Self::Strict,
|
||||
EnteredCertificateChecks::AcceptInvalidCertificates => Self::AcceptInvalidCertificates,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ pub mod contact;
|
||||
pub mod events;
|
||||
pub mod http;
|
||||
pub mod location;
|
||||
pub mod login_param;
|
||||
pub mod message;
|
||||
pub mod provider_info;
|
||||
pub mod qr;
|
||||
|
||||
Reference in New Issue
Block a user