Node abstraction layer

Change-Id: I3cbad5b566cd005d33a9fbd18ff4e6669dae3a31
Signed-off-by: Borawski.Lukasz <lukasz.borawski@intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d876375..e9cfad7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -92,6 +92,7 @@
 endif()
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/redfish-core/include)
 
 set(SRC_FILES
     ${GENERATED_SRC_FILES}
diff --git a/crow/include/crow/http_codes.h b/crow/include/crow/http_codes.h
index 9eff020..c1e5e5a 100644
--- a/crow/include/crow/http_codes.h
+++ b/crow/include/crow/http_codes.h
@@ -1,6 +1,6 @@
 #pragma once
 
-enum class HttpRespCode{
+enum class HttpRespCode {
   OK = 200,
   CREATED = 201,
   ACCEPTED = 202,
diff --git a/redfish-core/include/node.hpp b/redfish-core/include/node.hpp
new file mode 100644
index 0000000..46b37d9
--- /dev/null
+++ b/redfish-core/include/node.hpp
@@ -0,0 +1,115 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include "crow.h"
+#include "privileges.hpp"
+#include "token_authorization_middleware.hpp"
+
+namespace redfish {
+
+/**
+ * @brief  Abstract class used for implementing Redfish nodes.
+ *
+ */
+class Node {
+ public:
+  template <typename CrowApp, typename... Params>
+  Node(CrowApp& app, PrivilegeProvider& provider, std::string odataType,
+       std::string odataId, Params... params)
+      : odataType(odataType), odataId(odataId) {
+
+    // privileges for the node as defined in the privileges_registry.json
+    entityPrivileges = provider.getPrivileges(odataId, odataType);
+
+    app.route_dynamic(std::move(odataId))
+        .methods("GET"_method, "PATCH"_method, "POST"_method,
+                 "DELETE"_method)([&](const crow::request& req,
+                                      crow::response& res, Params... params) {
+          std::vector<std::string> paramVec = {params...};
+          dispatchRequest(app, req, res, paramVec);
+        });
+  }
+
+  template <typename CrowApp>
+  void dispatchRequest(CrowApp& app, const crow::request& req,
+                       crow::response& res,
+                       const std::vector<std::string>& params) {
+    // drop requests without required privileges
+    auto ctx =
+        app.template get_context<crow::TokenAuthorization::Middleware>(req);
+
+    if (!entityPrivileges.isMethodAllowed(req.method, ctx.session->username)) {
+      res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+      res.end();
+      return;
+    }
+
+    switch (req.method) {
+      case "GET"_method:
+        doGet(res, req, params);
+        break;
+
+      case "PATCH"_method:
+        doPatch(res, req, params);
+        break;
+
+      case "POST"_method:
+        doPost(res, req, params);
+        break;
+
+      case "DELETE"_method:
+        doDelete(res, req, params);
+        break;
+
+      default:
+        res.code = static_cast<int>(HttpRespCode::NOT_FOUND);
+        res.end();
+    }
+    return;
+  }
+
+ protected:
+  const std::string odataType;
+  const std::string odataId;
+
+  // Node is designed to be an abstract class, so doGet is pure virutal
+  virtual void doGet(crow::response& res, const crow::request& req,
+                     const std::vector<std::string>& params) = 0;
+
+  virtual void doPatch(crow::response& res, const crow::request& req,
+                       const std::vector<std::string>& params) {
+    res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+    res.end();
+  }
+
+  virtual void doPost(crow::response& res, const crow::request& req,
+                      const std::vector<std::string>& params) {
+    res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+    res.end();
+  }
+
+  virtual void doDelete(crow::response& res, const crow::request& req,
+                        const std::vector<std::string>& params) {
+    res.code = static_cast<int>(HttpRespCode::METHOD_NOT_ALLOWED);
+    res.end();
+  }
+
+  EntityPrivileges entityPrivileges;
+};
+
+}  // namespace redfish
+
diff --git a/redfish-core/include/privileges.hpp b/redfish-core/include/privileges.hpp
new file mode 100644
index 0000000..43c48c2
--- /dev/null
+++ b/redfish-core/include/privileges.hpp
@@ -0,0 +1,66 @@
+/*
+// Copyright (c) 2018 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+namespace redfish {
+
+/**
+ * @brief  Class used to store privileges for a given user.
+ */
+class UserPrivileges {
+  // TODO: Temporary stub, implementation will come with next patch-sets
+ private:
+  uint32_t redfishPrivileges;
+  uint32_t oemPrivileges;
+};
+
+/**
+ * @brief  Class used to store privileges for a given Redfish entity.
+ */
+class EntityPrivileges {
+  // TODO: Temporary stub, implementation will come with next patch-sets
+ public:
+  bool isMethodAllowed(const crow::HTTPMethod& method,
+                       const std::string& username) const {
+    return true;
+  }
+};
+
+/**
+ * @brief  Class used to:
+ *         -  read the PrivilegeRegistry file,
+ *         -  provide EntityPrivileges objects to callers.
+ *
+ *         To save runtime memory object of this class should
+ *         exist only for the time required to install all Nodes.
+ */
+class PrivilegeProvider {
+  // TODO: Temporary stub, implementation will come with next patch-sets
+ public:
+  PrivilegeProvider() {
+    // load privilege_registry.json to memory
+  }
+
+  EntityPrivileges getPrivileges(const std::string &entity_url,
+                                 const std::string &entity_type) const {
+    // return an entity privilege object based on the privilege_registry.json,
+    // currently returning default constructed object
+    return EntityPrivileges();
+  }
+};
+
+}  // namespace redfish
+