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(QLatin1String("attributes")).value<ParamsMultiMap>();
140 d->actionReverse = args.value(QLatin1String("reverse")).toString();
141
142 if (!attributes.contains(QLatin1String("RequiresRole")) &&
143 !attributes.contains(QLatin1String("AllowedRole"))) {
144 qFatal("RoleACL: Action %s requires at least one RequiresRole or AllowedRole attribute",
145 qPrintable(d->actionReverse));
146 } else {
147 const QStringList required = attributes.values(QLatin1String("RequiresRole"));
148 for (const QString &role : required) {
149 d->requiresRole.append(role);
150 }
151
152 const QStringList allowed = attributes.values(QLatin1String("AllowedRole"));
153 for (const QString &role : allowed) {
154 d->allowedRole.append(role);
155 }
156 }
157
158 auto it = attributes.constFind(QLatin1String("ACLDetachTo"));
159 if (it == attributes.constEnd() || it.value().isEmpty()) {
160 qFatal("RoleACL: Action %s requires the ACLDetachTo(<action>) attribute",
161 qPrintable(d->actionReverse));
162 }
163 d->aclDetachTo = it.value();
164
165 return true;
166}
167
169{
170 Q_D(const RoleACL);
171
172 if (canVisit(c)) {
173 return Component::aroundExecute(c, stack);
174 }
175
176 c->detach(d->detachTo);
177
178 return false;
179}
180
182{
183 Q_D(const RoleACL);
184
185 const QStringList user_has = Authentication::user(c).value(u"roles"_s).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 return std::ranges::all_of(
204 required, [user_has](const QString &role) { return user_has.contains(role); });
205 } else if (!allowed.isEmpty()) {
206 for (const QString &role : allowed) {
207 if (user_has.contains(role)) {
208 return true;
209 }
210 }
211 }
212
213 return false;
214}
215
216bool RoleACL::dispatcherReady(const Dispatcher *dispatcher, Cutelyst::Controller *controller)
217{
218 Q_D(RoleACL);
219 Q_UNUSED(dispatcher)
220
221 d->detachTo = controller->actionFor(d->aclDetachTo);
222 if (!d->detachTo) {
223 d->detachTo = dispatcher->getActionByPath(d->aclDetachTo);
224 if (!d->detachTo) {
225 qFatal(
226 "RoleACL: Action '%s' requires a valid action set on the ACLDetachTo(%s) attribute",
227 qPrintable(d->actionReverse),
228 qPrintable(d->aclDetachTo));
229 }
230 }
231
232 return true;
233}
234
235#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:340
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:181
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:168
Modifiers modifiers() const override
Definition roleacl.cpp:129
bool dispatcherReady(const Dispatcher *dispatcher, Controller *controller) override
Definition roleacl.cpp:216
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