Commit e2720e60 authored by armin's avatar armin
Browse files

Merge branch 'master' into clearIosCookies

parents ef4a78b6 390545a3
......@@ -274,13 +274,13 @@ CONFIG(release, debug|release) {
CONFIG += qt release
DEFINES += QT_NO_DEBUG_OUTPUT
DEFINES += QT_NO_DEBUG
CONFIG += ltcg
# compiler options: O3 optimize
linux:!android{
CONFIG += ltcg
QMAKE_CXXFLAGS += -Ofast -flto -funroll-loops -fno-signed-zeros -fno-trapping-math
}
android:{
QMAKE_CXXFLAGS += -Ofast -flto -funroll-loops -fno-signed-zeros -fno-trapping-math
QMAKE_CXXFLAGS += -Ofast -funroll-loops -fno-signed-zeros -fno-trapping-math
}
ios:{
QMAKE_CXXFLAGS += -O3
......
This diff is collapsed.
......@@ -5,6 +5,7 @@
#include <QObject>
#include <QMetaObject>
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlQuery>
#include <QFile>
#include <QMimeDatabase>
#include <QMimeType>
......@@ -48,6 +49,7 @@ class PersistanceLayer : public QObject
void addCustomEmoji( const QString &pTag, const QString &pPath, const QString &pHtml, const QString &pCategory, const QString &pUnicode );
void addCustomEmoji( const QString &pTag, const QString &pPath, const QString &pHtml, const QString &pCategory, const QString &pUnicode, int pOrder );
void addUserToBlockList( const QString &pUserId, const QString &pUsername );
void close();
public:
......@@ -83,7 +85,7 @@ class PersistanceLayer : public QObject
void removeFileCacheEntry( const QString &pUrl, const QString &pPath );
void transaction( void );
void commit( void );
void askForcommit( void );
void wipeDb( void );
bool transactionActive = false;
......@@ -91,19 +93,54 @@ class PersistanceLayer : public QObject
~PersistanceLayer();
void init();
void close();
bool mDbReady = false;
private:
void commit( void );
PersistanceLayer() {}
QSqlDatabase mDb{ QSqlDatabase::addDatabase( "QSQLITE" )};
QMimeDatabase mMimeDb;
QTimer commitTimer;
QMutex commitMutex;
void initShema();
void initQueries();
void upgradeSchema();
int mCommitCounter = 0;
int mTransactionCounter = 0;
QSqlQuery querySetUsername;
QSqlQuery querySetPassword;
QSqlQuery querySetToken;
QSqlQuery querySetUser;
QSqlQuery querySetUserId;
QSqlQuery querySetChannel;
QSqlQuery querySetSetting;
QSqlQuery queryAddChannel;
QSqlQuery queryDeleteChannel;
QSqlQuery queryDeleteMessagesFromChannel;
QSqlQuery queryAddMessage;
QSqlQuery queryAddCacheEntry;
QSqlQuery queryAddEmoji;
QSqlQuery queryAddUser;
QSqlQuery queryGetMessageByRid;
QSqlQuery queryGetName;
QSqlQuery queryGetCurrentChannel;
QSqlQuery queryGetPass;
QSqlQuery queryGetToken;
QSqlQuery queryGetUserId;
QSqlQuery queryGetMessagesByRid;
QSqlQuery queryGetMessageByRidAndRange;
QSqlQuery queryGetMessagesByRidLimit;
QSqlQuery queryGetBlockedUsers;
QSqlQuery queryGetChannels;
QSqlQuery queryGetEmojies;
QSqlQuery queryGetFileCacheEntry;
QSqlQuery queryGetSetting;
QSqlQuery queryRemoveFileCacheEntry;
signals:
void userDataChanged();
......
......@@ -87,7 +87,7 @@ RocketChat::RocketChat( QGuiApplication *app )
#endif
qRegisterMetaType<ConnectionState>( "ConnectionState" );
qRegisterMetaType<Qt::ApplicationState>( "Qt::ApplicationState" );
qInstallMessageHandler( customOutput );
// qInstallMessageHandler( customOutput );
}
RocketChat::~RocketChat()
......@@ -98,15 +98,17 @@ RocketChat::~RocketChat()
mServerThread.quit();
} else {
for ( auto element : mServerMap ) {
connect( element, &RocketChatServerData::destroyed, [ = ]() {
connect( element, &RocketChatServerData::destroyed, [ & ]() {
destructCounter--;
if ( !destructCounter ) {
mServerThread.quit();
connect( PersistanceLayer::instance(), &PersistanceLayer::destroyed, [&]() {
mServerThread.quit();
} );
QMetaObject::invokeMethod( PersistanceLayer::instance(), "close" );
}
} );
element->deleteLater();
QMetaObject::invokeMethod( element, "deleteLater" );
}
}
......@@ -886,7 +888,11 @@ void RocketChat::onApplicationStateChanged( const Qt::ApplicationState &pState )
} else {
mInitialized = 1;
}
} else if ( ( ( pState == Qt::ApplicationInactive ) || pState == Qt::ApplicationSuspended ) && mServerStatus ) {
}
#if defined(Q_OS_ANDROID)||defined(Q_OS_IOS)
else if ( ( ( pState == Qt::ApplicationInactive ) || pState == Qt::ApplicationSuspended ) && mServerStatus ) {
qDebug() << "away";
if ( mNetworkConfiguration.isOnline() ) {
......@@ -897,6 +903,8 @@ void RocketChat::onApplicationStateChanged( const Qt::ApplicationState &pState )
}
}
}
#endif
}
bool RocketChat::getDdpConnectionEstablished() const
......
......@@ -68,7 +68,7 @@ void RocketChatServerData::initConnections()
}
}
mStorage->commit();
mStorage->askForcommit();
delete messages;
......@@ -80,6 +80,34 @@ void RocketChatServerData::initConnections()
protocol = QStringLiteral( "http://" );
}
if ( mRestApi != nullptr ) {
mRestApi->deleteLater();
}
if ( mFileService != nullptr ) {
delete mFileService;
}
if ( mEmojiService != nullptr ) {
delete mEmojiService;
}
if ( mDdpApi != nullptr ) {
mDdpApi->deleteLater();
}
if ( mChannels != nullptr ) {
mChannels->deleteLater();
}
if ( mMessageService != nullptr ) {
mMessageService->deleteLater();
}
if ( mChannelService != nullptr ) {
mChannelService->deleteLater();
}
setRestApi( new RestApi( this, protocol + mBaseUrl ) );
mFileService = new FileService( this );
mEmojiService = new EmojiService( this, mFileService, mStorage );
......@@ -132,14 +160,15 @@ void RocketChatServerData::initConnections()
QString userDb = mStorage->getUserName();
QDateTime currentTime = QDateTime::currentDateTime();
//TODO: needs more testing
if ( !tokenDb.first.isEmpty() && tokenDb.second > currentTime.toTime_t() ) {
loginWithToken( userDb, tokenDb.first );
} else {
mStorage->wipeDb();
wipeDbAndReconnect();
emit loggedOut( mServerId );
}
} else if ( !lastServer.isEmpty() ) {
mStorage->wipeDb();
wipeDbAndReconnect();
emit loggedOut( mServerId );
}
......@@ -582,6 +611,13 @@ void RocketChatServerData::offlineLogin()
}
}
void RocketChatServerData::wipeDbAndReconnect()
{
disconnectFromServer();
mStorage->wipeDb();
resume();
}
QSharedPointer<RocketChatUser> RocketChatServerData::getOwnUser() const
{
return mOwnUser;
......@@ -605,66 +641,62 @@ QString RocketChatServerData::getBaseUrl() const
void RocketChatServerData::login( const QString &pUsername, const QString &pPassword )
{
if ( pUsername != mStorage->getUserName() ) {
mStorage->wipeDb();
}
QString pass;
QPair<QString, uint> tokenDb = mStorage->getToken();
QString userDb = mStorage->getUserName();
QDateTime currentTime = QDateTime::currentDateTime();
if ( !tokenDb.first.isEmpty() && tokenDb.second > currentTime.toTime_t() ) {
loginWithToken( userDb, tokenDb.first );
} else {
QString passDb = mStorage->getPassword();
QString pass;
QString username = pUsername;
QByteArray hashArray = QCryptographicHash::hash( pPassword.toUtf8(), QCryptographicHash::Sha256 );
pass = hashArray.toHex();
if ( passDb.length() ) {
username = userDb;
pass = passDb;
} else {
QByteArray hashArray = QCryptographicHash::hash( pPassword.toUtf8(), QCryptographicHash::Sha256 );
pass = hashArray.toHex();
}
loginWithHash( username, pass );
}
loginWithHash( pUsername, pass );
}
void RocketChatServerData::loginWithHash( const QString &pUsername, const QString &pPswHash )
{
qDebug() << "login with hash";
auto self = this;
RestRequestCallback meCallBackSuccess = [ = ]( QNetworkReply *, QJsonObject data, RestApi * ) {
if ( data.contains( QStringLiteral( "username" ) ) ) {
mUsername = data[QStringLiteral( "username" )].toString();
mStorage->transaction();
mStorage->setUserData( mUsername, "" );
mStorage->setToken( mResumeToken, mTokenExpire );
mStorage->setUserId( mUserId );
mStorage->askForcommit();
onResume();
onDDPAuthenticated();
}
};
auto request = QSharedPointer<DDPLoginRequest>::create( pUsername, pPswHash );
DdpCallback success = [ self, pUsername, pPswHash, request ]( QJsonObject pResponse, MeteorDDP * ) {
DdpCallback success = [ = ]( QJsonObject pResponse, MeteorDDP * ) {
qDebug() << "authenticated";
if ( pResponse.contains( QStringLiteral( "result" ) ) ) {
QJsonObject result = pResponse[QStringLiteral( "result" )].toObject();
if ( result.contains( QStringLiteral( "token" ) ) && result.contains( QStringLiteral( "id" ) ) ) {
self->mConnectionState = ConnectionState::ONLINE;
self->mResumeToken = result[QStringLiteral( "token" )].toString();
mConnectionState = ConnectionState::ONLINE;
mResumeToken = result[QStringLiteral( "token" )].toString();
QJsonObject expireObject = result[QStringLiteral( "tokenExpires" )].toObject();
double expireDouble = expireObject[QStringLiteral( "$date" )].toDouble();
self->mTokenExpire = static_cast<uint>( expireDouble / 1000 );
mTokenExpire = static_cast<uint>( expireDouble / 1000 );
QString userId = result[QStringLiteral( "id" )].toString();
self->setUserId( userId );
self->mStorage->transaction();
self->mStorage->setUserData( pUsername, pPswHash );
self->mStorage->setToken( self->mResumeToken, self->mTokenExpire );
self->mStorage->setUserId( userId );
self->mRestApi->setToken( self->mResumeToken );
self->mRestApi->setUserId( userId );
self->mStorage->commit();
self->mDdpApi->setToken( self->mResumeToken );
self->mDdpApi->unsetResponseBinding( request->getFrame() );
self->onDDPAuthenticated();
emit( self->onHashLoggedIn( self->mServerId ) );
setUserId( userId );
mStorage->transaction();
mStorage->setUserData( pUsername, pPswHash );
mRestApi->setToken( mResumeToken );
mRestApi->setUserId( userId );
mStorage->askForcommit();
mDdpApi->setToken( mResumeToken );
mDdpApi->unsetResponseBinding( request->getFrame() );
RestApiRequest meRequest
= RestApiRequest( new restMeRequest( meCallBackSuccess ) );
mRestApi->sendRequest( meRequest );
}
}
};
......@@ -842,7 +874,7 @@ void RocketChatServerData::loginWithOpenIDToken( const QString &pToken, const QS
self->mStorage->setUserData( self->mUsername, "" );
self->mStorage->setToken( self->mResumeToken, self->mTokenExpire );
self->mStorage->setUserId( self->mUserId );
self->mStorage->commit();
self->mStorage->askForcommit();
self->onResume();
self->onDDPAuthenticated();
}
......@@ -981,11 +1013,20 @@ void RocketChatServerData::handleChannelMessage( const QJsonObject &pMessage )
if ( firstArg == QStringLiteral( "insert" ) || firstArg == QStringLiteral( "inserted" ) ) {
QJsonObject newChannel = args[1].toObject();
if ( newChannel.contains( QStringLiteral( "name" ) ) && newChannel.contains( QStringLiteral( "rid" ) ) && newChannel.contains( "t" ) ) {
if ( newChannel.contains( QStringLiteral( "name" ) ) && ( newChannel.contains( QStringLiteral( "rid" ) ) || newChannel.contains( QStringLiteral( "_id" ) ) ) && newChannel.contains( "t" ) ) {
QString name = newChannel[QStringLiteral( "name" )].toString();
QString rid = newChannel[QStringLiteral( "rid" )].toString();
QString rid;
if ( !mChannels->contains( QStringLiteral( "id" ) ) ) {
if ( newChannel.contains( "rid" ) ) {
rid = newChannel[QStringLiteral( "rid" )].toString();
} else if ( newChannel.contains( QStringLiteral( "_id" ) ) ) {
rid = newChannel[QStringLiteral( "_id" )].toString();
} else {
qWarning() << "invalid channel inserted message";
return ;
}
if ( !mChannels->contains( rid ) ) {
auto channel = mChannelService->createChannelObject( rid, name, newChannel["t"].toString() );
if ( !channel.isNull() ) {
......@@ -1001,7 +1042,17 @@ void RocketChatServerData::handleChannelMessage( const QJsonObject &pMessage )
} else if ( firstArg == QStringLiteral( "updated" ) ) {
QJsonObject data = args[1].toObject();
int unread = data[QStringLiteral( "unread" )].toInt();
QString rid = data[QStringLiteral( "rid" )].toString();
QString rid;
if ( data.contains( "rid" ) ) {
rid = data[QStringLiteral( "rid" )].toString();
} else if ( data.contains( QStringLiteral( "_id" ) ) ) {
rid = data[QStringLiteral( "_id" )].toString();
} else {
qWarning() << "invalid channel update message";
return ;
}
QString type = data[QStringLiteral( "t" )].toString();
bool blocked = false;
QString name = data[QStringLiteral( "name" )].toString();
......@@ -1668,7 +1719,7 @@ void RocketChatServerData::getCustomEmojis()
Q_ASSERT( result );
}
mStorage->commit();
mStorage->askForcommit();
}
if ( !mCustomEmojisReady ) {
......
......@@ -221,7 +221,7 @@ class RocketChatServerData : public MessageListener
void getCustomEmojis();
RestApi *getRestApi() const;
ChannelRepository *getChannels() const;
RocketChatChannelService *mChannelService;
RocketChatChannelService *mChannelService = nullptr;
void handleChannelMessage( const QJsonObject &pMessage );
uint diffToLastDDPPing();
void sendUnsentMessages( void );
......@@ -244,6 +244,8 @@ class RocketChatServerData : public MessageListener
void offlineLogin();
void wipeDbAndReconnect();
protected:
RocketChatServerData();
......@@ -278,11 +280,11 @@ class RocketChatServerData : public MessageListener
QMap<QString, FileUploader *> mFileUploads;
QString mCurrentChannel;
QMutex mUnsentMutex;
UserModel *userModel;
LoginMethodsModel *loginMethodsModel;
ChannelModel *channelsModel;
ChannelModel *directModel;
ChannelModel *groupsModel;
UserModel *userModel = nullptr;
LoginMethodsModel *loginMethodsModel = nullptr;
ChannelModel *channelsModel = nullptr;
ChannelModel *directModel = nullptr;
ChannelModel *groupsModel = nullptr;
std::function<void ( QMultiMap<QString, QSharedPointer<RocketChatMessage>> *messages )> historyLoaded;
QString mPendingSwitchRoomRequest;
QString mPendingSwitchRoomRequestType;
......
......@@ -70,7 +70,7 @@ void SegfaultHandler::segfaultHandlerMethod( int pSigno )
PersistanceLayer *storage = PersistanceLayer::instance();
storage->transaction();
storage->setSetting( "ERROR", errorString );
storage->commit();
storage->askForcommit();
#if defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) || defined(Q_OS_LINUX) ||defined(Q_OS_IOS)
qDebug() << "currThread:" << QThread::currentThreadId();
......
......@@ -103,7 +103,7 @@ void MessageService::persistMessages( const MessageList &pMessage )
}
};
mPersistanceLayer->commit();
mPersistanceLayer->askForcommit();
}
QSharedPointer<RocketChatMessage> MessageService::parseMessage( const QJsonObject &pMessageData,
......
......@@ -188,7 +188,7 @@ QVector<QSharedPointer<RocketChatChannel> > RocketChatChannelService::processCha
}
}
mStorage->commit();
mStorage->askForcommit();
return vec;
......@@ -472,7 +472,7 @@ void RocketChatChannelService::deleteChannel( const QString &pId )
mChannels->remove( pId );
mStorage->transaction();
mStorage->deleteChannel( pId );
mStorage->commit();
mStorage->askForcommit();
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment