mirror of
https://github.com/chatmail/core.git
synced 2026-09-22 13:01:21 +03:00
api!: get rid of Qr::FprWithoutAddr variant
We don't look at the address in OPENPGP4FPR QR codes anymore. If we cannot find a contact by fingerprint, then we return Qr::FprMismatch without trying to look up the contact by address. BREAKING CHANGE: removed DC_QR_FPR_WITHOUT_ADDR constant from CFFI BREAKING CHANGE: removed FprWithoutAddr variant from JSON-RPC QrObject returned by check_qr
This commit is contained in:
@@ -2456,7 +2456,6 @@ void dc_stop_ongoing_process (dc_context_t* context);
|
|||||||
#define DC_QR_ASK_VERIFYBROADCAST 204 // text1=broadcast name
|
#define DC_QR_ASK_VERIFYBROADCAST 204 // text1=broadcast name
|
||||||
#define DC_QR_FPR_OK 210 // id=contact
|
#define DC_QR_FPR_OK 210 // id=contact
|
||||||
#define DC_QR_FPR_MISMATCH 220 // id=contact
|
#define DC_QR_FPR_MISMATCH 220 // id=contact
|
||||||
#define DC_QR_FPR_WITHOUT_ADDR 230 // test1=formatted fingerprint
|
|
||||||
#define DC_QR_ACCOUNT 250 // text1=domain
|
#define DC_QR_ACCOUNT 250 // text1=domain
|
||||||
#define DC_QR_BACKUP2 252
|
#define DC_QR_BACKUP2 252
|
||||||
#define DC_QR_BACKUP_TOO_NEW 255
|
#define DC_QR_BACKUP_TOO_NEW 255
|
||||||
@@ -2498,11 +2497,8 @@ void dc_stop_ongoing_process (dc_context_t* context);
|
|||||||
* if so, call dc_create_chat_by_contact_id().
|
* if so, call dc_create_chat_by_contact_id().
|
||||||
*
|
*
|
||||||
* - DC_QR_FPR_MISMATCH with dc_lot_t::id=Contact ID:
|
* - DC_QR_FPR_MISMATCH with dc_lot_t::id=Contact ID:
|
||||||
* scanned fingerprint does not match last seen fingerprint.
|
* scanned fingerprint does not match any contact
|
||||||
*
|
* or the key for this contact is not available.
|
||||||
* - DC_QR_FPR_WITHOUT_ADDR with dc_lot_t::text1=Formatted fingerprint
|
|
||||||
* the scanned QR code contains a fingerprint but no e-mail address;
|
|
||||||
* suggest the user to establish an encrypted connection first.
|
|
||||||
*
|
*
|
||||||
* - DC_QR_ACCOUNT dc_lot_t::text1=domain:
|
* - DC_QR_ACCOUNT dc_lot_t::text1=domain:
|
||||||
* ask the user if they want to create an account on the given domain,
|
* ask the user if they want to create an account on the given domain,
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ impl Lot {
|
|||||||
Qr::AskJoinBroadcast { name, .. } => Some(Cow::Borrowed(name)),
|
Qr::AskJoinBroadcast { name, .. } => Some(Cow::Borrowed(name)),
|
||||||
Qr::FprOk { .. } => None,
|
Qr::FprOk { .. } => None,
|
||||||
Qr::FprMismatch { .. } => None,
|
Qr::FprMismatch { .. } => None,
|
||||||
Qr::FprWithoutAddr { fingerprint, .. } => Some(Cow::Borrowed(fingerprint)),
|
|
||||||
Qr::Account { domain } => Some(Cow::Borrowed(domain)),
|
Qr::Account { domain } => Some(Cow::Borrowed(domain)),
|
||||||
Qr::Backup2 { .. } => None,
|
Qr::Backup2 { .. } => None,
|
||||||
Qr::BackupTooNew { .. } => None,
|
Qr::BackupTooNew { .. } => None,
|
||||||
@@ -104,7 +103,6 @@ impl Lot {
|
|||||||
Qr::AskJoinBroadcast { .. } => LotState::QrAskJoinBroadcast,
|
Qr::AskJoinBroadcast { .. } => LotState::QrAskJoinBroadcast,
|
||||||
Qr::FprOk { .. } => LotState::QrFprOk,
|
Qr::FprOk { .. } => LotState::QrFprOk,
|
||||||
Qr::FprMismatch { .. } => LotState::QrFprMismatch,
|
Qr::FprMismatch { .. } => LotState::QrFprMismatch,
|
||||||
Qr::FprWithoutAddr { .. } => LotState::QrFprWithoutAddr,
|
|
||||||
Qr::Account { .. } => LotState::QrAccount,
|
Qr::Account { .. } => LotState::QrAccount,
|
||||||
Qr::Backup2 { .. } => LotState::QrBackup2,
|
Qr::Backup2 { .. } => LotState::QrBackup2,
|
||||||
Qr::BackupTooNew { .. } => LotState::QrBackupTooNew,
|
Qr::BackupTooNew { .. } => LotState::QrBackupTooNew,
|
||||||
@@ -133,7 +131,6 @@ impl Lot {
|
|||||||
Qr::AskJoinBroadcast { .. } => Default::default(),
|
Qr::AskJoinBroadcast { .. } => Default::default(),
|
||||||
Qr::FprOk { contact_id } => contact_id.to_u32(),
|
Qr::FprOk { contact_id } => contact_id.to_u32(),
|
||||||
Qr::FprMismatch { contact_id } => contact_id.unwrap_or_default().to_u32(),
|
Qr::FprMismatch { contact_id } => contact_id.unwrap_or_default().to_u32(),
|
||||||
Qr::FprWithoutAddr { .. } => Default::default(),
|
|
||||||
Qr::Account { .. } => Default::default(),
|
Qr::Account { .. } => Default::default(),
|
||||||
Qr::Backup2 { .. } => Default::default(),
|
Qr::Backup2 { .. } => Default::default(),
|
||||||
Qr::BackupTooNew { .. } => Default::default(),
|
Qr::BackupTooNew { .. } => Default::default(),
|
||||||
@@ -184,9 +181,6 @@ pub enum LotState {
|
|||||||
/// id=contact
|
/// id=contact
|
||||||
QrFprMismatch = 220,
|
QrFprMismatch = 220,
|
||||||
|
|
||||||
/// text1=formatted fingerprint
|
|
||||||
QrFprWithoutAddr = 230,
|
|
||||||
|
|
||||||
/// text1=domain
|
/// text1=domain
|
||||||
QrAccount = 250,
|
QrAccount = 250,
|
||||||
|
|
||||||
|
|||||||
@@ -73,11 +73,6 @@ pub enum QrObject {
|
|||||||
/// Contact ID.
|
/// Contact ID.
|
||||||
contact_id: Option<u32>,
|
contact_id: Option<u32>,
|
||||||
},
|
},
|
||||||
/// The scanned QR code contains a fingerprint but no e-mail address.
|
|
||||||
FprWithoutAddr {
|
|
||||||
/// Key fingerprint.
|
|
||||||
fingerprint: String,
|
|
||||||
},
|
|
||||||
/// Ask the user if they want to create an account on the given domain.
|
/// Ask the user if they want to create an account on the given domain.
|
||||||
Account {
|
Account {
|
||||||
/// Server domain name.
|
/// Server domain name.
|
||||||
@@ -300,7 +295,6 @@ impl From<Qr> for QrObject {
|
|||||||
let contact_id = contact_id.map(|contact_id| contact_id.to_u32());
|
let contact_id = contact_id.map(|contact_id| contact_id.to_u32());
|
||||||
QrObject::FprMismatch { contact_id }
|
QrObject::FprMismatch { contact_id }
|
||||||
}
|
}
|
||||||
Qr::FprWithoutAddr { fingerprint } => QrObject::FprWithoutAddr { fingerprint },
|
|
||||||
Qr::Account { domain } => QrObject::Account { domain },
|
Qr::Account { domain } => QrObject::Account { domain },
|
||||||
Qr::Backup2 {
|
Qr::Backup2 {
|
||||||
ref node_addr,
|
ref node_addr,
|
||||||
|
|||||||
51
src/qr.rs
51
src/qr.rs
@@ -133,18 +133,15 @@ pub enum Qr {
|
|||||||
contact_id: ContactId,
|
contact_id: ContactId,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Scanned fingerprint does not match the last seen fingerprint.
|
/// Scanned fingerprint does not match any contact
|
||||||
|
/// or the key for this contact is not available.
|
||||||
FprMismatch {
|
FprMismatch {
|
||||||
/// Contact ID.
|
/// Contact ID if key-contact exists, but we have no key.
|
||||||
|
///
|
||||||
|
/// `None` if there is no contact corresponding to the scanned fingerprint.
|
||||||
contact_id: Option<ContactId>,
|
contact_id: Option<ContactId>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The scanned QR code contains a fingerprint but no e-mail address.
|
|
||||||
FprWithoutAddr {
|
|
||||||
/// Key fingerprint.
|
|
||||||
fingerprint: String,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// Ask the user if they want to create an account on the given domain.
|
/// Ask the user if they want to create an account on the given domain.
|
||||||
Account {
|
Account {
|
||||||
/// Server domain name.
|
/// Server domain name.
|
||||||
@@ -651,24 +648,28 @@ async fn decode_openpgp(context: &Context, qr: &str) -> Result<Qr> {
|
|||||||
is_v3,
|
is_v3,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if let Some(addr) = addrs.first() {
|
|
||||||
let fingerprint = fingerprint.hex();
|
|
||||||
let (contact_id, _) =
|
|
||||||
Contact::add_or_lookup_ext(context, "", addr, &fingerprint, Origin::UnhandledQrScan)
|
|
||||||
.await?;
|
|
||||||
let contact = Contact::get_by_id(context, contact_id).await?;
|
|
||||||
|
|
||||||
if contact.public_key(context).await?.is_some() {
|
|
||||||
Ok(Qr::FprOk { contact_id })
|
|
||||||
} else {
|
|
||||||
Ok(Qr::FprMismatch {
|
|
||||||
contact_id: Some(contact_id),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Ok(Qr::FprWithoutAddr {
|
let fingerprint = fingerprint.hex();
|
||||||
fingerprint: fingerprint.human_readable(),
|
let contact_id: Option<ContactId> = context
|
||||||
})
|
.sql
|
||||||
|
.query_get_value(
|
||||||
|
"SELECT id FROM contacts WHERE fingerprint=?",
|
||||||
|
(fingerprint,),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
if let Some(contact_id) = contact_id {
|
||||||
|
let contact = Contact::get_by_id(context, contact_id).await?;
|
||||||
|
if contact.public_key(context).await?.is_some() {
|
||||||
|
Ok(Qr::FprOk { contact_id })
|
||||||
|
} else {
|
||||||
|
Ok(Qr::FprMismatch {
|
||||||
|
contact_id: Some(contact_id),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(Qr::FprMismatch { contact_id: None })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -373,16 +373,15 @@ async fn test_decode_openpgp_fingerprint() -> Result<()> {
|
|||||||
let alice_contact = bob.add_or_lookup_contact(alice).await;
|
let alice_contact = bob.add_or_lookup_contact(alice).await;
|
||||||
let alice_contact_id = alice_contact.id;
|
let alice_contact_id = alice_contact.id;
|
||||||
|
|
||||||
|
// OPENPGP4FPR may have an address,
|
||||||
|
// but it is not used anymore since key contacts are introduced.
|
||||||
|
// We lookup the contact only by fingerprint and ignore the address.
|
||||||
let qr = check_qr(
|
let qr = check_qr(
|
||||||
bob,
|
bob,
|
||||||
"OPENPGP4FPR:1234567890123456789012345678901234567890#a=alice@example.org",
|
"OPENPGP4FPR:1234567890123456789012345678901234567890#a=alice@example.org",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
if let Qr::FprMismatch { contact_id, .. } = qr {
|
assert_eq!(qr, Qr::FprMismatch { contact_id: None });
|
||||||
assert_ne!(contact_id.unwrap(), alice_contact_id);
|
|
||||||
} else {
|
|
||||||
bail!("Wrong QR code type");
|
|
||||||
}
|
|
||||||
|
|
||||||
let qr = check_qr(
|
let qr = check_qr(
|
||||||
bob,
|
bob,
|
||||||
@@ -410,6 +409,10 @@ async fn test_decode_openpgp_fingerprint() -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tests OPENPGP4FPR QR codes without an email address.
|
||||||
|
///
|
||||||
|
/// Email address in OPENPGP4FPR QR codes was an extension
|
||||||
|
/// used before switch to identifying contacts by fingerprint.
|
||||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||||
async fn test_decode_openpgp_without_addr() -> Result<()> {
|
async fn test_decode_openpgp_without_addr() -> Result<()> {
|
||||||
let ctx = TestContext::new().await;
|
let ctx = TestContext::new().await;
|
||||||
@@ -419,12 +422,7 @@ async fn test_decode_openpgp_without_addr() -> Result<()> {
|
|||||||
"OPENPGP4FPR:1234567890123456789012345678901234567890",
|
"OPENPGP4FPR:1234567890123456789012345678901234567890",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(qr, Qr::FprMismatch { contact_id: None });
|
||||||
qr,
|
|
||||||
Qr::FprWithoutAddr {
|
|
||||||
fingerprint: "1234 5678 9012 3456 7890\n1234 5678 9012 3456 7890".to_string()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Test it again with lowercased "openpgp4fpr:" uri scheme
|
// Test it again with lowercased "openpgp4fpr:" uri scheme
|
||||||
|
|
||||||
@@ -433,12 +431,7 @@ async fn test_decode_openpgp_without_addr() -> Result<()> {
|
|||||||
"openpgp4fpr:1234567890123456789012345678901234567890",
|
"openpgp4fpr:1234567890123456789012345678901234567890",
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(
|
assert_eq!(qr, Qr::FprMismatch { contact_id: None });
|
||||||
qr,
|
|
||||||
Qr::FprWithoutAddr {
|
|
||||||
fingerprint: "1234 5678 9012 3456 7890\n1234 5678 9012 3456 7890".to_string()
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
let res = check_qr(&ctx.ctx, "OPENPGP4FPR:12345678901234567890").await;
|
let res = check_qr(&ctx.ctx, "OPENPGP4FPR:12345678901234567890").await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|||||||
Reference in New Issue
Block a user