/*
Kopete Groupwise Protocol
logintask . cpp - Send our credentials to the server and process the contact list and privacy details that it returns .
Copyright ( c ) 2004 SUSE Linux AG http : //www.suse.com
Based on Iris , Copyright ( C ) 2003 Justin Karneges
Kopete ( c ) 2002 - 2004 by the Kopete developers < kopete - devel @ kde . org >
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This library is free software ; you can redistribute it and / or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation ; either *
* version 2 of the License , or ( at your option ) any later version . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
# include "client.h"
# include "response.h"
# include "privacymanager.h"
# include "userdetailsmanager.h"
# include "logintask.h"
LoginTask : : LoginTask ( Task * parent )
: RequestTask ( parent )
{
}
LoginTask : : ~ LoginTask ( )
{
}
void LoginTask : : initialise ( )
{
TQString command = TQString : : fromLatin1 ( " login:%1:%2 " ) . arg ( client ( ) - > host ( ) ) . arg ( client ( ) - > port ( ) ) ;
Field : : FieldList lst ;
lst . append ( new Field : : SingleField ( NM_A_SZ_USERID , 0 , NMFIELD_TYPE_UTF8 , client ( ) - > userId ( ) ) ) ;
lst . append ( new Field : : SingleField ( NM_A_SZ_CREDENTIALS , 0 , NMFIELD_TYPE_UTF8 , client ( ) - > password ( ) ) ) ;
lst . append ( new Field : : SingleField ( NM_A_SZ_USER_AGENT , 0 , NMFIELD_TYPE_UTF8 , client ( ) - > userAgent ( ) ) ) ;
lst . append ( new Field : : SingleField ( NM_A_UD_BUILD , 0 , NMFIELD_TYPE_UDWORD , client ( ) - > protocolVersion ( ) ) ) ;
lst . append ( new Field : : SingleField ( NM_A_IP_ADDRESS , 0 , NMFIELD_TYPE_UTF8 , client ( ) - > ipAddress ( ) ) ) ;
createTransfer ( command , lst ) ;
}
bool LoginTask : : take ( Transfer * transfer )
{
if ( ! forMe ( transfer ) )
return false ;
Response * response = dynamic_cast < Response * > ( transfer ) ;
if ( ! response )
return false ;
if ( response - > resultCode ( ) )
{
setError ( response - > resultCode ( ) ) ;
return true ;
}
response - > fields ( ) . dump ( true ) ;
// read in myself()'s metadata fields and emit signal
Field : : FieldList loginResponseFields = response - > fields ( ) ;
ContactDetails cd = extractUserDetails ( loginResponseFields ) ;
emit gotMyself ( cd ) ;
// read the privacy settings first, because this affects all contacts' apparent status
extractPrivacy ( loginResponseFields ) ;
extractCustomStatuses ( loginResponseFields ) ;
// CREATE CONTACT LIST
// locate contact list
Field : : MultiField * contactList = loginResponseFields . findMultiField ( NM_A_FA_CONTACT_LIST ) ;
if ( contactList )
{
Field : : FieldList contactListFields = contactList - > fields ( ) ;
Field : : MultiField * container ;
// read folders
for ( Field : : FieldListIterator it = contactListFields . find ( NM_A_FA_FOLDER ) ;
it ! = contactListFields . end ( ) ;
it = contactListFields . find ( + + it , NM_A_FA_FOLDER ) )
{
container = static_cast < Field : : MultiField * > ( * it ) ;
extractFolder ( container ) ;
}
// read contacts
for ( Field : : FieldListIterator it = contactListFields . find ( NM_A_FA_CONTACT ) ;
it ! = contactListFields . end ( ) ;
it = contactListFields . find ( + + it , NM_A_FA_CONTACT ) )
{
container = static_cast < Field : : MultiField * > ( * it ) ;
extractContact ( container ) ;
}
}
extractKeepalivePeriod ( loginResponseFields ) ;
setSuccess ( ) ;
return true ;
}
void LoginTask : : extractFolder ( Field : : MultiField * folderContainer )
{
FolderItem folder ;
Field : : SingleField * current ;
Field : : FieldList fl = folderContainer - > fields ( ) ;
// object id
current = fl . findSingleField ( NM_A_SZ_OBJECT_ID ) ;
folder . id = current - > value ( ) . toInt ( ) ;
// sequence number
current = fl . findSingleField ( NM_A_SZ_SEQUENCE_NUMBER ) ;
folder . sequence = current - > value ( ) . toInt ( ) ;
// name
current = fl . findSingleField ( NM_A_SZ_DISPLAY_NAME ) ;
folder . name = current - > value ( ) . toString ( ) ;
// parent
current = fl . findSingleField ( NM_A_SZ_PARENT_ID ) ;
folder . parentId = current - > value ( ) . toInt ( ) ;
client ( ) - > debug ( TQString ( " Got folder: %1, obj: %2, parent: %3, seq: %3. " ) . arg ( folder . name ) . arg ( folder . id ) . arg ( folder . parentId ) . arg ( folder . sequence ) ) ;
// tell the world about it
emit gotFolder ( folder ) ;
}
void LoginTask : : extractContact ( Field : : MultiField * contactContainer )
{
if ( contactContainer - > tag ( ) ! = NM_A_FA_CONTACT )
return ;
ContactItem contact ;
Field : : SingleField * current ;
Field : : FieldList fl = contactContainer - > fields ( ) ;
// sequence number, object and parent IDs are a numeric values but are stored as strings...
current = fl . findSingleField ( NM_A_SZ_OBJECT_ID ) ;
contact . id = current - > value ( ) . toInt ( ) ;
current = fl . findSingleField ( NM_A_SZ_PARENT_ID ) ;
contact . parentId = current - > value ( ) . toInt ( ) ;
current = fl . findSingleField ( NM_A_SZ_SEQUENCE_NUMBER ) ;
contact . sequence = current - > value ( ) . toInt ( ) ;
current = fl . findSingleField ( NM_A_SZ_DISPLAY_NAME ) ;
contact . displayName = current - > value ( ) . toString ( ) ;
current = fl . findSingleField ( NM_A_SZ_DN ) ;
contact . dn = current - > value ( ) . toString ( ) . lower ( ) ;
emit gotContact ( contact ) ;
Field : : MultiField * details = fl . findMultiField ( NM_A_FA_USER_DETAILS ) ;
if ( details ) // not all contact list contacts have these
{
Field : : FieldList detailsFields = details - > fields ( ) ;
ContactDetails cd = extractUserDetails ( detailsFields ) ;
if ( cd . dn . isEmpty ( ) )
cd . dn = contact . dn ;
// tell the UserDetailsManager that we have this contact's details
client ( ) - > userDetailsManager ( ) - > addDetails ( cd ) ;
emit gotContactUserDetails ( cd ) ;
}
}
ContactDetails LoginTask : : extractUserDetails ( Field : : FieldList & fields )
{
ContactDetails cd ;
cd . status = GroupWise : : Invalid ;
cd . archive = false ;
// read the supplied fields, set metadata and status.
Field : : SingleField * sf ;
if ( ( sf = fields . findSingleField ( NM_A_SZ_AUTH_ATTRIBUTE ) ) )
cd . authAttribute = sf - > value ( ) . toString ( ) ;
if ( ( sf = fields . findSingleField ( NM_A_SZ_DN ) ) )
cd . dn = sf - > value ( ) . toString ( ) . lower ( ) ; // HACK: lowercased DN
if ( ( sf = fields . findSingleField ( " CN " ) ) )
cd . cn = sf - > value ( ) . toString ( ) ;
if ( ( sf = fields . findSingleField ( " Given Name " ) ) )
cd . givenName = sf - > value ( ) . toString ( ) ;
if ( ( sf = fields . findSingleField ( " Surname " ) ) )
cd . surname = sf - > value ( ) . toString ( ) ;
if ( ( sf = fields . findSingleField ( " Full Name " ) ) )
cd . fullName = sf - > value ( ) . toString ( ) ;
if ( ( sf = fields . findSingleField ( " nnmArchive " ) ) )
cd . archive = ( sf - > value ( ) . toInt ( ) = = 1 ) ;
if ( ( sf = fields . findSingleField ( NM_A_SZ_STATUS ) ) )
cd . status = sf - > value ( ) . toInt ( ) ;
if ( ( sf = fields . findSingleField ( NM_A_SZ_MESSAGE_BODY ) ) )
cd . awayMessage = sf - > value ( ) . toString ( ) ;
Field : : MultiField * mf ;
TQMap < TQString , TQString > propMap ;
if ( ( mf = fields . findMultiField ( NM_A_FA_INFO_DISPLAY_ARRAY ) ) )
{
Field : : FieldList fl = mf - > fields ( ) ;
const Field : : FieldListIterator end = fl . end ( ) ;
for ( Field : : FieldListIterator it = fl . begin ( ) ; it ! = end ; + + it )
{
Field : : SingleField * propField = dynamic_cast < Field : : SingleField * > ( * it ) ;
if ( propField )
{
TQString propName = propField - > tag ( ) ;
TQString propValue = propField - > value ( ) . toString ( ) ;
propMap . insert ( propName , propValue ) ;
}
else
{
Field : : MultiField * propList = dynamic_cast < Field : : MultiField * > ( * it ) ;
if ( propList )
{
// Hello A Nagappan. GW gave us a multiple field where we previously got a single field
TQString parentName = propList - > tag ( ) ;
Field : : FieldList propFields = propList - > fields ( ) ;
const Field : : FieldListIterator end = propFields . end ( ) ;
for ( Field : : FieldListIterator it = propFields . begin ( ) ; it ! = end ; + + it )
{
propField = dynamic_cast < Field : : SingleField * > ( * it ) ;
if ( propField /*&& propField->tag() == parentName */ )
{
TQString propValue = propField - > value ( ) . toString ( ) ;
TQString contents = propMap [ propField - > tag ( ) ] ;
if ( ! contents . isEmpty ( ) )
contents . append ( " , " ) ;
contents . append ( propField - > value ( ) . toString ( ) ) ;
propMap . insert ( propField - > tag ( ) , contents ) ;
}
}
}
}
}
}
if ( ! propMap . empty ( ) )
{
cd . properties = propMap ;
}
return cd ;
}
void LoginTask : : extractPrivacy ( Field : : FieldList & fields )
{
bool privacyLocked = false ;
bool defaultDeny = false ;
TQStringList allowList ;
TQStringList denyList ;
// read blocking
// may be a single field or may be an array
Field : : FieldListIterator it = fields . find ( NM_A_LOCKED_ATTR_LIST ) ;
if ( it ! = fields . end ( ) )
{
if ( Field : : SingleField * sf = dynamic_cast < Field : : SingleField * > ( * it ) )
{
if ( sf - > value ( ) . toString ( ) . find ( NM_A_BLOCKING ) )
privacyLocked = true ;
}
else if ( Field : : MultiField * mf = dynamic_cast < Field : : MultiField * > ( * it ) )
{
Field : : FieldList fl = mf - > fields ( ) ;
for ( Field : : FieldListIterator it = fl . begin ( ) ; it ! = fl . end ( ) ; + + it )
{
if ( Field : : SingleField * sf = dynamic_cast < Field : : SingleField * > ( * it ) )
{
if ( sf - > tag ( ) = = NM_A_BLOCKING )
{
privacyLocked = true ;
break ;
}
}
}
}
}
// read default privacy policy
Field : : SingleField * sf = fields . findSingleField ( NM_A_BLOCKING ) ;
if ( sf )
defaultDeny = ( sf - > value ( ) . toInt ( ) ! = 0 ) ;
// read deny list
denyList = readPrivacyItems ( NM_A_BLOCKING_DENY_LIST , fields ) ;
// read allow list
allowList = readPrivacyItems ( NM_A_BLOCKING_ALLOW_LIST , fields ) ;
emit gotPrivacySettings ( privacyLocked , defaultDeny , allowList , denyList ) ;
kdDebug ( GROUPWISE_DEBUG_GLOBAL ) < < " locked is " < < privacyLocked < < " , default is " < < defaultDeny < < " \n allow list is: " < < allowList < < " \n deny list is: " < < denyList < < endl ;
}
TQStringList LoginTask : : readPrivacyItems ( const TQCString & tag , Field : : FieldList & fields )
{
TQStringList items ;
Field : : FieldListIterator it = fields . find ( tag ) ;
if ( it ! = fields . end ( ) )
{
if ( Field : : SingleField * sf = dynamic_cast < Field : : SingleField * > ( * it ) )
{
items . append ( sf - > value ( ) . toString ( ) . lower ( ) ) ;
}
else if ( Field : : MultiField * mf = dynamic_cast < Field : : MultiField * > ( * it ) )
{
Field : : FieldList fl = mf - > fields ( ) ;
for ( Field : : FieldListIterator it = fl . begin ( ) ; it ! = fl . end ( ) ; + + it )
{
if ( Field : : SingleField * sf = dynamic_cast < Field : : SingleField * > ( * it ) )
{
items . append ( sf - > value ( ) . toString ( ) . lower ( ) ) ;
}
}
}
}
return items ;
}
void LoginTask : : extractCustomStatuses ( Field : : FieldList & fields )
{
Field : : FieldListIterator it = fields . find ( NM_A_FA_CUSTOM_STATUSES ) ;
if ( it ! = fields . end ( ) )
{
if ( Field : : MultiField * mf = dynamic_cast < Field : : MultiField * > ( * it ) )
{
Field : : FieldList fl = mf - > fields ( ) ;
for ( Field : : FieldListIterator custStatIt = fl . begin ( ) ; custStatIt ! = fl . end ( ) ; + + custStatIt )
{
Field : : MultiField * mf2 = dynamic_cast < Field : : MultiField * > ( * custStatIt ) ;
if ( mf2 & & ( mf2 - > tag ( ) = = NM_A_FA_STATUS ) )
{
GroupWise : : CustomStatus custom ;
Field : : FieldList fl2 = mf2 - > fields ( ) ;
for ( Field : : FieldListIterator custContentIt = fl2 . begin ( ) ; custContentIt ! = fl2 . end ( ) ; + + custContentIt )
{
if ( Field : : SingleField * sf3 = dynamic_cast < Field : : SingleField * > ( * custContentIt ) )
{
if ( sf3 - > tag ( ) = = NM_A_SZ_TYPE )
custom . status = ( GroupWise : : Status ) sf3 - > value ( ) . toInt ( ) ;
else if ( sf3 - > tag ( ) = = NM_A_SZ_DISPLAY_NAME )
custom . name = sf3 - > value ( ) . toString ( ) ;
else if ( sf3 - > tag ( ) = = NM_A_SZ_MESSAGE_BODY )
custom . autoReply = sf3 - > value ( ) . toString ( ) ;
}
}
emit gotCustomStatus ( custom ) ;
}
}
}
}
}
void LoginTask : : extractKeepalivePeriod ( Field : : FieldList & fields )
{
Field : : FieldListIterator it = fields . find ( NM_A_UD_KEEPALIVE ) ;
if ( it ! = fields . end ( ) )
{
if ( Field : : SingleField * sf = dynamic_cast < Field : : SingleField * > ( * it ) )
{
bool ok ;
int period = sf - > value ( ) . toInt ( & ok ) ;
if ( ok )
{
emit gotKeepalivePeriod ( period ) ;
}
}
}
}
# include "logintask.moc"