in src/vtok_srv/src/worker.rs [58:93]
fn add_token(token: schema::Token) -> ApiResponse {
let mut config = config::Config::load_rw().map_err(|_| ApiError::InternalError)?;
// Check if the token label is already in use by another token.
let dup = config
.slots()
.iter()
.filter(|s| match s {
None => false,
Some(tok) => tok.label == token.label,
})
.count();
if dup > 0 {
return Err(ApiError::TokenLabelInUse);
}
let private_keys = Self::decrypt_token_keys(token.keys, token.envelope_key)?;
// Find the first free slot.
let free_slot = config
.slots_mut()
.iter_mut()
.find(|s| s.is_none())
.ok_or(ApiError::TooManyTokens)?;
free_slot.replace(config::Token {
label: token.label,
pin: token.pin,
private_keys,
expiry_ts: util::time::monotonic_secs() + defs::TOKEN_EXPIRY_SECS,
});
config.save().map_err(|_| ApiError::InternalError)?;
Ok(ApiOk::None)
}