mirror of
https://github.com/chatmail/core.git
synced 2026-04-22 16:06:30 +03:00
Remove context refrence from Contact struct
This will allow the Rust Context API to be refactored without breaking
the C API. Full details in #476 aka
a0b5e32f98
This commit is contained in:
committed by
Floris Bruynooghe
parent
5ce27b16f1
commit
aefddf7f5e
@@ -1217,19 +1217,18 @@ pub unsafe extern "C" fn dc_delete_contact(
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_get_contact<'a>(
|
||||
pub unsafe extern "C" fn dc_get_contact(
|
||||
context: *mut dc_context_t,
|
||||
contact_id: u32,
|
||||
) -> *mut dc_contact_t<'a> {
|
||||
) -> *mut dc_contact_t {
|
||||
if context.is_null() {
|
||||
eprintln!("ignoring careless call to dc_get_contact()");
|
||||
return ptr::null_mut();
|
||||
}
|
||||
|
||||
let context = &*context;
|
||||
|
||||
Contact::get_by_id(context, contact_id)
|
||||
.map(|contact| Box::into_raw(Box::new(contact)))
|
||||
.map(|contact| Box::into_raw(Box::new(ContactWrapper { context, contact })))
|
||||
.unwrap_or_else(|_| std::ptr::null_mut())
|
||||
}
|
||||
|
||||
@@ -2299,8 +2298,20 @@ pub unsafe extern "C" fn dc_msg_latefiling_mediasize(
|
||||
|
||||
// dc_contact_t
|
||||
|
||||
/// FFI struct for [dc_contact_t]
|
||||
///
|
||||
/// This is the structure behind [dc_contact_t] which is the opaque
|
||||
/// structure representing a contact in the FFI API. It exists
|
||||
/// because the FFI API has a refernce from the message to the
|
||||
/// context, but the Rust API does not, so the FFI layer needs to glue
|
||||
/// these together.
|
||||
pub struct ContactWrapper {
|
||||
context: *const dc_context_t,
|
||||
contact: contact::Contact,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub type dc_contact_t<'a> = contact::Contact<'a>;
|
||||
pub type dc_contact_t = ContactWrapper;
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dc_contact_unref(contact: *mut dc_contact_t) {
|
||||
@@ -2308,7 +2319,6 @@ pub unsafe extern "C" fn dc_contact_unref(contact: *mut dc_contact_t) {
|
||||
eprintln!("ignoring careless call to dc_contact_unref()");
|
||||
return;
|
||||
}
|
||||
|
||||
Box::from_raw(contact);
|
||||
}
|
||||
|
||||
@@ -2318,10 +2328,8 @@ pub unsafe extern "C" fn dc_contact_get_id(contact: *mut dc_contact_t) -> u32 {
|
||||
eprintln!("ignoring careless call to dc_contact_get_id()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_id()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_id()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2330,10 +2338,8 @@ pub unsafe extern "C" fn dc_contact_get_addr(contact: *mut dc_contact_t) -> *mut
|
||||
eprintln!("ignoring careless call to dc_contact_get_addr()");
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_addr().strdup()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_addr().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2342,10 +2348,8 @@ pub unsafe extern "C" fn dc_contact_get_name(contact: *mut dc_contact_t) -> *mut
|
||||
eprintln!("ignoring careless call to dc_contact_get_name()");
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_name().strdup()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_name().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2356,10 +2360,8 @@ pub unsafe extern "C" fn dc_contact_get_display_name(
|
||||
eprintln!("ignoring careless call to dc_contact_get_display_name()");
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_display_name().strdup()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_display_name().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2370,10 +2372,8 @@ pub unsafe extern "C" fn dc_contact_get_name_n_addr(
|
||||
eprintln!("ignoring careless call to dc_contact_get_name_n_addr()");
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_name_n_addr().strdup()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_name_n_addr().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2384,10 +2384,8 @@ pub unsafe extern "C" fn dc_contact_get_first_name(
|
||||
eprintln!("ignoring careless call to dc_contact_get_first_name()");
|
||||
return dc_strdup(ptr::null());
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_first_name().strdup()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_first_name().strdup()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2398,11 +2396,10 @@ pub unsafe extern "C" fn dc_contact_get_profile_image(
|
||||
eprintln!("ignoring careless call to dc_contact_get_profile_image()");
|
||||
return ptr::null_mut(); // NULL explicitly defined as "no profile image"
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact
|
||||
.get_profile_image()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact
|
||||
.contact
|
||||
.get_profile_image(&*ffi_contact.context)
|
||||
.map(|p| p.to_str().unwrap().to_string().strdup())
|
||||
.unwrap_or_else(|| std::ptr::null_mut())
|
||||
}
|
||||
@@ -2413,10 +2410,8 @@ pub unsafe extern "C" fn dc_contact_get_color(contact: *mut dc_contact_t) -> u32
|
||||
eprintln!("ignoring careless call to dc_contact_get_color()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.get_color()
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.get_color()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2425,10 +2420,8 @@ pub unsafe extern "C" fn dc_contact_is_blocked(contact: *mut dc_contact_t) -> li
|
||||
eprintln!("ignoring careless call to dc_contact_is_blocked()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.is_blocked() as libc::c_int
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.is_blocked() as libc::c_int
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -2437,10 +2430,8 @@ pub unsafe extern "C" fn dc_contact_is_verified(contact: *mut dc_contact_t) -> l
|
||||
eprintln!("ignoring careless call to dc_contact_is_verified()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contact = &*contact;
|
||||
|
||||
contact.is_verified() as libc::c_int
|
||||
let ffi_contact = &*contact;
|
||||
ffi_contact.contact.is_verified(&*ffi_contact.context) as libc::c_int
|
||||
}
|
||||
|
||||
// dc_lot_t
|
||||
|
||||
@@ -301,7 +301,7 @@ unsafe fn log_contactlist(context: &Context, contacts: &Vec<u32>) {
|
||||
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
||||
let name = contact.get_name();
|
||||
let addr = contact.get_addr();
|
||||
let verified_state = contact.is_verified();
|
||||
let verified_state = contact.is_verified(context);
|
||||
let verified_str = if VerifiedStatus::Unverified != verified_state {
|
||||
if verified_state == VerifiedStatus::BidirectVerified {
|
||||
" √√"
|
||||
|
||||
@@ -189,7 +189,7 @@ impl Chat {
|
||||
let contacts = get_chat_contacts(context, self.id);
|
||||
if !contacts.is_empty() {
|
||||
if let Ok(contact) = Contact::get_by_id(context, contacts[0]) {
|
||||
return contact.get_profile_image();
|
||||
return contact.get_profile_image(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1365,7 +1365,7 @@ pub fn add_contact_to_chat_ex(
|
||||
} else {
|
||||
// else continue and send status mail
|
||||
if chat.typ == Chattype::VerifiedGroup {
|
||||
if contact.is_verified() != VerifiedStatus::BidirectVerified {
|
||||
if contact.is_verified(context) != VerifiedStatus::BidirectVerified {
|
||||
error!(
|
||||
context,
|
||||
"Only bidirectional verified contacts can be added to verified groups."
|
||||
|
||||
@@ -31,8 +31,7 @@ const DC_ORIGIN_MIN_CONTACT_LIST: i32 = 0x100;
|
||||
/// For this purpose, internally, two names are tracked -
|
||||
/// authorized-name and given-name.
|
||||
/// By default, these names are equal, but functions working with contact names
|
||||
pub struct Contact<'a> {
|
||||
context: &'a Context,
|
||||
pub struct Contact {
|
||||
/// The contact ID.
|
||||
///
|
||||
/// Special message IDs:
|
||||
@@ -139,11 +138,10 @@ pub enum VerifiedStatus {
|
||||
BidirectVerified = 2,
|
||||
}
|
||||
|
||||
impl<'a> Contact<'a> {
|
||||
pub fn load_from_db(context: &'a Context, contact_id: u32) -> Result<Self> {
|
||||
impl Contact {
|
||||
pub fn load_from_db(context: &Context, contact_id: u32) -> Result<Self> {
|
||||
if contact_id == DC_CONTACT_ID_SELF {
|
||||
let contact = Contact {
|
||||
context,
|
||||
id: contact_id,
|
||||
name: context.stock_str(StockMessage::SelfMsg).into(),
|
||||
authname: "".into(),
|
||||
@@ -162,7 +160,6 @@ impl<'a> Contact<'a> {
|
||||
params![contact_id as i32],
|
||||
|row| {
|
||||
let contact = Self {
|
||||
context,
|
||||
id: contact_id,
|
||||
name: row.get::<_, String>(0)?,
|
||||
authname: row.get::<_, String>(4)?,
|
||||
@@ -181,7 +178,7 @@ impl<'a> Contact<'a> {
|
||||
}
|
||||
|
||||
/// Check if a contact is blocked.
|
||||
pub fn is_blocked_load(context: &'a Context, id: u32) -> bool {
|
||||
pub fn is_blocked_load(context: &Context, id: u32) -> bool {
|
||||
Self::load_from_db(context, id)
|
||||
.map(|contact| contact.blocked)
|
||||
.unwrap_or_default()
|
||||
@@ -766,9 +763,9 @@ impl<'a> Contact<'a> {
|
||||
/// Get the contact's profile image.
|
||||
/// This is the image set by each remote user on their own
|
||||
/// using dc_set_config(context, "selfavatar", image).
|
||||
pub fn get_profile_image(&self) -> Option<PathBuf> {
|
||||
pub fn get_profile_image(&self, context: &Context) -> Option<PathBuf> {
|
||||
if self.id == DC_CONTACT_ID_SELF {
|
||||
if let Some(p) = self.context.get_config(Config::Selfavatar) {
|
||||
if let Some(p) = context.get_config(Config::Selfavatar) {
|
||||
return Some(PathBuf::from(p));
|
||||
}
|
||||
}
|
||||
@@ -789,14 +786,18 @@ impl<'a> Contact<'a> {
|
||||
///
|
||||
/// The UI may draw a checkbox or something like that beside verified contacts.
|
||||
///
|
||||
pub fn is_verified(&self) -> VerifiedStatus {
|
||||
self.is_verified_ex(None)
|
||||
pub fn is_verified(&self, context: &Context) -> VerifiedStatus {
|
||||
self.is_verified_ex(context, None)
|
||||
}
|
||||
|
||||
/// Same as `Contact::is_verified` but allows speeding up things
|
||||
/// by adding the peerstate belonging to the contact.
|
||||
/// If you do not have the peerstate available, it is loaded automatically.
|
||||
pub fn is_verified_ex(&self, peerstate: Option<&Peerstate<'a>>) -> VerifiedStatus {
|
||||
pub fn is_verified_ex(
|
||||
&self,
|
||||
context: &Context,
|
||||
peerstate: Option<&Peerstate>,
|
||||
) -> VerifiedStatus {
|
||||
// We're always sort of secured-verified as we could verify the key on this device any time with the key
|
||||
// on this device
|
||||
if self.id == DC_CONTACT_ID_SELF {
|
||||
@@ -809,7 +810,7 @@ impl<'a> Contact<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
let peerstate = Peerstate::from_addr(self.context, &self.context.sql, &self.addr);
|
||||
let peerstate = Peerstate::from_addr(context, &context.sql, &self.addr);
|
||||
if let Some(ps) = peerstate {
|
||||
if ps.verified_key().is_some() {
|
||||
return VerifiedStatus::BidirectVerified;
|
||||
|
||||
@@ -1760,7 +1760,8 @@ unsafe fn check_verified_properties(
|
||||
let peerstate = Peerstate::from_addr(context, &context.sql, contact.get_addr());
|
||||
|
||||
if peerstate.is_none()
|
||||
|| contact.is_verified_ex(peerstate.as_ref()) != VerifiedStatus::BidirectVerified
|
||||
|| contact.is_verified_ex(context, peerstate.as_ref())
|
||||
!= VerifiedStatus::BidirectVerified
|
||||
{
|
||||
verify_fail("The sender of this message is not verified.".into());
|
||||
return 0;
|
||||
|
||||
@@ -617,7 +617,7 @@ pub fn handle_securejoin_handshake(
|
||||
==== Step 8 in "Out-of-band verified groups" protocol ====
|
||||
============================================================ */
|
||||
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
||||
if contact.is_verified() == VerifiedStatus::Unverified {
|
||||
if contact.is_verified(context) == VerifiedStatus::Unverified {
|
||||
warn!(context, "vg-member-added-received invalid.",);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user