Skip to content

Instantly share code, notes, and snippets.

@bstrie
Created August 16, 2019 17:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bstrie/1d8acbf8992d7e2ac3c0c60531e3d9c8 to your computer and use it in GitHub Desktop.
Save bstrie/1d8acbf8992d7e2ac3c0c60531e3d9c8 to your computer and use it in GitHub Desktop.
fn redis_insert_account(
&self,
specified_id: Option<u64>,
account: AccountDetails,
) -> Box<dyn Future<Item = Account, Error = ()> + Send> {
let connection = self.connection.clone();
let routing_table = self.routes.clone();
let encryption_key = self.encryption_key.clone();
// Instead of storing the incoming secrets, we store the HMAC digest of them
// (This is better than encrypting because the output is deterministic so we can look
// up the account by the HMAC of the auth details submitted by the account holder over the wire)
let btp_incoming_token_hmac = account
.btp_incoming_token
.clone()
.map(|token| hmac::sign(&self.hmac_key, token.as_bytes()));
let btp_incoming_token_hmac_clone = btp_incoming_token_hmac;
let http_incoming_token_hmac = account
.http_incoming_token
.clone()
.map(|token| hmac::sign(&self.hmac_key, token.as_bytes()));
let http_incoming_token_hmac_clone = http_incoming_token_hmac;
Box::new(
match specified_id {
Some(id) => Either::A(Ok((connection.as_ref().clone(), Account::try_from(id, account).unwrap()))),
None => Either::B(self.get_next_account_id()
.and_then(|id| {
debug!("Next account id is: {}", id);
Account::try_from(id, account)
})
// TODO RACE
.and_then(move |account| {
// Check that there isn't already an account with values that must be unique
let mut keys: Vec<String> = vec!["ID".to_string()];
let mut pipe = redis::pipe();
pipe.exists(accounts_key(account.id));
if let Some(auth) = btp_incoming_token_hmac {
keys.push("BTP auth".to_string());
pipe.hexists("btp_auth", auth.as_ref());
}
if let Some(auth) = http_incoming_token_hmac {
keys.push("HTTP auth".to_string());
pipe.hexists("http_auth", auth.as_ref());
}
pipe.query_async(connection.as_ref().clone())
.map_err(|err| {
error!(
"Error checking whether account details already exist: {:?}",
err
)
})
.and_then(
move |(connection, results): (SharedConnection, Vec<bool>)| {
if let Some(index) = results.iter().position(|val| *val) {
warn!("An account already exists with the same {}. Cannot insert account: {:?}", keys[index], account);
Err(())
} else {
Ok((connection, account))
}
},
)
})
)
}
.and_then( /* the rest */ ),
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment