Cutelyst  1.11.0
htpasswd.cpp
1 /*
2  * Copyright (C) 2014-2017 Daniel Nicoletti <dantti12@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #include "htpasswd.h"
19 
20 #include <QFile>
21 #include <QTemporaryFile>
22 #include <QLoggingCategory>
23 
24 #include "common.h"
25 
26 using namespace Cutelyst;
27 
28 StoreHtpasswd::StoreHtpasswd(const QString &name, QObject *parent) : AuthenticationStore(parent)
29 {
30  setProperty("_file", name);
31 }
32 
33 StoreHtpasswd::~StoreHtpasswd()
34 {
35 
36 }
37 
39 {
40  QString username = user.value(QStringLiteral("username"));
41 
42  QString fileName = property("_file").toString();
43  QTemporaryFile tmp(fileName + QLatin1String("-XXXXXXX"));
44  tmp.setAutoRemove(false); // sort of a backup
45  if (!tmp.open()) {
46  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to open temporary file for writing";
47  return;
48  }
49 
50  bool wrote = false;
51  QFile file(fileName);
52  if (file.exists() && file.open(QFile::ReadWrite | QFile::Text)) {
53  while (!file.atEnd()) {
54  QByteArray line = file.readLine();
55  QByteArrayList parts = line.split(':');
56  if (!wrote && parts.size() >= 2 && parts.first() == username.toLatin1()) {
57  line = username.toLatin1() + ':' + user.value(QStringLiteral("password")).toLatin1().replace(':', ',') + '\n';
58  wrote = true;
59  }
60  tmp.write(line);
61  }
62  file.close();
63  }
64 
65  if (!wrote) {
66  QByteArray line = username.toLatin1() + ':' + user.value(QStringLiteral("password")).toLatin1() + '\n';
67  tmp.write(line);
68  }
69 
70  if (file.exists() && !file.remove()) {
71  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to remove auth file for replacement";
72  return;
73  }
74 
75  if (!tmp.rename(fileName)) {
76  qCWarning(CUTELYST_UTILS_AUTH) << "Failed to rename temporary file";
77  }
78 }
79 
81 {
83  QString username = userInfo.value(QStringLiteral("username"));
84 
85  QString fileName = property("_file").toString();
86  QFile file(fileName);
87  if (file.open(QFile::ReadOnly | QFile::Text)) {
88  while (!file.atEnd()) {
89  QByteArray line = file.readLine();
90  QByteArrayList parts = line.trimmed().split(':');
91  if (parts.size() >= 2 && !parts.first().startsWith('#') && parts.first() == username.toLatin1()) {
92  ret.insert(QStringLiteral("username"), username);
93  ret.setId(username);
94  QByteArray password = parts.at(1);
95  ret.insert(QStringLiteral("password"), QString::fromLatin1(password.replace(',', ':')));
96  break;
97  // TODO maybe support additional fields
98  }
99  }
100  }
101  return ret;
102 }
103 
105 {
106  return user.id();
107 }
108 
110 {
111  return findUser(c, {
112  {QStringLiteral("username"), frozenUser.toString()}
113  });
114 }
115 
116 #include "moc_htpasswd.cpp"
QMap< QString, QString > ParamsMultiMap
void addUser(const ParamsMultiMap &user)
Definition: htpasswd.cpp:38
The Cutelyst Context.
Definition: context.h:50
virtual AuthenticationUser fromSession(Context *c, const QVariant &frozenUser) final
Definition: htpasswd.cpp:109
virtual QVariant forSession(Context *c, const AuthenticationUser &user) final
Definition: htpasswd.cpp:104
The Cutelyst namespace holds all public Cutelyst API.
Definition: Mainpage.dox:7
StoreHtpasswd(const QString &name, QObject *parent=nullptr)
Definition: htpasswd.cpp:28
void setId(const QString &id)
Sets the unique user id restored from the store.
virtual AuthenticationUser findUser(Context *c, const ParamsMultiMap &userInfo) final
Definition: htpasswd.cpp:80