2019-09-06 23:43:07 -04:00
# include "cast.h"
// This file is part of MRCI.
// MRCI 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.
// MRCI 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 MRCI under the LICENSE.md file. If not, see
// <http://www.gnu.org/licenses/>.
2019-11-08 22:06:09 -05:00
Cast : : Cast ( QObject * parent ) : CmdObject ( parent ) { }
OpenSubChannel : : OpenSubChannel ( QObject * parent ) : CmdObject ( parent ) { }
CloseSubChannel : : CloseSubChannel ( QObject * parent ) : CmdObject ( parent ) { }
LsOpenChannels : : LsOpenChannels ( QObject * parent ) : CmdObject ( parent ) { }
PingPeers : : PingPeers ( QObject * parent ) : CmdObject ( parent ) { }
AddRDOnlyFlag : : AddRDOnlyFlag ( QObject * parent ) : CmdObject ( parent ) { }
RemoveRDOnlyFlag : : RemoveRDOnlyFlag ( QObject * parent ) : CmdObject ( parent ) { }
2019-09-06 23:43:07 -04:00
ListRDonlyFlags : : ListRDonlyFlags ( QObject * parent ) : TableViewer ( parent )
{
2019-11-08 22:06:09 -05:00
setParams ( TABLE_RDONLY_CAST , false ) ;
addJointColumn ( TABLE_CHANNELS , COLUMN_CHANNEL_ID ) ;
addTableColumn ( TABLE_CHANNELS , COLUMN_CHANNEL_NAME ) ;
addTableColumn ( TABLE_RDONLY_CAST , COLUMN_CHANNEL_ID ) ;
addTableColumn ( TABLE_RDONLY_CAST , COLUMN_SUB_CH_ID ) ;
addTableColumn ( TABLE_RDONLY_CAST , COLUMN_ACCESS_LEVEL ) ;
2019-09-06 23:43:07 -04:00
}
QString Cast : : cmdName ( ) { return " cast " ; }
QString OpenSubChannel : : cmdName ( ) { return " open_sub_ch " ; }
QString CloseSubChannel : : cmdName ( ) { return " close_sub_ch " ; }
QString LsOpenChannels : : cmdName ( ) { return " ls_open_chs " ; }
QString PingPeers : : cmdName ( ) { return " ping_peers " ; }
QString AddRDOnlyFlag : : cmdName ( ) { return " add_rdonly_flag " ; }
QString RemoveRDOnlyFlag : : cmdName ( ) { return " rm_rdonly_flag " ; }
QString ListRDonlyFlags : : cmdName ( ) { return " ls_rdonly_flags " ; }
2019-11-08 22:06:09 -05:00
bool canOpenSubChannel ( const QByteArray & uId , const char * override , quint64 chId , quint8 subId )
2019-09-06 23:43:07 -04:00
{
2020-01-29 12:29:01 -05:00
auto uLevel = channelAccessLevel ( uId , override , chId ) ;
auto sLevel = lowestAcessLevel ( chId , subId ) ;
2019-09-06 23:43:07 -04:00
2019-11-08 22:06:09 -05:00
return uLevel < = sLevel ;
2019-09-06 23:43:07 -04:00
}
2019-11-08 22:06:09 -05:00
int lowestAcessLevel ( quint64 chId , quint8 subId )
2019-09-06 23:43:07 -04:00
{
2020-01-29 12:29:01 -05:00
auto ret = 5000 ;
2019-09-06 23:43:07 -04:00
2019-11-08 22:06:09 -05:00
Query db ;
db . setType ( Query : : PULL , TABLE_SUB_CHANNELS ) ;
db . addColumn ( COLUMN_LOWEST_LEVEL ) ;
db . addCondition ( COLUMN_CHANNEL_ID , chId ) ;
db . addCondition ( COLUMN_SUB_CH_ID , subId ) ;
db . exec ( ) ;
if ( db . rows ( ) )
{
ret = db . getData ( COLUMN_LOWEST_LEVEL ) . toInt ( ) ;
}
return ret ;
}
void Cast : : procIn ( const QByteArray & binIn , quint8 dType )
{
2020-03-08 14:58:51 -04:00
async ( ASYNC_CAST , rdFromBlock ( openWritableSubChs , BLKSIZE_SUB_CHANNEL * MAX_OPEN_SUB_CHANNELS ) + wrInt ( dType , 8 ) + binIn ) ;
2019-11-08 22:06:09 -05:00
}
void OpenSubChannel : : procIn ( const QByteArray & binIn , quint8 dType )
{
2019-09-06 23:43:07 -04:00
if ( dType = = TEXT )
{
2020-01-29 12:29:01 -05:00
auto args = parseArgs ( binIn , 4 ) ;
auto ch = getParam ( " -ch_name " , args ) ;
auto sub = getParam ( " -sub_name " , args ) ;
quint64 chId ;
quint8 subId ;
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
if ( ch . isEmpty ( ) )
{
errTxt ( " err: Channel name (-ch_name) argument not found or is empty. \n " ) ;
}
else if ( sub . isEmpty ( ) )
{
errTxt ( " err: Sub-Channel name (-sub_name) argument not found or is empty. \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( ! channelExists ( ch , & chId ) )
{
errTxt ( " err: The requested channel does not exists. \n " ) ;
}
else if ( ! channelSubExists ( chId , sub , & subId ) )
{
errTxt ( " err: The requested sub-channel does not exists. \n " ) ;
}
else if ( ! canOpenSubChannel ( rdFromBlock ( userId , BLKSIZE_USER_ID ) , chOwnerOverride , chId , subId ) )
{
errTxt ( " err: Access denied. \n " ) ;
}
2019-09-06 23:43:07 -04:00
else
{
2020-01-29 12:29:01 -05:00
retCode = NO_ERRORS ;
2020-03-08 14:58:51 -04:00
async ( ASYNC_OPEN_SUBCH , wrInt ( chId , 64 ) + wrInt ( subId , 8 ) ) ;
2019-09-06 23:43:07 -04:00
}
}
}
2019-11-08 22:06:09 -05:00
void CloseSubChannel : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
if ( dType = = TEXT )
{
2020-01-29 12:29:01 -05:00
auto args = parseArgs ( binIn , 4 ) ;
auto ch = getParam ( " -ch_name " , args ) ;
auto sub = getParam ( " -sub_name " , args ) ;
quint64 chId ;
quint8 subId ;
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
if ( ch . isEmpty ( ) )
{
errTxt ( " err: Channel name (-ch_name) argument not found or is empty. \n " ) ;
}
else if ( sub . isEmpty ( ) )
{
errTxt ( " err: Sub-Channel name (-sub_name) argument not found or is empty. \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( ! channelExists ( ch , & chId ) )
{
errTxt ( " err: The requested channel does not exists. \n " ) ;
}
else if ( ! channelSubExists ( chId , sub , & subId ) )
{
errTxt ( " err: The requested sub-channel does not exists. \n " ) ;
}
2019-09-06 23:43:07 -04:00
else
{
2020-01-29 12:29:01 -05:00
retCode = NO_ERRORS ;
2020-03-08 14:58:51 -04:00
async ( ASYNC_CLOSE_SUBCH , wrInt ( chId , 64 ) + wrInt ( subId , 8 ) ) ;
2019-09-06 23:43:07 -04:00
}
}
}
2019-11-08 22:06:09 -05:00
void LsOpenChannels : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
2019-11-08 22:06:09 -05:00
Q_UNUSED ( binIn )
2019-09-06 23:43:07 -04:00
if ( dType = = TEXT )
{
Query db ;
QList < QStringList > tableData ;
QStringList separators ;
QList < int > justLens ;
for ( int i = 0 ; i < 5 ; + + i )
{
justLens . append ( 14 ) ;
separators . append ( " ------- " ) ;
}
tableData . append ( QStringList ( ) < < COLUMN_CHANNEL_NAME < < COLUMN_SUB_CH_NAME < < COLUMN_CHANNEL_ID < < COLUMN_SUB_CH_ID < < " read_only " ) ;
tableData . append ( separators ) ;
2019-11-08 22:06:09 -05:00
for ( int i = 0 ; i < MAX_OPEN_SUB_CHANNELS ; i + = BLKSIZE_SUB_CHANNEL )
2019-09-06 23:43:07 -04:00
{
2020-01-29 12:29:01 -05:00
auto chId = rd64BitFromBlock ( openSubChs + i ) ;
auto subId = rd8BitFromBlock ( openSubChs + ( i + 8 ) ) ;
2019-09-06 23:43:07 -04:00
if ( chId )
{
QStringList columnData ;
2020-04-01 11:34:13 -04:00
db . setType ( Query : : PULL , TABLE_CHANNELS ) ;
db . addColumn ( COLUMN_CHANNEL_NAME ) ;
2019-09-06 23:43:07 -04:00
db . addCondition ( COLUMN_CHANNEL_ID , chId ) ;
2020-04-01 11:34:13 -04:00
db . exec ( ) ;
columnData . append ( db . getData ( COLUMN_CHANNEL_NAME ) . toString ( ) ) ;
db . setType ( Query : : PULL , TABLE_SUB_CHANNELS ) ;
db . addColumn ( COLUMN_SUB_CH_NAME ) ;
2019-09-06 23:43:07 -04:00
db . addCondition ( COLUMN_SUB_CH_ID , subId ) ;
db . exec ( ) ;
2020-04-01 11:34:13 -04:00
columnData . append ( db . getData ( COLUMN_SUB_CH_NAME ) . toString ( ) ) ;
columnData . append ( QString : : number ( chId ) ) ;
columnData . append ( QString : : number ( subId ) ) ;
2020-01-29 12:29:01 -05:00
2020-04-01 11:34:13 -04:00
if ( posOfBlock ( openSubChs + i , openWritableSubChs , MAX_OPEN_SUB_CHANNELS , BLKSIZE_SUB_CHANNEL ) ! = - 1 )
{
// the sub-channel id being present in openWritableSubChs mean it is writable and
// therefore is NOT read only.
2019-09-06 23:43:07 -04:00
2020-04-01 11:34:13 -04:00
columnData . append ( " 0 " ) ;
2019-09-06 23:43:07 -04:00
}
else
{
2020-04-01 11:34:13 -04:00
columnData . append ( " 1 " ) ;
2019-09-06 23:43:07 -04:00
}
for ( int k = 0 ; k < justLens . size ( ) ; + + k )
{
if ( justLens [ k ] < columnData [ k ] . size ( ) ) justLens [ k ] = columnData [ k ] . size ( ) ;
}
tableData . append ( columnData ) ;
}
}
mainTxt ( " \n " ) ;
for ( auto & & row : tableData )
{
for ( int i = 0 ; i < row . size ( ) ; + + i )
{
2019-11-08 22:06:09 -05:00
mainTxt ( row [ i ] . leftJustified ( justLens [ i ] + 4 , ' ' ) ) ;
2019-09-06 23:43:07 -04:00
}
mainTxt ( " \n " ) ;
}
}
}
2019-11-08 22:06:09 -05:00
void PingPeers : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
2019-11-08 22:06:09 -05:00
Q_UNUSED ( binIn )
2019-09-06 23:43:07 -04:00
if ( dType = = TEXT )
{
2019-11-08 22:06:09 -05:00
if ( rd8BitFromBlock ( activeUpdate ) = = 0 )
2019-09-06 23:43:07 -04:00
{
2020-01-29 12:29:01 -05:00
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
errTxt ( " err: You don't currently have any active update sub-channels open. sending a ping request is pointless because peers won't be able to respond. \n " ) ;
}
else
{
2020-03-08 14:58:51 -04:00
async ( ASYNC_PING_PEERS ) ;
2019-09-06 23:43:07 -04:00
}
}
}
2019-11-08 22:06:09 -05:00
void AddRDOnlyFlag : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
if ( dType = = TEXT )
{
2020-01-29 12:29:01 -05:00
auto args = parseArgs ( binIn , 6 ) ;
auto chName = getParam ( " -ch_name " , args ) ;
auto subId = getParam ( " -sub_id " , args ) ;
auto level = getParam ( " -level " , args ) ;
quint64 chId ;
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
if ( chName . isEmpty ( ) )
{
errTxt ( " err: The channel name (-ch_name) argument was not found or is empty. \n " ) ;
}
else if ( subId . isEmpty ( ) )
{
errTxt ( " err: The sub-channel id (-sub_id) was not found or is empty. \n " ) ;
}
else if ( level . isEmpty ( ) )
{
errTxt ( " err: The privilage level (-level) argument was not found or is empty. \n " ) ;
}
else if ( ! validChName ( chName ) )
{
errTxt ( " err: Invalid channel name. \n " ) ;
}
else if ( ! validSubId ( subId ) )
{
errTxt ( " err: Invalid sub-channel id. valid range (0-255). \n " ) ;
}
else if ( ! validLevel ( level , true ) )
{
errTxt ( " err: Invalid privilage level. valid range (1-5). \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( ! channelExists ( chName , & chId ) )
2019-09-06 23:43:07 -04:00
{
errTxt ( " err: Channel name ' " + chName + " ' does not exists. \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( channelAccessLevel ( rdFromBlock ( userId , BLKSIZE_USER_ID ) , chOwnerOverride , chId ) > ADMIN )
2019-09-06 23:43:07 -04:00
{
errTxt ( " err: Access denied. \n " ) ;
}
2020-04-01 11:34:13 -04:00
else if ( rdOnlyFlagExists ( chId , static_cast < quint8 > ( subId . toInt ( ) ) , level . toUInt ( ) ) )
2019-09-06 23:43:07 -04:00
{
2020-04-01 11:34:13 -04:00
errTxt ( " err: A read only flag for sub_id: " + QString : : number ( subId . toInt ( ) ) + " level: " + QString : : number ( level . toUInt ( ) ) + " already exists. \n " ) ;
2019-09-06 23:43:07 -04:00
}
else
2019-11-08 22:06:09 -05:00
{
2020-01-29 12:29:01 -05:00
retCode = NO_ERRORS ;
auto frame = wrInt ( chId , 64 ) + wrInt ( subId . toUInt ( ) , 8 ) + wrInt ( level . toUInt ( ) , 8 ) ;
2019-11-08 22:06:09 -05:00
2019-09-06 23:43:07 -04:00
Query db ( this ) ;
db . setType ( Query : : PUSH , TABLE_RDONLY_CAST ) ;
2019-11-08 22:06:09 -05:00
db . addColumn ( COLUMN_CHANNEL_ID , chId ) ;
2019-09-06 23:43:07 -04:00
db . addColumn ( COLUMN_SUB_CH_ID , subId . toInt ( ) ) ;
db . addColumn ( COLUMN_ACCESS_LEVEL , level . toInt ( ) ) ;
db . exec ( ) ;
2020-03-08 14:58:51 -04:00
async ( ASYNC_ADD_RDONLY , frame ) ;
2019-09-06 23:43:07 -04:00
}
}
}
2019-11-08 22:06:09 -05:00
void RemoveRDOnlyFlag : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
if ( dType = = TEXT )
{
2020-01-29 12:29:01 -05:00
auto args = parseArgs ( binIn , 6 ) ;
auto chName = getParam ( " -ch_name " , args ) ;
auto subId = getParam ( " -sub_id " , args ) ;
auto level = getParam ( " -level " , args ) ;
quint64 chId ;
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
if ( chName . isEmpty ( ) )
{
errTxt ( " err: The channel name (-ch_name) argument was not found or is empty. \n " ) ;
}
else if ( subId . isEmpty ( ) )
{
errTxt ( " err: The sub-channel id (-sub_id) was not found or is empty. \n " ) ;
}
else if ( level . isEmpty ( ) )
{
errTxt ( " err: The privilage level (-level) argument was not found or is empty. \n " ) ;
}
else if ( ! validChName ( chName ) )
{
errTxt ( " err: Invalid channel name. \n " ) ;
}
else if ( ! validSubId ( subId ) )
{
errTxt ( " err: Invalid sub-channel id. valid range (0-255). \n " ) ;
}
else if ( ! validLevel ( level , true ) )
{
errTxt ( " err: Invalid privilage level. valid range (1-5). \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( ! channelExists ( chName , & chId ) )
2019-09-06 23:43:07 -04:00
{
errTxt ( " err: Channel name ' " + chName + " ' does not exists. \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( channelAccessLevel ( rdFromBlock ( userId , BLKSIZE_USER_ID ) , chOwnerOverride , chId ) > ADMIN )
2019-09-06 23:43:07 -04:00
{
errTxt ( " err: Access denied. \n " ) ;
}
2020-04-01 11:34:13 -04:00
else if ( ! rdOnlyFlagExists ( chId , static_cast < quint8 > ( subId . toUInt ( ) ) , level . toUInt ( ) ) )
2019-09-06 23:43:07 -04:00
{
2020-04-01 11:34:13 -04:00
errTxt ( " err: A read only flag for sub_id: " + QString : : number ( subId . toUInt ( ) ) + " level: " + QString : : number ( level . toUInt ( ) ) + " does not exists. \n " ) ;
2019-09-06 23:43:07 -04:00
}
else
{
2020-01-29 12:29:01 -05:00
retCode = NO_ERRORS ;
auto frame = wrInt ( chId , 64 ) + wrInt ( subId . toUInt ( ) , 8 ) + wrInt ( level . toUInt ( ) , 8 ) ;
2019-11-08 22:06:09 -05:00
2019-09-06 23:43:07 -04:00
Query db ( this ) ;
db . setType ( Query : : DEL , TABLE_RDONLY_CAST ) ;
2019-11-08 22:06:09 -05:00
db . addCondition ( COLUMN_CHANNEL_ID , chId ) ;
2019-09-06 23:43:07 -04:00
db . addCondition ( COLUMN_SUB_CH_ID , subId . toInt ( ) ) ;
db . addCondition ( COLUMN_ACCESS_LEVEL , level . toInt ( ) ) ;
db . exec ( ) ;
2020-03-08 14:58:51 -04:00
async ( ASYNC_RM_RDONLY , frame ) ;
2019-09-06 23:43:07 -04:00
}
}
}
2019-11-08 22:06:09 -05:00
void ListRDonlyFlags : : procIn ( const QByteArray & binIn , quint8 dType )
2019-09-06 23:43:07 -04:00
{
if ( dType = = TEXT )
{
2019-11-08 22:06:09 -05:00
if ( flags & MORE_INPUT )
2019-09-06 23:43:07 -04:00
{
2019-11-08 22:06:09 -05:00
TableViewer : : procIn ( binIn , dType ) ;
2019-09-06 23:43:07 -04:00
}
else
{
2020-01-29 12:29:01 -05:00
auto args = parseArgs ( binIn , 2 ) ;
auto chName = getParam ( " -ch_name " , args ) ;
quint64 chId ;
retCode = INVALID_PARAMS ;
2019-09-06 23:43:07 -04:00
if ( chName . isEmpty ( ) )
{
errTxt ( " err: The channel name (-ch_name) argument was not found or is empty. \n " ) ;
}
else if ( ! validChName ( chName ) )
{
errTxt ( " err: Invalid channel name. \n " ) ;
}
2019-11-08 22:06:09 -05:00
else if ( ! channelExists ( chName , & chId ) )
2019-09-06 23:43:07 -04:00
{
errTxt ( " err: Channel name ' " + chName + " ' does not exists. \n " ) ;
}
else
{
2020-01-29 12:29:01 -05:00
retCode = NO_ERRORS ;
2019-11-08 22:06:09 -05:00
if ( channelAccessLevel ( rdFromBlock ( userId , BLKSIZE_USER_ID ) , chOwnerOverride , chId ) > REGULAR )
2019-09-06 23:43:07 -04:00
{
2019-11-08 22:06:09 -05:00
TableViewer : : procIn ( toTEXT ( " - " + QString ( COLUMN_CHANNEL_NAME ) + " " + chName + " - " + QString ( COLUMN_LOWEST_LEVEL ) + " " + QString : : number ( PUBLIC ) ) , dType ) ;
2019-09-06 23:43:07 -04:00
}
else
{
2019-11-08 22:06:09 -05:00
TableViewer : : procIn ( toTEXT ( " - " + QString ( COLUMN_CHANNEL_NAME ) + " " + chName ) , dType ) ;
2019-09-06 23:43:07 -04:00
}
}
}
}
}