cutelyst  3.9.1
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
statusmessage.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2016-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "statusmessage.h"
6 
7 #include <Cutelyst/Application>
8 #include <Cutelyst/Plugins/Session/session.h>
9 
10 #include <QRandomGenerator>
11 #include <QtCore/QDateTime>
12 #include <QtCore/QLoggingCategory>
13 
14 using namespace Cutelyst;
15 
16 Q_LOGGING_CATEGORY(C_STATUSMESSAGE, "cutelyst.plugins.statusmessage", QtWarningMsg)
17 
18 static thread_local StatusMessage *m_instance = nullptr;
19 
20 namespace Cutelyst {
21 
23 {
24 public:
25  static void _q_postFork(Application *app);
26 
27  QString sessionPrefix = QStringLiteral("status_msg");
28  QString tokenParam = QStringLiteral("mid");
29  QString statusMsgStashKey = QStringLiteral("status_msg");
30  QString errorMsgStashKey = QStringLiteral("error_msg");
31 };
32 
33 void StatusMessagePrivate::_q_postFork(Application *app)
34 {
35  m_instance = app->plugin<StatusMessage *>();
36 }
37 
38 } // namespace Cutelyst
39 
40 StatusMessage::StatusMessage(Application *parent)
41  : Plugin(parent)
42  , d_ptr(new StatusMessagePrivate)
43 {
44  m_instance = this;
45 }
46 
47 StatusMessage::~StatusMessage()
48 {
49  delete d_ptr;
50 }
51 
53 {
54  Q_D(const StatusMessage);
55  return d->sessionPrefix;
56 }
57 
58 void StatusMessage::setSessionPrefix(const QString &sessionPrefix)
59 {
60  Q_D(StatusMessage);
61  d->sessionPrefix = sessionPrefix;
62 }
63 
65 {
66  Q_D(const StatusMessage);
67  return d->tokenParam;
68 }
69 
70 void StatusMessage::setTokenParam(const QString &tokenParam)
71 {
72  Q_D(StatusMessage);
73  d->tokenParam = tokenParam;
74 }
75 
77 {
78  Q_D(const StatusMessage);
79  return d->statusMsgStashKey;
80 }
81 
82 void StatusMessage::setStatusMsgStashKey(const QString &statusMsgStashKey)
83 {
84  Q_D(StatusMessage);
85  d->statusMsgStashKey = statusMsgStashKey;
86 }
87 
89 {
90  Q_D(const StatusMessage);
91  return d->errorMsgStashKey;
92 }
93 
94 void StatusMessage::setErrorMgStashKey(const QString &errorMgStashKey)
95 {
96  Q_D(StatusMessage);
97  d->errorMsgStashKey = errorMgStashKey;
98 }
99 
101 {
102  if (Q_UNLIKELY(!m_instance)) {
103  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
104  return;
105  }
106  StatusMessagePrivate *priv = m_instance->d_ptr;
107 
108  const QString token = c->request()->queryParam(priv->tokenParam);
109  if (token.isEmpty()) {
110  return;
111  }
112 
113  QStringList deleteKeys;
114  const QString statusKey = priv->sessionPrefix + QLatin1String("status") + token;
115  const QVariant statusValue = Session::value(c, statusKey);
116  if (!statusValue.isNull()) {
117  deleteKeys.append(statusKey);
118  c->setStash(priv->statusMsgStashKey, statusValue);
119  }
120 
121  const QString errorKey = priv->sessionPrefix + QLatin1String("error") + token;
122  const QVariant errorValue = Session::value(c, errorKey);
123  if (!errorValue.isNull()) {
124  deleteKeys.append(errorKey);
125  c->setStash(priv->errorMsgStashKey, errorValue);
126  }
127 
128  if (!deleteKeys.isEmpty()) {
129  Session::deleteValues(c, deleteKeys);
130  }
131 }
132 
133 inline QString createToken()
134 {
135  return QString::number(QRandomGenerator::global()->generate() % 99999999)
136  .rightJustified(8, u'0', true);
137 }
138 
140 {
141  QString token;
142  if (Q_UNLIKELY(!m_instance)) {
143  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
144  return token;
145  }
146 
147  token = createToken();
148  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("error") + token, msg);
149  return token;
150 }
151 
153 {
154  ParamsMultiMap map(query);
155  if (Q_UNLIKELY(!m_instance)) {
156  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
157  return map;
158  }
159  StatusMessagePrivate *priv = m_instance->d_ptr;
160 
161  const QString token = createToken();
162  Session::setValue(c, priv->sessionPrefix + QLatin1String("error") + token, msg);
163  map.insert(priv->tokenParam, token);
164  return map;
165 }
166 
168 {
169  QString token;
170  if (Q_UNLIKELY(!m_instance)) {
171  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
172  return token;
173  }
174 
175  token = createToken();
176  Session::setValue(c, m_instance->d_ptr->sessionPrefix + QLatin1String("status") + token, msg);
177  return token;
178 }
179 
181 {
182  ParamsMultiMap map(query);
183  if (Q_UNLIKELY(!m_instance)) {
184  qCCritical(C_STATUSMESSAGE, "StatusMessage plugin not registered");
185  return map;
186  }
187  StatusMessagePrivate *priv = m_instance->d_ptr;
188 
189  const QString token = createToken();
190  Session::setValue(c, priv->sessionPrefix + QLatin1String("status") + token, msg);
191  map.insert(priv->tokenParam, token);
192  return map;
193 }
194 
196 {
197  connect(app, &Application::postForked, this, &StatusMessagePrivate::_q_postFork);
198  return true;
199 }
200 
201 #include "moc_statusmessage.cpp"
void setTokenParam(const QString &tokenParam)
static QString status(Context *c, const QString &msg)
void postForked(Cutelyst::Application *app)
QString sessionPrefix() const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void setStash(const QString &key, const QVariant &value)
Definition: context.cpp:217
T plugin()
Returns the registered plugin that casts to the template type T.
Definition: application.h:107
QString queryParam(const QString &key, const QString &defaultValue={}) const
Definition: request.h:561
static ParamsMultiMap statusQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
static void load(Context *c)
The Cutelyst Context.
Definition: context.h:38
QString number(double n, char format, int precision)
QString tokenParam() const
bool isNull() const const
QString rightJustified(qsizetype width, QChar fill, bool truncate) const const
bool isEmpty() const const
bool isEmpty() const const
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:185
iterator insert(const Key &key, const T &value)
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
void setStatusMsgStashKey(const QString &statusMsgStashKey)
virtual bool setup(Application *app) override
QString errorMgStashKey() const
void append(QList< T > &&value)
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:233
QString statusMsgStashKey() const
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:170
The Cutelyst Application.
Definition: application.h:42
static ParamsMultiMap errorQuery(Context *c, const QString &msg, ParamsMultiMap query=ParamsMultiMap())
static QString error(Context *c, const QString &msg)
void setErrorMgStashKey(const QString &errorMgStashKey)
QRandomGenerator * global()
void setSessionPrefix(const QString &sessionPrefix)