cutelyst  4.4.0
A C++ Web Framework built on top of Qt, using the simple approach of Catalyst (Perl) framework.
htpasswd.cpp
1 /*
2  * SPDX-FileCopyrightText: (C) 2014-2022 Daniel Nicoletti <dantti12@gmail.com>
3  * SPDX-License-Identifier: BSD-3-Clause
4  */
5 #include "htpasswd.h"
6 
7 #include "common.h"
8 
9 #include <QFile>
10 #include <QLoggingCategory>
11 #include <QTemporaryFile>
12 
13 using namespace Cutelyst;
14 
15 Q_LOGGING_CATEGORY(C_AUTH_HTPASSWD, "cutelyst.plugin.authentication.htpasswd", QtWarningMsg)
16 
18  : m_filename(name)
19 {
20 }
21 
23 {
24 }
25 
27 {
28  const QString username = user.value(QStringLiteral("username"));
29 
30  QTemporaryFile tmp(m_filename + QLatin1String("-XXXXXXX"));
31  tmp.setAutoRemove(false); // sort of a backup
32  if (!tmp.open()) {
33  qCWarning(C_AUTH_HTPASSWD) << "Failed to open temporary file for writing";
34  return;
35  }
36 
37  bool wrote = false;
38  QFile file(m_filename);
39  if (file.exists() && file.open(QFile::ReadWrite | QFile::Text)) {
40  while (!file.atEnd()) {
41  QByteArray line = file.readLine();
42  QByteArrayList parts = line.split(':');
43  if (!wrote && parts.size() >= 2 && parts.first() == username.toLatin1()) {
44  line = username.toLatin1() + ':' +
45  user.value(QStringLiteral("password")).toLatin1().replace(':', ',') + '\n';
46  wrote = true;
47  }
48  tmp.write(line);
49  }
50  file.close();
51  }
52 
53  if (!wrote) {
54  QByteArray line = username.toLatin1() + ':' +
55  user.value(QStringLiteral("password")).toLatin1().replace(':', ',') +
56  '\n';
57  tmp.write(line);
58  }
59 
60  if (file.exists() && !file.remove()) {
61  qCWarning(C_AUTH_HTPASSWD) << "Failed to remove auth file for replacement";
62  return;
63  }
64 
65  if (!tmp.rename(m_filename)) {
66  qCWarning(C_AUTH_HTPASSWD) << "Failed to rename temporary file";
67  }
68 }
69 
71 {
72  Q_UNUSED(c);
74  const QString username = userInfo.value(QStringLiteral("username"));
75 
76  QFile file(m_filename);
77  if (file.open(QFile::ReadOnly | QFile::Text)) {
78  while (!file.atEnd()) {
79  QByteArray line = file.readLine();
80  QByteArrayList parts = line.trimmed().split(':');
81  if (parts.size() >= 2 && !parts.first().startsWith('#') &&
82  parts.first() == username.toLatin1()) {
83  ret.insert(QStringLiteral("username"), username);
84  ret.setId(username);
85  QByteArray password = parts.at(1);
86  ret.insert(QStringLiteral("password"),
87  QString::fromLatin1(password.replace(',', ':')));
88  break;
89  }
90  }
91  }
92  return ret;
93 }
94 
96 {
97  Q_UNUSED(c);
98  return user.id();
99 }
100 
102 {
103  return findUser(c, {{QStringLiteral("username"), frozenUser.toString()}});
104 }
Container for user data retrieved from an AuthenticationStore.
void setId(const QVariant &id)
void insert(const QString &key, const QVariant &value)
The Cutelyst Context.
Definition: context.h:42
Authentication data store using a flat file.
Definition: htpasswd.h:21
virtual ~StoreHtpasswd() override
Definition: htpasswd.cpp:22
QVariant forSession(Context *c, const AuthenticationUser &user) override final
Definition: htpasswd.cpp:95
AuthenticationUser findUser(Context *c, const ParamsMultiMap &userInfo) override final
Definition: htpasswd.cpp:70
AuthenticationUser fromSession(Context *c, const QVariant &frozenUser) override final
Definition: htpasswd.cpp:101
void addUser(const ParamsMultiMap &user)
Definition: htpasswd.cpp:26
The Cutelyst namespace holds all public Cutelyst API.
QByteArray & replace(QByteArrayView before, QByteArrayView after)
QList< QByteArray > split(char sep) const const
QByteArray trimmed() const const
bool exists(const QString &fileName)
bool open(FILE *fh, QIODeviceBase::OpenMode mode, QFileDevice::FileHandleFlags handleFlags)
bool remove()
virtual bool atEnd() const const override
virtual void close() override
QByteArray readLine(qint64 maxSize)
qint64 write(const QByteArray &data)
QList::const_reference at(qsizetype i) const const
T & first()
qsizetype size() const const
T value(const Key &key, const T &defaultValue) const const
QString fromLatin1(QByteArrayView str)
QByteArray toLatin1() const const
bool rename(const QString &newName)
void setAutoRemove(bool b)
QString toString() const const