cutelyst  5.1.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
authenticationrealm.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2013-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "authenticationrealm.h"
6 
7 #include "authenticationstore.h"
8 #include "common.h"
9 #include "context.h"
10 #include "credentialpassword.h"
11 #include "storeldap.h"
12 
13 #include <Cutelyst/Plugins/Session/session.h>
14 
15 using namespace Cutelyst;
16 
17 Q_LOGGING_CATEGORY(C_AUTH_REALM, "cutelyst.plugin.authentication.realm", QtWarningMsg)
18 
19 #define SESSION_AUTHENTICATION_USER "__authentication_user"
20 #define SESSION_AUTHENTICATION_USER_REALM "__authentication_user_realm" // in authentication.cpp
21 
22 AuthenticationRealm::AuthenticationRealm(std::shared_ptr<AuthenticationStore> store,
23  std::shared_ptr<AuthenticationCredential> credential,
24  QStringView name,
25  QObject *parent)
26  : Component(parent)
27  , m_store(store)
28  , m_credential(credential)
29 {
30  m_credential->setParent(this);
31 
32  const QString realmName = name.toString();
33  setObjectName(realmName);
34  setName(realmName);
35 }
36 
37 AuthenticationRealm::~AuthenticationRealm()
38 {
39 }
40 
41 std::shared_ptr<AuthenticationStore> AuthenticationRealm::store() const noexcept
42 {
43  return m_store;
44 }
45 
46 std::shared_ptr<AuthenticationCredential> AuthenticationRealm::credential() const noexcept
47 {
48  return m_credential;
49 }
50 
52 {
53  AuthenticationUser ret = m_store->findUser(c, userinfo);
54 
55  if (ret.isNull()) {
56  if (m_store->canAutoCreateUser()) {
57  ret = m_store->autoCreateUser(c, userinfo);
58  }
59  } else {
60  if (m_store->canAutoUpdateUser()) {
61  ret = m_store->autoUpdateUser(c, userinfo);
62  }
63  }
64 
65  if (!ret.isNull() && ret.authRealm() != name()) {
66  ret.setAuthRealm(name());
67  }
68 
69  return ret;
70 }
71 
73 {
74  return m_credential->authenticate(c, this, authinfo);
75 }
76 
78 {
80  {QStringLiteral(SESSION_AUTHENTICATION_USER),
81  QStringLiteral(SESSION_AUTHENTICATION_USER_REALM)});
82 }
83 
85 {
86  Session::setValue(c, QStringLiteral(SESSION_AUTHENTICATION_USER), m_store->forSession(c, user));
87  Session::setValue(c, QStringLiteral(SESSION_AUTHENTICATION_USER_REALM), objectName());
88 
89  return user;
90 }
91 
93 {
94  AuthenticationUser user;
95  QVariant _frozenUser = frozenUser;
96  if (_frozenUser.isNull()) {
97  _frozenUser = userIsRestorable(c);
98  }
99 
100  if (_frozenUser.isNull()) {
101  return user;
102  }
103 
104  user = m_store->fromSession(c, _frozenUser);
105 
106  if (!user.isNull()) {
107  // Sets the realm the user originated in
108  user.setAuthRealm(objectName());
109  } else {
110  qCWarning(C_AUTH_REALM) << "Store claimed to have a restorable user, but restoration "
111  "failed. Did you change the user's id_field?";
112  }
113 
114  return user;
115 }
116 
118 {
119  // No need to check if session is valid
120  // as ::value will do that for us
121  return Session::value(c, QStringLiteral(SESSION_AUTHENTICATION_USER));
122 }
123 
125  const AuthenticationUser &user,
126  const QString &password,
127  const QString &passwordField)
128 {
129  // If the credential is CredentialPassword with LdapBind mode, delegate to store's
130  // validatePassword
131  auto credPassword = std::dynamic_pointer_cast<CredentialPassword>(m_credential);
132  if (credPassword &&
133  credPassword->passwordType() == CredentialPassword::PasswordType::SelfCheck) {
134  if (m_store) {
135  return m_store->validatePassword(c, user, password);
136  }
137  return false;
138  }
139  // For other password types (Hashed, Clear, None), return false (handled by credential)
140  return false;
141 }
142 
143 #include "moc_authenticationrealm.cpp"
void setName(const QString &name)
Definition: component.cpp:39
AuthenticationUser restoreUser(Context *c, const QVariant &frozenUser)
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userinfo)
AuthenticationUser persistUser(Context *c, const AuthenticationUser &user)
virtual AuthenticationUser authenticate(Context *c, const ParamsMultiMap &authinfo)
Use password based authentication to authenticate a user.
The Cutelyst Component base class.
Definition: component.h:30
The Cutelyst Context.
Definition: context.h:42
bool isNull() const const
QString objectName() const const
QString name() const noexcept
Definition: component.cpp:33
void setObjectName(QAnyStringView name)
static void setValue(Context *c, const QString &key, const QVariant &value)
Definition: session.cpp:186
The Cutelyst namespace holds all public Cutelyst API.
Container for user data retrieved from an AuthenticationStore.
std::shared_ptr< AuthenticationStore > store() const noexcept
static void deleteValues(Context *c, const QStringList &keys)
Definition: session.cpp:234
static QVariant value(Context *c, const QString &key, const QVariant &defaultValue=QVariant())
Definition: session.cpp:171
std::shared_ptr< AuthenticationCredential > credential() const noexcept
void setAuthRealm(const QString &authRealm)
AuthenticationRealm(std::shared_ptr< AuthenticationStore > store, std::shared_ptr< AuthenticationCredential > credential, QStringView name=defaultRealm, QObject *parent=nullptr)
bool checkPassword(Context *c, const AuthenticationUser &user, const QString &password, const QString &passwordField=QStringLiteral("password"))