qrcode: Document the qrcode crate.
This commit is contained in:
parent
f49f5f1636
commit
8018b43443
4 changed files with 361 additions and 28 deletions
|
@ -4,10 +4,16 @@ version = "0.1.0"
|
|||
authors = ["Damir Jelić <poljar@termina.org.uk>"]
|
||||
edition = "2018"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["docs"]
|
||||
rustdoc-args = ["--cfg", "feature=\"docs\""]
|
||||
|
||||
[features]
|
||||
default = ["decode_image"]
|
||||
decode_image = ["image", "rqrr", "qrcode/image", "qrcode/svg"]
|
||||
|
||||
docs = ["decode_image"]
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.13.0"
|
||||
byteorder = "1.4.3"
|
||||
|
|
|
@ -14,34 +14,48 @@
|
|||
|
||||
use thiserror::Error;
|
||||
|
||||
/// Error type describing errors that happen while QR data is being decoded.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum DecodingError {
|
||||
/// Error decoding the QR code.
|
||||
#[cfg(feature = "decode_image")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(decode_image)))]
|
||||
#[error(transparent)]
|
||||
Qr(#[from] rqrr::DeQRError),
|
||||
/// The QR code data is missing the mandatory Matrix header.
|
||||
#[error("the decoded QR code is missing the Matrix header")]
|
||||
Header,
|
||||
/// The QR code data is containing an invalid, non UTF-8, flow id.
|
||||
#[error(transparent)]
|
||||
Utf8(#[from] std::string::FromUtf8Error),
|
||||
/// The QR code data is using an unsupported or invalid verification mode.
|
||||
#[error("the QR code contains an invalid verification mode: {0}")]
|
||||
Mode(u8),
|
||||
/// The flow id is not a valid event ID.
|
||||
#[error(transparent)]
|
||||
Identifier(#[from] ruma_identifiers::Error),
|
||||
#[error(transparent)]
|
||||
/// The QR code data does not contain all the necessary fields.
|
||||
Read(#[from] std::io::Error),
|
||||
/// The QR code data uses an invalid shared secret.
|
||||
#[error("the QR code contains a too short shared secret, length: {0}")]
|
||||
SharedSecret(usize),
|
||||
/// The QR code data uses an invalid or unsupported version.
|
||||
#[error("the QR code contains an invalid or unsupported version: {0}")]
|
||||
Version(u8),
|
||||
}
|
||||
|
||||
/// Error type describing errors that happen while QR data is being encoded.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum EncodingError {
|
||||
/// Error generating a QR code from the data, likely because the data
|
||||
/// doesn't fit into a QR code.
|
||||
#[error(transparent)]
|
||||
Qr(#[from] qrcode::types::QrError),
|
||||
/// Error decoding the identity keys as base64.
|
||||
#[error(transparent)]
|
||||
Base64(#[from] base64::DecodeError),
|
||||
/// Error encoding the given flow id, the flow id is too large.
|
||||
#[error("The verification flow id length can't be converted into a u16: {0}")]
|
||||
FlowId(#[from] std::num::TryFromIntError),
|
||||
}
|
||||
|
|
|
@ -30,10 +30,12 @@
|
|||
//! # }
|
||||
//! ```
|
||||
|
||||
#![cfg_attr(feature = "docs", feature(doc_cfg))]
|
||||
#![deny(
|
||||
missing_debug_implementations,
|
||||
dead_code,
|
||||
trivial_casts,
|
||||
missing_docs,
|
||||
trivial_numeric_casts,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
|
|
|
@ -31,10 +31,16 @@ use crate::{
|
|||
utils::{base_64_encode, to_bytes, to_qr_code, HEADER, MAX_MODE, MIN_SECRET_LEN, VERSION},
|
||||
};
|
||||
|
||||
/// An enum representing the different modes a QR verification can be in.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum QrVerification {
|
||||
/// The QR verification is verifying another user
|
||||
Verification(VerificationData),
|
||||
/// The QR verification is self-verifying and the current device trusts or
|
||||
/// owns the master key
|
||||
SelfVerification(SelfVerificationData),
|
||||
/// The QR verification is self-verifying in which the current device does
|
||||
/// not yet trust the master key
|
||||
SelfVerificationNoMasterKey(SelfVerificationNoMasterKey),
|
||||
}
|
||||
|
||||
|
@ -75,6 +81,26 @@ impl TryFrom<Vec<u8>> for QrVerification {
|
|||
}
|
||||
|
||||
impl QrVerification {
|
||||
/// Decode and parse an image of a QR code into a `QrVerification`
|
||||
///
|
||||
/// The image will be converted into a grey scale image before decoding is
|
||||
/// attempted
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `image` - The image containing the QR code.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// use image;
|
||||
///
|
||||
/// let image = image::open("/path/to/my/image.png").unwrap();
|
||||
/// let result = QrVerification::from_image(image)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "decode_image")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(decode_image)))]
|
||||
pub fn from_image(image: DynamicImage) -> Result<Self, DecodingError> {
|
||||
|
@ -82,16 +108,85 @@ impl QrVerification {
|
|||
Self::decode(image)
|
||||
}
|
||||
|
||||
/// Decode and parse an grey scale image of a QR code into a
|
||||
/// `QrVerification`
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `image` - The grey scale image containing the QR code.
|
||||
///
|
||||
/// # Example
|
||||
/// ```no_run
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// use image;
|
||||
///
|
||||
/// let image = image::open("/path/to/my/image.png").unwrap();
|
||||
/// let image = image.to_luma8();
|
||||
/// let result = QrVerification::from_luma(image)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "decode_image")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(decode_image)))]
|
||||
pub fn from_luma(image: ImageBuffer<Luma<u8>, Vec<u8>>) -> Result<Self, DecodingError> {
|
||||
Self::decode(image)
|
||||
}
|
||||
|
||||
/// Parse the decoded payload of a QR code in byte slice form as a
|
||||
/// `QrVerification`
|
||||
///
|
||||
/// This method is useful if you would like to do your own custom QR code
|
||||
/// decoding.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `bytes` - The raw bytes of a decoded QR code.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x02\x00\x07\
|
||||
/// FLOW_ID\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn from_bytes(bytes: impl AsRef<[u8]>) -> Result<Self, DecodingError> {
|
||||
Self::decode_bytes(bytes)
|
||||
}
|
||||
|
||||
/// Encode the `QrVerification` into a `QrCode`.
|
||||
///
|
||||
/// This method turns the `QrVerification` into a QR code that can be
|
||||
/// rendered and presented to be scanned.
|
||||
///
|
||||
/// The encoding can fail if the data doesn't fit into a QR code or if the
|
||||
/// identity keys that should be encoded into the QR code are not valid
|
||||
/// base64.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x02\x00\x07\
|
||||
/// FLOW_ID\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// let encoded = result.to_qr_code().unwrap();
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_qr_code(&self) -> Result<QrCode, EncodingError> {
|
||||
match self {
|
||||
QrVerification::Verification(v) => v.to_qr_code(),
|
||||
|
@ -100,6 +195,30 @@ impl QrVerification {
|
|||
}
|
||||
}
|
||||
|
||||
/// Encode the `QrVerification` into a vector of bytes that can be encoded
|
||||
/// as a QR code.
|
||||
///
|
||||
/// The encoding can fail if the identity keys that should be encoded are
|
||||
/// not valid base64.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x02\x00\x07\
|
||||
/// FLOW_ID\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// let encoded = result.to_bytes().unwrap();
|
||||
///
|
||||
/// assert_eq!(data.as_ref(), encoded.as_slice());
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> {
|
||||
match self {
|
||||
QrVerification::Verification(v) => v.to_bytes(),
|
||||
|
@ -108,6 +227,34 @@ impl QrVerification {
|
|||
}
|
||||
}
|
||||
|
||||
/// Decode the byte slice containing the decoded QR code data.
|
||||
///
|
||||
/// The format is defined in the [spec].
|
||||
///
|
||||
/// The byte slice consists of the following parts:
|
||||
///
|
||||
/// * the ASCII string MATRIX
|
||||
/// * one byte indicating the QR code version (must be 0x02)
|
||||
/// * one byte indicating the QR code verification mode. one of the
|
||||
/// following
|
||||
/// values:
|
||||
/// * 0x00 verifying another user with cross-signing
|
||||
/// * 0x01 self-verifying in which the current device does trust the
|
||||
/// master key
|
||||
/// * 0x02 self-verifying in which the current device does not yet trust
|
||||
/// the master key
|
||||
/// * the event ID or transaction_id of the associated verification request
|
||||
/// event, encoded as:
|
||||
/// * two bytes in network byte order (big-endian) indicating the length
|
||||
/// in bytes of the ID as a UTF-8 string
|
||||
/// * the ID as a UTF-8 string
|
||||
/// * the first key, as 32 bytes
|
||||
/// * the second key, as 32 bytes
|
||||
/// * a random shared secret, as a byte string. as we do not share the
|
||||
/// length of the secret, and it is not a fixed size, clients will just
|
||||
/// use the remainder of binary string as the shared secret.
|
||||
///
|
||||
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#qr-code-format
|
||||
fn decode_bytes(bytes: impl AsRef<[u8]>) -> Result<Self, DecodingError> {
|
||||
let mut decoded = Cursor::new(bytes);
|
||||
|
||||
|
@ -145,8 +292,9 @@ impl QrVerification {
|
|||
QrVerification::new(mode, flow_id, first_key, second_key, shared_secret)
|
||||
}
|
||||
|
||||
/// Decode the given image of an QR code and if we find a valid code, try to
|
||||
/// decode it as a `QrVerification`.
|
||||
#[cfg(feature = "decode_image")]
|
||||
#[cfg_attr(feature = "docs", doc(cfg(decode_image)))]
|
||||
fn decode(image: ImageBuffer<Luma<u8>, Vec<u8>>) -> Result<QrVerification, DecodingError> {
|
||||
let decoded = decode_qr(image)?;
|
||||
Self::decode_bytes(decoded)
|
||||
|
@ -181,6 +329,10 @@ impl QrVerification {
|
|||
}
|
||||
}
|
||||
|
||||
/// The non-encoded data for the first mode of QR code verification.
|
||||
///
|
||||
/// This mode is used for verification between two users using their master
|
||||
/// cross signing keys.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct VerificationData {
|
||||
event_id: EventId,
|
||||
|
@ -192,6 +344,55 @@ pub struct VerificationData {
|
|||
impl VerificationData {
|
||||
const QR_MODE: u8 = 0x00;
|
||||
|
||||
/// Create a new `VerificationData` struct that can be encoded as a QR code.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `event_id` - The event id of the `m.key.verification.request` event
|
||||
/// that initiated the verification flow this QR code should be part of.
|
||||
///
|
||||
/// * `first_key` - Our own cross signing master key. Needs to be encoded as
|
||||
/// unpadded base64
|
||||
///
|
||||
/// * `second_key` - The cross signing master key of the other user.
|
||||
///
|
||||
/// * ` shared_secret` - A random bytestring encoded as unpadded base64,
|
||||
/// needs to be at least 8 bytes long.
|
||||
pub fn new(
|
||||
event_id: EventId,
|
||||
first_key: String,
|
||||
second_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { event_id, first_master_key: first_key, second_master_key: second_key, shared_secret }
|
||||
}
|
||||
|
||||
/// Encode the `VerificationData` into a vector of bytes that can be
|
||||
/// encoded as a QR code.
|
||||
///
|
||||
/// The encoding can fail if the master keys that should be encoded are not
|
||||
/// valid base64.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x00\x00\x0f\
|
||||
/// $test:localhost\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// if let QrVerification::Verification(decoded) = result {
|
||||
/// let encoded = decoded.to_bytes().unwrap();
|
||||
/// assert_eq!(data.as_ref(), encoded.as_slice());
|
||||
/// } else {
|
||||
/// panic!("Data was encoded as an incorrect mode");
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> {
|
||||
to_bytes(
|
||||
Self::QR_MODE,
|
||||
|
@ -202,6 +403,13 @@ impl VerificationData {
|
|||
)
|
||||
}
|
||||
|
||||
/// Encode the `VerificationData` into a `QrCode`.
|
||||
///
|
||||
/// This method turns the `VerificationData` into a QR code that can be
|
||||
/// rendered and presented to be scanned.
|
||||
///
|
||||
/// The encoding can fail if the data doesn't fit into a QR code or if the
|
||||
/// keys that should be encoded into the QR code are not valid base64.
|
||||
pub fn to_qr_code(&self) -> Result<QrCode, EncodingError> {
|
||||
to_qr_code(
|
||||
Self::QR_MODE,
|
||||
|
@ -211,15 +419,6 @@ impl VerificationData {
|
|||
&self.shared_secret,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
event_id: EventId,
|
||||
first_key: String,
|
||||
second_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { event_id, first_master_key: first_key, second_master_key: second_key, shared_secret }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VerificationData> for QrVerification {
|
||||
|
@ -228,6 +427,11 @@ impl From<VerificationData> for QrVerification {
|
|||
}
|
||||
}
|
||||
|
||||
/// The non-encoded data for the second mode of QR code verification.
|
||||
///
|
||||
/// This mode is used for verification between two devices of the same user
|
||||
/// where this device, that is creating this QR code, is trusting or owning
|
||||
/// the cross signing master key.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SelfVerificationData {
|
||||
transaction_id: String,
|
||||
|
@ -239,6 +443,59 @@ pub struct SelfVerificationData {
|
|||
impl SelfVerificationData {
|
||||
const QR_MODE: u8 = 0x01;
|
||||
|
||||
/// Create a new `SelfVerificationData` struct that can be encoded as a QR
|
||||
/// code.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `transaction_id` - The transaction id of this verification flow, the
|
||||
/// transaction id was sent by the `m.key.verification.request` event
|
||||
/// that initiated the verification flow this QR code should be part of.
|
||||
///
|
||||
/// * `master_key` - Our own cross signing master key. Needs to be encoded
|
||||
/// as
|
||||
/// unpadded base64
|
||||
///
|
||||
/// * `device_key` - The ed25519 key of the other device, encoded as
|
||||
/// unpadded base64.
|
||||
///
|
||||
/// * ` shared_secret` - A random bytestring encoded as unpadded base64,
|
||||
/// needs to be at least 8 bytes long.
|
||||
pub fn new(
|
||||
transaction_id: String,
|
||||
master_key: String,
|
||||
device_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { transaction_id, master_key, device_key, shared_secret }
|
||||
}
|
||||
|
||||
/// Encode the `SelfVerificationData` into a vector of bytes that can be
|
||||
/// encoded as a QR code.
|
||||
///
|
||||
/// The encoding can fail if the keys that should be encoded are not valid
|
||||
/// base64.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x01\x00\x06\
|
||||
/// FLOWID\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// if let QrVerification::SelfVerification(decoded) = result {
|
||||
/// let encoded = decoded.to_bytes().unwrap();
|
||||
/// assert_eq!(data.as_ref(), encoded.as_slice());
|
||||
/// } else {
|
||||
/// panic!("Data was encoded as an incorrect mode");
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> {
|
||||
to_bytes(
|
||||
Self::QR_MODE,
|
||||
|
@ -249,6 +506,13 @@ impl SelfVerificationData {
|
|||
)
|
||||
}
|
||||
|
||||
/// Encode the `SelfVerificationData` into a `QrCode`.
|
||||
///
|
||||
/// This method turns the `SelfVerificationData` into a QR code that can be
|
||||
/// rendered and presented to be scanned.
|
||||
///
|
||||
/// The encoding can fail if the data doesn't fit into a QR code or if the
|
||||
/// keys that should be encoded into the QR code are not valid base64.
|
||||
pub fn to_qr_code(&self) -> Result<QrCode, EncodingError> {
|
||||
to_qr_code(
|
||||
Self::QR_MODE,
|
||||
|
@ -258,15 +522,6 @@ impl SelfVerificationData {
|
|||
&self.shared_secret,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
transaction_id: String,
|
||||
master_key: String,
|
||||
device_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { transaction_id, master_key, device_key, shared_secret }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SelfVerificationData> for QrVerification {
|
||||
|
@ -275,6 +530,11 @@ impl From<SelfVerificationData> for QrVerification {
|
|||
}
|
||||
}
|
||||
|
||||
/// The non-encoded data for the third mode of QR code verification.
|
||||
///
|
||||
/// This mode is used for verification between two devices of the same user
|
||||
/// where this device, that is creating this QR code, is not trusting the
|
||||
/// cross signing master key.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct SelfVerificationNoMasterKey {
|
||||
transaction_id: String,
|
||||
|
@ -286,6 +546,59 @@ pub struct SelfVerificationNoMasterKey {
|
|||
impl SelfVerificationNoMasterKey {
|
||||
const QR_MODE: u8 = 0x02;
|
||||
|
||||
/// Create a new `SelfVerificationData` struct that can be encoded as a QR
|
||||
/// code.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `transaction_id` - The transaction id of this verification flow, the
|
||||
/// transaction id was sent by the `m.key.verification.request` event
|
||||
/// that initiated the verification flow this QR code should be part of.
|
||||
///
|
||||
/// * `device_key` - The ed25519 key of our own device, encoded as unpadded
|
||||
/// base64.
|
||||
///
|
||||
/// * `master_key` - Our own cross signing master key. Needs to be encoded
|
||||
/// as
|
||||
/// unpadded base64
|
||||
///
|
||||
/// * ` shared_secret` - A random bytestring encoded as unpadded base64,
|
||||
/// needs to be at least 8 bytes long.
|
||||
pub fn new(
|
||||
transaction_id: String,
|
||||
device_key: String,
|
||||
master_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { transaction_id, device_key, master_key, shared_secret }
|
||||
}
|
||||
|
||||
/// Encode the `SelfVerificationNoMasterKey` into a vector of bytes that can
|
||||
/// be encoded as a QR code.
|
||||
///
|
||||
/// The encoding can fail if the keys that should be encoded are not valid
|
||||
/// base64.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use matrix_qrcode::{QrVerification, DecodingError};
|
||||
/// # fn main() -> Result<(), DecodingError> {
|
||||
/// let data = b"MATRIX\
|
||||
/// \x02\x02\x00\x06\
|
||||
/// FLOWID\
|
||||
/// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
|
||||
/// BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\
|
||||
/// SHARED_SECRET";
|
||||
///
|
||||
/// let result = QrVerification::from_bytes(data)?;
|
||||
/// if let QrVerification::SelfVerificationNoMasterKey(decoded) = result {
|
||||
/// let encoded = decoded.to_bytes().unwrap();
|
||||
/// assert_eq!(data.as_ref(), encoded.as_slice());
|
||||
/// } else {
|
||||
/// panic!("Data was encoded as an incorrect mode");
|
||||
/// }
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn to_bytes(&self) -> Result<Vec<u8>, EncodingError> {
|
||||
to_bytes(
|
||||
Self::QR_MODE,
|
||||
|
@ -296,6 +609,13 @@ impl SelfVerificationNoMasterKey {
|
|||
)
|
||||
}
|
||||
|
||||
/// Encode the `SelfVerificationNoMasterKey` into a `QrCode`.
|
||||
///
|
||||
/// This method turns the `SelfVerificationNoMasterKey` into a QR code that
|
||||
/// can be rendered and presented to be scanned.
|
||||
///
|
||||
/// The encoding can fail if the data doesn't fit into a QR code or if the
|
||||
/// keys that should be encoded into the QR code are not valid base64.
|
||||
pub fn to_qr_code(&self) -> Result<QrCode, EncodingError> {
|
||||
to_qr_code(
|
||||
Self::QR_MODE,
|
||||
|
@ -305,15 +625,6 @@ impl SelfVerificationNoMasterKey {
|
|||
&self.shared_secret,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn new(
|
||||
transaction_id: String,
|
||||
device_key: String,
|
||||
master_key: String,
|
||||
shared_secret: String,
|
||||
) -> Self {
|
||||
Self { transaction_id, device_key, master_key, shared_secret }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SelfVerificationNoMasterKey> for QrVerification {
|
||||
|
|
Loading…
Reference in a new issue