Cutelyst  3.5.0
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 <QFile>
8 #include <QTemporaryFile>
9 #include <QLoggingCategory>
10 
11 #include "common.h"
12 
13 using namespace Cutelyst;
14 
16  , m_filename(name)
17 {
18 
19 }
20 
21 StoreHtpasswd::~StoreHtpasswd()
22 {
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(CUTELYST_UTILS_AUTH) << "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() + ':' + 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() + ':' + user.value(QStringLiteral("password")).toLatin1().replace(':', ',') + '\n';
54  tmp.write(line);
55  }
56 
57  if (file.exists() && !file.remove()) {
58  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to remove auth file for replacement";
59  return;
60  }
61 
62  if (!tmp.rename(m_filename)) {
63  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to rename temporary file";
64  }
65 }
66 
68 {
69  Q_UNUSED(c);
71  const QString username = userInfo.value(QStringLiteral("username"));
72 
73  QFile file(m_filename);
74  if (file.open(QFile::ReadOnly | QFile::Text)) {
75  while (!file.atEnd()) {
76  QByteArray line = file.readLine();
77  QByteArrayList parts = line.trimmed().split(':');
78  if (parts.size() >= 2 && !parts.first().startsWith('#') && parts.first() == username.toLatin1()) {
79  ret.insert(QStringLiteral("username"), username);
80  ret.setId(username);
81  QByteArray password = parts.at(1);
82  ret.insert(QStringLiteral("password"), QString::fromLatin1(password.replace(',', ':')));
83  break;
84  }
85  }
86  }
87  return ret;
88 }
89 
91 {
92  Q_UNUSED(c);
93  return user.id();
94 }
95 
97 {
98  return findUser(c, {
99  {QStringLiteral("username"), frozenUser.toString()}
100  });
101 }
102 
103 #include "moc_htpasswd.cpp"
void setId(const QVariant &id)
Sets the unique user id restored from the store.
void addUser(const ParamsMultiMap &user)
Definition: htpasswd.cpp:26
QList< QByteArray > split(char sep) const const
QByteArray trimmed() const const
bool remove()
const T & at(int i) const const
bool rename(const QString &newName)
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:96
virtual QVariant forSession(Context *c, const AuthenticationUser &user) final
Definition: htpasswd.cpp:90
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:67
qint64 readLine(char *data, qint64 maxSize)
const T value(const Key &key, const T &defaultValue) const const