From 15ca847c37c170590abe6caa53dba5606d956341 Mon Sep 17 00:00:00 2001 From: mo8it Date: Mon, 15 Apr 2024 02:11:27 +0200 Subject: Implement third-party exercises trust handling --- src/main.rs | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index ed5becf..7b63f70 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ use anyhow::{Context, Result}; -use app_state::StateFileStatus; use clap::{Parser, Subcommand}; use crossterm::{ terminal::{Clear, ClearType}, @@ -19,14 +18,16 @@ mod init; mod list; mod progress_bar; mod run; +mod trust; mod watch; use self::{ - app_state::AppState, + app_state::{AppState, StateFileStatus}, info_file::InfoFile, init::init, list::list, run::run, + trust::{current_dir_is_trusted, trust_current_dir}, watch::{watch, WatchExit}, }; @@ -61,6 +62,11 @@ enum Subcommands { /// The name of the exercise name: String, }, + /// Trust the current directory with its exercises. + /// + /// You only need to run this if you want to work on third-party exercises or after you moved + /// the official exercises that were initialized with `rustlings init`. + Trust, } fn main() -> Result<()> { @@ -72,14 +78,26 @@ fn main() -> Result<()> { if matches!(args.command, Some(Subcommands::Init)) { init(&info_file.exercises).context("Initialization failed")?; - println!("{POST_INIT_MSG}"); return Ok(()); - } else if !Path::new("exercises").is_dir() { + } + + if !Path::new("exercises").is_dir() { println!("{PRE_INIT_MSG}"); exit(1); } + if matches!(args.command, Some(Subcommands::Trust)) { + trust_current_dir()?; + println!("{POST_TRUST_MSG}"); + return Ok(()); + } + + if !current_dir_is_trusted()? { + println!("{NOT_TRUSTED_MSG}"); + exit(1); + } + let (mut app_state, state_file_status) = AppState::new( info_file.exercises, info_file.final_message.unwrap_or_default(), @@ -130,8 +148,6 @@ fn main() -> Result<()> { } } } - // `Init` is handled above. - Some(Subcommands::Init) => (), Some(Subcommands::Run { name }) => { if let Some(name) = name { app_state.set_current_exercise_by_name(&name)?; @@ -149,6 +165,8 @@ fn main() -> Result<()> { app_state.set_current_exercise_by_name(&name)?; println!("{}", app_state.current_exercise().hint); } + // `Init` and `Trust` are handled above. + Some(Subcommands::Init | Subcommands::Trust) => (), } Ok(()) @@ -158,8 +176,13 @@ const CARGO_NOT_FOUND_ERR: &str = "Failed to find `cargo`. Did you already install Rust? Try running `cargo --version` to diagnose the problem."; +const POST_INIT_MSG: &str = "Done initialization! + +Run `cd rustlings` to go into the generated directory. +Then run `rustlings` to get started."; + const PRE_INIT_MSG: &str = r" - welcome to... + Welcome to... _ _ _ _ __ _ _ ___| |_| (_)_ __ __ _ ___ | '__| | | / __| __| | | '_ \ / _` / __| @@ -170,11 +193,19 @@ const PRE_INIT_MSG: &str = r" The `exercises` directory wasn't found in the current directory. If you are just starting with Rustlings, run the command `rustlings init` to initialize it."; -const POST_INIT_MSG: &str = " -Done initialization! +const POST_TRUST_MSG: &str = "You now trust the exercises in the current directory. +Run `rustlings` to start working on them."; -Run `cd rustlings` to go into the generated directory. -Then run `rustlings` to get started."; +const NOT_TRUSTED_MSG: &str = "It looks like you are trying to work on third-party exercises. +Rustlings supports third-party exercises. But because Rustlings runs the code inside an exercise, +we need to warn you about the possibility of malicious code. +We recommend that you read all the exercise files in the `exercises` directory and check the +dependencies in the `Cargo.toml` file. +If everything looks fine and you want to trust this directory, run `rustlings trust`. + +If you you are trying to work on the official exercises that were generated using `rustlings init`, +then you probably moved the directory containing them. In that case, you can run `rustlings trust` +without a problem."; const FENISH_LINE: &str = "+----------------------------------------------------+ | You made it to the Fe-nish line! | -- cgit v1.2.3