add name assignment templates

Change-Id: Ia42d4431011b9eae1b5f888b07774cd170719008
diff --git a/src/name-assignments/assignment-funcs.cpp b/src/name-assignments/assignment-funcs.cpp
new file mode 100644
index 0000000..7e806f8
--- /dev/null
+++ b/src/name-assignments/assignment-funcs.cpp
@@ -0,0 +1,56 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2019, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert 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.
+ *
+ * ndncert 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 copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#include "assignment-funcs.hpp"
+#include <ndn-cxx/util/random.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+NameAssignmentFuncFactory::NameAssignmentFuncFactory(const std::string& factoryType)
+  : FACTORY_TYPE(factoryType)
+{
+}
+
+bool
+NameAssignmentFuncFactory::isChallengeSupported(const std::string& challengeType)
+{
+  FuncFactoryFactory& factory = getFactory();
+  auto i = factory.find(challengeType);
+  return i != factory.end();
+}
+
+unique_ptr<NameAssignmentFuncFactory>
+NameAssignmentFuncFactory::createNameAssignmentConfigFuncs(const std::string& challengeType)
+{
+  FuncFactoryFactory& factory = getFactory();
+  auto i = factory.find(challengeType);
+  return i == factory.end() ? nullptr : i->second();
+}
+
+NameAssignmentFuncFactory::FuncFactoryFactory&
+NameAssignmentFuncFactory::getFactory()
+{
+  static NameAssignmentFuncFactory::FuncFactoryFactory factory;
+  return factory;
+}
+
+} // namespace ndncert
+} // namespace ndn
diff --git a/src/name-assignments/assignment-funcs.hpp b/src/name-assignments/assignment-funcs.hpp
new file mode 100644
index 0000000..d45f082
--- /dev/null
+++ b/src/name-assignments/assignment-funcs.hpp
@@ -0,0 +1,78 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2017-2019, Regents of the University of California.
+ *
+ * This file is part of ndncert, a certificate management system based on NDN.
+ *
+ * ndncert 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.
+ *
+ * ndncert 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 copies of the GNU General Public License along with
+ * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndncert authors and contributors.
+ */
+
+#ifndef NDNCERT_ASSIGNMENT_FUNCS_HPP
+#define NDNCERT_ASSIGNMENT_FUNCS_HPP
+
+#include <configuration.hpp>
+#include "ca-state.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+class NameAssignmentFuncFactory : noncopyable {
+public:
+  explicit
+  NameAssignmentFuncFactory(const std::string& factoryType);
+
+  virtual ~NameAssignmentFuncFactory() = default;
+
+  template <class ChallengeType>
+  static void
+  registerNameAssignmentFuncFactorys(const std::string& typeName)
+  {
+    FuncFactoryFactory& factory = getFactory();
+    BOOST_ASSERT(factory.count(typeName) == 0);
+    factory[typeName] = [] { return make_unique<ChallengeType>(); };
+  }
+
+  static bool
+  isChallengeSupported(const std::string& challengeType);
+
+  static unique_ptr<NameAssignmentFuncFactory>
+  createNameAssignmentConfigFuncs(const std::string& challengeType);
+
+  virtual NameAssignmentFunc
+  getFunction(const std::string& factoryParam) = 0;
+
+public:
+  const std::string FACTORY_TYPE;
+
+private:
+  typedef function<unique_ptr<NameAssignmentFuncFactory>()> FactoryCreateFunc;
+  typedef std::map<std::string, FactoryCreateFunc> FuncFactoryFactory;
+
+  static FuncFactoryFactory&
+  getFactory();
+};
+
+#define NDNCERT_REGISTER_FUNCFACTORY(C, T)                              \
+  static class NdnCert##C##FuncFactoryRegistrationClass {               \
+  public:                                                             \
+    NdnCert##C##FuncFactoryRegistrationClass()                          \
+    {                                                                 \
+      ::ndn::ndncert::NameAssignmentFuncFactory::registerNameAssignmentFuncFactorys<C>(T); \
+    }                                                                 \
+  } g_NdnCert##C##ChallengeRegistrationVariable
+
+}  // namespace ndncert
+}  // namespace ndn
+
+#endif  // NDNCERT_ASSIGNMENT_FUNCS_HPP
diff --git a/src/name-assignments/assignment-hash.cpp b/src/name-assignments/assignment-hash.cpp
new file mode 100644
index 0000000..9a73e0e
--- /dev/null
+++ b/src/name-assignments/assignment-hash.cpp
@@ -0,0 +1,67 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#include "assignment-hash.hpp"
+#include <ndn-cxx/util/sha256.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+_LOG_INIT(ndncert.assignment.hash);
+NDNCERT_REGISTER_FUNCFACTORY(AssignmentHash, "hash");
+
+AssignmentHash::AssignmentHash()
+    : NameAssignmentFuncFactory("hash")
+{
+}
+
+NameAssignmentFunc
+AssignmentHash::getFunction(const std::string &factoryParam) {
+    std::list<std::string> paramList;
+    size_t index = 0, startIndex = 0;
+    while ((index = factoryParam.find(":", startIndex)) != factoryParam.npos) {
+        paramList.push_back(factoryParam.substr(startIndex, index));
+        startIndex = index + 1;
+    }
+    if (startIndex != factoryParam.size()) {
+        paramList.push_back(factoryParam.substr(startIndex));
+    }
+    return HashAssignmentFunc(paramList);
+}
+
+AssignmentHash::HashAssignmentFunc::HashAssignmentFunc(std::list<std::string> paramList)
+    : m_paramList(std::move(paramList))
+{}
+
+std::vector<PartialName>
+AssignmentHash::HashAssignmentFunc::operator() (const std::vector<std::tuple<std::string, std::string>> params)
+{
+  if (params.size() > m_paramList.size() * 8) { // might be attack
+      BOOST_THROW_EXCEPTION(std::runtime_error("Too many extra parameters given"));
+  }
+  std::map<std::string, std::string> paramMap;
+  for (const auto& param : params) {
+      paramMap[std::get<0>(param)] = std::get<1>(param);
+  }
+
+  //construct name
+  PartialName name;
+  for (const auto& field : m_paramList) {
+      auto it = paramMap.find(field);
+      if (it == paramMap.end()) {
+          return std::vector<PartialName>();
+      } else {
+          name.append(it->second);
+      }
+  }
+  std::vector<PartialName> nameList;
+  util::Sha256 digest;
+  digest << name.wireEncode();
+  nameList.emplace_back(digest.toString());
+
+  return nameList;
+}
+
+}
+}
diff --git a/src/name-assignments/assignment-hash.hpp b/src/name-assignments/assignment-hash.hpp
new file mode 100644
index 0000000..19b0618
--- /dev/null
+++ b/src/name-assignments/assignment-hash.hpp
@@ -0,0 +1,38 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#ifndef NDNCERT_ASSIGNMENT_HASH_HPP
+#define NDNCERT_ASSIGNMENT_HASH_HPP
+
+#include "assignment-funcs.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+/**
+ * assign names base on client probe parameter
+ */
+class AssignmentHash: public NameAssignmentFuncFactory{
+public:
+  AssignmentHash();
+
+  NameAssignmentFunc getFunction(const std::string &factoryParam) override;
+
+  class HashAssignmentFunc {
+  public:
+    HashAssignmentFunc(std::list<std::string> paramList);
+
+    std::vector<PartialName>
+    operator() (const std::vector<std::tuple<std::string, std::string>> params);
+  private:
+    std::list<std::string> m_paramList;
+  };
+
+};
+}
+}
+
+
+
+#endif //NDNCERT_ASSIGNMENT_HASH_HPP
diff --git a/src/name-assignments/assignment-param.cpp b/src/name-assignments/assignment-param.cpp
new file mode 100644
index 0000000..83de6a4
--- /dev/null
+++ b/src/name-assignments/assignment-param.cpp
@@ -0,0 +1,63 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#include "assignment-param.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+_LOG_INIT(ndncert.assignment.param);
+NDNCERT_REGISTER_FUNCFACTORY(AssignmentParam, "param");
+
+AssignmentParam::AssignmentParam()
+    : NameAssignmentFuncFactory("param")
+{
+}
+
+NameAssignmentFunc
+AssignmentParam::getFunction(const std::string &factoryParam) {
+    std::list<std::string> paramList;
+    size_t index = 0, startIndex = 0;
+    while ((index = factoryParam.find(":", startIndex)) != factoryParam.npos) {
+        paramList.push_back(factoryParam.substr(startIndex, index));
+        startIndex = index + 1;
+    }
+    if (startIndex != factoryParam.size()) {
+        paramList.push_back(factoryParam.substr(startIndex));
+    }
+    return ParamAssignmentFunc(paramList);
+}
+
+AssignmentParam::ParamAssignmentFunc::ParamAssignmentFunc(std::list<std::string> paramList)
+    : m_paramList(std::move(paramList))
+{}
+
+std::vector<PartialName>
+AssignmentParam::ParamAssignmentFunc::operator() (const std::vector<std::tuple<std::string, std::string>> params)
+{
+  if (params.size() > m_paramList.size() * 8) { // might be attack
+      BOOST_THROW_EXCEPTION(std::runtime_error("Too many extra parameters given"));
+  }
+  std::map<std::string, std::string> paramMap;
+  for (const auto& param : params) {
+      paramMap[std::get<0>(param)] = std::get<1>(param);
+  }
+
+  //construct name
+  PartialName name;
+  for (const auto& field : m_paramList) {
+      auto it = paramMap.find(field);
+      if (it == paramMap.end()) {
+          return std::vector<PartialName>();
+      } else {
+          name.append(it->second);
+      }
+  }
+  std::vector<PartialName> nameList;
+  nameList.push_back(name);
+  return nameList;
+}
+
+}
+}
diff --git a/src/name-assignments/assignment-param.hpp b/src/name-assignments/assignment-param.hpp
new file mode 100644
index 0000000..7c6a377
--- /dev/null
+++ b/src/name-assignments/assignment-param.hpp
@@ -0,0 +1,38 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#ifndef NDNCERT_ASSIGNMENT_PARAM_HPP
+#define NDNCERT_ASSIGNMENT_PARAM_HPP
+
+#include "assignment-funcs.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+/**
+ * assign names base on client probe parameter
+ */
+class AssignmentParam: public NameAssignmentFuncFactory{
+public:
+  AssignmentParam();
+
+  NameAssignmentFunc getFunction(const std::string &factoryParam) override;
+
+  class ParamAssignmentFunc {
+  public:
+    ParamAssignmentFunc(std::list<std::string> paramList);
+
+    std::vector<PartialName>
+    operator() (const std::vector<std::tuple<std::string, std::string>> params);
+  private:
+    std::list<std::string> m_paramList;
+  };
+
+};
+}
+}
+
+
+
+#endif //NDNCERT_ASSIGNMENT_PARAM_HPP
diff --git a/src/name-assignments/assignment-random.cpp b/src/name-assignments/assignment-random.cpp
new file mode 100644
index 0000000..b713665
--- /dev/null
+++ b/src/name-assignments/assignment-random.cpp
@@ -0,0 +1,29 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#include "assignment-random.hpp"
+#include <ndn-cxx/util/random.hpp>
+
+namespace ndn {
+namespace ndncert {
+
+_LOG_INIT(ndncert.assignment.random);
+NDNCERT_REGISTER_FUNCFACTORY(AssignmentRandom, "random");
+
+AssignmentRandom::AssignmentRandom()
+    : NameAssignmentFuncFactory("random")
+{
+}
+
+NameAssignmentFunc
+AssignmentRandom::getFunction(const std::string &factoryParam) {
+  return [](const std::vector<std::tuple<std::string, std::string>>){
+        std::vector<PartialName> names;
+        names.emplace_back(to_string(random::generateSecureWord64()));
+        return names;
+  };
+}
+
+}
+}
diff --git a/src/name-assignments/assignment-random.hpp b/src/name-assignments/assignment-random.hpp
new file mode 100644
index 0000000..64de3df
--- /dev/null
+++ b/src/name-assignments/assignment-random.hpp
@@ -0,0 +1,29 @@
+//
+// Created by Tyler on 10/6/20.
+//
+
+#ifndef NDNCERT_ASSIGNMENT_RANDOM_HPP
+#define NDNCERT_ASSIGNMENT_RANDOM_HPP
+
+#include "assignment-funcs.hpp"
+
+namespace ndn {
+namespace ndncert {
+
+/**
+ * assign names base on client probe parameter
+ */
+class AssignmentRandom: public NameAssignmentFuncFactory{
+public:
+  AssignmentRandom();
+
+  NameAssignmentFunc getFunction(const std::string &factoryParam) override;
+
+};
+
+}
+}
+
+
+
+#endif //NDNCERT_ASSIGNMENT_RANDOM_HPP