blob: bad010cc281ec33aef2bcd44a4da9d304a5e4892 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2018, Regents of the University of California
*
* This file is part of NAC (Name-Based Access Control for NDN).
* See AUTHORS.md for complete list of NAC authors and contributors.
*
* NAC is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* NAC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* NAC, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*
* @author Zhiyi Zhang <zhiyi@cs.ucla.edu>
*/
#include "group-manager-db.hpp"
#include "boost-test.hpp"
#include "algo/rsa.hpp"
#include <boost/filesystem.hpp>
namespace ndn {
namespace nac {
namespace tests {
const uint8_t SCHEDULE[] = {
0x8f, 0xc4,// Schedule
0x8d, 0x90,// WhiteIntervalList
0x8c, 0x2e, // RepetitiveInterval
0x86, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x35, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x87, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x38, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x88, 0x01,
0x05,
0x89, 0x01,
0x0a,
0x8a, 0x01,
0x02,
0x8b, 0x01,
0x01,
0x8c, 0x2e, // RepetitiveInterval
0x86, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x35, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x87, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x38, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x88, 0x01,
0x06,
0x89, 0x01,
0x08,
0x8a, 0x01,
0x01,
0x8b, 0x01,
0x01,
0x8c, 0x2e, // RepetitiveInterval
0x86, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x35, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x87, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x35, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x88, 0x01,
0x04,
0x89, 0x01,
0x07,
0x8a, 0x01,
0x00,
0x8b, 0x01,
0x00,
0x8e, 0x30, // BlackIntervalList
0x8c, 0x2e, // RepetitiveInterval
0x86, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x37, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x87, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x37, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x88, 0x01,
0x07,
0x89, 0x01,
0x08,
0x8a, 0x01,
0x00,
0x8b, 0x01,
0x00
};
const uint8_t REPETITIVE_INTERVAL[] = {
0x8c, 0x2e, // RepetitiveInterval
0x86, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x38, 0x32, 0x35, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x87, 0x0f,
0x32, 0x30, 0x31, 0x35, 0x30, 0x39, 0x32, 0x31, 0x54, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
0x88, 0x01,
0x02,
0x89, 0x01,
0x0a,
0x8a, 0x01,
0x05,
0x8b, 0x01,
0x01
};
class GroupManagerDBFixture
{
public:
GroupManagerDBFixture()
: tmpPath(boost::filesystem::path(TMP_TESTS_PATH))
{
boost::filesystem::create_directories(tmpPath);
}
~GroupManagerDBFixture()
{
boost::filesystem::remove_all(tmpPath);
}
public:
boost::filesystem::path tmpPath;
};
BOOST_FIXTURE_TEST_SUITE(TestGroupManagerDB, GroupManagerDBFixture)
BOOST_AUTO_TEST_CASE(DatabaseFunctions)
{
// construction
std::string dbDir = tmpPath.c_str();
dbDir += "/test.db";
GroupManagerDB db(dbDir);
Block scheduleBlock(SCHEDULE, sizeof(SCHEDULE));
// create schedule
Schedule schedule(scheduleBlock);
// create member
RsaKeyParams params;
DecryptKey<algo::Rsa> decryptKey = algo::Rsa::generateKey(params);
EncryptKey<algo::Rsa> encryptKey = algo::Rsa::deriveEncryptKey(decryptKey.getKeyBits());
Buffer keyBuf = encryptKey.getKeyBits();
Name name1("/ndn/BoyA/ksk-123");
Name name2("/ndn/BoyB/ksk-1233");
Name name3("/ndn/GirlC/ksk-123");
Name name4("/ndn/GirlD/ksk-123");
Name name5("/ndn/Hello/ksk-123");
// add schedules into the database
BOOST_CHECK_NO_THROW(db.addSchedule("work-time", schedule));
BOOST_CHECK_NO_THROW(db.addSchedule("rest-time", schedule));
BOOST_CHECK_NO_THROW(db.addSchedule("play-time", schedule));
BOOST_CHECK_NO_THROW(db.addSchedule("boelter-time", schedule));
// throw exception when adding a schedule called an existing name
BOOST_CHECK_THROW(db.addSchedule("boelter-time", schedule), GroupManagerDB::Error);
// add members into the database
BOOST_CHECK_NO_THROW(db.addMember("work-time", name1, keyBuf));
BOOST_CHECK_NO_THROW(db.addMember("rest-time", name2, keyBuf));
BOOST_CHECK_NO_THROW(db.addMember("play-time", name3, keyBuf));
BOOST_CHECK_NO_THROW(db.addMember("play-time", name4, keyBuf));
// throw exception when adding a member having a not existing schedule name
BOOST_CHECK_THROW(db.addMember("false-time", name5, keyBuf), GroupManagerDB::Error);
BOOST_CHECK_NO_THROW(db.addMember("boelter-time", name5, keyBuf));
// throw exception when adding a member having an existing identity
BOOST_CHECK_THROW(db.addMember("work-time", name5, keyBuf), GroupManagerDB::Error);
// has function
BOOST_CHECK_EQUAL(db.hasSchedule("work-time"), true);
BOOST_CHECK_EQUAL(db.hasSchedule("rest-time"), true);
BOOST_CHECK_EQUAL(db.hasSchedule("play-time"), true);
BOOST_CHECK_EQUAL(db.hasSchedule("sleep-time"), false);
BOOST_CHECK_EQUAL(db.hasSchedule(""), false);
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/BoyA")), true);
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/BoyB")), true);
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/BoyC")), false);
// get schedule
Schedule scheduleResult = db.getSchedule("work-time");
BOOST_CHECK(scheduleResult.wireEncode() == scheduleBlock);
scheduleResult = db.getSchedule("play-time");
BOOST_CHECK(scheduleResult.wireEncode() == scheduleBlock);
// throw exception when there is no such schedule in database
BOOST_CHECK_THROW(db.getSchedule("work-time-11"), GroupManagerDB::Error);
// list all schedule names
std::list<std::string> names = db.listAllScheduleNames();
BOOST_CHECK(std::find(names.begin(), names.end(), "work-time") != names.end());
BOOST_CHECK(std::find(names.begin(), names.end(), "play-time") != names.end());
BOOST_CHECK(std::find(names.begin(), names.end(), "rest-time") != names.end());
BOOST_CHECK(std::find(names.begin(), names.end(), "sleep-time") == names.end());
// list members of a schedule
std::map<Name, Buffer> memberMap = db.getScheduleMembers("play-time");
BOOST_CHECK(memberMap.size() != 0);
// when there's no such schedule, the return list's size is 0
BOOST_CHECK_EQUAL(db.getScheduleMembers("sleep-time").size(), 0);
// list all members
std::list<Name> members = db.listAllMembers();
BOOST_CHECK(std::find(members.begin(), members.end(), Name("/ndn/GirlC")) != members.end());
BOOST_CHECK(std::find(members.begin(), members.end(), Name("/ndn/GirlD")) != members.end());
BOOST_CHECK(std::find(members.begin(), members.end(), Name("/ndn/BoyA")) != members.end());
BOOST_CHECK(std::find(members.begin(), members.end(), Name("/ndn/BoyB")) != members.end());
// rename schedule
BOOST_CHECK_EQUAL(db.hasSchedule("boelter-time"), true);
db.renameSchedule("boelter-time", "rieber-time");
BOOST_CHECK_EQUAL(db.hasSchedule("boelter-time"), false);
BOOST_CHECK_EQUAL(db.hasSchedule("rieber-time"), true);
BOOST_CHECK_EQUAL(db.getMemberSchedule("/ndn/Hello"), "rieber-time");
// update schedule
Schedule newSchedule(scheduleBlock);
Block repIntervalBlock(REPETITIVE_INTERVAL, sizeof(REPETITIVE_INTERVAL));
newSchedule.addWhiteInterval(RepetitiveInterval(repIntervalBlock));
db.updateSchedule("rieber-time", newSchedule);
scheduleResult = db.getSchedule("rieber-time");
BOOST_CHECK(scheduleResult.wireEncode() != scheduleBlock);
BOOST_CHECK(scheduleResult.wireEncode() == newSchedule.wireEncode());
// add a new schedule when update a not existing schedule
BOOST_CHECK_EQUAL(db.hasSchedule("ralphs-time"), false);
db.updateSchedule("ralphs-time", newSchedule);
BOOST_CHECK_EQUAL(db.hasSchedule("ralphs-time"), true);
// update schedule of member
db.updateMemberSchedule(Name("/ndn/Hello"), "play-time");
BOOST_CHECK_EQUAL(db.getMemberSchedule(Name("/ndn/Hello")), "play-time");
// delete member
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/Hello")), true);
db.deleteMember(Name("/ndn/Hello"));
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/Hello")), false);
// delete a not existing member
BOOST_CHECK_NO_THROW(db.deleteMember(Name("/ndn/notExisting")));
// delete the schedule and all the members using this schedule should be deleted
db.deleteSchedule("play-time");
BOOST_CHECK_EQUAL(db.hasSchedule("play-time"), false);
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/GirlC")), false);
BOOST_CHECK_EQUAL(db.hasMember(Name("/ndn/GirlD")), false);
// delete a not existing schedule
BOOST_CHECK_NO_THROW(db.deleteSchedule("not-existing-time"));
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace nac
} // namespace ndn