cutelyst 4.3.0
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
12using namespace Cutelyst;
13
124 : Component(new RoleACLPrivate, parent)
125{
126}
127
128Component::Modifiers RoleACL::modifiers() const
129{
130 return AroundExecute;
131}
132
133bool RoleACL::init(Cutelyst::Application *application, const QVariantHash &args)
134{
135 Q_D(RoleACL);
136 Q_UNUSED(application)
137
138 const auto attributes = args.value(QLatin1String("attributes")).value<ParamsMultiMap>();
139 d->actionReverse = args.value(QLatin1String("reverse")).toString();
140
141 if (!attributes.contains(QLatin1String("RequiresRole")) &&
142 !attributes.contains(QLatin1String("AllowedRole"))) {
143 qFatal("RoleACL: Action %s requires at least one RequiresRole or AllowedRole attribute",
144 qPrintable(d->actionReverse));
145 } else {
146 const QStringList required = attributes.values(QLatin1String("RequiresRole"));
147 for (const QString &role : required) {
148 d->requiresRole.append(role);
149 }
150
151 const QStringList allowed = attributes.values(QLatin1String("AllowedRole"));
152 for (const QString &role : allowed) {
153 d->allowedRole.append(role);
154 }
155 }
156
157 auto it = attributes.constFind(QLatin1String("ACLDetachTo"));
158 if (it == attributes.constEnd() || it.value().isEmpty()) {
159 qFatal("RoleACL: Action %s requires the ACLDetachTo(<action>) attribute",
160 qPrintable(d->actionReverse));
161 }
162 d->aclDetachTo = it.value();
163
164 return true;
165}
166
168{
169 Q_D(const RoleACL);
170
171 if (canVisit(c)) {
172 return Component::aroundExecute(c, stack);
173 }
174
175 c->detach(d->detachTo);
176
177 return false;
178}
179
181{
182 Q_D(const RoleACL);
183
184 const QStringList user_has =
185 Authentication::user(c).value(QStringLiteral("roles")).toStringList();
186
187 const QStringList required = d->requiresRole;
188 const QStringList allowed = d->allowedRole;
189
190 if (!required.isEmpty() && !allowed.isEmpty()) {
191 for (const QString &role : required) {
192 if (!user_has.contains(role)) {
193 return false;
194 }
195 }
196
197 for (const QString &role : allowed) {
198 if (user_has.contains(role)) {
199 return true;
200 }
201 }
202 } else if (!required.isEmpty()) {
203 for (const QString &role : required) {
204 if (!user_has.contains(role)) {
205 return false;
206 }
207 }
208 return true;
209 } else if (!allowed.isEmpty()) {
210 for (const QString &role : allowed) {
211 if (user_has.contains(role)) {
212 return true;
213 }
214 }
215 }
216
217 return false;
218}
219
220bool RoleACL::dispatcherReady(const Dispatcher *dispatcher, Cutelyst::Controller *controller)
221{
222 Q_D(RoleACL);
223 Q_UNUSED(dispatcher)
224
225 d->detachTo = controller->actionFor(d->aclDetachTo);
226 if (!d->detachTo) {
227 d->detachTo = dispatcher->getActionByPath(d->aclDetachTo);
228 if (!d->detachTo) {
229 qFatal(
230 "RoleACL: Action '%s' requires a valid action set on the ACLDetachTo(%s) attribute",
231 qPrintable(d->actionReverse),
232 qPrintable(d->aclDetachTo));
233 }
234 }
235
236 return true;
237}
238
239#include "moc_roleacl.cpp"
The Cutelyst application.
Definition application.h:66
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
static AuthenticationUser user(Context *c)
The Cutelyst Component base class.
Definition component.h:30
virtual bool aroundExecute(Context *c, QStack< Component * > stack)
The Cutelyst Context.
Definition context.h:42
void detach(Action *action=nullptr)
Definition context.cpp:339
Cutelyst Controller base class.
Definition controller.h:56
Action * actionFor(QStringView name) const
The Cutelyst Dispatcher.
Definition dispatcher.h:29
Action * getActionByPath(QStringView path) const
User role-based authorization action role.
Definition roleacl.h:19
bool canVisit(Context *c) const
Definition roleacl.cpp:180
bool init(Application *application, const QVariantHash &args) override
Definition roleacl.cpp:133
RoleACL(QObject *parent=nullptr)
Definition roleacl.cpp:123
bool aroundExecute(Context *c, QStack< Component * > stack) override
Definition roleacl.cpp:167
Modifiers modifiers() const override
Definition roleacl.cpp:128
virtual bool dispatcherReady(const Dispatcher *dispatcher, Controller *controller) override
Definition roleacl.cpp:220
The Cutelyst namespace holds all public Cutelyst API.
void append(QList::parameter_type value)
bool isEmpty() const const
T value(const Key &key, const T &defaultValue) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QStringList toStringList() const const