now loads passwords for irc

This commit is contained in:
fourtf 2019-09-14 18:38:09 +02:00
parent b45a6eea22
commit d33a8b1b3a
11 changed files with 116 additions and 83 deletions

View file

@ -70,8 +70,6 @@ Application::Application(Settings &_settings, Paths &_paths)
this->fonts->fontChanged.connect( this->fonts->fontChanged.connect(
[this]() { this->windows->layoutChannelViews(); }); [this]() { this->windows->layoutChannelViews(); });
Irc::getInstance().load();
this->twitch.server = this->twitch2; this->twitch.server = this->twitch2;
this->twitch.pubsub = this->twitch2->pubsub; this->twitch.pubsub = this->twitch2->pubsub;
} }
@ -100,6 +98,7 @@ int Application::run(QApplication &qtApp)
assert(isAppInitialized); assert(isAppInitialized);
this->twitch.server->connect(); this->twitch.server->connect();
Irc::getInstance().load();
this->windows->getMainWindow().show(); this->windows->getMainWindow().show();

View file

@ -85,8 +85,8 @@ Credentials::Credentials()
{ {
} }
QString Credentials::get(const QString &provider, const QString &name_, void Credentials::get(const QString &provider, const QString &name_,
std::function<void(QString)> &&onLoaded) std::function<void(const QString &)> &&onLoaded)
{ {
assertInGuiThread(); assertInGuiThread();
@ -100,16 +100,15 @@ QString Credentials::get(const QString &provider, const QString &name_,
QObject::connect(job, &QKeychain::Job::finished, qApp, QObject::connect(job, &QKeychain::Job::finished, qApp,
[job, onLoaded = std::move(onLoaded)](auto) mutable { [job, onLoaded = std::move(onLoaded)](auto) mutable {
onLoaded(job->textData()); onLoaded(job->textData());
}); },
Qt::DirectConnection);
job->start(); job->start();
return job->textData();
} }
else else
{ {
auto &instance = insecureInstance(); auto &instance = insecureInstance();
return instance.object().find(name).value().toString(); onLoaded(instance.object().find(name).value().toString());
} }
} }

View file

@ -10,8 +10,8 @@ class Credentials
public: public:
static Credentials &getInstance(); static Credentials &getInstance();
QString get(const QString &provider, const QString &name, void get(const QString &provider, const QString &name,
std::function<void(QString)> &&onLoaded); std::function<void(const QString &)> &&onLoaded);
void set(const QString &provider, const QString &name, void set(const QString &provider, const QString &name,
const QString &credential); const QString &credential);
void erase(const QString &provider, const QString &name); void erase(const QString &provider, const QString &name);

View file

@ -9,6 +9,7 @@
#include "util/StandardItemHelper.hpp" #include "util/StandardItemHelper.hpp"
#include <QSaveFile> #include <QSaveFile>
#include <QtConcurrent>
namespace chatterino { namespace chatterino {
@ -22,7 +23,7 @@ namespace {
{ {
public: public:
Model(QObject *parent) Model(QObject *parent)
: SignalVectorModel<IrcServerData>(8, parent) : SignalVectorModel<IrcServerData>(6, parent)
{ {
} }
@ -30,8 +31,6 @@ namespace {
IrcServerData getItemFromRow(std::vector<QStandardItem *> &row, IrcServerData getItemFromRow(std::vector<QStandardItem *> &row,
const IrcServerData &original) const IrcServerData &original)
{ {
qDebug() << row[2]->data(Qt::CheckStateRole).toBool();
return IrcServerData{ return IrcServerData{
row[0]->data(Qt::EditRole).toString(), // host row[0]->data(Qt::EditRole).toString(), // host
row[1]->data(Qt::EditRole).toInt(), // port row[1]->data(Qt::EditRole).toInt(), // port
@ -39,7 +38,8 @@ namespace {
row[3]->data(Qt::EditRole).toString(), // user row[3]->data(Qt::EditRole).toString(), // user
row[4]->data(Qt::EditRole).toString(), // nick row[4]->data(Qt::EditRole).toString(), // nick
row[5]->data(Qt::EditRole).toString(), // real row[5]->data(Qt::EditRole).toString(), // real
row[6]->data(Qt::EditRole).toString(), // password original.password, // password
original.connectCommands, // connectCommands
original.id, // id original.id, // id
}; };
} }
@ -54,30 +54,21 @@ namespace {
setStringItem(row[3], item.user); setStringItem(row[3], item.user);
setStringItem(row[4], item.nick); setStringItem(row[4], item.nick);
setStringItem(row[5], item.real); setStringItem(row[5], item.real);
setStringItem(row[6], item.password);
} }
}; };
} // namespace } // namespace
//inline QString escape(QString str) inline QString escape(QString str)
//{ {
// return str.replace(":", "::"); return str.replace(":", "::");
//} }
//inline QString getCredentialName(const IrcConnection_ &conn) // This returns a unique id for every server which is understandeable in the systems credential manager.
//{ inline QString getCredentialName(const IrcServerData &data)
// //return escape(conn.host) + escape(conn. {
//} return escape(QString::number(data.id)) + ":" + escape(data.user) + "@" +
escape(data.host);
//QString IrcConnection_::getPassword() }
//{
// return
//}
//void IrcConnection_::setPassword(const QString &str)
//{
// //Credentials::set("irc",
//}
Irc::Irc() Irc::Irc()
{ {
@ -85,6 +76,7 @@ Irc::Irc()
// make sure only one id can only exist for one server // make sure only one id can only exist for one server
assert(this->servers_.find(args.item.id) == this->servers_.end()); assert(this->servers_.find(args.item.id) == this->servers_.end());
// add new server
if (auto ab = this->abandonedChannels_.find(args.item.id); if (auto ab = this->abandonedChannels_.find(args.item.id);
ab != this->abandonedChannels_.end()) ab != this->abandonedChannels_.end())
{ {
@ -107,6 +99,10 @@ Irc::Irc()
this->servers_.emplace(args.item.id, this->servers_.emplace(args.item.id,
std::make_unique<IrcServer>(args.item)); std::make_unique<IrcServer>(args.item));
} }
// store password
Credentials::getInstance().set("irc", getCredentialName(args.item),
args.item.password);
}); });
this->connections.itemRemoved.connect([this](auto &&args) { this->connections.itemRemoved.connect([this](auto &&args) {
@ -125,6 +121,10 @@ Irc::Irc()
this->abandonedChannels_[args.item.id] = abandoned; this->abandonedChannels_[args.item.id] = abandoned;
this->servers_.erase(server); this->servers_.erase(server);
// delete password
Credentials::getInstance().erase("irc",
getCredentialName(args.item));
} }
}); });
@ -146,7 +146,11 @@ ChannelPtr Irc::getOrAddChannel(int id, QString name)
} }
else else
{ {
return Channel::getEmpty(); auto channel = std::make_shared<IrcChannel>(name, nullptr);
this->abandonedChannels_[id].push_back(channel);
return std::move(channel);
} }
} }
@ -187,7 +191,8 @@ void Irc::save()
obj.insert("username", conn.user); obj.insert("username", conn.user);
obj.insert("nickname", conn.nick); obj.insert("nickname", conn.nick);
obj.insert("realname", conn.real); obj.insert("realname", conn.real);
//obj.insert("password", conn.password); obj.insert("connectCommands",
QJsonArray::fromStringList(conn.connectCommands));
obj.insert("id", conn.id); obj.insert("id", conn.id);
servers.append(obj); servers.append(obj);
} }
@ -210,29 +215,36 @@ void Irc::load()
QString config = configPath(); QString config = configPath();
QFile file(configPath()); QFile file(configPath());
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
auto doc = QJsonDocument::fromJson(file.readAll()); auto object = QJsonDocument::fromJson(file.readAll()).object();
auto object = doc.object(); // load servers
std::unordered_set<int> ids; for (auto server : object.value("servers").toArray())
for (auto server : doc.object().value("servers").toArray())
{ {
auto obj = server.toObject(); auto obj = server.toObject();
IrcServerData conn; IrcServerData data;
conn.host = obj.value("host").toString(conn.host); data.host = obj.value("host").toString(data.host);
conn.port = obj.value("port").toInt(conn.port); data.port = obj.value("port").toInt(data.port);
conn.ssl = obj.value("ssl").toBool(conn.ssl); data.ssl = obj.value("ssl").toBool(data.ssl);
conn.user = obj.value("username").toString(conn.user); data.user = obj.value("username").toString(data.user);
conn.nick = obj.value("nickname").toString(conn.nick); data.nick = obj.value("nickname").toString(data.nick);
conn.real = obj.value("realname").toString(conn.real); data.real = obj.value("realname").toString(data.real);
// conn.password = obj.value("password").toString(conn.password); data.connectCommands =
conn.id = obj.value("id").toInt(conn.id); obj.value("connectCommands").toVariant().toStringList();
data.id = obj.value("id").toInt(data.id);
// duplicate id's are not allowed :( // duplicate id's are not allowed :(
if (ids.find(conn.id) == ids.end()) if (this->abandonedChannels_.find(data.id) ==
this->abandonedChannels_.end())
{ {
this->connections.appendItem(conn); // insert element
ids.insert(conn.id); this->abandonedChannels_[data.id];
Credentials::getInstance().get(
"irc", getCredentialName(data),
[=](const QString &password) mutable {
data.password = password;
this->connections.appendItem(data);
});
} }
} }
} }

View file

@ -23,6 +23,7 @@ struct IrcServerData {
// IrcAuthType authType = Anonymous; // IrcAuthType authType = Anonymous;
QString password; QString password;
QStringList connectCommands;
int id; int id;
}; };
@ -44,9 +45,6 @@ public:
int uniqueId(); int uniqueId();
signals:
void connectionUpdated(int id);
private: private:
int currentId_{}; int currentId_{};
bool loaded_{}; bool loaded_{};

View file

@ -14,6 +14,7 @@ public:
void sendMessage(const QString &message) override; void sendMessage(const QString &message) override;
// server may be nullptr
IrcServer *server(); IrcServer *server();
private: private:

View file

@ -80,6 +80,11 @@ void IrcServer::onReadConnected(IrcConnection *connection)
std::lock_guard lock(this->channelMutex); std::lock_guard lock(this->channelMutex);
for (auto &&command : this->data_->connectCommands)
{
connection->sendRaw(command + "\r\n");
}
for (auto &&weak : this->channels) for (auto &&weak : this->channels)
{ {
if (auto channel = weak.lock()) if (auto channel = weak.lock())

View file

@ -621,7 +621,10 @@ void WindowManager::encodeChannel(IndirectChannel channel, QJsonObject &obj)
dynamic_cast<IrcChannel *>(channel.get().get())) dynamic_cast<IrcChannel *>(channel.get().get()))
{ {
obj.insert("type", "irc"); obj.insert("type", "irc");
obj.insert("server", ircChannel->server()->id()); if (ircChannel->server())
{
obj.insert("server", ircChannel->server()->id());
}
obj.insert("channel", ircChannel->getName()); obj.insert("channel", ircChannel->getName());
} }
} }

View file

@ -26,7 +26,13 @@ IrcConnectionEditor::IrcConnectionEditor(const IrcServerData &data, bool isAdd,
this->ui_->userNameLineEdit->setText(data.user); this->ui_->userNameLineEdit->setText(data.user);
this->ui_->nickNameLineEdit->setText(data.nick); this->ui_->nickNameLineEdit->setText(data.nick);
this->ui_->realNameLineEdit->setText(data.real); this->ui_->realNameLineEdit->setText(data.real);
this->ui_->connectCommandsEditor->setPlainText(
data.connectCommands.join('\n'));
this->ui_->passwordLineEdit->setText(data.password); this->ui_->passwordLineEdit->setText(data.password);
QFont font("Monospace");
font.setStyleHint(QFont::TypeWriter);
this->ui_->connectCommandsEditor->setFont(font);
} // namespace chatterino } // namespace chatterino
IrcConnectionEditor::~IrcConnectionEditor() IrcConnectionEditor::~IrcConnectionEditor()
@ -43,6 +49,8 @@ IrcServerData IrcConnectionEditor::data()
data.user = this->ui_->userNameLineEdit->text(); data.user = this->ui_->userNameLineEdit->text();
data.nick = this->ui_->nickNameLineEdit->text(); data.nick = this->ui_->nickNameLineEdit->text();
data.real = this->ui_->realNameLineEdit->text(); data.real = this->ui_->realNameLineEdit->text();
data.connectCommands =
this->ui_->connectCommandsEditor->toPlainText().split('\n');
data.password = this->ui_->passwordLineEdit->text(); data.password = this->ui_->passwordLineEdit->text();
return data; return data;
} }

View file

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>264</width> <width>264</width>
<height>350</height> <height>414</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -155,21 +155,38 @@
</item> </item>
</widget> </widget>
</item> </item>
<item row="10" column="0">
<widget class="QLabel" name="connectCommandsLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Send IRC commands&lt;/p&gt;&lt;p&gt;on connect:&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QPlainTextEdit" name="connectCommandsEditor">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="11" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout> </layout>
</item> </item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item> <item>
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">

View file

@ -130,7 +130,7 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
// irc // irc
{ {
LayoutCreator<QWidget> obj(new QWidget()); LayoutCreator<QWidget> obj(new QWidget());
auto outerBox = obj.setLayoutType<QVBoxLayout>(); auto outerBox = obj.setLayoutType<QFormLayout>();
// outerBox.emplace<QLabel>("Connection:"); // outerBox.emplace<QLabel>("Connection:");
{ {
@ -140,16 +140,11 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
view->setTitles({"host", "port", "ssl", "user", "nick", "real", view->setTitles({"host", "port", "ssl", "user", "nick", "real",
"password", "login command"}); "password", "login command"});
view->getTableView()->horizontalHeader()->resizeSection(0, 140); view->getTableView()->horizontalHeader()->resizeSection(0, 140);
view->getTableView()->horizontalHeader()->resizeSection(1, 40);
view->getTableView()->horizontalHeader()->resizeSection(2, 30);
//view->getTableView()->horizontalHeader()->setVisible(false);
view->getTableView()->horizontalHeader()->setSectionHidden(1, true); view->getTableView()->horizontalHeader()->setSectionHidden(1, true);
view->getTableView()->horizontalHeader()->setSectionHidden(2, true); view->getTableView()->horizontalHeader()->setSectionHidden(2, true);
view->getTableView()->horizontalHeader()->setSectionHidden(4, true); view->getTableView()->horizontalHeader()->setSectionHidden(4, true);
view->getTableView()->horizontalHeader()->setSectionHidden(5, true); view->getTableView()->horizontalHeader()->setSectionHidden(5, true);
view->getTableView()->horizontalHeader()->setSectionHidden(6, true);
view->getTableView()->horizontalHeader()->setSectionHidden(7, true);
view->addButtonPressed.connect([] { view->addButtonPressed.connect([] {
auto unique = IrcServerData{}; auto unique = IrcServerData{};
@ -158,7 +153,7 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
auto editor = new IrcConnectionEditor(unique); auto editor = new IrcConnectionEditor(unique);
if (editor->exec() == QDialog::Accepted) if (editor->exec() == QDialog::Accepted)
{ {
Irc::getInstance().connections.appendItem(unique); Irc::getInstance().connections.appendItem(editor->data());
} }
}); });
@ -188,14 +183,10 @@ SelectChannelDialog::SelectChannelDialog(QWidget *parent)
} }
}); });
outerBox->addWidget(view); outerBox->addRow("Server:", view);
} }
{ outerBox->addRow("Channel:", this->ui_.irc.channel = new QLineEdit);
auto box = outerBox.emplace<QHBoxLayout>().withoutMargin();
box.emplace<QLabel>("Channel:");
this->ui_.irc.channel = box.emplace<QLineEdit>().getElement();
}
auto tab = notebook->addPage(obj.getElement()); auto tab = notebook->addPage(obj.getElement());
tab->setCustomTitle("Irc"); tab->setCustomTitle("Irc");