Leosac  0.8.0
Open Source Access Control
CRUDHandler.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2017 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
22 #include "hardware/Buzzer_odb.h"
23 #include "hardware/LED_odb.h"
26 #include "tools/JSONUtils.hpp"
27 #include "tools/db/DBService.hpp"
30 
31 namespace Leosac
32 {
33 namespace Module
34 {
35 namespace LedBuzzer
36 {
37 constexpr const char CRUDHandlerHelper::led_object_id_key[];
38 constexpr const char CRUDHandlerHelper::buzzer_object_id_key[];
39 
40 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
41 std::vector<WebSockAPI::ICRUDResourceHandler::ActionActionParam>
43  WebSockAPI::ICRUDResourceHandler::Verb verb, const json &req) const
44 {
45  std::vector<CRUDResourceHandler::ActionActionParam> ret;
46 
47  SecurityContext::HardwareDeviceActionParam hardware_action_param{};
48  try
49  {
50  hardware_action_param.device_id =
51  req.at(ObjectIdKey).get<Hardware::DeviceId>();
52  }
53  catch (json::out_of_range &e)
54  {
55  hardware_action_param.device_id = Hardware::DeviceId{};
56  }
57 
58  switch (verb)
59  {
60  case Verb::READ:
62  hardware_action_param);
63  break;
64  case Verb::CREATE:
66  hardware_action_param);
67  break;
68  case Verb::UPDATE:
70  hardware_action_param);
71  break;
72  case Verb::DELETE:
74  hardware_action_param);
75  break;
76  }
77  return ret;
78 }
79 
80 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
81 boost::optional<json>
83 {
84  json rep;
85  DBPtr db = ctx_.dbsrv->db();
86  odb::transaction t(db->begin());
87 
88  auto new_led_or_buzzer = std::make_shared<ObjectT>();
89  SerializerT::unserialize(*new_led_or_buzzer, req.at("attributes"),
90  security_context());
91  db->persist(new_led_or_buzzer);
92 
93  rep["data"] = SerializerT::serialize(*new_led_or_buzzer, security_context());
94  t.commit();
95  return rep;
96 }
97 
98 
99 // Declare function to retrieve either led or buzzer.
100 // We need to specialize this template to be able to throw
101 // a correct EntityNotFound exception (because object's type is a string)
102 template <typename T>
103 std::shared_ptr<T> find_led_or_buzzer_by_id(const Hardware::DeviceId &id, DBPtr db);
104 
105 template <>
107 find_led_or_buzzer_by_id<Hardware::LED>(const Hardware::DeviceId &id, DBPtr db)
108 {
109  db::OptionalTransaction t(db->begin());
110  auto led = db->find<Hardware::LED>(id);
111  t.commit();
112  if (!led)
113  throw EntityNotFound(id, "led");
114  return led;
115 }
116 
117 template <>
119 find_led_or_buzzer_by_id<Hardware::Buzzer>(const Hardware::DeviceId &id, DBPtr db)
120 {
121  db::OptionalTransaction t(db->begin());
122  auto buzzer = db->find<Hardware::Buzzer>(id);
123  t.commit();
124  if (!buzzer)
125  throw EntityNotFound(id, "buzzer");
126  return buzzer;
127 }
128 
129 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
130 boost::optional<json>
132 {
133  json rep;
134 
135  using Result = odb::result<ObjectT>;
136  DBPtr db = ctx_.dbsrv->db();
137  odb::transaction t(db->begin());
138  auto led_or_buzzer_id = req.at(ObjectIdKey).get<Hardware::DeviceId>();
139 
140  if (!led_or_buzzer_id.is_nil())
141  {
142  auto led_or_buzzer = find_led_or_buzzer_by_id<ObjectT>(led_or_buzzer_id, db);
143  rep["data"] = SerializerT::serialize(*led_or_buzzer, security_context());
144  }
145  else
146  {
147  Result result = db->query<ObjectT>();
148  rep["data"] = json::array();
149  auto current_user = ctx_.session->current_user();
150 
151  // fixme: may be rather slow.
152  for (const auto &led_or_buzzer : result)
153  {
155  led_or_buzzer.id()};
156  if (ctx_.session->security_context().check_permission(
158  {
159  rep["data"].push_back(
160  SerializerT::serialize(led_or_buzzer, security_context()));
161  }
162  }
163  }
164  t.commit();
165  return rep;
166 }
167 
168 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
169 boost::optional<json>
171 {
172  json rep;
173  DBPtr db = ctx_.dbsrv->db();
174  odb::transaction t(db->begin());
175  auto led_or_buzzer_id = req.at(ObjectIdKey).get<Hardware::DeviceId>();
176  auto led_or_buzzer = find_led_or_buzzer_by_id<ObjectT>(led_or_buzzer_id, db);
177 
178  SerializerT::unserialize(*led_or_buzzer, req.at("attributes"),
179  security_context());
180 
181  db->update(led_or_buzzer);
182  rep["data"] = SerializerT::serialize(*led_or_buzzer, security_context());
183  t.commit();
184  return rep;
185 }
186 
187 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
188 boost::optional<json>
190 {
191  auto did = req.at(ObjectIdKey).get<Hardware::DeviceId>();
192  DBPtr db = ctx_.dbsrv->db();
193  odb::transaction t(db->begin());
194 
195  auto led_or_buzzer = find_led_or_buzzer_by_id<ObjectT>(did, db);
196  db->erase(led_or_buzzer);
197  t.commit();
198 
199  return json{};
200 }
201 
202 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
204  const WebSockAPI::RequestContext &ctx)
205  : CRUDResourceHandler(ctx)
206 {
207  static_assert(std::is_same<ObjectT, Hardware::LED>::value ||
208  std::is_same<ObjectT, Hardware::Buzzer>::value,
209  "This CRUDHandler can only work with either LED or Buzzer type");
210 }
211 
212 template <typename ObjectT, const char *ObjectIdKey, typename SerializerT>
216 {
217  auto instance = WebSockAPI::CRUDResourceHandlerUPtr(
219  return instance;
220 }
221 
224 
227 }
228 }
229 }
Leosac::Module::LedBuzzer::CRUDHandler::update_impl
boost::optional< WebSockAPI::json > update_impl(const WebSockAPI::json &req) override
Definition: CRUDHandler.cpp:170
Leosac::Hardware::BuzzerSerializer
Definition: BuzzerSerializer.hpp:32
Leosac::db::OptionalTransaction
An optional transaction is an object that behave like an odb::transaction if there is no currently ac...
Definition: OptionalTransaction.hpp:43
Leosac::db::OptionalTransaction::commit
void commit()
Commit the transaction, if there was no currently active transaction at the time of this object's cre...
Definition: OptionalTransaction.cpp:38
Leosac::SecurityContext::Action::HARDWARE_CREATE
@ HARDWARE_CREATE
LEDSerializer.hpp
Leosac::Module::LedBuzzer::CRUDHandler::required_permission
std::vector< ActionActionParam > required_permission(Verb verb, const WebSockAPI::json &req) const override
Definition: CRUDHandler.cpp:42
Leosac::json
nlohmann::json json
Definition: AuditSerializer.hpp:29
Leosac::SecurityContext::Action::HARDWARE_DELETE
@ HARDWARE_DELETE
Leosac::Hardware::LEDPtr
std::shared_ptr< LED > LEDPtr
Definition: HardwareFwd.hpp:61
Leosac::Module::LedBuzzer::CRUDHandlerHelper::led_object_id_key
static constexpr const char led_object_id_key[]
How to retrieve the object's id when instanciate the crud handler for led.
Definition: CRUDHandler.hpp:40
Leosac::Hardware::LEDSerializer
Serializer code is copy-pasted from buzzer's serializer.
Definition: LEDSerializer.hpp:35
Leosac::Module::WebSockAPI::CRUDResourceHandlerUPtr
std::unique_ptr< CRUDResourceHandler > CRUDResourceHandlerUPtr
Definition: WebSockFwd.hpp:39
Leosac::SecurityContext::HardwareDeviceActionParam::device_id
Hardware::DeviceId device_id
Definition: SecurityContext.hpp:226
Leosac::DBPtr
std::shared_ptr< odb::database > DBPtr
Definition: db_fwd.hpp:31
Leosac::Module::LedBuzzer::CRUDHandler::create_impl
boost::optional< WebSockAPI::json > create_impl(const WebSockAPI::json &req) override
Definition: CRUDHandler.cpp:82
Leosac::Module::LedBuzzer::CRUDHandler::delete_impl
boost::optional< WebSockAPI::json > delete_impl(const WebSockAPI::json &req) override
Definition: CRUDHandler.cpp:189
Leosac::EntityNotFound
Definition: EntityNotFound.hpp:27
Leosac::Module::LedBuzzer::CRUDHandler
CRUD handler for Buzzer and LED.
Definition: CRUDHandler.hpp:54
Leosac::SecurityContext::Action::HARDWARE_READ
@ HARDWARE_READ
Permissions for hardware devices.
BuzzerSerializer.hpp
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
OptionalTransaction.hpp
Leosac::SecurityContext::Action::HARDWARE_UPDATE
@ HARDWARE_UPDATE
JSONUtils.hpp
Leosac::Module::LedBuzzer::CRUDHandlerHelper::buzzer_object_id_key
static constexpr const char buzzer_object_id_key[]
How to retrieve the object's id when instanciate the crud handler for buzzer.
Definition: CRUDHandler.hpp:36
CRUDHandler.hpp
Leosac::Hardware::LED
Abstraction of LED device attributes.
Definition: LED.hpp:36
DBService.hpp
APISession.hpp
Leosac::Module::LedBuzzer::find_led_or_buzzer_by_id
std::shared_ptr< T > find_led_or_buzzer_by_id(const Hardware::DeviceId &id, DBPtr db)
Leosac::Module::LedBuzzer::CRUDHandler::CRUDHandler
CRUDHandler(const WebSockAPI::RequestContext &ctx)
Definition: CRUDHandler.cpp:203
Leosac::Module::WebSockAPI::RequestContext
Holds valuable pointer to provide context to a request.
Definition: RequestContext.hpp:36
Leosac::Hardware::Buzzer
Abstraction of Buzzer device attributes.
Definition: Buzzer.hpp:42
Leosac::Module::LedBuzzer::CRUDHandler::read_impl
boost::optional< WebSockAPI::json > read_impl(const WebSockAPI::json &req) override
Definition: CRUDHandler.cpp:131
Leosac::Module::LedBuzzer::CRUDHandler::instanciate
static WebSockAPI::CRUDResourceHandlerUPtr instanciate(WebSockAPI::RequestContext)
Definition: CRUDHandler.cpp:214
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb
Verb
Definition: CRUDResourceHandler.hpp:43
EntityNotFound.hpp
Leosac::Hardware::BuzzerPtr
std::shared_ptr< Buzzer > BuzzerPtr
Definition: HardwareFwd.hpp:64
Result
odb::result< Tools::LogEntry > Result
Definition: LogEntry.cpp:37
Leosac::SecurityContext::HardwareDeviceActionParam
Definition: SecurityContext.hpp:224
Leosac::UUID
Thin wrapper around boost::uuids::uuid.
Definition: Uuid.hpp:35