Repository: denoland/deno
File: runtime/permissions/lib.rs (Rust)

Code before:
    format!(
      "specify the required permissions during compilation using `deno compile --allow-{name}`"
    )
  } else {
    format!("run again with the --allow-{name} flag")
  }
}

fn write_audit<T>(flag_name: &str, value: T)
where
  T: Serialize,
{
  if let Some(file) = AUDIT_FILE.get() {
    let mut file = file.lock();

    let mut map = serde_json::Map::with_capacity(3);
    let _ = map.insert(
      "permission".into(),
      serde_json::to_value(flag_name).unwrap(),
    );
    let _ = map.insert("value".into(), serde_json::to_value(value).unwrap());

    let get_stack = MAYBE_CURRENT_STACKTRACE.lock();
    if let Some(stack) = get_stack.as_ref().map(|s| s()) {
      let _ = map.insert("stack".into(), serde_json::to_value(&stack).unwrap());
    }

    file
      .write_all(
        format!("{}\n", serde_json::to_string(&map).unwrap()).as_bytes(),
      )
      .unwrap();
  }
}

/// Fast exit from permission check routines if this permission
/// is in the "fully-granted" state.
macro_rules! audit_and_skip_check_if_is_permission_fully_granted {
  ($this:expr, $flag_name:expr, $value:expr) => {
    write_audit($flag_name, $value);

    if $this.is_allow_all() {
      return Ok(());
    }
  };
}

static DEBUG_LOG_ENABLED: Lazy<bool> =
  Lazy::new(|| log::log_enabled!(log::Level::Debug));

/// Quadri-state value for storing permission state

Review comment (security):
I'm not 100% sure, but I think this might be faster if you construct a single struct and then do `serde_json::to_value()` instead of doing it several times.

Can you tell a bit more about the choice of the format? It appears that this one is quite constly, while also missing some crucial data like datetime of permission access

Code after:
    format!(
      "specify the required permissions during compilation using `deno compile --allow-{name}`"
    )
  } else {
    format!("run again with the --allow-{name} flag")
  }
}

fn write_audit<T>(flag_name: &str, value: T)
where
  T: Serialize,
{
  let Some(file) = AUDIT_FILE.get() else {
    return;
  };

  let mut file = file.lock();

  let mut map = serde_json::Map::with_capacity(5);
  let _ = map.insert("v".into(), serde_json::Value::Number(1.into()));
  let _ = map.insert(
    "datetime".into(),
    serde_json::Value::String(
      chrono::Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true),
    ),
  );
  let _ = map.insert(
    "permission".into(),
    serde_json::to_value(flag_name).unwrap(),
  );
  let _ = map.insert("value".into(), serde_json::to_value(value).unwrap());

  let get_stack = MAYBE_CURRENT_STACKTRACE.lock();
  if let Some(stack) = get_stack.as_ref().map(|s| s()) {
    let _ = map.insert("stack".into(), serde_json::to_value(&stack).unwrap());
  }

  let _ = file.write_all(
    format!("{}\n", serde_json::to_string(&map).unwrap()).as_bytes(),
  );
}

/// Fast exit from permission check routines if this permission
/// is in the "fully-granted" state.
macro_rules! audit_and_skip_check_if_is_permission_fully_granted {
  ($this:expr, $flag_name:expr, $value:expr) => {
    write_audit($flag_name, $value);

    if $this.is_allow_all() {
      return Ok(());
    }