Leosac  0.7.0
OpenSourceAccessControl
AccessPointCRUD.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/AccessPointCRUD.hpp"
21 #include "Exceptions.hpp"
22 #include "WSServer.hpp"
23 #include "api/APISession.hpp"
28 #include "core/auth/AccessPoint_odb.h"
29 #include "core/auth/User.hpp"
32 #include "tools/AssertCast.hpp"
33 #include "tools/db/DBService.hpp"
34 #include <cctype>
36 
37 using namespace Leosac;
38 using namespace Leosac::Module;
39 using namespace Leosac::Module::WebSockAPI;
40 
42  : CRUDResourceHandler(ctx)
43 {
44 }
45 
47 {
49 }
50 
51 boost::optional<json> AccessPointCRUD::create_impl(const json &req)
52 {
53  auto service_ptr =
55  auto controller_module =
56  req.at("attributes").at("controller-module").get<std::string>();
57  auto ap_backend_ptr = service_ptr->get_backend(controller_module);
58  if (ap_backend_ptr)
59  return ap_backend_ptr->create(security_context(), ctx_.audit, req);
60 
61  // No backend for the requested type of controller module...
62  // Throw a general exception that will be mostly useless to the end user
63  // but may make sense to devs or system administrators.
65  "Cannot find an AccessPointBackend corresponding to controller-module "
66  << controller_module));
67 }
68 
69 boost::optional<json> AccessPointCRUD::read_impl(const json &req)
70 {
71  // Read is not forwarded to the implementation module.
72  // Instead we let the serializer server do its job.
73  json rep;
74 
75  using Result = odb::result<Auth::AccessPoint>;
76  DBPtr db = ctx_.dbsrv->db();
77  odb::transaction t(db->begin());
78  auto ap_id = req.at("access_point_id").get<Auth::AccessPointId>();
79 
80  auto service_ptr =
82 
83  if (ap_id != 0)
84  {
85  auto ap = ctx_.dbsrv->find_access_point_by_id(ap_id,
87  rep["data"] = service_ptr->serialize(*ap, security_context());
88  }
89  else
90  {
91  Result result = db->query<Auth::AccessPoint>();
92  rep["data"] = json::array();
93  auto current_user = ctx_.session->current_user();
94 
95  // fixme: may be rather slow.
96  for (const auto &ap : result)
97  {
99  if (ctx_.session->security_context().check_permission(
101  {
102  rep["data"].push_back(
103  service_ptr->serialize(ap, security_context()));
104  }
105  }
106  }
107  t.commit();
108  return rep;
109 }
110 
111 boost::optional<json> AccessPointCRUD::update_impl(const json &req)
112 {
113  // To perform update, we first lookup the base access point object.
114  // We then forward the update request to its controller module.
115  auto ap_id = req.at("access_point_id").get<Auth::AccessPointId>();
116  auto ap =
117  ctx_.dbsrv->find_access_point_by_id(ap_id, DBService::THROW_IF_NOT_FOUND);
118 
119  auto service_ptr =
121  auto ap_backend_ptr = service_ptr->get_backend(ap->controller_module());
122  if (ap_backend_ptr)
123  return ap_backend_ptr->update(security_context(), ctx_.audit, req, ap);
125  "Cannot find an AccessPointBackend corresponding to controller-module "
126  << ap->controller_module()));
127 }
128 
129 boost::optional<json> AccessPointCRUD::delete_impl(const json &req)
130 {
131  // To perform deletion, we first lookup the base access point object.
132  // We then forward the deletion request to its controller module.
133  auto ap_id = req.at("access_point_id").get<Auth::AccessPointId>();
134  auto ap =
135  ctx_.dbsrv->find_access_point_by_id(ap_id, DBService::THROW_IF_NOT_FOUND);
136 
137  auto service_ptr =
139  auto ap_backend_ptr = service_ptr->get_backend(ap->controller_module());
140 
141  if (ap_backend_ptr)
142  return ap_backend_ptr->erase(security_context(), ctx_.audit, req, ap);
144  "Cannot find an AccessPointBackend corresponding to controller-module "
145  << ap->controller_module()));
146 }
147 
148 std::vector<CRUDResourceHandler::ActionActionParam>
150  const json &req) const
151 {
152  std::vector<CRUDResourceHandler::ActionActionParam> ret;
154  try
155  {
156  aap.ap_id = req.at("access_point_id").get<Auth::AccessPointId>();
157  }
158  catch (json::out_of_range &e)
159  {
160  aap.ap_id = 0;
161  }
162  switch (verb)
163  {
164  case Verb::READ:
165  ret.emplace_back(SecurityContext::Action::ACCESS_POINT_READ, aap);
166  break;
167  case Verb::CREATE:
168  ret.emplace_back(SecurityContext::Action::ACCESS_POINT_CREATE, aap);
169  break;
170  case Verb::UPDATE:
171  ret.emplace_back(SecurityContext::Action::ACCESS_POINT_UPDATE, aap);
172  break;
173  case Verb::DELETE:
174  ret.emplace_back(SecurityContext::Action::ACCESS_POINT_DELETE, aap);
175  break;
176  }
177  return ret;
178 }
static CRUDResourceHandlerUPtr instanciate(RequestContext)
virtual boost::optional< json > create_impl(const json &req) override
unsigned long AccessPointId
Definition: AuthFwd.hpp:128
This is the header file for a generated source file, GitSHA1.cpp.
virtual UserSecurityContext & security_context() const override
Helper function that returns the security context.
Audit::IAuditEntryPtr audit
The initial audit trail for the request.
ServiceRegistry & get_service_registry()
A function to retrieve the ServiceRegistry from pretty much anywhere.
std::unique_ptr< CRUDResourceHandler > CRUDResourceHandlerUPtr
Definition: WebSockFwd.hpp:39
virtual boost::optional< json > update_impl(const json &req) override
AccessPointBackend * get_backend(const std::string &controller_module)
Get the AccessPointBackend that supports the given controller_module.
This service lets various AccessPoint backend register and provide implementation to use by the Acces...
All modules that provides features to Leosac shall be in this namespace.
virtual std::vector< ActionActionParam > required_permission(Verb verb, const json &req) const override
virtual json create(SecurityContext &sec_ctx, Audit::IAuditEntryPtr, const json &req)=0
virtual boost::optional< json > delete_impl(const json &req) override
Base CRUD handler for use within the websocket module.
std::shared_ptr< ServiceInterface > get_service() const
Retrieve the service instance implementing the ServiceInterface, or nullptr if no such service was re...
virtual boost::optional< json > read_impl(const json &req) override
#define BUILD_STR(param)
Internal macro.
Definition: log.hpp:66
A base class for Leosac specific exception.
odb::result< Tools::LogEntry > Result
Definition: LogEntry.cpp:37
Holds valuable pointer to provide context to a request.
std::shared_ptr< odb::database > DBPtr
Definition: db_fwd.hpp:31