mirror of
https://github.com/chatmail/core.git
synced 2026-04-27 10:26:29 +03:00
restricted webxdc internet access (#3516)
* add request_internet_access manifest option * test request_internet_access * update CHANGELOG * force warning when internet access is enabled if internet access is enabled, show a warning instead of the normal summary (the internet access is currently mainly to test out integrations as maps for video chat; the summary is dispensable in the cases currently) * adapt json-rpc's WebxdcMessageInfo
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
### Changes
|
||||
- order contact lists by "last seen";
|
||||
this affects `dc_get_chat_contacts()`, `dc_get_contacts()` and `dc_get_blocked_contacts()` #3562
|
||||
- add `internet_access` flag to `dc_msg_get_webxdc_info()` #3516
|
||||
|
||||
### Fixes
|
||||
- do not emit notifications for blocked chats #3557
|
||||
|
||||
@@ -3763,6 +3763,11 @@ char* dc_msg_get_webxdc_blob (const dc_msg_t* msg, const char*
|
||||
* URL where the source code of the Webxdc and other information can be found;
|
||||
* defaults to an empty string.
|
||||
* Implementations may offer an menu or a button to open this URL.
|
||||
* - internet_access:
|
||||
* true if the Webxdc should get full internet access, including Webrtc.
|
||||
* currently, this is only true for encrypted Webxdc's in the self chat
|
||||
* that have requested internet access in the manifest.
|
||||
* this is useful for development and maybe for internal integrations at some point.
|
||||
*
|
||||
* @memberof dc_msg_t
|
||||
* @param msg The webxdc instance.
|
||||
|
||||
@@ -33,6 +33,8 @@ pub struct WebxdcMessageInfo {
|
||||
/// defaults to an empty string.
|
||||
/// Implementations may offer an menu or a button to open this URL.
|
||||
source_code_url: Option<String>,
|
||||
/// True if full internet access should be granted to the app.
|
||||
internet_access: bool,
|
||||
}
|
||||
|
||||
impl WebxdcMessageInfo {
|
||||
@@ -47,6 +49,7 @@ impl WebxdcMessageInfo {
|
||||
document,
|
||||
summary,
|
||||
source_code_url,
|
||||
internet_access,
|
||||
} = message.get_webxdc_info(context).await?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -55,6 +58,7 @@ impl WebxdcMessageInfo {
|
||||
document: maybe_empty_string_to_option(document),
|
||||
summary: maybe_empty_string_to_option(summary),
|
||||
source_code_url: maybe_empty_string_to_option(source_code_url),
|
||||
internet_access,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,5 +94,9 @@ export type WebxdcMessageInfo={
|
||||
* defaults to an empty string.
|
||||
* Implementations may offer an menu or a button to open this URL.
|
||||
*/
|
||||
"sourceCodeUrl":(string|null);};
|
||||
"sourceCodeUrl":(string|null);
|
||||
/**
|
||||
* True if full internet access should be granted to the app.
|
||||
*/
|
||||
"internetAccess":boolean;};
|
||||
export type __AllTyps=[string,boolean,Record<string,string>,U32,U32,null,(U32)[],U32,null,(U32|null),(Account)[],U32,Account,U32,string,(ProviderInfo|null),U32,boolean,U32,Record<string,string>,U32,string,(string|null),null,U32,Record<string,(string|null)>,null,U32,string,null,U32,string,Qr,U32,string,(string|null),U32,(string)[],Record<string,(string|null)>,U32,null,U32,null,U32,(U32)[],U32,U32,Usize,U32,string,U32,U32,string,null,U32,(U32|null),(string|null),(U32|null),(ChatListEntry)[],U32,(ChatListEntry)[],Record<U32,ChatListItemFetchResult>,U32,U32,FullChat,U32,U32,null,U32,U32,null,U32,string,string,U32,U32,U32,U32,(U32)[],U32,U32,Message,U32,(U32)[],Record<U32,Message>,U32,U32,Contact,U32,string,(string|null),U32,U32,U32,U32,U32,U32,null,U32,U32,null,U32,(Contact)[],U32,U32,(string|null),(U32)[],U32,U32,(string|null),(Contact)[],U32,(U32)[],Record<U32,Contact>,U32,(U32|null),Viewtype,(Viewtype|null),(Viewtype|null),(U32)[],U32,U32,string,string,null,U32,U32,U32,string,U32,U32,WebxdcMessageInfo,U32,string,U32,U32];
|
||||
|
||||
@@ -56,6 +56,7 @@ struct WebxdcManifest {
|
||||
name: Option<String>,
|
||||
min_api: Option<u32>,
|
||||
source_code_url: Option<String>,
|
||||
request_internet_access: Option<bool>,
|
||||
}
|
||||
|
||||
/// Parsed information from WebxdcManifest and fallbacks.
|
||||
@@ -66,6 +67,7 @@ pub struct WebxdcInfo {
|
||||
pub document: String,
|
||||
pub summary: String,
|
||||
pub source_code_url: String,
|
||||
pub internet_access: bool,
|
||||
}
|
||||
|
||||
/// Status Update ID.
|
||||
@@ -676,6 +678,7 @@ impl Message {
|
||||
name: None,
|
||||
min_api: None,
|
||||
source_code_url: None,
|
||||
request_internet_access: None,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -683,6 +686,7 @@ impl Message {
|
||||
name: None,
|
||||
min_api: None,
|
||||
source_code_url: None,
|
||||
request_internet_access: None,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -694,6 +698,10 @@ impl Message {
|
||||
}
|
||||
}
|
||||
|
||||
let internet_access = manifest.request_internet_access.unwrap_or_default()
|
||||
&& self.chat_id.is_self_talk(context).await.unwrap_or_default()
|
||||
&& self.get_showpadlock();
|
||||
|
||||
Ok(WebxdcInfo {
|
||||
name: if let Some(name) = manifest.name {
|
||||
name
|
||||
@@ -712,16 +720,20 @@ impl Message {
|
||||
.get(Param::WebxdcDocument)
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
summary: self
|
||||
.param
|
||||
.get(Param::WebxdcSummary)
|
||||
.unwrap_or_default()
|
||||
.to_string(),
|
||||
summary: if internet_access {
|
||||
"Dev Mode: Do not enter sensitive data!".to_string()
|
||||
} else {
|
||||
self.param
|
||||
.get(Param::WebxdcSummary)
|
||||
.unwrap_or_default()
|
||||
.to_string()
|
||||
},
|
||||
source_code_url: if let Some(url) = manifest.source_code_url {
|
||||
url
|
||||
} else {
|
||||
"".to_string()
|
||||
},
|
||||
internet_access,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -729,8 +741,8 @@ impl Message {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::chat::{
|
||||
add_contact_to_chat, create_group_chat, forward_msgs, resend_msgs, send_msg, send_text_msg,
|
||||
ChatId, ProtectionStatus,
|
||||
add_contact_to_chat, create_broadcast_list, create_group_chat, forward_msgs, resend_msgs,
|
||||
send_msg, send_text_msg, ChatId, ProtectionStatus,
|
||||
};
|
||||
use crate::chatlist::Chatlist;
|
||||
use crate::config::Config;
|
||||
@@ -1781,6 +1793,19 @@ sth_for_the = "future""#
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_parse_webxdc_manifest_request_internet_access() -> Result<()> {
|
||||
let result = parse_webxdc_manifest(r#"request_internet_access = 3"#.as_bytes());
|
||||
assert!(result.is_err());
|
||||
let manifest = parse_webxdc_manifest(r#" source_code_url="https://foo.org""#.as_bytes())?;
|
||||
assert_eq!(manifest.request_internet_access, None);
|
||||
let manifest = parse_webxdc_manifest(r#" request_internet_access=false"#.as_bytes())?;
|
||||
assert_eq!(manifest.request_internet_access, Some(false));
|
||||
let manifest = parse_webxdc_manifest(r#"request_internet_access = true"#.as_bytes())?;
|
||||
assert_eq!(manifest.request_internet_access, Some(true));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_webxdc_min_api_too_large() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
@@ -2191,6 +2216,51 @@ sth_for_the = "future""#
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_webxdc_internet_access() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
let self_id = t.get_self_chat().await.id;
|
||||
let single_id = t.create_chat_with_contact("bob", "bob@e.com").await.id;
|
||||
let group_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
|
||||
let broadcast_id = create_broadcast_list(&t).await?;
|
||||
|
||||
let mut first_test = true; // only the first test has all conditions for internet access
|
||||
|
||||
for e2ee in ["1", "0"] {
|
||||
t.set_config(Config::E2eeEnabled, Some(e2ee)).await?;
|
||||
for chat_id in [self_id, single_id, group_id, broadcast_id] {
|
||||
for internet_xdc in [true, false] {
|
||||
let mut instance = create_webxdc_instance(
|
||||
&t,
|
||||
"foo.xdc",
|
||||
if internet_xdc {
|
||||
include_bytes!("../test-data/webxdc/request-internet-access.xdc")
|
||||
} else {
|
||||
include_bytes!("../test-data/webxdc/minimal.xdc")
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
let instance_id = send_msg(&t, chat_id, &mut instance).await?;
|
||||
t.send_webxdc_status_update(
|
||||
instance_id,
|
||||
r#"{"summary":"real summary", "payload": 42}"#,
|
||||
"descr",
|
||||
)
|
||||
.await?;
|
||||
let instance = Message::load_from_db(&t, instance_id).await?;
|
||||
let info = instance.get_webxdc_info(&t).await?;
|
||||
assert_eq!(info.internet_access, first_test);
|
||||
assert_eq!(info.summary.contains("Do not enter sensitive"), first_test);
|
||||
assert_eq!(info.summary.contains("real summary"), !first_test);
|
||||
|
||||
first_test = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_webxdc_chatlist_summary() -> Result<()> {
|
||||
let t = TestContext::new_alice().await;
|
||||
|
||||
BIN
test-data/webxdc/request-internet-access.xdc
Normal file
BIN
test-data/webxdc/request-internet-access.xdc
Normal file
Binary file not shown.
Reference in New Issue
Block a user