#include "namereplace.h"
#include <QString>
#include <QRegularExpression>
#include <QFile>
#include <QTextStream>
#include <QDebug>
#include <QProcess>
#define SOURCE_FILE "/opt/openslx/lightdm/login-regexp"
#define LOOKUP_PROCESS "/opt/openslx/pam/get_username"
static QList< QPair< QRegularExpression, QString > > list;
static inline int find(QChar c, int start, const QString& line)
{
do {
int next = line.indexOf(c, start);
if (next == -1)
return -1;
if (line.at(next - 1) != '\\')
return next;
start = next + 1;
} while (true);
}
void NameReplace::loadSubs()
{
int idx = 0;
QFile inputFile(SOURCE_FILE);
if (!inputFile.open(QIODevice::ReadOnly))
return;
QTextStream in(&inputFile);
in.setCodec("UTF-8");
while (!in.atEnd()) {
QString line = in.readLine();
idx++;
if (line.isEmpty())
continue;
QChar delim = line.at(0);
int first = find(delim, 1, line);
if (first == -1)
continue;
int second = find(delim, first + 1, line);
if (second == -1)
continue;
QString regex = line.mid(1, first - 1).replace(QString("\\") + delim, QString(delim));
QString replace = line.mid(first + 1, second - first - 1).replace(QString("\\") + delim, QString(delim));
QString flags = line.mid(second + 1);
// ...
QRegularExpression::PatternOptions opts = QRegularExpression::NoPatternOption;
if (flags.contains("i")) {
opts |= QRegularExpression::CaseInsensitiveOption;
}
QRegularExpression re(regex, opts);
if (!re.isValid()) {
qWarning() << "Invalid regex:" << regex << "on line" << idx;
continue;
}
list.append(QPair<QRegularExpression, QString>(re, replace));
}
inputFile.close();
}
void NameReplace::replace(QString& input)
{
if (!list.isEmpty()) {
// First, apply user defined replacement
for (auto &brumm : list) {
input = input.replace(brumm.first, brumm.second);
}
}
// Now, prefix names that start with a digit, since systemd/logind refuses
// to work with those in more recent versions. It was never a good idea to
// do this anyways, but now we don't have a choice, since sessions without
// a proper systemd user instance will become more and more broken in the
// future.
if (*input.constData() >= '0' && *input.constData() <= '9') {
input = QLatin1String("_x_") + input;
}
// Finally, look up the proper casing of the desired username, as some
// servers (AD) are case insensitive, which can lead to problems if what the
// user entered doesn't exactly match what it's actually spelled like
// server-side.
QProcess getCaps;
getCaps.start(LOOKUP_PROCESS, QStringList(input));
getCaps.waitForFinished(8000);
QString output = QString::fromLocal8Bit(getCaps.readAllStandardOutput());
int idx = output.indexOf('\n');
if (idx != -1) {
output = output.left(idx);
}
if (output.length() == input.length()) {
input = output;
} else {
qDebug() << "Not replacing" << input << "by" << output;
}
}