in src/vtok_srv/src/worker.rs [248:289]
fn update_token(label: String, pin: String, token: schema::Token) -> ApiResponse {
let mut config = config::Config::load_rw().map_err(|_| ApiError::InternalError)?;
// If this update is changing the token label, we need to make sure that the
// new label is unique.
if label != token.label {
let dup = config
.slots()
.iter()
.find(|s| s.as_ref().filter(|t| t.label == token.label).is_some())
.is_some();
if dup {
return Err(ApiError::TokenLabelInUse);
}
}
config
.slots_mut()
.iter_mut()
.find(|s| match s {
None => false,
Some(tok) => tok.label == label,
})
.ok_or(ApiError::TokenNotFound)
.and_then(|slot| {
// It's safe to unwrap here, since the above find() ensures slot != None
if slot.as_ref().unwrap().pin != pin {
return Err(ApiError::AccessDenied);
}
slot.replace(config::Token {
label,
pin,
expiry_ts: util::time::monotonic_secs() + defs::TOKEN_EXPIRY_SECS,
private_keys: Self::decrypt_token_keys(token.keys, token.envelope_key)?,
});
Ok(())
})?;
config.save().map_err(|_| ApiError::InternalError)?;
Ok(ApiOk::None)
}