diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc new file mode 100644 index 000000000..63566131e --- /dev/null +++ b/src/libexpr/flake/config.cc @@ -0,0 +1,81 @@ +#include "flake.hh" + +#include + +namespace nix::flake { + +// setting name -> setting value -> allow or ignore. +typedef std::map> TrustedList; + +Path trustedListPath() +{ + return getDataDir() + "/nix/trusted-settings.json"; +} + +static TrustedList readTrustedList() +{ + auto path = trustedListPath(); + if (!pathExists(path)) return {}; + auto json = nlohmann::json::parse(readFile(path)); + return json; +} + +static void writeTrustedList(const TrustedList & trustedList) +{ + writeFile(trustedListPath(), nlohmann::json(trustedList).dump()); +} + +void ConfigFile::apply() +{ + std::set whitelist{"bash-prompt", "bash-prompt-suffix"}; + + for (auto & [name, value] : settings) { + + auto baseName = hasPrefix(name, "extra-") ? std::string(name, 6) : name; + + // FIXME: Move into libutil/config.cc. + std::string valueS; + if (auto s = std::get_if(&value)) + valueS = *s; + else if (auto n = std::get_if(&value)) + valueS = fmt("%d", n); + else if (auto b = std::get_if>(&value)) + valueS = b->t ? "true" : "false"; + else if (auto ss = std::get_if>(&value)) + valueS = concatStringsSep(" ", *ss); // FIXME: evil + else + assert(false); + + if (!whitelist.count(baseName)) { + auto trustedList = readTrustedList(); + + bool trusted = false; + + if (auto saved = get(get(trustedList, name).value_or(std::map()), valueS)) { + trusted = *saved; + } else { + // FIXME: filter ANSI escapes, newlines, \r, etc. + if (std::tolower(logger->ask(fmt("do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)?", name, valueS)).value_or('n')) != 'y') { + if (std::tolower(logger->ask("do you want to permanently mark this value as untrusted (y/N)?").value_or('n')) == 'y') { + trustedList[name][valueS] = false; + writeTrustedList(trustedList); + } + } else { + if (std::tolower(logger->ask("do you want to permanently mark this value as trusted (y/N)?").value_or('n')) == 'y') { + trustedList[name][valueS] = trusted = true; + writeTrustedList(trustedList); + } + } + } + + if (!trusted) { + warn("ignoring untrusted flake configuration setting '%s'", name); + continue; + } + } + + globalConfig.set(name, valueS); + } +} + +} diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 0eadd94db..3e866e1f9 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -6,8 +6,6 @@ #include "fetchers.hh" #include "finally.hh" -#include - namespace nix { using namespace flake; @@ -637,78 +635,4 @@ Fingerprint LockedFlake::getFingerprint() const Flake::~Flake() { } -// setting name -> setting value -> allow or ignore. -typedef std::map> TrustedList; - -Path trustedListPath() -{ - return getDataDir() + "/nix/trusted-settings.json"; -} - -static TrustedList readTrustedList() -{ - auto path = trustedListPath(); - if (!pathExists(path)) return {}; - auto json = nlohmann::json::parse(readFile(path)); - return json; -} - -static void writeTrustedList(const TrustedList & trustedList) -{ - writeFile(trustedListPath(), nlohmann::json(trustedList).dump()); -} - -void ConfigFile::apply() -{ - std::set whitelist{"bash-prompt", "bash-prompt-suffix"}; - - for (auto & [name, value] : settings) { - - auto baseName = hasPrefix(name, "extra-") ? std::string(name, 6) : name; - - // FIXME: Move into libutil/config.cc. - std::string valueS; - if (auto s = std::get_if(&value)) - valueS = *s; - else if (auto n = std::get_if(&value)) - valueS = fmt("%d", n); - else if (auto b = std::get_if>(&value)) - valueS = b->t ? "true" : "false"; - else if (auto ss = std::get_if>(&value)) - valueS = concatStringsSep(" ", *ss); // FIXME: evil - else - assert(false); - - if (!whitelist.count(baseName)) { - auto trustedList = readTrustedList(); - - bool trusted = false; - - if (auto saved = get(get(trustedList, name).value_or(std::map()), valueS)) { - trusted = *saved; - } else { - // FIXME: filter ANSI escapes, newlines, \r, etc. - if (std::tolower(logger->ask(fmt("do you want to allow configuration setting '%s' to be set to '" ANSI_RED "%s" ANSI_NORMAL "' (y/N)?", name, valueS)).value_or('n')) != 'y') { - if (std::tolower(logger->ask("do you want to permanently mark this value as untrusted (y/N)?").value_or('n')) == 'y') { - trustedList[name][valueS] = false; - writeTrustedList(trustedList); - } - } else { - if (std::tolower(logger->ask("do you want to permanently mark this value as trusted (y/N)?").value_or('n')) == 'y') { - trustedList[name][valueS] = trusted = true; - writeTrustedList(trustedList); - } - } - } - - if (!trusted) { - warn("ignoring untrusted flake configuration setting '%s'", name); - continue; - } - } - - globalConfig.set(name, valueS); - } -} - }