cutelyst 5.0.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 Qt::StringLiterals;
13using namespace Cutelyst;
14
125 : Component(new RoleACLPrivate, parent)
126{
127}
128
129Component::Modifiers RoleACL::modifiers() const
130{
131 return AroundExecute;
132}
133
134bool RoleACL::init(Cutelyst::Application *application, const QVariantHash &args)
135{
136 Q_D(RoleACL);
137 Q_UNUSED(application)
138
139 const auto attributes = args.value(u"attributes"_s).value<ParamsMultiMap>();
140 d->actionReverse = args.value(u"reverse"_s).toString();
141
142 if (!attributes.contains(u"RequiresRole"_s) && !attributes.contains(u"AllowedRole"_s)) {
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(u"RequiresRole"_s);
147 for (const QString &role : required) {
148 d->requiresRole.append(role);
149 }
150
151 const QStringList allowed = attributes.values(u"AllowedRole"_s);
152 for (const QString &role : allowed) {
153 d->allowedRole.append(role);
154 }
155 }
156
157 auto it = attributes.constFind(u"ACLDetachTo"_s);
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 = Authentication::user(c).value(u"roles"_s).toStringList();
185
186 const QStringList required = d->requiresRole;
187 const QStringList allowed = d->allowedRole;
188
189 if (!required.isEmpty() && !allowed.isEmpty()) {
190 bool allRequired = std::ranges::all_of(
191 required, [&user_has](const QString &role) { return user_has.contains(role); });
192 if (!allRequired) {
193 return false;
194 }
195
196 return std::ranges::any_of(
197 allowed, [&user_has](const QString &role) { return user_has.contains(role); });
198 } else if (!required.isEmpty()) {
199 return std::ranges::all_of(
200 required, [&user_has](const QString &role) { return user_has.contains(role); });
201 } else if (!allowed.isEmpty()) {
202 return std::ranges::any_of(
203 allowed, [&user_has](const QString &role) { return user_has.contains(role); });
204 }
205
206 return false;
207}
208
209bool RoleACL::dispatcherReady(const Dispatcher *dispatcher, Cutelyst::Controller *controller)
210{
211 Q_D(RoleACL);
212 Q_UNUSED(dispatcher)
213
214 d->detachTo = controller->actionFor(d->aclDetachTo);
215 if (!d->detachTo) {
216 d->detachTo = dispatcher->getActionByPath(d->aclDetachTo);
217 if (!d->detachTo) {
218 qFatal(
219 "RoleACL: Action '%s' requires a valid action set on the ACLDetachTo(%s) attribute",
220 qPrintable(d->actionReverse),
221 qPrintable(d->aclDetachTo));
222 }
223 }
224
225 return true;
226}
227
228#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:338
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:18
bool canVisit(Context *c) const
Definition roleacl.cpp:180
bool init(Application *application, const QVariantHash &args) override
Definition roleacl.cpp:134
RoleACL(QObject *parent=nullptr)
Definition roleacl.cpp:124
bool aroundExecute(Context *c, QStack< Component * > stack) override
Definition roleacl.cpp:167
Modifiers modifiers() const override
Definition roleacl.cpp:129
bool dispatcherReady(const Dispatcher *dispatcher, Controller *controller) override
Definition roleacl.cpp:209
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