Skip to content

Commit

Permalink
Merge branch 'theo/phone_number_verification' into 'master'
Browse files Browse the repository at this point in the history
add sms_verification

See merge request TankerHQ/sdk-rust!43
  • Loading branch information
theodelrieu committed Jun 30, 2021
2 parents bac38c1 + 333f29e commit fc1666c
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/ctanker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use self::bindings::*;

pub type CVerification = tanker_verification;
pub type CEmailVerification = tanker_email_verification;
pub type CPhoneNumberVerification = tanker_phone_number_verification;
pub type CVerificationMethod = tanker_verification_method;
pub type CDevice = tanker_device_list_elem;
pub type CTankerPtr = *mut tanker_t;
Expand Down
33 changes: 31 additions & 2 deletions src/verification.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::ctanker::{CEmailVerification, CVerification};
use crate::ctanker::{CEmailVerification, CPhoneNumberVerification, CVerification};
use std::ffi::CString;

const CVERIFICATION_VERSION: u8 = 3;
const CVERIFICATION_VERSION: u8 = 4;
const CEMAIL_VERIFICATION_VERSION: u8 = 1;
const CPHONE_NUMBER_VERIFICATION_VERSION: u8 = 1;

#[repr(u8)]
enum Type {
Expand All @@ -11,6 +12,7 @@ enum Type {
VerificationKey = 3,
#[allow(clippy::upper_case_acronyms)]
OIDCIDToken = 4,
PhoneNumber = 5,
}

pub(crate) struct CVerificationWrapper {
Expand All @@ -33,6 +35,11 @@ impl CVerificationWrapper {
},
passphrase: std::ptr::null(),
oidc_id_token: std::ptr::null(),
phone_number_verification: CPhoneNumberVerification {
version: CPHONE_NUMBER_VERIFICATION_VERSION,
phone_number: std::ptr::null(),
verification_code: std::ptr::null(),
},
},
}
}
Expand All @@ -51,6 +58,20 @@ impl CVerificationWrapper {
wrapper
}

pub(self) fn with_phone_number(phone_number: &str, verif_code: &str) -> Self {
let mut wrapper = Self::new();
let cphone_number = CString::new(phone_number).unwrap();
let cverif_code = CString::new(verif_code).unwrap();

wrapper.cverif.verification_method_type = Type::PhoneNumber as u8;
wrapper.cverif.phone_number_verification.phone_number = cphone_number.as_ptr();
wrapper.cverif.phone_number_verification.verification_code = cverif_code.as_ptr();

wrapper.cstrings.push(cphone_number);
wrapper.cstrings.push(cverif_code);
wrapper
}

pub(self) fn with_passphrase(passphrase: &str) -> Self {
let mut wrapper = Self::new();
let cpass = CString::new(passphrase).unwrap();
Expand Down Expand Up @@ -100,6 +121,10 @@ pub enum Verification {
VerificationKey(String),
#[allow(clippy::upper_case_acronyms)]
OIDCIDToken(String),
PhoneNumber {
phone_number: String,
verification_code: String,
},
}

impl Verification {
Expand All @@ -114,6 +139,10 @@ impl Verification {
}
Verification::VerificationKey(key) => CVerificationWrapper::with_verification_key(&key),
Verification::OIDCIDToken(token) => CVerificationWrapper::with_oidc_id_token(&token),
Verification::PhoneNumber {
phone_number,
verification_code,
} => CVerificationWrapper::with_phone_number(&phone_number, &verification_code),
}
}
}
10 changes: 9 additions & 1 deletion src/verification_methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum VerificationMethod {
VerificationKey,
#[allow(clippy::upper_case_acronyms)]
OIDCIDToken,
PhoneNumber(String),
}

#[derive(FromPrimitive)]
Expand All @@ -27,6 +28,7 @@ enum CMethodType {
VerificationKey = 3,
#[allow(clippy::upper_case_acronyms)]
OIDCIDToken = 4,
PhoneNumber = 5,

#[num_enum(default)]
Invalid,
Expand All @@ -38,13 +40,19 @@ impl VerificationMethod {
match ctype.into() {
CMethodType::Email => {
// SAFETY: If we get a valid Email verification method, the email is a valid string
let c_email = unsafe { CStr::from_ptr(method.email) };
let c_email = unsafe { CStr::from_ptr(method.value) };
let email = c_email.to_str().unwrap().into();
Ok(VerificationMethod::Email(email))
}
CMethodType::Passphrase => Ok(VerificationMethod::Passphrase),
CMethodType::VerificationKey => Ok(VerificationMethod::VerificationKey),
CMethodType::OIDCIDToken => Ok(VerificationMethod::OIDCIDToken),
CMethodType::PhoneNumber => {
// SAFETY: If we get a valid PhoneNumber verification method, the number is a valid string
let c_phone_number = unsafe { CStr::from_ptr(method.value) };
let phone_number = c_phone_number.to_str().unwrap().into();
Ok(VerificationMethod::PhoneNumber(phone_number))
}
CMethodType::Invalid => Err(Error::new(
ErrorCode::InternalError,
format!("Invalid verification method type {}", ctype),
Expand Down
18 changes: 17 additions & 1 deletion tests/identity/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct App {
}

impl App {
pub async fn get_verification_code(&self, email: &str) -> Result<String, Error> {
pub async fn get_email_verification_code(&self, email: &str) -> Result<String, Error> {
let client = reqwest::Client::new();
let reply = admin_rest_request(
client
Expand All @@ -27,4 +27,20 @@ impl App {
let code = reply["verification_code"].as_str().unwrap().to_owned();
Ok(code)
}

pub async fn get_sms_verification_code(&self, phone_number: &str) -> Result<String, Error> {
let client = reqwest::Client::new();
let reply = admin_rest_request(
client
.post(&format!("{}/verification/sms/code", &self.url))
.json(
&json!({ "phone_number": phone_number, "app_id": &self.id, "auth_token": &self.auth_token }),
)
.header(ACCEPT, "application/json"),
)
.await?;

let code = reply["verification_code"].as_str().unwrap().to_owned();
Ok(code)
}
}
8 changes: 6 additions & 2 deletions tests/identity/test_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,12 @@ impl TestApp {
&self.app.auth_token
}

pub async fn get_verification_code(&self, email: &str) -> Result<String, Error> {
self.app.get_verification_code(email).await
pub async fn get_email_verification_code(&self, email: &str) -> Result<String, Error> {
self.app.get_email_verification_code(email).await
}

pub async fn get_sms_verification_code(&self, phone_number: &str) -> Result<String, Error> {
self.app.get_sms_verification_code(phone_number).await
}

pub async fn app_update(
Expand Down
8 changes: 4 additions & 4 deletions tests/tanker_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ async fn share_with_provisional_user() -> Result<(), Error> {

let verif = Verification::Email {
email: bob_email.clone(),
verification_code: app.get_verification_code(&bob_email).await?,
verification_code: app.get_email_verification_code(&bob_email).await?,
};
bob.verify_provisional_identity(&verif).await?;

Expand Down Expand Up @@ -209,7 +209,7 @@ async fn throws_if_identity_is_already_attached() -> Result<(), Error> {

let verif = Verification::Email {
email: bob_email.clone(),
verification_code: app.get_verification_code(&bob_email).await?,
verification_code: app.get_email_verification_code(&bob_email).await?,
};
bob.verify_provisional_identity(&verif).await?;

Expand All @@ -218,7 +218,7 @@ async fn throws_if_identity_is_already_attached() -> Result<(), Error> {
assert_eq!(attach_result.status, Status::IdentityVerificationNeeded);
let verif = Verification::Email {
email: bob_email.clone(),
verification_code: app.get_verification_code(&bob_email).await?,
verification_code: app.get_email_verification_code(&bob_email).await?,
};
let err = alice.verify_provisional_identity(&verif).await.unwrap_err();
assert_eq!(err.code(), ErrorCode::IdentityAlreadyAttached);
Expand Down Expand Up @@ -246,7 +246,7 @@ async fn attach_provisional_with_single_verif() -> Result<(), Error> {
bob.start(&app.create_identity(None)).await?;
let verif = Verification::Email {
email: bob_email.clone(),
verification_code: app.get_verification_code(&bob_email).await?,
verification_code: app.get_email_verification_code(&bob_email).await?,
};
bob.register_identity(&verif, &VerificationOptions::new())
.await?;
Expand Down
28 changes: 25 additions & 3 deletions tests/verify_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ async fn check_email_verif_is_setup() -> Result<(), Error> {
let email = "[email protected]".to_string();
let verif = Verification::Email {
email: email.clone(),
verification_code: app.get_verification_code(&email).await?,
verification_code: app.get_email_verification_code(&email).await?,
};

let tanker = Core::new(app.make_options()).await?;
Expand All @@ -112,6 +112,28 @@ async fn check_email_verif_is_setup() -> Result<(), Error> {
Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn check_sms_verif_is_setup() -> Result<(), Error> {
let app = TestApp::get().await;
let id = &app.create_identity(None);
let phone_number = "+33600001111".to_string();
let verif = Verification::PhoneNumber {
phone_number: phone_number.clone(),
verification_code: app.get_sms_verification_code(&phone_number).await?,
};

let tanker = Core::new(app.make_options()).await?;
tanker.start(&id).await?;
tanker
.register_identity(&verif, &VerificationOptions::new())
.await?;
let methods = tanker.get_verification_methods().await?;
tanker.stop().await?;

assert_eq!(&methods, &[VerificationMethod::PhoneNumber(phone_number)]);
Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn unlock_with_verif_code() -> Result<(), Error> {
let app = TestApp::get().await;
Expand All @@ -122,7 +144,7 @@ async fn unlock_with_verif_code() -> Result<(), Error> {
tanker.start(&id).await?;
let verif = Verification::Email {
email: email.to_owned(),
verification_code: app.get_verification_code(&email).await?,
verification_code: app.get_email_verification_code(&email).await?,
};
tanker
.register_identity(&verif, &VerificationOptions::new())
Expand All @@ -133,7 +155,7 @@ async fn unlock_with_verif_code() -> Result<(), Error> {
tanker.start(&id).await?;
let verif = Verification::Email {
email: email.to_owned(),
verification_code: app.get_verification_code(&email).await?,
verification_code: app.get_email_verification_code(&email).await?,
};
tanker
.verify_identity(&verif, &VerificationOptions::new())
Expand Down

0 comments on commit fc1666c

Please sign in to comment.