/***************************************************************************
- * Copyright (C) 2005-2015 by the Quassel Project *
+ * Copyright (C) 2005-2016 by the Quassel Project *
* devel@quassel-irc.org *
* *
* This program is free software; you can redistribute it and/or modify *
}
+QString SqliteStorage::backendId() const
+{
+ return QString("SQLite");
+}
+
+
QString SqliteStorage::displayName() const
{
+ // Note: Pre-0.13 clients use the displayName property for backend idenfication
// We identify the backend to use for the monolithic core by its displayname.
// so only change this string if you _really_ have to and make sure the core
// setup for the mono client still works ;)
- return QString("SQLite");
+ return backendId();
}
}
-UserId SqliteStorage::addUser(const QString &user, const QString &password)
+UserId SqliteStorage::addUser(const QString &user, const QString &password, const QString &authenticator)
{
QSqlDatabase db = logDb();
UserId uid;
QSqlQuery query(db);
query.prepare(queryString("insert_quasseluser"));
query.bindValue(":username", user);
- query.bindValue(":password", cryptedPassword(password));
+ query.bindValue(":password", hashPassword(password));
+ query.bindValue(":hashversion", Storage::HashVersion::Latest);
+ query.bindValue(":authenticator", authenticator);
lockForWrite();
safeExec(query);
if (query.lastError().isValid() && query.lastError().number() == 19) { // user already exists - sadly 19 seems to be the general constraint violation error...
QSqlQuery query(db);
query.prepare(queryString("update_userpassword"));
query.bindValue(":userid", user.toInt());
- query.bindValue(":password", cryptedPassword(password));
+ query.bindValue(":password", hashPassword(password));
+ query.bindValue(":hashversion", Storage::HashVersion::Latest);
lockForWrite();
safeExec(query);
success = query.numRowsAffected() != 0;
UserId SqliteStorage::validateUser(const QString &user, const QString &password)
{
UserId userId;
+ QString hashedPassword;
+ Storage::HashVersion hashVersion = Storage::HashVersion::Latest;
{
QSqlQuery query(logDb());
query.prepare(queryString("select_authuser"));
query.bindValue(":username", user);
- query.bindValue(":password", cryptedPassword(password));
lockForRead();
safeExec(query);
if (query.first()) {
userId = query.value(0).toInt();
+ hashedPassword = query.value(1).toString();
+ hashVersion = static_cast<Storage::HashVersion>(query.value(2).toInt());
}
}
unlock();
- return userId;
+ UserId returnUserId;
+ if (userId != 0 && checkHashedPassword(userId, password, hashedPassword, hashVersion)) {
+ returnUserId = userId;
+ }
+ return returnUserId;
}
return userId;
}
+QString SqliteStorage::getUserAuthenticator(const UserId userid)
+{
+ QString authenticator = QString("");
+
+ {
+ QSqlQuery query(logDb());
+ query.prepare(queryString("select_authenticator"));
+ query.bindValue(":userid", userid.toInt());
+
+ lockForRead();
+ safeExec(query);
+
+ if (query.first()) {
+ authenticator = query.value(0).toString();
+ }
+ }
+ unlock();
+
+ return authenticator;
+}
UserId SqliteStorage::internalUser()
{
query.bindValue(":autoreconnectretries", info.autoReconnectRetries);
query.bindValue(":unlimitedconnectretries", info.unlimitedReconnectRetries ? 1 : 0);
query.bindValue(":rejoinchannels", info.rejoinChannels ? 1 : 0);
+ // Custom rate limiting
+ query.bindValue(":usecustomessagerate", info.useCustomMessageRate ? 1 : 0);
+ query.bindValue(":messagerateburstsize", info.messageRateBurstSize);
+ query.bindValue(":messageratedelay", info.messageRateDelay);
+ query.bindValue(":unlimitedmessagerate", info.unlimitedMessageRate ? 1 : 0);
if (info.networkId.isValid())
query.bindValue(":networkid", info.networkId.toInt());
}
query.bindValue(":proxyport", server.proxyPort);
query.bindValue(":proxyuser", server.proxyUser);
query.bindValue(":proxypass", server.proxyPass);
+ query.bindValue(":sslverify", server.sslVerify ? 1 : 0);
}
net.useSasl = networksQuery.value(16).toInt() == 1 ? true : false;
net.saslAccount = networksQuery.value(17).toString();
net.saslPassword = networksQuery.value(18).toString();
+ // Custom rate limiting
+ net.useCustomMessageRate = networksQuery.value(19).toInt() == 1 ? true : false;
+ net.messageRateBurstSize = networksQuery.value(20).toUInt();
+ net.messageRateDelay = networksQuery.value(21).toUInt();
+ net.unlimitedMessageRate = networksQuery.value(22).toInt() == 1 ? true : false;
serversQuery.bindValue(":networkid", net.networkId.toInt());
safeExec(serversQuery);
server.proxyPort = serversQuery.value(8).toUInt();
server.proxyUser = serversQuery.value(9).toString();
server.proxyPass = serversQuery.value(10).toString();
+ server.sslVerify = serversQuery.value(11).toInt() == 1 ? true : false;
servers << server;
}
net.serverList = servers;
QSqlQuery query(db);
query.prepare(queryString("update_buffer_persistent_channel"));
query.bindValue(":userid", user.toInt());
- query.bindValue(":networkId", networkId.toInt());
+ query.bindValue(":networkid", networkId.toInt());
query.bindValue(":buffercname", channel.toLower());
query.bindValue(":joined", isJoined ? 1 : 0);
QSqlQuery query(db);
query.prepare(queryString("update_buffer_set_channel_key"));
query.bindValue(":userid", user.toInt());
- query.bindValue(":networkId", networkId.toInt());
+ query.bindValue(":networkid", networkId.toInt());
query.bindValue(":buffercname", channel.toLower());
query.bindValue(":key", key);
return markerLineHash;
}
+void SqliteStorage::setBufferActivity(UserId user, BufferId bufferId, Message::Types bufferActivity)
+{
+ QSqlDatabase db = logDb();
+ db.transaction();
+
+ {
+ QSqlQuery query(db);
+ query.prepare(queryString("update_buffer_bufferactivity"));
+ query.bindValue(":userid", user.toInt());
+ query.bindValue(":bufferid", bufferId.toInt());
+ query.bindValue(":bufferactivity", (int) bufferActivity);
+
+ lockForWrite();
+ safeExec(query);
+ watchQuery(query);
+ }
+ db.commit();
+ unlock();
+}
+
+
+QHash<BufferId, Message::Types> SqliteStorage::bufferActivities(UserId user)
+{
+ QHash<BufferId, Message::Types> bufferActivityHash;
+
+ QSqlDatabase db = logDb();
+ db.transaction();
+
+ bool error = false;
+ {
+ QSqlQuery query(db);
+ query.prepare(queryString("select_buffer_bufferactivities"));
+ query.bindValue(":userid", user.toInt());
+
+ lockForRead();
+ safeExec(query);
+ error = !watchQuery(query);
+ if (!error) {
+ while (query.next()) {
+ bufferActivityHash[query.value(0).toInt()] = Message::Types(query.value(1).toInt());
+ }
+ }
+ }
+
+ db.commit();
+ unlock();
+ return bufferActivityHash;
+}
+
+
+Message::Types SqliteStorage::bufferActivity(BufferId bufferId, MsgId lastSeenMsgId)
+{
+ QSqlDatabase db = logDb();
+ db.transaction();
+
+ Message::Types result = Message::Types(0);
+ {
+ QSqlQuery query(db);
+ query.prepare(queryString("select_buffer_bufferactivity"));
+ query.bindValue(":bufferid", bufferId.toInt());
+ query.bindValue(":lastseenmsgid", lastSeenMsgId.toInt());
+
+ lockForRead();
+ safeExec(query);
+ if (query.first())
+ result = Message::Types(query.value(0).toInt());
+ }
+
+ db.commit();
+ unlock();
+ return result;
+}
bool SqliteStorage::logMessage(Message &msg)
{
logMessageQuery.bindValue(":type", msg.type());
logMessageQuery.bindValue(":flags", (int)msg.flags());
logMessageQuery.bindValue(":sender", msg.sender());
+ logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes());
logMessageQuery.bindValue(":message", msg.contents());
lockForWrite();
logMessageQuery.bindValue(":type", msg.type());
logMessageQuery.bindValue(":flags", (int)msg.flags());
logMessageQuery.bindValue(":sender", msg.sender());
+ logMessageQuery.bindValue(":senderprefixes", msg.senderPrefixes());
logMessageQuery.bindValue(":message", msg.contents());
safeExec(logMessageQuery);
query.bindValue(":firstmsg", first.toInt());
}
else {
- query.prepare(queryString("select_messages"));
+ query.prepare(queryString("select_messagesRange"));
query.bindValue(":lastmsg", last.toInt());
query.bindValue(":firstmsg", first.toInt());
}
Message msg(QDateTime::fromTime_t(query.value(1).toInt()),
bufferInfo,
(Message::Type)query.value(2).toUInt(),
- query.value(5).toString(),
+ query.value(6).toString(),
query.value(4).toString(),
+ query.value(5).toString(),
(Message::Flags)query.value(3).toUInt());
msg.setMsgId(query.value(0).toInt());
messagelist << msg;
Message msg(QDateTime::fromTime_t(query.value(2).toInt()),
bufferInfoHash[query.value(1).toInt()],
(Message::Type)query.value(3).toUInt(),
- query.value(6).toString(),
+ query.value(7).toString(),
query.value(5).toString(),
+ query.value(6).toString(),
(Message::Flags)query.value(4).toUInt());
msg.setMsgId(query.value(0).toInt());
messagelist << msg;
switch (query.lastError().number()) {
case 5: // SQLITE_BUSY 5 /* The database file is locked */
+ [[fallthrough]];
case 6: // SQLITE_LOCKED 6 /* A table in the database is locked */
if (retryCount < _maxRetryCount)
return safeExec(query, retryCount + 1);
+ break;
default:
- return false;
+ ;
}
+ return false;
}
user.id = value(0).toInt();
user.username = value(1).toString();
user.password = value(2).toString();
+ user.hashversion = value(3).toInt();
+ user.authenticator = value(4).toString();
return true;
}
network.usesasl = value(22).toInt() == 1 ? true : false;
network.saslaccount = value(23).toString();
network.saslpassword = value(24).toString();
+ // Custom rate limiting
+ network.usecustommessagerate = value(25).toInt() == 1 ? true : false;
+ network.messagerateburstsize = value(26).toInt();
+ network.messageratedelay = value(27).toUInt();
+ network.unlimitedmessagerate = value(28).toInt() == 1 ? true : false;
return true;
}
buffer.buffername = value(4).toString();
buffer.buffercname = value(5).toString();
buffer.buffertype = value(6).toInt();
- buffer.lastseenmsgid = value(7).toInt();
- buffer.markerlinemsgid = value(8).toInt();
- buffer.key = value(9).toString();
- buffer.joined = value(10).toInt() == 1 ? true : false;
+ buffer.lastmsgid = value(7).toInt();
+ buffer.lastseenmsgid = value(8).toInt();
+ buffer.markerlinemsgid = value(9).toInt();
+ buffer.bufferactivity = value(10).toInt();
+ buffer.key = value(11).toString();
+ buffer.joined = value(12).toInt() == 1 ? true : false;
return true;
}
backlog.type = value(3).toInt();
backlog.flags = value(4).toInt();
backlog.senderid = value(5).toInt();
- backlog.message = value(6).toString();
+ backlog.senderprefixes = value(6).toString();
+ backlog.message = value(7).toString();
return true;
}
ircserver.proxyport = value(11).toInt();
ircserver.proxyuser = value(12).toString();
ircserver.proxypass = value(13).toString();
+ ircserver.sslverify = value(14).toInt() == 1 ? true : false;
return true;
}