Commit 02e5f222 authored by Sylvain Fargier's avatar Sylvain Fargier 🐾
Browse files

Merge branch 'wip-filepath' into 'master'

filepath

See merge request apc/experiments/ntof/addh!2
parents dc710657 9c14956c
Pipeline #1569689 passed with stages
in 4 minutes and 14 seconds
# ADDH
# Build
Only needed first time to fetch the docker image
```
docker pull $(cat .docker-builder)
```
Start a temporary container, binding current directory inside
```
docker run -v "$PWD:$PWD" -w "$PWD" --rm -it gitlab-registry.cern.ch/apc/experiments/ntof/builder /bin/bash
```
```
mkdir build && cd build
cmake3 .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCOVERAGE=ON -DTESTS=ON
make -j4
```
# Styling
```
make style
```
# Testing
```
cd tests
./test_all
```
......@@ -3,6 +3,7 @@
<commandServiceName value="ADDH/Command"></commandServiceName>
<stateServiceName value="ADDH/State"></stateServiceName>
<serverName value="ADDH"></serverName>
<outputDirPrefix value="ADDH/Prefix"></outputDirPrefix>
<header version="0">
<data destination="BCT372" destinationPrefix="" fromService="F16.BCT372" fromName="totalIntensityPreferred" />
......
......@@ -7,9 +7,13 @@
#include "ADDHCmd.h"
#include <boost/filesystem.hpp>
#include "ADDHWriter.h"
#include "Config.h"
namespace bfs = boost::filesystem;
/*! \namespace ntof
*
* namespace used for all the element of the nTOF
......@@ -23,7 +27,12 @@ namespace addh {
ADDHCmd::ADDHCmd() :
DIMSuperCommand(
Config::instance().getValue("commandServiceName", "ADDH/Command"))
{}
{
char hostname[_SC_HOST_NAME_MAX];
gethostname(hostname, _SC_HOST_NAME_MAX);
std::string hostnameString(hostname);
this->m_filePathPrefix = Config::instance().getValue("outputDirPrefix", "");
}
ADDHCmd::~ADDHCmd() {}
......@@ -53,16 +62,26 @@ void ADDHCmd::commandReceived(ntof::dim::DIMCmd &cmdData)
command.timingEvent = timingEvent;
command.filePath = filePath;
// Check if the command can be accepted
LOG(INFO) << "Command " << textValue << " received.";
if (textValue != "write" && textValue != "reset" && textValue != "clear")
// Check if filePath is subpath of m_filePathPrefix
if (isValidPath(filePath, m_filePathPrefix))
{
setError(cmdData.getKey(), CMD_UNKNOWN, "Command unknown.");
// Check if the command can be accepted
LOG(INFO) << "Command " << textValue << " received.";
if (textValue != "write" && textValue != "reset" &&
textValue != "clear")
{
setError(cmdData.getKey(), CMD_UNKNOWN, "Command unknown.");
}
else
{
ADDHWriter::instance().addCommand(command);
setOk(cmdData.getKey(), std::string("Done!"));
}
}
else
{
ADDHWriter::instance().addCommand(command);
setOk(cmdData.getKey(), std::string("Done!"));
setError(cmdData.getKey(), WRITE_ERR,
"Permission denied: invalid output path");
}
}
else
......@@ -71,5 +90,32 @@ void ADDHCmd::commandReceived(ntof::dim::DIMCmd &cmdData)
setError(cmdData.getKey(), CMD_EMPTY, "Parent node is empty");
}
}
bool ADDHCmd::isValidPath(const std::string &filePath,
const std::string &m_filePathPrefix)
{
if (m_filePathPrefix != "")
{
bfs::path absPath = filePath;
if (filePath[0] != '/')
{
// filePath is relative, convert to m_filePathPrefix/filePath form
absPath = m_filePathPrefix + "/" + filePath;
}
try
{
absPath = bfs::canonical(absPath).string();
}
catch (std::exception const &e)
{
// No such file or directory
return false;
}
return (absPath.string().compare(0, m_filePathPrefix.length(),
m_filePathPrefix) == 0);
}
return true;
}
} // namespace addh
} // namespace ntof
......@@ -44,11 +44,17 @@ public:
*/
~ADDHCmd();
bool isValidPath(const std::string &filePath,
const std::string &m_filePathPrefix);
/*!
* \brief Receive all the commands send to the DIM Super Command. This
* method is executed each time a command is received
*/
void commandReceived(ntof::dim::DIMCmd &cmdData);
protected:
std::string m_filePathPrefix;
};
} // namespace addh
} // namespace ntof
......
......@@ -17,6 +17,7 @@ set(test_SRCS test_main.cpp test_init.cpp
test_helpers_dim.hpp test_helpers_dim.cpp
test_WriterFile.cpp
test_ADDH.cpp
test_ADDHCmd.cpp
)
add_executable(test_all ${test_SRCS})
......
#include <fstream>
#include <memory>
#include <boost/filesystem.hpp>
#include <DIMDataSet.h>
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include "ADDH.h"
#include "ADDHCmd.h"
#include "Config.h"
#include "WriterFile.h"
#include "local-config.h"
#include "test_helpers.hpp"
namespace bfs = boost::filesystem;
using namespace ntof::addh;
class TestADDHCmdFile : public CppUnit::TestFixture
{
protected:
CPPUNIT_TEST_SUITE(TestADDHCmdFile);
CPPUNIT_TEST(validatePathCheck);
CPPUNIT_TEST(receiveCommandWithCorrectAbsolutePath);
CPPUNIT_TEST(receiveCommandWithCorrectRelativePath);
CPPUNIT_TEST_SUITE_END();
bfs::path m_top_level_dir, m_correct_prefix_dir, m_incorrect_prefix_dir;
std::unique_ptr<DimTestHelper> m_dim;
public:
void setUp()
{
m_top_level_dir = bfs::temp_directory_path() / "ADDHCmd_test";
bfs::create_directories(m_top_level_dir);
m_correct_prefix_dir = m_top_level_dir / "correct_prefix_dir";
bfs::create_directories(m_correct_prefix_dir);
m_incorrect_prefix_dir = m_top_level_dir / "incorrect_prefix_dir";
bfs::create_directories(m_incorrect_prefix_dir);
m_dim.reset(new DimTestHelper());
}
void tearDown()
{
bfs::remove_all(m_top_level_dir);
m_dim.reset();
}
void receiveCommand(const bfs::path &filename)
{
std::shared_ptr<ADDH> addh(new ADDH);
WriterFile writer(addh);
DimInfoWaiter info("ADDH/Events");
EQ(true, info.waitUpdate());
writer.addCommand(
{std::string("write"), 6789, 12345, filename.string()});
EQ(true, info.waitUpdate(2));
EQ(true, bfs::exists(filename));
}
void receiveCommandWithCorrectRelativePath()
{
bfs::path filename = "correct_path";
receiveCommand(filename);
}
void receiveCommandWithCorrectAbsolutePath()
{
bfs::path filename = m_correct_prefix_dir / "correct_path";
receiveCommand(filename);
}
void validatePathCheck()
{
std::shared_ptr<ADDHCmd> addhCmd_(new ADDHCmd);
bfs::path correct_prefixed_path = m_correct_prefix_dir / "correct_path";
bfs::create_directories(correct_prefixed_path);
bfs::path incorrect_prefixed_path = m_incorrect_prefix_dir /
"incorrect_path";
bfs::create_directories(incorrect_prefixed_path);
bfs::path non_existent_path = m_top_level_dir / "non_existent_path";
// correct absolute path
EQ(true,
addhCmd_->isValidPath(correct_prefixed_path.string(),
m_correct_prefix_dir.string()));
// correct relative path
EQ(true,
addhCmd_->isValidPath("correct_path", m_correct_prefix_dir.string()));
// incorrect absolute path
EQ(false,
addhCmd_->isValidPath(incorrect_prefixed_path.string(),
m_correct_prefix_dir.string()));
// non existent absolute path
EQ(false,
addhCmd_->isValidPath(non_existent_path.string(),
m_correct_prefix_dir.string()));
// illegal paths
EQ(false,
addhCmd_->isValidPath("/tmp/../etc/correct_path",
m_correct_prefix_dir.string()));
EQ(false,
addhCmd_->isValidPath(correct_prefixed_path.string() + "/../..",
m_correct_prefix_dir.string()));
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestADDHCmdFile);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment