cutelyst  3.9.1
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 
16  : AuthenticationStore(parent)
17  , m_filename(name)
18 {
19 }
20 
21 StoreHtpasswd::~StoreHtpasswd()
22 {
23 }
24 
26 {
27  const QString username = user.value(QStringLiteral("username"));
28 
29  QTemporaryFile tmp(m_filename + QLatin1String("-XXXXXXX"));
30  tmp.setAutoRemove(false); // sort of a backup
31  if (!tmp.open()) {
32  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to open temporary file for writing";
33  return;
34  }
35 
36  bool wrote = false;
37  QFile file(m_filename);
38  if (file.exists() && file.open(QFile::ReadWrite | QFile::Text)) {
39  while (!file.atEnd()) {
40  QByteArray line = file.readLine();
41  QByteArrayList parts = line.split(':');
42  if (!wrote && parts.size() >= 2 && parts.first() == username.toLatin1()) {
43  line = username.toLatin1() + ':' +
44  user.value(QStringLiteral("password")).toLatin1().replace(':', ',') + '\n';
45  wrote = true;
46  }
47  tmp.write(line);
48  }
49  file.close();
50  }
51 
52  if (!wrote) {
53  QByteArray line = username.toLatin1() + ':' +
54  user.value(QStringLiteral("password")).toLatin1().replace(':', ',') +
55  '\n';
56  tmp.write(line);
57  }
58 
59  if (file.exists() && !file.remove()) {
60  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to remove auth file for replacement";
61  return;
62  }
63 
64  if (!tmp.rename(m_filename)) {
65  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to rename temporary file";
66  }
67 }
68 
70 {
71  Q_UNUSED(c);
73  const QString username = userInfo.value(QStringLiteral("username"));
74 
75  QFile file(m_filename);
76  if (file.open(QFile::ReadOnly | QFile::Text)) {
77  while (!file.atEnd()) {
78  QByteArray line = file.readLine();
79  QByteArrayList parts = line.trimmed().split(':');
80  if (parts.size() >= 2 && !parts.first().startsWith('#') &&
81  parts.first() == username.toLatin1()) {
82  ret.insert(QStringLiteral("username"), username);
83  ret.setId(username);
84  QByteArray password = parts.at(1);
85  ret.insert(QStringLiteral("password"),
86  QString::fromLatin1(password.replace(',', ':')));
87  break;
88  }
89  }
90  }
91  return ret;
92 }
93 
95 {
96  Q_UNUSED(c);
97  return user.id();
98 }
99 
101 {
102  return findUser(c, {{QStringLiteral("username"), frozenUser.toString()}});
103 }
104 
105 #include "moc_htpasswd.cpp"
bool rename(const QString &newName)
void setId(const QVariant &id)
Sets the unique user id restored from the store.
void addUser(const ParamsMultiMap &user)
Definition: htpasswd.cpp:25
QList< QByteArray > split(char sep) const const
QByteArray trimmed() const const
bool remove()
const T & at(int i) const const
bool exists() const const
int size() const const
The Cutelyst Context.
Definition: context.h:38
void setAutoRemove(bool b)
QByteArray & replace(int pos, int len, const char *after)
virtual AuthenticationUser fromSession(Context *c, const QVariant &frozenUser) final
Definition: htpasswd.cpp:100
virtual QVariant forSession(Context *c, const AuthenticationUser &user) final
Definition: htpasswd.cpp:94
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
T & first()
virtual bool open(QIODevice::OpenMode mode) override
virtual bool atEnd() const const override
QByteArray toLatin1() const const
virtual void close() override
StoreHtpasswd(const QString &name, QObject *parent=nullptr)
Definition: htpasswd.cpp:15
qint64 write(const char *data, qint64 maxSize)
QString fromLatin1(const char *str, int size)
QString toString() const const
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userInfo) final
Definition: htpasswd.cpp:69
qint64 readLine(char *data, qint64 maxSize)
const T value(const Key &key, const T &defaultValue) const const