Leosac  0.8.0
Open Source Access Control
DoormanModule.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 "DoormanModule.hpp"
21 #include "DoormanInstance.hpp"
22 #include "core/Scheduler.hpp"
23 #include "core/auth/Auth.hpp"
24 #include "core/kernel.hpp"
25 #include "tools/log.hpp"
26 
27 using namespace Leosac::Module::Doorman;
28 using namespace Leosac::Auth;
29 
30 DoormanModule::DoormanModule(zmqpp::context &ctx, zmqpp::socket *pipe,
31  const boost::property_tree::ptree &cfg,
32  CoreUtilsPtr utils)
33  : BaseModule(ctx, pipe, cfg, utils)
34 {
35  try
36  {
38  }
39  catch (boost::property_tree::ptree_error &e)
40  {
41  std::throw_with_nested(
42  ConfigException("main", "Doorman module configuration is invalid"));
43  }
44 
45  for (auto &&doorman : doormen_)
46  {
47  reactor_.add(doorman->bus_sub(),
48  std::bind(&DoormanInstance::handle_bus_msg, doorman));
49 
50  for (auto &&door : doorman->doors())
51  {
52  reactor_.add(door->bus_sub(),
53  std::bind(&DoormanDoor::handle_bus_msg, door));
54  }
55  }
56 }
57 
59 {
60  boost::property_tree::ptree module_config = config_.get_child("module_config");
61 
62  auto doors_cfg = module_config.get_child_optional("doors");
63  if (doors_cfg)
64  process_doors_config(*doors_cfg);
65 
66  for (const auto &node : module_config.get_child("instances"))
67  {
68  // one doorman instance
69  boost::property_tree::ptree cfg_doorman = node.second;
70 
71  std::vector<std::string> auth_ctx_names;
72  std::vector<DoormanAction> actions;
73  std::string doorman_name = cfg_doorman.get_child("name").data();
74 
75  for (const auto &auth_contexts_node : cfg_doorman.get_child("auth_contexts"))
76  {
77  // each auth context we listen to
78  auth_ctx_names.push_back(
79  auth_contexts_node.second.get<std::string>("name"));
80  }
81 
82  for (const auto &action_node : cfg_doorman.get_child("actions"))
83  {
84  // every action we take
85  boost::property_tree::ptree cfg_action = action_node.second;
86  DoormanAction a;
87  std::string on_status;
88 
89  on_status = cfg_action.get<std::string>("on");
90  a.on_ = (on_status == "GRANTED" ? AccessStatus::GRANTED
91  : AccessStatus::DENIED);
92  a.target_ = cfg_action.get<std::string>("target");
94 
95  for (auto &cmd_node : cfg_action.get_child("cmd"))
96  {
97  // each frame in command
98  // fixme ORDER
99  // fixme ONLY ONE FRAME
100  a.cmd_.push_back(cmd_node.second.data());
101  }
102  actions.push_back(a);
103  }
104 
105  INFO("Creating Doorman instance " << doorman_name);
106  doormen_.push_back(std::make_shared<DoormanInstance>(
107  *this, ctx_, doorman_name, auth_ctx_names, actions));
108  }
109 }
110 
112 {
113  while (is_running_)
114  {
115  update();
116  reactor_.poll(2000);
117  }
118 }
119 
121  const boost::property_tree::ptree &doors_cfg)
122 {
123  DEBUG("Processing doors config");
124  for (const auto &door_cfg : doors_cfg)
125  {
126  std::string name = door_cfg.second.get<std::string>("name");
127  std::string gpio = door_cfg.second.get<std::string>("gpio");
128  const auto &open_schedule =
129  door_cfg.second.get_child_optional("on.schedules");
130  const auto &close_schedule =
131  door_cfg.second.get_child_optional("off.schedules");
132 
133  AuthTargetPtr door(new AuthTarget(name));
134  door->gpio(
135  std::unique_ptr<Hardware::FGPIO>(new Hardware::FGPIO(ctx_, gpio)));
136 
137  if (open_schedule)
138  {
139  Tools::XmlScheduleLoader xml_sched;
140  xml_sched.load(*open_schedule);
141  for (const auto &map_entry : xml_sched.schedules())
142  {
143  door->add_always_open_sched(map_entry.second);
144  }
145  }
146  if (close_schedule)
147  {
148  Tools::XmlScheduleLoader xml_sched;
149  xml_sched.load(*close_schedule);
150  for (const auto &map_entry : xml_sched.schedules())
151  {
152  door->add_always_close_sched(map_entry.second);
153  }
154  }
155 
156  const auto &exitreq =
157  door_cfg.second.get_child_optional("exitreq");
158  if (exitreq)
159  {
160  std::string exitreq_gpio = exitreq.get().get<std::string>("gpio");
161  door->exitreq_gpio(
162  std::unique_ptr<Hardware::FGPIO>(new Hardware::FGPIO(ctx_, exitreq_gpio)));
163  door->exitreq_duration(std::chrono::milliseconds(exitreq.get().get<uint16_t>("duration")));
164  }
165 
166  const auto &contact =
167  door_cfg.second.get_child_optional("contact");
168  if (contact)
169  {
170  std::string contact_gpio = contact.get().get<std::string>("gpio");
171  door->contact_gpio(
172  std::unique_ptr<Hardware::FGPIO>(new Hardware::FGPIO(ctx_, contact_gpio)));
173  door->contact_duration(std::chrono::milliseconds(contact.get().get<uint16_t>("duration")));
174  }
175  doors_.push_back(door);
176  }
177 }
178 
180 {
181  auto now = std::chrono::system_clock::now();
182 
183  for (auto &&door : doors_)
184  {
185  door->resetToExpectedState(now);
186  }
187 }
188 
189 std::vector<AuthTargetPtr> const &DoormanModule::doors() const
190 {
191  return doors_;
192 }
Leosac::Auth
Holds classes relevant to the Authentication and Authorization subsystem.
Definition: AccessPoint.hpp:27
Leosac::Auth::AuthTarget
Represent an object that we are authorizing against (a door).
Definition: AuthTarget.hpp:37
Leosac::Tools::XmlScheduleLoader
Load a list of schedules from a boost::property_tree.
Definition: XmlScheduleLoader.hpp:36
Leosac::Module::BaseModule
Base class for module implementation.
Definition: BaseModule.hpp:110
Leosac::Module::Doorman::DoormanAction::on_
Leosac::Auth::AccessStatus on_
When should this action be done? on GRANTED or DENIED ?
Definition: DoormanInstance.hpp:50
Leosac::Module::BaseModule::config_check
void config_check(const std::string &obj_name, Leosac::Hardware::DeviceClass type)
An helper that checks configuration the existence of some objects.
Definition: BaseModule.cpp:143
DEBUG
@ DEBUG
Definition: log.hpp:35
Auth.hpp
Leosac::Module::Doorman::DoormanAction::target_
std::string target_
Target component.
Definition: DoormanInstance.hpp:45
DoormanModule.hpp
INFO
@ INFO
Definition: log.hpp:34
DoormanInstance.hpp
Leosac::Module::Doorman::DoormanAction
Helper struct to wrap an "action".
Definition: DoormanInstance.hpp:40
Scheduler.hpp
Leosac::Tools::XmlScheduleLoader::load
bool load(const boost::property_tree::ptree &t)
Load all schedules from a tree and stores them in the map.
Definition: XmlScheduleLoader.cpp:49
Leosac::Module::Doorman::DoormanModule::doormen_
std::vector< std::shared_ptr< DoormanInstance > > doormen_
Authenticator instances.
Definition: DoormanModule.hpp:83
Leosac::Hardware::FGPIO
A Facade to a GPIO object.
Definition: FGPIO.hpp:45
Leosac::Auth::AuthTargetPtr
std::shared_ptr< AuthTarget > AuthTargetPtr
Definition: AuthFwd.hpp:93
kernel.hpp
Leosac::Module::BaseModule::config_
boost::property_tree::ptree config_
The configuration tree passed to the start_module function.
Definition: BaseModule.hpp:193
Leosac::Module::Doorman::DoormanModule::doors_
std::vector< Auth::AuthTargetPtr > doors_
Doors, to manage the always-on or always off stuff.
Definition: DoormanModule.hpp:88
ConfigException
Definition: configexception.hpp:87
Leosac::Module::BaseModule::reactor_
zmqpp::reactor reactor_
The reactor object we poll() on in the main loop.
Definition: BaseModule.hpp:214
Leosac::Module::Doorman::DoormanAction::cmd_
std::vector< std::string > cmd_
The command to be send.
Definition: DoormanInstance.hpp:56
Leosac::Module::Doorman::DoormanModule::DoormanModule
DoormanModule(zmqpp::context &ctx, zmqpp::socket *pipe, const boost::property_tree::ptree &cfg, CoreUtilsPtr utils)
Definition: DoormanModule.cpp:30
Leosac::Module::BaseModule::is_running_
bool is_running_
Boolean indicating whether the main loop should run or not.
Definition: BaseModule.hpp:203
Leosac::Module::Doorman::DoormanModule::run
virtual void run() override
This is the main loop of the module.
Definition: DoormanModule.cpp:111
Leosac::Module::Doorman::DoormanDoor::handle_bus_msg
void handle_bus_msg()
Activity we care about happened on the bus.
Definition: DoormanDoor.cpp:56
Leosac::Module::Doorman::DoormanModule::update
void update()
Definition: DoormanModule.cpp:179
Leosac::Tools::XmlScheduleLoader::schedules
const std::map< std::string, ISchedulePtr > & schedules() const
Access the map of stored schedules.
Definition: XmlScheduleLoader.cpp:111
Leosac::Module::Doorman::DoormanModule::process_doors_config
void process_doors_config(const boost::property_tree::ptree &t)
Definition: DoormanModule.cpp:120
Leosac::Module::Doorman::DoormanModule::process_config
void process_config()
Processing the configuration tree, spawning AuthFileInstance object as described in the configuration...
Definition: DoormanModule.cpp:58
log.hpp
Leosac::Module::Doorman
Module that allows user to configure action to be taken to react to messages from other modules.
Definition: DoormanDoor.hpp:31
Leosac::Module::BaseModule::ctx_
zmqpp::context & ctx_
A reference to the ZeroMQ context in case you need it to create additional socket.
Definition: BaseModule.hpp:183
Leosac::CoreUtilsPtr
std::shared_ptr< CoreUtils > CoreUtilsPtr
Definition: LeosacFwd.hpp:35
Leosac::Module::Doorman::DoormanInstance::handle_bus_msg
void handle_bus_msg()
Activity we care about happened on the bus.
Definition: DoormanInstance.cpp:63
Leosac::Module::Doorman::DoormanModule::doors
const std::vector< Auth::AuthTargetPtr > & doors() const
Definition: DoormanModule.cpp:189