mirror of
https://github.com/chatmail/core.git
synced 2026-05-07 08:56:30 +03:00
add set_chat_protection() api
This commit is contained in:
@@ -1170,6 +1170,24 @@ dc_array_t* dc_get_chat_media (dc_context_t* context, uint32_t ch
|
|||||||
uint32_t dc_get_next_media (dc_context_t* context, uint32_t msg_id, int dir, int msg_type, int msg_type2, int msg_type3);
|
uint32_t dc_get_next_media (dc_context_t* context, uint32_t msg_id, int dir, int msg_type, int msg_type2, int msg_type3);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable protection against active attacks.
|
||||||
|
* To enable protection, it is needed that all members are verified;
|
||||||
|
* if this condition is met, end-to-end-encryption is always enabled
|
||||||
|
* and only the verified keys are used.
|
||||||
|
*
|
||||||
|
* Sends out #DC_EVENT_CHAT_MODIFIED on changes
|
||||||
|
* and #DC_EVENT_MSGS_CHANGED if a status message was sent.
|
||||||
|
*
|
||||||
|
* @memberof dc_context_t
|
||||||
|
* @param context The context object as returned from dc_context_new().
|
||||||
|
* @param chat_id The ID of the chat to change the protection for.
|
||||||
|
* @param protect 1=protect chat, 0=unprotect chat
|
||||||
|
* @return 1=success, 0=error, eg. some members may be unverified
|
||||||
|
*/
|
||||||
|
int dc_set_chat_protection (dc_context_t* context, uint32_t chat_id, int protect);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set chat visibility to pinned, archived or normal.
|
* Set chat visibility to pinned, archived or normal.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1057,6 +1057,35 @@ pub unsafe extern "C" fn dc_get_next_media(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn dc_set_chat_protection(
|
||||||
|
context: *mut dc_context_t,
|
||||||
|
chat_id: u32,
|
||||||
|
protect: libc::c_int,
|
||||||
|
) -> libc::c_int {
|
||||||
|
if context.is_null() {
|
||||||
|
eprintln!("ignoring careless call to dc_set_chat_protection()");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let ctx = &*context;
|
||||||
|
let protect = if let Some(s) = contact::ProtectionStatus::from_i32(protect) {
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
eprintln!("bad protect-value for dc_set_chat_protection()");
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
block_on(async move {
|
||||||
|
match ChatId::new(chat_id).set_protection(&ctx, protect).await {
|
||||||
|
Ok(()) => 1,
|
||||||
|
Err(err) => {
|
||||||
|
error!(ctx, "Cannot protect chat. Are all members verified?");
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn dc_set_chat_visibility(
|
pub unsafe extern "C" fn dc_set_chat_visibility(
|
||||||
context: *mut dc_context_t,
|
context: *mut dc_context_t,
|
||||||
|
|||||||
@@ -379,6 +379,8 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
unarchive <chat-id>\n\
|
unarchive <chat-id>\n\
|
||||||
pin <chat-id>\n\
|
pin <chat-id>\n\
|
||||||
unpin <chat-id>\n\
|
unpin <chat-id>\n\
|
||||||
|
protect <chat-id>\n\
|
||||||
|
unprotect <chat-id>\n\
|
||||||
delchat <chat-id>\n\
|
delchat <chat-id>\n\
|
||||||
===========================Message commands==\n\
|
===========================Message commands==\n\
|
||||||
listmsgs <query>\n\
|
listmsgs <query>\n\
|
||||||
@@ -918,6 +920,20 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
|
"protect" | "unprotect" => {
|
||||||
|
ensure!(!arg1.is_empty(), "Argument <chat-id> missing.");
|
||||||
|
let chat_id = ChatId::new(arg1.parse()?);
|
||||||
|
chat_id
|
||||||
|
.set_protection(
|
||||||
|
&context,
|
||||||
|
match arg0 {
|
||||||
|
"protect" => ProtectionStatus::Protected,
|
||||||
|
"unprotect" => ProtectionStatus::Unprotected,
|
||||||
|
_ => panic!("Unexpected command (This should never happen)"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
"delchat" => {
|
"delchat" => {
|
||||||
ensure!(!arg1.is_empty(), "Argument <chat-id> missing.");
|
ensure!(!arg1.is_empty(), "Argument <chat-id> missing.");
|
||||||
let chat_id = ChatId::new(arg1.parse()?);
|
let chat_id = ChatId::new(arg1.parse()?);
|
||||||
|
|||||||
82
src/chat.rs
82
src/chat.rs
@@ -174,6 +174,79 @@ impl ChatId {
|
|||||||
self.set_blocked(context, Blocked::Not).await;
|
self.set_blocked(context, Blocked::Not).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set protection without sending a message.
|
||||||
|
/// Used when a message arrives indicating that someone else has
|
||||||
|
/// changed the protection value for a chat.
|
||||||
|
pub(crate) async fn inner_set_protection(
|
||||||
|
self,
|
||||||
|
context: &Context,
|
||||||
|
protect: ProtectionStatus,
|
||||||
|
send_to_others: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
ensure!(!self.is_special(), "set protection: invalid chat-id.");
|
||||||
|
|
||||||
|
let chat = Chat::load_from_db(context, self).await?;
|
||||||
|
|
||||||
|
if protect == chat.protected {
|
||||||
|
info!(context, "Protection status unchanged for {}.", self);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
match protect {
|
||||||
|
ProtectionStatus::Protected => match chat.typ {
|
||||||
|
Chattype::Single | Chattype::Group => {
|
||||||
|
let contact_ids = get_chat_contacts(context, self).await;
|
||||||
|
for contact_id in contact_ids.into_iter() {
|
||||||
|
let contact = Contact::get_by_id(context, contact_id).await?;
|
||||||
|
if contact.is_verified(context).await != VerifiedStatus::BidirectVerified {
|
||||||
|
bail!(
|
||||||
|
"{} is not verified; cannot enable protection.",
|
||||||
|
contact.get_display_name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Chattype::Undefined => bail!("set protection: undefined group type"),
|
||||||
|
},
|
||||||
|
ProtectionStatus::Unprotected => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.execute(
|
||||||
|
"UPDATE chats SET protected=? WHERE id=?;",
|
||||||
|
paramsv![protect, self],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
context.emit_event(EventType::ChatModified(self));
|
||||||
|
|
||||||
|
if send_to_others {}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_protection(
|
||||||
|
self,
|
||||||
|
context: &Context,
|
||||||
|
protect: ProtectionStatus,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
ensure!(!self.is_special(), "set protection: invalid chat-id.");
|
||||||
|
|
||||||
|
let chat = Chat::load_from_db(context, self).await?;
|
||||||
|
|
||||||
|
match self
|
||||||
|
.inner_set_protection(context, protect, chat.is_promoted())
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(()) => Ok(()),
|
||||||
|
Err(err) => {
|
||||||
|
error!(context, "{}", err); // make error user-visible
|
||||||
|
Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Archives or unarchives a chat.
|
/// Archives or unarchives a chat.
|
||||||
pub async fn set_visibility(
|
pub async fn set_visibility(
|
||||||
self,
|
self,
|
||||||
@@ -1904,13 +1977,12 @@ pub async fn create_group_chat(
|
|||||||
let grpid = dc_create_id();
|
let grpid = dc_create_id();
|
||||||
|
|
||||||
context.sql.execute(
|
context.sql.execute(
|
||||||
"INSERT INTO chats (type, name, grpid, param, created_timestamp, protected) VALUES(?, ?, ?, \'U=1\', ?, ?);",
|
"INSERT INTO chats (type, name, grpid, param, created_timestamp) VALUES(?, ?, ?, \'U=1\', ?);",
|
||||||
paramsv![
|
paramsv![
|
||||||
Chattype::Group,
|
Chattype::Group,
|
||||||
chat_name,
|
chat_name,
|
||||||
grpid,
|
grpid,
|
||||||
time(),
|
time(),
|
||||||
protect,
|
|
||||||
],
|
],
|
||||||
).await?;
|
).await?;
|
||||||
|
|
||||||
@@ -1931,6 +2003,12 @@ pub async fn create_group_chat(
|
|||||||
chat_id: ChatId::new(0),
|
chat_id: ChatId::new(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if protect == ProtectionStatus::Protected {
|
||||||
|
chat_id
|
||||||
|
.inner_set_protection(context, protect, false)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(chat_id)
|
Ok(chat_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user