Leosac  0.8.0
Open Source Access Control
ScheduleCRUD.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 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 
20 #include "api/ScheduleCRUD.hpp"
24 #include "tools/AssertCast.hpp"
25 #include "tools/ISchedule.hpp"
26 #include "tools/Schedule.hpp"
27 #include "tools/Schedule_odb.h"
28 #include "tools/db/DBService.hpp"
29 #include "tools/enforce.hpp"
32 
33 using namespace Leosac;
34 using namespace Leosac::Module;
35 using namespace Leosac::Module::WebSockAPI;
36 
38  : CRUDResourceHandler(ctx)
39 {
40 }
41 
43 {
44  auto instance = CRUDResourceHandlerUPtr(new ScheduleCRUD(ctx));
45 
46  return instance;
47 }
48 
49 std::vector<CRUDResourceHandler::ActionActionParam>
51  const json &req) const
52 {
53  std::vector<CRUDResourceHandler::ActionActionParam> ret;
55  try
56  {
57  sap.schedule_id = req.at("schedule_id").get<Auth::GroupId>();
58  }
59  catch (const json::out_of_range &e)
60  {
61  sap.schedule_id = 0;
62  }
63  switch (verb)
64  {
65  case Verb::READ:
66  ret.emplace_back(SecurityContext::Action::SCHEDULE_READ, sap);
67  break;
68  case Verb::CREATE:
69  ret.emplace_back(SecurityContext::Action::SCHEDULE_CREATE, sap);
70  break;
71  case Verb::UPDATE:
72  ret.emplace_back(SecurityContext::Action::SCHEDULE_UPDATE, sap);
73  break;
74  case Verb::DELETE:
75  ret.emplace_back(SecurityContext::Action::SCHEDULE_DELETE, sap);
76  break;
77  }
78  return ret;
79 }
80 
81 boost::optional<json> ScheduleCRUD::create_impl(const json &req)
82 {
83  json rep;
84  DBPtr db = ctx_.dbsrv->db();
85  odb::transaction t(db->begin());
86 
87  Tools::SchedulePtr schedule = std::make_shared<Tools::Schedule>();
88  Tools::ScheduleJSONSerializer::unserialize(*schedule, req.at("attributes"),
90 
91  db->persist(schedule);
94  audit->event_mask(Audit::EventType::SCHEDULE_CREATED);
96  *schedule, SystemSecurityContext::instance()));
97  audit->finalize();
98  rep["data"] =
100  t.commit();
101  return rep;
102 }
103 
112 static void include_schedule_mapping_infos(json &dest,
113  const Tools::ISchedule &schedule,
114  SecurityContext &sc)
115 {
116  ASSERT_LOG(dest.is_array(), "Destination is not array.");
117  for (const auto &mapping : schedule.mapping())
118  {
119  dest.push_back(
121  }
122 }
123 
124 boost::optional<json> ScheduleCRUD::read_impl(const json &req)
125 {
126  json rep;
127 
128  using Result = odb::result<Tools::Schedule>;
129  DBPtr db = ctx_.dbsrv->db();
130  odb::transaction t(db->begin());
131 
132  auto sid = req.at("schedule_id").get<Tools::ScheduleId>();
133  rep["included"] = json::array();
134 
135  if (sid != 0)
136  {
137  Tools::ISchedulePtr schedule =
138  ctx_.dbsrv->find_schedule_by_id(sid, DBService::THROW_IF_NOT_FOUND);
139  rep["data"] =
141  include_schedule_mapping_infos(rep["included"], *schedule,
142  security_context());
143  }
144  else
145  {
146  Result result = db->query<Tools::Schedule>();
147  rep["data"] = json::array();
148  for (const auto &schedule : result)
149  {
150  rep["data"].push_back(Tools::ScheduleJSONSerializer::serialize(
151  schedule, security_context()));
152  include_schedule_mapping_infos(rep["included"], schedule,
153  security_context());
154  }
155  }
156  return rep;
157 }
158 
159 boost::optional<json> ScheduleCRUD::update_impl(const json &req)
160 {
161  json rep;
162  DBPtr db = ctx_.dbsrv->db();
163  odb::transaction t(db->begin());
164  auto sid = req.at("schedule_id").get<Tools::ScheduleId>();
165 
166  rep["included"] = json::array(); // Will contain ScheduleMapping data.
167 
168  auto schedule =
169  ctx_.dbsrv->find_schedule_by_id(sid, DBService::THROW_IF_NOT_FOUND);
172  audit->event_mask(Audit::EventType::SCHEDULE_UPDATED);
174  *schedule, SystemSecurityContext::instance()));
175 
176  Tools::ScheduleJSONSerializer::unserialize(*schedule, req.at("attributes"),
177  security_context());
178 
179  for (const auto &mapping : schedule->mapping())
180  {
181  // fixme: A bit hackish -- Generate an event for the door to let it knows its
182  // mapping may have changed.
183  for (const auto &lazy_weak_door : mapping->doors())
184  {
185  auto lazy_door = LEOSAC_ENFORCE(lazy_weak_door.load(), "Failed to load");
186  auto door_event = Audit::Factory::DoorEvent(db, lazy_door, audit);
187  door_event->event_mask(Audit::EventType::MAPPING_MAY_HAVE_CHANGED);
188  door_event->finalize();
189  }
190  db->erase(mapping);
191  }
192  schedule->clear_mapping();
193  // Extract mappings.
194  for (const auto &json_mapping : req.at("mapping"))
195  {
196  Tools::ScheduleMappingPtr mapping =
197  std::make_shared<Tools::ScheduleMapping>();
199  security_context());
200  db->persist(mapping);
201  schedule->add_mapping(mapping);
202  }
203  include_schedule_mapping_infos(rep["included"], *schedule, security_context());
204 
205  db->update(assert_cast<Tools::SchedulePtr>(schedule));
207  *schedule, SystemSecurityContext::instance()));
208  audit->finalize();
209 
210  rep["data"] =
212  t.commit();
213  return rep;
214 }
215 
216 boost::optional<json> ScheduleCRUD::delete_impl(const json &req)
217 {
218  auto sid = req.at("schedule_id").get<Tools::ScheduleId>();
219  auto db = ctx_.dbsrv->db();
220  odb::transaction t(db->begin());
221 
222  if (sid != 0)
223  {
224  auto schedule =
225  ctx_.dbsrv->find_schedule_by_id(sid, DBService::THROW_IF_NOT_FOUND);
228 
229  audit->event_mask(Audit::EventType::SCHEDULE_DELETED);
231  *schedule, SystemSecurityContext::instance()));
232 
233  for (const auto &mapping : schedule->mapping())
234  {
235  db->erase(mapping);
236  }
237 
238  audit->finalize();
239  db->erase<Tools::Schedule>(schedule->id());
240  t.commit();
241  }
242  return json{};
243 }
Leosac::Module::WebSockAPI::ScheduleCRUD::required_permission
virtual std::vector< ActionActionParam > required_permission(Verb verb, const json &req) const override
Definition: ScheduleCRUD.cpp:50
Leosac::SecurityContext::ScheduleActionParam
Definition: SecurityContext.hpp:196
Leosac::Tools::ISchedule::add_mapping
virtual void add_mapping(const Tools::ScheduleMappingPtr &map)=0
AuditFactory.hpp
Leosac::SystemSecurityContext::instance
static SecurityContext & instance()
Definition: SecurityContext.cpp:64
Leosac::Tools::ISchedulePtr
std::shared_ptr< ISchedule > ISchedulePtr
Definition: ToolsFwd.hpp:37
Leosac::Module::WebSockAPI::ScheduleCRUD::read_impl
virtual boost::optional< json > read_impl(const json &req) override
Definition: ScheduleCRUD.cpp:124
Leosac::SecurityContext::Action::SCHEDULE_CREATE
@ SCHEDULE_CREATE
Leosac::Module::WebSockAPI::ScheduleCRUD::ScheduleCRUD
ScheduleCRUD(RequestContext ctx)
Definition: ScheduleCRUD.cpp:37
Leosac::Module::WebSockAPI::CRUDResourceHandlerUPtr
std::unique_ptr< CRUDResourceHandler > CRUDResourceHandlerUPtr
Definition: WebSockFwd.hpp:39
ScheduleMappingSerializer.hpp
Leosac::Module::WebSockAPI::RequestContext::dbsrv
DBServicePtr dbsrv
Definition: RequestContext.hpp:39
ASSERT_LOG
#define ASSERT_LOG(cond, msg)
Definition: log.hpp:190
Leosac::Module::WebSockAPI::CRUDResourceHandler
Base CRUD handler for use within the websocket module.
Definition: CRUDResourceHandler.hpp:84
Leosac::SecurityContext::Action::SCHEDULE_READ
@ SCHEDULE_READ
Leosac::Module::WebSockAPI::ScheduleCRUD::update_impl
virtual boost::optional< json > update_impl(const json &req) override
Update a schedule object.
Definition: ScheduleCRUD.cpp:159
Leosac::Audit::Factory::DoorEvent
static IDoorEventPtr DoorEvent(const DBPtr &database, Auth::IDoorPtr target_door, IAuditEntryPtr parent)
Definition: AuditFactory.cpp:124
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb::DELETE
@ DELETE
Leosac::Audit::EventType::SCHEDULE_UPDATED
@ SCHEDULE_UPDATED
Leosac::DBPtr
std::shared_ptr< odb::database > DBPtr
Definition: db_fwd.hpp:31
Leosac::Tools::ScheduleMappingJSONSerializer::unserialize
static void unserialize(Tools::ScheduleMapping &out, const json &in, const SecurityContext &sc)
Definition: ScheduleMappingSerializer.cpp:83
Leosac::Tools::ScheduleMappingPtr
std::shared_ptr< ScheduleMapping > ScheduleMappingPtr
Definition: ToolsFwd.hpp:41
Leosac::Tools::ISchedule::id
virtual ScheduleId id() const =0
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb::CREATE
@ CREATE
IDoorEvent.hpp
Leosac::Module
All modules that provides features to Leosac shall be in this namespace.
Leosac::Audit::EventType::MAPPING_MAY_HAVE_CHANGED
@ MAPPING_MAY_HAVE_CHANGED
This event is linked to door.
Leosac::Tools::ScheduleMappingJSONSerializer::serialize
static json serialize(const Tools::ScheduleMapping &in, const SecurityContext &sc)
Definition: ScheduleMappingSerializer.cpp:34
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb::READ
@ READ
ScheduleCRUD.hpp
ISchedule.hpp
Leosac::Tools::SchedulePtr
std::shared_ptr< Schedule > SchedulePtr
Definition: ToolsFwd.hpp:32
Leosac::Tools::ScheduleJSONSerializer::serialize
static json serialize(const Tools::ISchedule &in, const SecurityContext &sc)
Definition: ScheduleSerializer.cpp:30
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb::UPDATE
@ UPDATE
enforce.hpp
Leosac::SecurityContext::ScheduleActionParam::schedule_id
Tools::ScheduleId schedule_id
Definition: SecurityContext.hpp:198
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
Leosac::Tools::ScheduleJSONStringSerializer::serialize
static std::string serialize(const Tools::ISchedule &in, const SecurityContext &sc)
Definition: ScheduleSerializer.cpp:103
ScheduleSerializer.hpp
Leosac::Module::WebSockAPI::ScheduleCRUD::delete_impl
virtual boost::optional< json > delete_impl(const json &req) override
Definition: ScheduleCRUD.cpp:216
Leosac::Tools::ScheduleJSONSerializer::unserialize
static void unserialize(Tools::ISchedule &out, const json &in, const SecurityContext &sc)
Definition: ScheduleSerializer.cpp:83
Leosac::Module::WebSockAPI::CRUDResourceHandler::ctx_
RequestContext ctx_
Definition: CRUDResourceHandler.hpp:95
Leosac::Tools::ScheduleId
unsigned long ScheduleId
Definition: ToolsFwd.hpp:33
Leosac::Audit::EventType::SCHEDULE_DELETED
@ SCHEDULE_DELETED
Leosac::Tools::ISchedule::clear_mapping
virtual void clear_mapping()=0
Leosac::Audit::IScheduleEventPtr
std::shared_ptr< IScheduleEvent > IScheduleEventPtr
Definition: AuditFwd.hpp:61
Leosac::Tools::ISchedule::mapping
virtual std::vector< Tools::ScheduleMappingPtr > mapping() const =0
DBService.hpp
Leosac::Audit::EventType::SCHEDULE_CREATED
@ SCHEDULE_CREATED
Leosac::Auth::GroupId
unsigned long GroupId
Definition: AuthFwd.hpp:41
Leosac::Module::WebSockAPI::RequestContext::audit
Audit::IAuditEntryPtr audit
The initial audit trail for the request.
Definition: RequestContext.hpp:55
Leosac::Tools::ISchedule
Definition: ISchedule.hpp:38
Leosac::DBService::THROW_IF_NOT_FOUND
@ THROW_IF_NOT_FOUND
Definition: DBService.hpp:40
Leosac::Module::WebSockAPI::json
nlohmann::json json
Definition: AccessOverview.hpp:30
Leosac::Module::WebSockAPI::RequestContext
Holds valuable pointer to provide context to a request.
Definition: RequestContext.hpp:36
Leosac::Module::WebSockAPI::ScheduleCRUD::instanciate
static CRUDResourceHandlerUPtr instanciate(RequestContext)
Definition: ScheduleCRUD.cpp:42
Leosac::Audit::Factory::ScheduleEvent
static IScheduleEventPtr ScheduleEvent(const DBPtr &database, Tools::ISchedulePtr target_sched, IAuditEntryPtr parent)
Definition: AuditFactory.cpp:112
IScheduleEvent.hpp
Leosac::Tools::Schedule
A schedule is simply a list of time frame (SingleTimeFrame) with a name.
Definition: Schedule.hpp:41
Leosac::SecurityContext::Action::SCHEDULE_DELETE
@ SCHEDULE_DELETE
Leosac::SecurityContext::Action::SCHEDULE_UPDATE
@ SCHEDULE_UPDATE
Leosac::Module::WebSockAPI
Definition: ActionActionParam.hpp:28
Schedule.hpp
LEOSAC_ENFORCE
#define LEOSAC_ENFORCE(cond,...)
Similar to enforce, except that it will throw a LEOSACException.
Definition: enforce.hpp:47
Leosac::Module::WebSockAPI::ICRUDResourceHandler::Verb
Verb
Definition: CRUDResourceHandler.hpp:43
Leosac::Module::WebSockAPI::ScheduleCRUD::create_impl
virtual boost::optional< json > create_impl(const json &req) override
Create a new schedule.
Definition: ScheduleCRUD.cpp:81
Leosac::SecurityContext
A SecurityContext is used to query permission while doing an operation.
Definition: SecurityContext.hpp:40
Result
odb::result< Tools::LogEntry > Result
Definition: LogEntry.cpp:37
AssertCast.hpp
Leosac::Module::WebSockAPI::CRUDResourceHandler::security_context
virtual UserSecurityContext & security_context() const override
Helper function that returns the security context.
Definition: CRUDResourceHandler.cpp:96