2020-11-26 14:16:36 +02:00
# include "flake.hh"
2021-11-12 16:50:07 +02:00
# include "globals.hh"
2022-03-01 03:29:34 +02:00
# include "fetch-settings.hh"
2020-11-26 14:16:36 +02:00
# include <nlohmann/json.hpp>
namespace nix : : flake {
// setting name -> setting value -> allow or ignore.
typedef std : : map < std : : string , std : : map < std : : string , bool > > 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 )
{
2021-05-09 05:31:28 +03:00
auto path = trustedListPath ( ) ;
createDirs ( dirOf ( path ) ) ;
writeFile ( path , nlohmann : : json ( trustedList ) . dump ( ) ) ;
2020-11-26 14:16:36 +02:00
}
void ConfigFile : : apply ( )
{
2021-08-07 14:42:59 +03:00
std : : set < std : : string > whitelist { " bash-prompt " , " bash-prompt-suffix " , " flake-registry " } ;
2020-11-26 14:16:36 +02:00
for ( auto & [ name , value ] : settings ) {
auto baseName = hasPrefix ( name , " extra- " ) ? std : : string ( name , 6 ) : name ;
// FIXME: Move into libutil/config.cc.
std : : string valueS ;
2021-11-22 14:29:49 +02:00
if ( auto * s = std : : get_if < std : : string > ( & value ) )
2020-11-26 14:16:36 +02:00
valueS = * s ;
2021-11-22 14:29:49 +02:00
else if ( auto * n = std : : get_if < int64_t > ( & value ) )
valueS = fmt ( " %d " , * n ) ;
else if ( auto * b = std : : get_if < Explicit < bool > > ( & value ) )
2020-11-26 14:16:36 +02:00
valueS = b - > t ? " true " : " false " ;
else if ( auto ss = std : : get_if < std : : vector < std : : string > > ( & value ) )
valueS = concatStringsSep ( " " , * ss ) ; // FIXME: evil
else
assert ( false ) ;
2022-05-04 08:44:32 +03:00
if ( ! whitelist . count ( baseName ) & & ! nix : : fetchSettings . acceptFlakeConfig ) {
2020-11-26 14:16:36 +02:00
bool trusted = false ;
2022-05-04 08:44:32 +03:00
auto trustedList = readTrustedList ( ) ;
auto tlname = get ( trustedList , name ) ;
if ( auto saved = tlname ? get ( * tlname , valueS ) : nullptr ) {
2020-11-26 14:16:36 +02:00
trusted = * saved ;
2021-11-12 16:50:07 +02:00
warn ( " Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json. " , name , valueS ) ;
2020-11-26 14:16:36 +02:00
} else {
// FIXME: filter ANSI escapes, newlines, \r, etc.
2021-11-12 16:50:07 +02:00
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 ' ) {
trusted = true ;
}
if ( std : : tolower ( logger - > ask ( fmt ( " do you want to permanently mark this value as %s (y/N)? " , trusted ? " trusted " : " untrusted " ) ) . value_or ( ' n ' ) ) = = ' y ' ) {
trustedList [ name ] [ valueS ] = trusted ;
writeTrustedList ( trustedList ) ;
2020-11-26 14:16:36 +02:00
}
}
if ( ! trusted ) {
warn ( " ignoring untrusted flake configuration setting '%s' " , name ) ;
continue ;
}
}
globalConfig . set ( name , valueS ) ;
}
}
}