cutelyst  5.0.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 using namespace Qt::StringLiterals;
15 
16 Q_LOGGING_CATEGORY(C_AUTH_HTPASSWD, "cutelyst.plugin.authentication.htpasswd", QtWarningMsg)
17 
19  : m_filename(name)
20 {
21 }
22 
24 {
25 }
26 
28 {
29  const QString username = user.value(u"username"_s);
30 
31  QTemporaryFile tmp(m_filename + u"-XXXXXXX");
32  tmp.setAutoRemove(false); // sort of a backup
33  if (!tmp.open()) {
34  qCWarning(C_AUTH_HTPASSWD) << "Failed to open temporary file for writing";
35  return;
36  }
37 
38  bool wrote = false;
39  QFile file(m_filename);
40  if (file.exists() && file.open(QFile::ReadWrite | QFile::Text)) {
41  while (!file.atEnd()) {
42  QByteArray line = file.readLine();
43  QByteArrayList parts = line.split(':');
44  if (!wrote && parts.size() >= 2 && parts.first() == username.toLatin1()) {
45  line = username.toLatin1() + ':' +
46  user.value(u"password"_s).toLatin1().replace(':', ',') + '\n';
47  wrote = true;
48  }
49  tmp.write(line);
50  }
51  file.close();
52  }
53 
54  if (!wrote) {
55  QByteArray line = username.toLatin1() + ':' +
56  user.value(u"password"_s).toLatin1().replace(':', ',') + '\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(u"username"_s);
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(u"username"_s, username);
84  ret.setId(username);
85  QByteArray password = parts.at(1);
86  ret.insert(u"password"_s, 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, {{u"username"_s, frozenUser.toString()}});
103 }
void insert(const QString &key, const QVariant &value)
bool rename(const QString &newName)
void setId(const QVariant &id)
void addUser(const ParamsMultiMap &user)
Definition: htpasswd.cpp:27
QList< QByteArray > split(char sep) const const
QByteArray trimmed() const const
bool remove()
bool exists(const QString &fileName)
const_reference at(qsizetype i) const const
AuthenticationUser fromSession(Context *c, const QVariant &frozenUser) override final
Definition: htpasswd.cpp:100
qsizetype size() const const
QVariant forSession(Context *c, const AuthenticationUser &user) override final
Definition: htpasswd.cpp:94
The Cutelyst Context.
Definition: context.h:42
Authentication data store using a flat file.
Definition: htpasswd.h:20
void setAutoRemove(bool b)
QByteArray & replace(QByteArrayView before, QByteArrayView after)
qint64 write(const QByteArray &data)
The Cutelyst namespace holds all public Cutelyst API.
T & first()
AuthenticationUser findUser(Context *c, const ParamsMultiMap &userInfo) override final
Definition: htpasswd.cpp:70
Container for user data retrieved from an AuthenticationStore.
virtual bool atEnd() const const override
QString fromLatin1(QByteArrayView str)
QByteArray toLatin1() const const
virtual void close() override
virtual ~StoreHtpasswd() override
Definition: htpasswd.cpp:23
QByteArray readLine(qint64 maxSize)
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
QString toString() const const
T value(const Key &key, const T &defaultValue) const const