This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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