fn update_token()

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)
    }