cutelyst  3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
roleacl.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2014-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "common.h"
6 #include "roleacl_p.h"
7 
8 #include <Cutelyst/Controller>
9 #include <Cutelyst/Dispatcher>
10 #include <Cutelyst/Plugins/Authentication/authentication.h>
11 
12 using namespace Cutelyst;
13 
123  : Component(new RoleACLPrivate, parent)
124 {
125 }
126 
127 Component::Modifiers RoleACL::modifiers() const
128 {
129  return AroundExecute;
130 }
131 
132 bool RoleACL::init(Cutelyst::Application *application, const QVariantHash &args)
133 {
134  Q_D(RoleACL);
135  Q_UNUSED(application)
136 
137  const auto attributes = args.value(QLatin1String("attributes")).value<ParamsMultiMap>();
138  d->actionReverse = args.value(QLatin1String("reverse")).toString();
139 
140  if (!attributes.contains(QLatin1String("RequiresRole")) &&
141  !attributes.contains(QLatin1String("AllowedRole"))) {
142  qFatal("RoleACL: Action %s requires at least one RequiresRole or AllowedRole attribute",
143  qPrintable(d->actionReverse));
144  } else {
145  const QStringList required = attributes.values(QLatin1String("RequiresRole"));
146  for (const QString &role : required) {
147  d->requiresRole.append(role);
148  }
149 
150  const QStringList allowed = attributes.values(QLatin1String("AllowedRole"));
151  for (const QString &role : allowed) {
152  d->allowedRole.append(role);
153  }
154  }
155 
156  auto it = attributes.constFind(QLatin1String("ACLDetachTo"));
157  if (it == attributes.constEnd() || it.value().isEmpty()) {
158  qFatal("RoleACL: Action %s requires the ACLDetachTo(<action>) attribute",
159  qPrintable(d->actionReverse));
160  }
161  d->aclDetachTo = it.value();
162 
163  return true;
164 }
165 
167 {
168  Q_D(const RoleACL);
169 
170  if (canVisit(c)) {
171  return Component::aroundExecute(c, stack);
172  }
173 
174  c->detach(d->detachTo);
175 
176  return false;
177 }
178 
180 {
181  Q_D(const RoleACL);
182 
183  const QStringList user_has =
184  Authentication::user(c).value(QStringLiteral("roles")).toStringList();
185 
186  const QStringList required = d->requiresRole;
187  const QStringList allowed = d->allowedRole;
188 
189  if (!required.isEmpty() && !allowed.isEmpty()) {
190  for (const QString &role : required) {
191  if (!user_has.contains(role)) {
192  return false;
193  }
194  }
195 
196  for (const QString &role : allowed) {
197  if (user_has.contains(role)) {
198  return true;
199  }
200  }
201  } else if (!required.isEmpty()) {
202  for (const QString &role : required) {
203  if (!user_has.contains(role)) {
204  return false;
205  }
206  }
207  return true;
208  } else if (!allowed.isEmpty()) {
209  for (const QString &role : allowed) {
210  if (user_has.contains(role)) {
211  return true;
212  }
213  }
214  }
215 
216  return false;
217 }
218 
219 bool RoleACL::dispatcherReady(const Dispatcher *dispatcher, Cutelyst::Controller *controller)
220 {
221  Q_D(RoleACL);
222  Q_UNUSED(dispatcher)
223 
224  d->detachTo = controller->actionFor(d->aclDetachTo);
225  if (!d->detachTo) {
226  d->detachTo = dispatcher->getActionByPath(d->aclDetachTo);
227  if (!d->detachTo) {
228  qFatal(
229  "RoleACL: Action '%s' requires a valid action set on the ACLDetachTo(%s) attribute",
230  qPrintable(d->actionReverse),
231  qPrintable(d->aclDetachTo));
232  }
233  }
234 
235  return true;
236 }
237 
238 #include "moc_roleacl.cpp"
virtual bool init(Application *application, const QVariantHash &args) override
Definition: roleacl.cpp:132
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void detach(Action *action=nullptr)
Definition: context.cpp:345
Action * actionFor(const QString &name) const
Definition: controller.cpp:36
virtual bool aroundExecute(Context *c, QStack< Component *> stack) override
Definition: roleacl.cpp:166
The Cutelyst Component base class.
Definition: component.h:25
The Cutelyst Context.
Definition: context.h:38
Cutelyst Controller base class
Definition: controller.h:87
void append(const T &value)
bool canVisit(Context *c) const
Definition: roleacl.cpp:179
User role-based authorization action class.
Definition: roleacl.h:18
bool isEmpty() const const
virtual Modifiers modifiers() const override
Definition: roleacl.cpp:127
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
RoleACL(QObject *parent=nullptr)
Definition: roleacl.cpp:122
virtual bool dispatcherReady(const Dispatcher *dispatcher, Controller *controller) override
Definition: roleacl.cpp:219
QStringList toStringList() const const
virtual bool aroundExecute(Context *c, QStack< Component *> stack)
Definition: component.cpp:103
The Cutelyst Application.
Definition: application.h:42
static AuthenticationUser user(Context *c)
Action * getActionByPath(const QString &path) const
Definition: dispatcher.cpp:223
The Cutelyst Dispatcher.
Definition: dispatcher.h:27
const T value(const Key &key, const T &defaultValue) const const