2019-08-14 14:54:46 +00:00
/*
* Squawk messenger .
* Copyright ( C ) 2019 Yury Gubich < blue @ macaw . me >
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2019-03-29 14:54:34 +00:00
# include "squawk.h"
2019-03-30 20:13:13 +00:00
# include <QDebug>
2019-04-02 21:58:43 +00:00
# include <QSettings>
2019-05-29 15:05:54 +00:00
# include <QDir>
# include <QStandardPaths>
2019-03-29 14:54:34 +00:00
2019-03-30 20:13:13 +00:00
Core : : Squawk : : Squawk ( QObject * parent ) :
2019-03-29 14:54:34 +00:00
QObject ( parent ) ,
2019-03-31 21:05:09 +00:00
accounts ( ) ,
2019-09-11 15:03:52 +00:00
amap ( ) ,
2022-04-12 20:33:10 +00:00
state ( Shared : : Availability : : offline ) ,
2020-04-04 16:40:32 +00:00
network ( ) ,
2022-08-22 20:29:43 +00:00
isInitialized ( false ) ,
clientCache ( ) ,
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2022-08-22 20:29:43 +00:00
kwallet ( )
2020-04-10 22:15:08 +00:00
# endif
2019-03-29 14:54:34 +00:00
{
2021-04-18 12:49:20 +00:00
connect ( & network , & NetworkAccess : : loadFileProgress , this , & Squawk : : fileProgress ) ;
connect ( & network , & NetworkAccess : : loadFileError , this , & Squawk : : fileError ) ;
connect ( & network , & NetworkAccess : : downloadFileComplete , this , & Squawk : : fileDownloadComplete ) ;
connect ( & network , & NetworkAccess : : uploadFileComplete , this , & Squawk : : fileUploadComplete ) ;
2020-04-09 22:48:08 +00:00
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2020-04-09 22:48:08 +00:00
if ( kwallet . supportState ( ) = = PSE : : KWallet : : success ) {
connect ( & kwallet , & PSE : : KWallet : : opened , this , & Squawk : : onWalletOpened ) ;
connect ( & kwallet , & PSE : : KWallet : : rejectPassword , this , & Squawk : : onWalletRejectPassword ) ;
2022-04-12 20:33:10 +00:00
connect ( & kwallet , & PSE : : KWallet : : responsePassword , this , & Squawk : : responsePassword ) ;
2020-04-10 22:15:08 +00:00
Shared : : Global : : setSupported ( " KWallet " , true ) ;
2020-04-09 22:48:08 +00:00
}
2020-04-10 22:15:08 +00:00
# endif
2019-03-29 14:54:34 +00:00
}
2019-03-30 20:13:13 +00:00
Core : : Squawk : : ~ Squawk ( )
2019-03-29 14:54:34 +00:00
{
2019-03-30 20:13:13 +00:00
Accounts : : const_iterator itr = accounts . begin ( ) ;
Accounts : : const_iterator end = accounts . end ( ) ;
for ( ; itr ! = end ; + + itr ) {
2019-04-02 21:58:43 +00:00
delete ( * itr ) ;
2019-03-30 20:13:13 +00:00
}
}
2020-04-09 22:48:08 +00:00
void Core : : Squawk : : onWalletOpened ( bool success )
{
qDebug ( ) < < " KWallet opened: " < < success ;
}
2019-04-02 21:58:43 +00:00
void Core : : Squawk : : stop ( )
{
qDebug ( " Stopping squawk core.. " ) ;
2019-09-17 15:16:09 +00:00
network . stop ( ) ;
2022-08-22 20:29:43 +00:00
clientCache . close ( ) ;
2021-10-06 14:52:20 +00:00
if ( isInitialized ) {
QSettings settings ;
settings . beginGroup ( " core " ) ;
settings . beginWriteArray ( " accounts " ) ;
SimpleCrypt crypto ( passwordHash ) ;
for ( std : : deque < Account * > : : size_type i = 0 ; i < accounts . size ( ) ; + + i ) {
settings . setArrayIndex ( i ) ;
Account * acc = accounts [ i ] ;
Shared : : AccountPassword ap = acc - > getPasswordType ( ) ;
QString password ;
switch ( ap ) {
case Shared : : AccountPassword : : plain :
password = acc - > getPassword ( ) ;
break ;
case Shared : : AccountPassword : : jammed :
password = crypto . encryptToString ( acc - > getPassword ( ) ) ;
break ;
default :
break ;
}
settings . setValue ( " name " , acc - > getName ( ) ) ;
settings . setValue ( " server " , acc - > getServer ( ) ) ;
settings . setValue ( " login " , acc - > getLogin ( ) ) ;
settings . setValue ( " password " , password ) ;
settings . setValue ( " resource " , acc - > getResource ( ) ) ;
settings . setValue ( " passwordType " , static_cast < int > ( ap ) ) ;
2022-04-12 20:33:10 +00:00
settings . setValue ( " active " , acc - > getActive ( ) ) ;
2020-04-07 20:33:03 +00:00
}
2021-10-06 14:52:20 +00:00
settings . endArray ( ) ;
settings . endGroup ( ) ;
settings . sync ( ) ;
2019-04-02 21:58:43 +00:00
}
emit quit ( ) ;
}
2019-03-30 20:13:13 +00:00
void Core : : Squawk : : start ( )
{
2019-04-02 21:58:43 +00:00
qDebug ( " Starting squawk core.. " ) ;
2020-04-04 16:40:32 +00:00
readSettings ( ) ;
2021-10-06 14:52:20 +00:00
isInitialized = true ;
2019-09-17 15:16:09 +00:00
network . start ( ) ;
2022-08-22 20:29:43 +00:00
clientCache . open ( ) ;
2019-03-30 20:13:13 +00:00
}
2019-03-29 14:54:34 +00:00
2019-03-30 20:13:13 +00:00
void Core : : Squawk : : newAccountRequest ( const QMap < QString , QVariant > & map )
{
QString name = map . value ( " name " ) . toString ( ) ;
QString login = map . value ( " login " ) . toString ( ) ;
QString server = map . value ( " server " ) . toString ( ) ;
QString password = map . value ( " password " ) . toString ( ) ;
2019-04-12 05:51:36 +00:00
QString resource = map . value ( " resource " ) . toString ( ) ;
2021-10-06 14:55:23 +00:00
int passwordType = map . value ( " passwordType " ) . toInt ( ) ;
2022-04-12 20:33:10 +00:00
bool active = map . value ( " active " ) . toBool ( ) ;
2019-03-30 20:13:13 +00:00
2022-04-12 20:33:10 +00:00
addAccount ( login , server , password , name , resource , active , Shared : : Global : : fromInt < Shared : : AccountPassword > ( passwordType ) ) ;
2019-03-30 20:13:13 +00:00
}
2020-04-04 16:40:32 +00:00
void Core : : Squawk : : addAccount (
const QString & login ,
const QString & server ,
const QString & password ,
const QString & name ,
2022-04-12 20:33:10 +00:00
const QString & resource ,
bool active ,
Shared : : AccountPassword passwordType )
2019-03-30 20:13:13 +00:00
{
2022-04-13 19:02:48 +00:00
if ( amap . count ( name ) > 0 ) {
qDebug ( ) < < " An attempt to add account " < < name < < " but an account with such name already exist, ignoring " ;
return ;
}
2022-04-12 20:33:10 +00:00
Account * acc = new Account ( login , server , password , name , active , & network ) ;
2019-04-12 05:51:36 +00:00
acc - > setResource ( resource ) ;
2020-04-04 16:40:32 +00:00
acc - > setPasswordType ( passwordType ) ;
2019-03-30 20:13:13 +00:00
accounts . push_back ( acc ) ;
2019-03-31 21:05:09 +00:00
amap . insert ( std : : make_pair ( name , acc ) ) ;
2019-10-16 19:38:35 +00:00
connect ( acc , & Account : : connectionStateChanged , this , & Squawk : : onAccountConnectionStateChanged ) ;
connect ( acc , & Account : : changed , this , & Squawk : : onAccountChanged ) ;
connect ( acc , & Account : : error , this , & Squawk : : onAccountError ) ;
2022-04-12 20:33:10 +00:00
connect ( acc , & Account : : needPassword , this , & Squawk : : onAccountNeedPassword ) ;
2019-10-16 19:38:35 +00:00
connect ( acc , & Account : : availabilityChanged , this , & Squawk : : onAccountAvailabilityChanged ) ;
connect ( acc , & Account : : addContact , this , & Squawk : : onAccountAddContact ) ;
connect ( acc , & Account : : addGroup , this , & Squawk : : onAccountAddGroup ) ;
connect ( acc , & Account : : removeGroup , this , & Squawk : : onAccountRemoveGroup ) ;
2020-04-04 16:40:32 +00:00
connect ( acc , qOverload < const QString & , const QString & > ( & Account : : removeContact ) ,
this , qOverload < const QString & , const QString & > ( & Squawk : : onAccountRemoveContact ) ) ;
connect ( acc , qOverload < const QString & > ( & Account : : removeContact ) ,
this , qOverload < const QString & > ( & Squawk : : onAccountRemoveContact ) ) ;
2019-10-16 19:38:35 +00:00
connect ( acc , & Account : : changeContact , this , & Squawk : : onAccountChangeContact ) ;
connect ( acc , & Account : : addPresence , this , & Squawk : : onAccountAddPresence ) ;
connect ( acc , & Account : : removePresence , this , & Squawk : : onAccountRemovePresence ) ;
connect ( acc , & Account : : message , this , & Squawk : : onAccountMessage ) ;
2020-03-25 15:28:36 +00:00
connect ( acc , & Account : : changeMessage , this , & Squawk : : onAccountChangeMessage ) ;
2019-10-16 19:38:35 +00:00
connect ( acc , & Account : : responseArchive , this , & Squawk : : onAccountResponseArchive ) ;
connect ( acc , & Account : : addRoom , this , & Squawk : : onAccountAddRoom ) ;
connect ( acc , & Account : : changeRoom , this , & Squawk : : onAccountChangeRoom ) ;
connect ( acc , & Account : : removeRoom , this , & Squawk : : onAccountRemoveRoom ) ;
2019-07-11 08:51:52 +00:00
2019-10-16 19:38:35 +00:00
connect ( acc , & Account : : addRoomParticipant , this , & Squawk : : onAccountAddRoomPresence ) ;
connect ( acc , & Account : : changeRoomParticipant , this , & Squawk : : onAccountChangeRoomPresence ) ;
connect ( acc , & Account : : removeRoomParticipant , this , & Squawk : : onAccountRemoveRoomPresence ) ;
2019-09-02 11:17:28 +00:00
2023-02-20 18:12:32 +00:00
connect ( acc , & Account : : infoReady , this , & Squawk : : responseInfo ) ;
2019-07-11 08:51:52 +00:00
2021-04-18 12:49:20 +00:00
connect ( acc , & Account : : uploadFileError , this , & Squawk : : onAccountUploadFileError ) ;
2022-08-22 20:29:43 +00:00
connect ( acc , & Account : : infoDiscovered , this , & Squawk : : onAccountInfoDiscovered ) ;
2019-11-14 11:43:43 +00:00
2019-03-30 20:13:13 +00:00
QMap < QString , QVariant > map = {
{ " login " , login } ,
{ " server " , server } ,
{ " name " , name } ,
{ " password " , password } ,
2019-04-12 05:51:36 +00:00
{ " resource " , resource } ,
2020-04-03 22:28:15 +00:00
{ " state " , QVariant : : fromValue ( Shared : : ConnectionState : : disconnected ) } ,
{ " offline " , QVariant : : fromValue ( Shared : : Availability : : offline ) } ,
2019-10-16 19:38:35 +00:00
{ " error " , " " } ,
2020-04-04 16:40:32 +00:00
{ " avatarPath " , acc - > getAvatarPath ( ) } ,
2022-04-12 20:33:10 +00:00
{ " passwordType " , QVariant : : fromValue ( passwordType ) } ,
{ " active " , active }
2019-03-30 20:13:13 +00:00
} ;
2019-10-16 19:38:35 +00:00
2019-03-30 20:13:13 +00:00
emit newAccount ( map ) ;
2022-04-12 20:33:10 +00:00
switch ( passwordType ) {
case Shared : : AccountPassword : : alwaysAsk :
case Shared : : AccountPassword : : kwallet :
2022-04-13 19:02:48 +00:00
if ( password = = " " ) {
acc - > invalidatePassword ( ) ;
break ;
}
2022-04-12 20:33:10 +00:00
default :
break ;
}
if ( state ! = Shared : : Availability : : offline ) {
acc - > setAvailability ( state ) ;
if ( acc - > getActive ( ) ) {
acc - > connect ( ) ;
}
}
2019-03-29 14:54:34 +00:00
}
2019-03-31 21:05:09 +00:00
2020-04-03 22:28:15 +00:00
void Core : : Squawk : : changeState ( Shared : : Availability p_state )
2019-04-07 20:14:15 +00:00
{
2020-04-03 22:28:15 +00:00
if ( state ! = p_state ) {
2022-04-12 20:33:10 +00:00
for ( std : : deque < Account * > : : iterator itr = accounts . begin ( ) , end = accounts . end ( ) ; itr ! = end ; + + itr ) {
Account * acc = * itr ;
acc - > setAvailability ( p_state ) ;
if ( state = = Shared : : Availability : : offline & & acc - > getActive ( ) ) {
acc - > connect ( ) ;
}
}
2020-04-03 22:28:15 +00:00
state = p_state ;
2022-04-12 20:33:10 +00:00
emit stateChanged ( p_state ) ;
2019-04-07 20:14:15 +00:00
}
}
2019-03-31 21:05:09 +00:00
void Core : : Squawk : : connectAccount ( const QString & account )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to connect non existing account, skipping " ) ;
return ;
}
2022-04-12 20:33:10 +00:00
itr - > second - > setActive ( true ) ;
if ( state ! = Shared : : Availability : : offline ) {
itr - > second - > connect ( ) ;
}
2019-03-31 21:05:09 +00:00
}
void Core : : Squawk : : disconnectAccount ( const QString & account )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to connect non existing account, skipping " ) ;
return ;
}
2022-04-12 20:33:10 +00:00
itr - > second - > setActive ( false ) ;
2019-04-02 15:46:18 +00:00
itr - > second - > disconnect ( ) ;
2019-03-31 21:05:09 +00:00
}
2020-04-03 22:28:15 +00:00
void Core : : Squawk : : onAccountConnectionStateChanged ( Shared : : ConnectionState p_state )
2019-03-31 21:05:09 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2022-12-26 22:01:01 +00:00
QMap < QString , QVariant > changes = {
{ " state " , QVariant : : fromValue ( p_state ) }
} ;
if ( acc - > getLastError ( ) = = Account : : Error : : none ) {
changes . insert ( " error " , " " ) ;
}
emit changeAccount ( acc - > getName ( ) , changes ) ;
2022-04-12 20:33:10 +00:00
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2020-08-07 23:33:03 +00:00
if ( p_state = = Shared : : ConnectionState : : connected ) {
if ( acc - > getPasswordType ( ) = = Shared : : AccountPassword : : kwallet & & kwallet . supportState ( ) = = PSE : : KWallet : : success ) {
kwallet . requestWritePassword ( acc - > getName ( ) , acc - > getPassword ( ) , true ) ;
}
}
2020-04-10 22:15:08 +00:00
# endif
2019-03-31 21:05:09 +00:00
}
2019-04-07 20:14:15 +00:00
void Core : : Squawk : : onAccountAddContact ( const QString & jid , const QString & group , const QMap < QString , QVariant > & data )
2019-04-03 21:23:51 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2019-04-07 20:14:15 +00:00
emit addContact ( acc - > getName ( ) , jid , group , data ) ;
2019-04-03 21:23:51 +00:00
}
void Core : : Squawk : : onAccountAddGroup ( const QString & name )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit addGroup ( acc - > getName ( ) , name ) ;
}
void Core : : Squawk : : onAccountRemoveGroup ( const QString & name )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removeGroup ( acc - > getName ( ) , name ) ;
}
2019-04-06 10:14:32 +00:00
2019-04-07 20:14:15 +00:00
void Core : : Squawk : : onAccountChangeContact ( const QString & jid , const QMap < QString , QVariant > & data )
2019-04-06 10:14:32 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2019-04-07 20:14:15 +00:00
emit changeContact ( acc - > getName ( ) , jid , data ) ;
2019-04-06 10:14:32 +00:00
}
void Core : : Squawk : : onAccountRemoveContact ( const QString & jid )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removeContact ( acc - > getName ( ) , jid ) ;
}
void Core : : Squawk : : onAccountRemoveContact ( const QString & jid , const QString & group )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removeContact ( acc - > getName ( ) , jid , group ) ;
}
2019-04-07 14:02:41 +00:00
void Core : : Squawk : : onAccountAddPresence ( const QString & jid , const QString & name , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit addPresence ( acc - > getName ( ) , jid , name , data ) ;
2022-08-22 20:29:43 +00:00
2022-08-24 22:41:06 +00:00
//it's equal if a MUC sends its status with presence of the same jid (ex: muc@srv.im/muc@srv.im), it's not a client, so, no need to request
if ( jid ! = name ) {
QString node = data [ " capabilityNode " ] . toString ( ) ;
QString ver = data [ " capabilityVer " ] . toString ( ) ;
QString hash = data [ " capabilityHash " ] . toString ( ) ;
if ( ! clientCache . checkClient ( node , ver , hash ) ) {
acc - > discoverInfo ( jid + " / " + name , node + " / " + ver ) ;
}
2022-08-22 20:29:43 +00:00
}
}
void Core : : Squawk : : onAccountInfoDiscovered (
const QString & address ,
const QString & node ,
2022-08-24 22:41:06 +00:00
const std : : set < Shared : : Identity > & identities ,
2022-08-22 20:29:43 +00:00
const std : : set < QString > & features )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2022-08-24 22:41:06 +00:00
if ( ! clientCache . registerClientInfo ( address , node , identities , features ) ) {
2022-08-22 20:29:43 +00:00
qDebug ( ) < < " Account " < < acc - > getName ( ) < < " received an ill-formed client discovery response from " < < address < < " about " < < node ;
}
2019-04-07 14:02:41 +00:00
}
void Core : : Squawk : : onAccountRemovePresence ( const QString & jid , const QString & name )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removePresence ( acc - > getName ( ) , jid , name ) ;
}
2019-04-07 20:14:15 +00:00
2020-04-03 22:28:15 +00:00
void Core : : Squawk : : onAccountAvailabilityChanged ( Shared : : Availability state )
2019-04-07 20:14:15 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2020-04-03 22:28:15 +00:00
emit changeAccount ( acc - > getName ( ) , { { " availability " , QVariant : : fromValue ( state ) } } ) ;
2019-04-07 20:14:15 +00:00
}
2019-04-09 22:01:25 +00:00
2019-10-16 19:38:35 +00:00
void Core : : Squawk : : onAccountChanged ( const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit changeAccount ( acc - > getName ( ) , data ) ;
}
2019-04-11 14:58:59 +00:00
void Core : : Squawk : : onAccountMessage ( const Shared : : Message & data )
2019-04-09 22:01:25 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit accountMessage ( acc - > getName ( ) , data ) ;
}
2019-04-10 20:53:42 +00:00
2019-04-11 14:58:59 +00:00
void Core : : Squawk : : sendMessage ( const QString & account , const Shared : : Message & data )
2019-04-10 20:53:42 +00:00
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2021-05-22 22:03:14 +00:00
qDebug ( ) < < " An attempt to send a message with non existing account " < < account < < " , skipping " ;
2019-04-10 20:53:42 +00:00
return ;
}
itr - > second - > sendMessage ( data ) ;
}
2019-04-13 20:38:20 +00:00
2022-03-28 20:25:33 +00:00
void Core : : Squawk : : replaceMessage ( const QString & account , const QString & originalId , const Shared : : Message & data )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to replace a message with non existing account " < < account < < " , skipping " ;
return ;
}
itr - > second - > replaceMessage ( originalId , data ) ;
}
2021-05-22 22:03:14 +00:00
void Core : : Squawk : : resendMessage ( const QString & account , const QString & jid , const QString & id )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to resend a message with non existing account " < < account < < " , skipping " ;
return ;
}
itr - > second - > resendMessage ( jid , id ) ;
}
2019-05-15 17:36:37 +00:00
void Core : : Squawk : : requestArchive ( const QString & account , const QString & jid , int count , const QString & before )
2019-04-13 20:38:20 +00:00
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to request an archive of non existing account, skipping " ) ;
return ;
}
2019-05-15 17:36:37 +00:00
itr - > second - > requestArchive ( jid , count , before ) ;
2019-04-13 20:38:20 +00:00
}
2019-05-15 17:36:37 +00:00
2020-08-21 20:57:48 +00:00
void Core : : Squawk : : onAccountResponseArchive ( const QString & jid , const std : : list < Shared : : Message > & list , bool last )
2019-05-15 17:36:37 +00:00
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
2020-08-21 20:57:48 +00:00
emit responseArchive ( acc - > getName ( ) , jid , list , last ) ;
2019-05-15 17:36:37 +00:00
}
2019-05-24 14:46:34 +00:00
void Core : : Squawk : : modifyAccountRequest ( const QString & name , const QMap < QString , QVariant > & map )
{
AccountsMap : : const_iterator itr = amap . find ( name ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to modify non existing account, skipping " ) ;
return ;
}
Core : : Account * acc = itr - > second ;
Shared : : ConnectionState st = acc - > getState ( ) ;
2020-04-07 20:33:03 +00:00
QMap < QString , QVariant > : : const_iterator mItr ;
bool needToReconnect = false ;
2022-04-14 08:13:27 +00:00
bool wentReconnecting = false ;
2020-04-07 20:33:03 +00:00
mItr = map . find ( " login " ) ;
if ( mItr ! = map . end ( ) ) {
needToReconnect = acc - > getLogin ( ) ! = mItr - > toString ( ) ;
}
if ( ! needToReconnect ) {
mItr = map . find ( " password " ) ;
if ( mItr ! = map . end ( ) ) {
needToReconnect = acc - > getPassword ( ) ! = mItr - > toString ( ) ;
}
}
if ( ! needToReconnect ) {
mItr = map . find ( " server " ) ;
if ( mItr ! = map . end ( ) ) {
needToReconnect = acc - > getServer ( ) ! = mItr - > toString ( ) ;
}
}
if ( ! needToReconnect ) {
mItr = map . find ( " resource " ) ;
if ( mItr ! = map . end ( ) ) {
needToReconnect = acc - > getResource ( ) ! = mItr - > toString ( ) ;
}
}
2019-05-24 14:46:34 +00:00
2022-04-12 20:33:10 +00:00
bool activeChanged = false ;
mItr = map . find ( " active " ) ;
if ( mItr = = map . end ( ) | | mItr - > toBool ( ) = = acc - > getActive ( ) ) {
if ( needToReconnect & & st ! = Shared : : ConnectionState : : disconnected ) {
acc - > reconnect ( ) ;
2022-04-14 08:13:27 +00:00
wentReconnecting = true ;
2022-04-12 20:33:10 +00:00
}
} else {
acc - > setActive ( mItr - > toBool ( ) ) ;
activeChanged = true ;
2019-05-24 14:46:34 +00:00
}
mItr = map . find ( " login " ) ;
if ( mItr ! = map . end ( ) ) {
acc - > setLogin ( mItr - > toString ( ) ) ;
}
mItr = map . find ( " password " ) ;
if ( mItr ! = map . end ( ) ) {
acc - > setPassword ( mItr - > toString ( ) ) ;
}
mItr = map . find ( " resource " ) ;
if ( mItr ! = map . end ( ) ) {
acc - > setResource ( mItr - > toString ( ) ) ;
}
mItr = map . find ( " server " ) ;
if ( mItr ! = map . end ( ) ) {
acc - > setServer ( mItr - > toString ( ) ) ;
}
2020-04-07 20:33:03 +00:00
mItr = map . find ( " passwordType " ) ;
if ( mItr ! = map . end ( ) ) {
acc - > setPasswordType ( Shared : : Global : : fromInt < Shared : : AccountPassword > ( mItr - > toInt ( ) ) ) ;
}
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2020-04-09 22:48:08 +00:00
if ( acc - > getPasswordType ( ) = = Shared : : AccountPassword : : kwallet
& & kwallet . supportState ( ) = = PSE : : KWallet : : success
& & ! needToReconnect
) {
kwallet . requestWritePassword ( acc - > getName ( ) , acc - > getPassword ( ) , true ) ;
}
2020-04-10 22:15:08 +00:00
# endif
2020-04-09 22:48:08 +00:00
2022-04-14 08:13:27 +00:00
if ( state ! = Shared : : Availability : : offline ) {
if ( activeChanged & & acc - > getActive ( ) ) {
acc - > connect ( ) ;
} else if ( ! wentReconnecting & & acc - > getActive ( ) & & acc - > getLastError ( ) = = Account : : Error : : authentication ) {
acc - > connect ( ) ;
}
2022-04-12 20:33:10 +00:00
}
2019-05-24 14:46:34 +00:00
emit changeAccount ( name , map ) ;
}
void Core : : Squawk : : onAccountError ( const QString & text )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit changeAccount ( acc - > getName ( ) , { { " error " , text } } ) ;
2022-04-14 08:13:27 +00:00
if ( acc - > getLastError ( ) = = Account : : Error : : authentication ) {
emit requestPassword ( acc - > getName ( ) , true ) ;
}
2019-05-24 14:46:34 +00:00
}
2019-05-29 15:05:54 +00:00
void Core : : Squawk : : removeAccountRequest ( const QString & name )
{
AccountsMap : : const_iterator itr = amap . find ( name ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to remove non existing account " < < name < < " from core, skipping " ;
return ;
}
Account * acc = itr - > second ;
2020-04-03 22:28:15 +00:00
if ( acc - > getState ( ) ! = Shared : : ConnectionState : : disconnected ) {
2019-05-30 09:36:21 +00:00
acc - > disconnect ( ) ;
}
2019-05-29 15:05:54 +00:00
for ( Accounts : : const_iterator aItr = accounts . begin ( ) ; aItr ! = accounts . end ( ) ; + + aItr ) {
if ( * aItr = = acc ) {
accounts . erase ( aItr ) ;
break ;
}
}
amap . erase ( itr ) ;
QString path ( QStandardPaths : : writableLocation ( QStandardPaths : : CacheLocation ) ) ;
path + = " / " + name ;
QDir dir ( path ) ;
dir . removeRecursively ( ) ;
emit removeAccount ( name ) ;
2019-05-30 09:36:21 +00:00
acc - > deleteLater ( ) ;
2019-05-29 15:05:54 +00:00
}
2019-06-12 17:18:18 +00:00
void Core : : Squawk : : subscribeContact ( const QString & account , const QString & jid , const QString & reason )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to subscribe to the contact with non existing account, skipping " ) ;
return ;
}
itr - > second - > subscribeToContact ( jid , reason ) ;
}
void Core : : Squawk : : unsubscribeContact ( const QString & account , const QString & jid , const QString & reason )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to subscribe to the contact with non existing account, skipping " ) ;
return ;
}
itr - > second - > unsubscribeFromContact ( jid , reason ) ;
}
2019-06-14 16:36:04 +00:00
void Core : : Squawk : : removeContactRequest ( const QString & account , const QString & jid )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to remove contact from non existing account, skipping " ) ;
return ;
}
itr - > second - > removeContactRequest ( jid ) ;
}
2019-06-15 15:29:15 +00:00
void Core : : Squawk : : addContactRequest ( const QString & account , const QString & jid , const QString & name , const QSet < QString > & groups )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( " An attempt to add contact to a non existing account, skipping " ) ;
return ;
}
itr - > second - > addContactRequest ( jid , name , groups ) ;
}
2019-07-11 08:51:52 +00:00
void Core : : Squawk : : onAccountAddRoom ( const QString jid , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit addRoom ( acc - > getName ( ) , jid , data ) ;
}
void Core : : Squawk : : onAccountChangeRoom ( const QString jid , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit changeRoom ( acc - > getName ( ) , jid , data ) ;
}
void Core : : Squawk : : onAccountRemoveRoom ( const QString jid )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removeRoom ( acc - > getName ( ) , jid ) ;
}
2019-08-29 14:19:35 +00:00
void Core : : Squawk : : setRoomJoined ( const QString & account , const QString & jid , bool joined )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2019-08-31 20:50:05 +00:00
qDebug ( ) < < " An attempt to set jouned to the room " < < jid < < " of non existing account " < < account < < " , skipping " ;
2019-08-29 14:19:35 +00:00
return ;
}
itr - > second - > setRoomJoined ( jid , joined ) ;
}
void Core : : Squawk : : setRoomAutoJoin ( const QString & account , const QString & jid , bool joined )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to set autoJoin to the room " < < jid < < " of non existing account " < < account < < " , skipping " ;
return ;
}
itr - > second - > setRoomAutoJoin ( jid , joined ) ;
}
2019-09-01 19:46:12 +00:00
void Core : : Squawk : : onAccountAddRoomPresence ( const QString & jid , const QString & nick , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit addRoomParticipant ( acc - > getName ( ) , jid , nick , data ) ;
}
void Core : : Squawk : : onAccountChangeRoomPresence ( const QString & jid , const QString & nick , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit changeRoomParticipant ( acc - > getName ( ) , jid , nick , data ) ;
}
void Core : : Squawk : : onAccountRemoveRoomPresence ( const QString & jid , const QString & nick )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit removeRoomParticipant ( acc - > getName ( ) , jid , nick ) ;
}
2019-09-03 20:28:58 +00:00
2020-03-25 15:28:36 +00:00
void Core : : Squawk : : onAccountChangeMessage ( const QString & jid , const QString & id , const QMap < QString , QVariant > & data )
{
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit changeMessage ( acc - > getName ( ) , jid , id , data ) ;
}
2019-09-03 20:28:58 +00:00
void Core : : Squawk : : removeRoomRequest ( const QString & account , const QString & jid )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to remove the room " < < jid < < " of non existing account " < < account < < " , skipping " ;
return ;
}
itr - > second - > removeRoomRequest ( jid ) ;
}
2019-09-04 16:38:52 +00:00
void Core : : Squawk : : addRoomRequest ( const QString & account , const QString & jid , const QString & nick , const QString & password , bool autoJoin )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
qDebug ( ) < < " An attempt to add the room " < < jid < < " to non existing account " < < account < < " , skipping " ;
return ;
}
itr - > second - > addRoomRequest ( jid , nick , password , autoJoin ) ;
}
2021-04-18 12:49:20 +00:00
void Core : : Squawk : : fileDownloadRequest ( const QString & url )
2019-09-11 15:03:52 +00:00
{
2021-04-18 12:49:20 +00:00
network . downladFile ( url ) ;
2019-09-11 15:03:52 +00:00
}
2019-09-28 14:30:16 +00:00
void Core : : Squawk : : addContactToGroupRequest ( const QString & account , const QString & jid , const QString & groupName )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2019-10-22 15:13:56 +00:00
qDebug ( ) < < " An attempt to add contact " < < jid < < " of non existing account " < < account < < " to the group " < < groupName < < " , skipping " ;
2019-09-28 14:30:16 +00:00
return ;
}
itr - > second - > addContactToGroupRequest ( jid , groupName ) ;
}
void Core : : Squawk : : removeContactFromGroupRequest ( const QString & account , const QString & jid , const QString & groupName )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2019-10-22 15:13:56 +00:00
qDebug ( ) < < " An attempt to add contact " < < jid < < " of non existing account " < < account < < " to the group " < < groupName < < " , skipping " ;
2019-09-28 14:30:16 +00:00
return ;
}
itr - > second - > removeContactFromGroupRequest ( jid , groupName ) ;
}
2019-10-01 08:47:40 +00:00
void Core : : Squawk : : renameContactRequest ( const QString & account , const QString & jid , const QString & newName )
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2019-10-22 15:13:56 +00:00
qDebug ( ) < < " An attempt to rename contact " < < jid < < " of non existing account " < < account < < " , skipping " ;
2019-10-01 08:47:40 +00:00
return ;
}
itr - > second - > renameContactRequest ( jid , newName ) ;
}
2019-10-22 15:13:56 +00:00
2023-02-20 18:12:32 +00:00
void Core : : Squawk : : requestInfo ( const QString & account , const QString & jid )
2019-10-22 15:13:56 +00:00
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2023-02-20 18:12:32 +00:00
qDebug ( ) < < " An attempt to request info about " < < jid < < " of non existing account " < < account < < " , skipping " ;
2019-10-22 15:13:56 +00:00
return ;
}
2023-02-20 18:12:32 +00:00
itr - > second - > requestInfo ( jid ) ;
2019-10-22 15:13:56 +00:00
}
2019-10-24 09:42:38 +00:00
2023-02-20 18:12:32 +00:00
void Core : : Squawk : : updateInfo ( const QString & account , const Shared : : Info & info )
2019-10-24 09:42:38 +00:00
{
AccountsMap : : const_iterator itr = amap . find ( account ) ;
if ( itr = = amap . end ( ) ) {
2023-02-20 18:12:32 +00:00
qDebug ( ) < < " An attempt to update info to non existing account " < < account < < " , skipping " ;
2019-10-24 09:42:38 +00:00
return ;
}
2023-02-20 18:12:32 +00:00
itr - > second - > updateInfo ( info ) ;
2019-10-24 09:42:38 +00:00
}
2020-03-25 15:28:36 +00:00
2020-04-04 16:40:32 +00:00
void Core : : Squawk : : readSettings ( )
{
QSettings settings ;
settings . beginGroup ( " core " ) ;
int size = settings . beginReadArray ( " accounts " ) ;
for ( int i = 0 ; i < size ; + + i ) {
settings . setArrayIndex ( i ) ;
2022-04-12 20:33:10 +00:00
Shared : : AccountPassword passwordType =
Shared : : Global : : fromInt < Shared : : AccountPassword > (
settings . value ( " passwordType " , static_cast < int > ( Shared : : AccountPassword : : plain ) ) . toInt ( )
) ;
QString password = settings . value ( " password " , " " ) . toString ( ) ;
if ( passwordType = = Shared : : AccountPassword : : jammed ) {
SimpleCrypt crypto ( passwordHash ) ;
password = crypto . decryptToString ( password ) ;
}
addAccount (
2020-04-04 16:40:32 +00:00
settings . value ( " login " ) . toString ( ) ,
settings . value ( " server " ) . toString ( ) ,
2022-04-12 20:33:10 +00:00
password ,
2021-04-13 13:27:31 +00:00
settings . value ( " name " ) . toString ( ) ,
2020-04-04 16:40:32 +00:00
settings . value ( " resource " ) . toString ( ) ,
2022-04-12 20:33:10 +00:00
settings . value ( " active " ) . toBool ( ) ,
passwordType
2020-04-04 16:40:32 +00:00
) ;
}
settings . endArray ( ) ;
settings . endGroup ( ) ;
2022-04-12 20:33:10 +00:00
qDebug ( ) < < " Squawk core is ready " ;
emit ready ( ) ;
2020-04-04 16:40:32 +00:00
}
2022-04-12 20:33:10 +00:00
void Core : : Squawk : : onAccountNeedPassword ( )
2020-04-04 16:40:32 +00:00
{
2022-04-12 20:33:10 +00:00
Account * acc = static_cast < Account * > ( sender ( ) ) ;
switch ( acc - > getPasswordType ( ) ) {
case Shared : : AccountPassword : : alwaysAsk :
2022-04-14 08:13:27 +00:00
emit requestPassword ( acc - > getName ( ) , false ) ;
2020-04-07 20:33:03 +00:00
break ;
2020-04-09 22:48:08 +00:00
case Shared : : AccountPassword : : kwallet : {
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2020-04-09 22:48:08 +00:00
if ( kwallet . supportState ( ) = = PSE : : KWallet : : success ) {
2022-04-12 20:33:10 +00:00
kwallet . requestReadPassword ( acc - > getName ( ) ) ;
2020-04-09 22:48:08 +00:00
} else {
2020-04-10 22:15:08 +00:00
# endif
2022-04-14 08:13:27 +00:00
emit requestPassword ( acc - > getName ( ) , false ) ;
2020-04-10 22:15:08 +00:00
# ifdef WITH_KWALLET
2020-04-09 22:48:08 +00:00
}
2020-04-10 22:15:08 +00:00
# endif
2022-04-12 20:33:10 +00:00
break ;
2020-04-09 22:48:08 +00:00
}
2022-04-12 20:33:10 +00:00
default :
break ; //should never happen;
2020-04-09 22:48:08 +00:00
}
}
void Core : : Squawk : : onWalletRejectPassword ( const QString & login )
{
2022-04-14 08:13:27 +00:00
emit requestPassword ( login , false ) ;
2020-04-09 22:48:08 +00:00
}
2022-04-12 20:33:10 +00:00
void Core : : Squawk : : responsePassword ( const QString & account , const QString & password )
2020-04-09 22:48:08 +00:00
{
2022-04-12 20:33:10 +00:00
AccountsMap : : const_iterator itr = amap . find ( account ) ;
2020-04-09 22:48:08 +00:00
if ( itr = = amap . end ( ) ) {
2022-04-12 20:33:10 +00:00
qDebug ( ) < < " An attempt to set password to non existing account " < < account < < " , skipping " ;
2020-04-09 22:48:08 +00:00
return ;
2020-04-04 16:40:32 +00:00
}
2022-04-12 20:33:10 +00:00
Account * acc = itr - > second ;
acc - > setPassword ( password ) ;
emit changeAccount ( account , { { " password " , password } } ) ;
if ( state ! = Shared : : Availability : : offline & & acc - > getActive ( ) ) {
acc - > connect ( ) ;
}
2020-04-04 16:40:32 +00:00
}
2021-04-13 13:27:31 +00:00
2021-04-18 12:49:20 +00:00
void Core : : Squawk : : onAccountUploadFileError ( const QString & jid , const QString id , const QString & errorText )
2021-04-13 13:27:31 +00:00
{
2021-04-18 12:49:20 +00:00
Account * acc = static_cast < Account * > ( sender ( ) ) ;
emit fileError ( { { acc - > getName ( ) , jid , id } } , errorText , true ) ;
2021-04-13 13:27:31 +00:00
}
2021-04-28 20:26:19 +00:00
void Core : : Squawk : : onLocalPathInvalid ( const QString & path )
{
std : : list < Shared : : MessageInfo > list = network . reportPathInvalid ( path ) ;
QMap < QString , QVariant > data ( {
{ " attachPath " , " " }
} ) ;
for ( const Shared : : MessageInfo & info : list ) {
AccountsMap : : const_iterator itr = amap . find ( info . account ) ;
if ( itr ! = amap . end ( ) ) {
itr - > second - > requestChangeMessage ( info . jid , info . messageId , data ) ;
} else {
qDebug ( ) < < " Reacting on failure to reach file " < < path < < " there was an attempt to change message in account " < < info . account < < " which doesn't exist, skipping " ;
}
}
}
2022-02-19 18:31:49 +00:00
void Core : : Squawk : : changeDownloadsPath ( const QString & path )
{
network . moveFilesDirectory ( path ) ;
}