If the given base or mount directory doesn't exist, offer to create them

This commit is contained in:
Sebastian Messmer 2016-01-25 15:01:34 +01:00
parent af4ef5d425
commit 29065746c2
6 changed files with 42 additions and 9 deletions

View File

@ -2,6 +2,7 @@ Version 0.8.5
---------------
* Fix package manager warning when installing the .deb package
* Offer a default configuration when creating new filesystems
* If the given base or mount directory doesn't exist, offer to create them
Version 0.8.4
---------------

View File

@ -47,6 +47,7 @@ using cpputils::TempFile;
using cpputils::RandomGenerator;
using cpputils::unique_ref;
using cpputils::SCryptSettings;
using cpputils::Console;
using std::cout;
using std::string;
using std::endl;
@ -71,8 +72,8 @@ using boost::chrono::milliseconds;
namespace cryfs {
Cli::Cli(RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings):
_keyGenerator(keyGenerator), _scryptSettings(scryptSettings) {}
Cli::Cli(RandomGenerator &keyGenerator, const SCryptSettings &scryptSettings, shared_ptr<Console> console):
_keyGenerator(keyGenerator), _scryptSettings(scryptSettings), _console(console) {}
void Cli::_showVersion() {
cout << "CryFS Version " << version::VERSION_STRING << endl;
@ -174,8 +175,7 @@ namespace cryfs {
CryConfigFile Cli::_loadOrCreateConfig(const ProgramOptions &options) {
try {
auto configFile = _determineConfigFile(options);
auto console = make_shared<IOStreamConsole>();
auto config = CryConfigLoader(console, _keyGenerator, _scryptSettings,
auto config = CryConfigLoader(_console, _keyGenerator, _scryptSettings,
std::bind(&Cli::_getPassword, this, std::cref(options), &Cli::_askPasswordForExistingFilesystem),
std::bind(&Cli::_getPassword, this, std::cref(options), &Cli::_askPasswordForNewFilesystem),
options.cipher()).loadOrCreate(configFile);
@ -247,7 +247,14 @@ namespace cryfs {
void Cli::_checkDirAccessible(const bf::path &dir, const std::string &name) {
if (!bf::exists(dir)) {
throw std::runtime_error(name+" not found.");
bool create = _console->askYesNo("Could not find " + name + ". Do you want to create it?");
if (create) {
if (!bf::create_directory(dir)) {
throw std::runtime_error("Error creating "+name);
}
} else {
throw std::runtime_error(name + " not found.");
}
}
if (!bf::is_directory(dir)) {
throw std::runtime_error(name+" is not a directory.");

View File

@ -6,13 +6,14 @@
#include "../config/CryConfigFile.h"
#include <boost/filesystem/path.hpp>
#include <messmer/cpp-utils/tempfile/TempFile.h>
#include <messmer/cpp-utils/io/Console.h>
#include <messmer/cpp-utils/random/RandomGenerator.h>
#include "CallAfterTimeout.h"
namespace cryfs {
class Cli final {
public:
Cli(cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings &scryptSettings);
Cli(cpputils::RandomGenerator &keyGenerator, const cpputils::SCryptSettings &scryptSettings, std::shared_ptr<cpputils::Console> console);
int main(int argc, char *argv[]);
private:
@ -36,6 +37,7 @@ namespace cryfs {
cpputils::RandomGenerator &_keyGenerator;
cpputils::SCryptSettings _scryptSettings;
std::shared_ptr<cpputils::Console> _console;
DISALLOW_COPY_AND_ASSIGN(Cli);
};

View File

@ -5,8 +5,10 @@
using namespace cryfs;
using cpputils::Random;
using cpputils::SCrypt;
using std::make_shared;
using cpputils::IOStreamConsole;
int main(int argc, char *argv[]) {
auto &keyGenerator = Random::OSRandom();
return Cli(keyGenerator, SCrypt::DefaultSettings).main(argc, argv);
return Cli(keyGenerator, SCrypt::DefaultSettings, make_shared<IOStreamConsole>()).main(argc, argv);
}

View File

@ -3,6 +3,7 @@
namespace bf = boost::filesystem;
using ::testing::Values;
using ::testing::WithParamInterface;
using ::testing::Return;
using std::vector;
using cpputils::TempFile;
@ -117,9 +118,18 @@ TEST_P(CliTest_WrongEnvironment, MountDirIsBaseDir_BothRelative) {
TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist) {
_basedir.remove();
ON_CALL(*console, askYesNo("Could not find base directory. Do you want to create it?")).WillByDefault(Return(false)); // ON_CALL and not EXPECT_CALL, because this is a death test (i.e. it is forked) and gmock EXPECT_CALL in fork children don't report to parents.
Test_Run_Error("Error: base directory not found");
}
TEST_P(CliTest_WrongEnvironment, BaseDir_DoesntExist_Create) {
if (!GetParam().runningInForeground) {return;} // TODO Make this work also if run in background (see CliTest::EXPECT_RUN_SUCCESS)
_basedir.remove();
ON_CALL(*console, askYesNo("Could not find base directory. Do you want to create it?")).WillByDefault(Return(true));
Test_Run_Success();
EXPECT_TRUE(bf::exists(_basedir.path()) && bf::is_directory(_basedir.path()));
}
TEST_P(CliTest_WrongEnvironment, BaseDir_IsNotDirectory) {
TempFile basedirfile;
basedir = basedirfile.path();
@ -155,9 +165,18 @@ TEST_P(CliTest_WrongEnvironment, BaseDir_NoPermission) {
TEST_P(CliTest_WrongEnvironment, MountDir_DoesntExist) {
_mountdir.remove();
ON_CALL(*console, askYesNo("Could not find mount directory. Do you want to create it?")).WillByDefault(Return(false)); // ON_CALL and not EXPECT_CALL, because this is a death test (i.e. it is forked) and gmock EXPECT_CALL in fork children don't report to parents.
Test_Run_Error("Error: mount directory not found");
}
TEST_P(CliTest_WrongEnvironment, MountDir_DoesntExist_Create) {
if (!GetParam().runningInForeground) {return;} // TODO Make this work also if run in background (see CliTest::EXPECT_RUN_SUCCESS)
_mountdir.remove();
ON_CALL(*console, askYesNo("Could not find mount directory. Do you want to create it?")).WillByDefault(Return(true));
Test_Run_Success();
EXPECT_TRUE(bf::exists(_mountdir.path()) && bf::is_directory(_mountdir.path()));
}
TEST_P(CliTest_WrongEnvironment, MountDir_IsNotDirectory) {
TempFile mountdirfile;
mountdir = mountdirfile.path();

View File

@ -9,10 +9,11 @@
#include "../../../src/cli/Cli.h"
#include <messmer/cpp-utils/logging/logging.h>
#include <messmer/cpp-utils/process/subprocess.h>
#include "../../testutils/MockConsole.h"
class CliTest : public ::testing::Test {
public:
CliTest(): _basedir(), _mountdir(), basedir(_basedir.path()), mountdir(_mountdir.path()), logfile(), configfile(false) {}
CliTest(): _basedir(), _mountdir(), basedir(_basedir.path()), mountdir(_mountdir.path()), logfile(), configfile(false), console(std::make_shared<MockConsole>()) {}
cpputils::TempDir _basedir;
cpputils::TempDir _mountdir;
@ -20,6 +21,7 @@ public:
boost::filesystem::path mountdir;
cpputils::TempFile logfile;
cpputils::TempFile configfile;
std::shared_ptr<MockConsole> console;
void run(std::vector<const char*> args) {
std::vector<char*> _args;
@ -29,7 +31,7 @@ public:
_args.push_back(const_cast<char*>(arg));
}
auto &keyGenerator = cpputils::Random::PseudoRandom();
cryfs::Cli(keyGenerator, cpputils::SCrypt::TestSettings).main(_args.size(), _args.data());
cryfs::Cli(keyGenerator, cpputils::SCrypt::TestSettings, console).main(_args.size(), _args.data());
}
void EXPECT_EXIT_WITH_HELP_MESSAGE(std::vector<const char*> args, const std::string &message = "") {