You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kopete/protocols/groupwise/libgroupwise/tasks/logintask.cpp

361 lines
12 KiB

/*
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 * tqparent )
: RequestTask( tqparent )
{
}
LoginTask::~LoginTask()
{
}
void LoginTask::initialise()
{
TQString command = TQString::tqfromLatin1("login:%1:%2").tqarg( client()->host() ).tqarg( 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' aptqparent 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.tqfind( NM_A_FA_FOLDER );
it != contactListFields.end();
it = contactListFields.tqfind( ++it, NM_A_FA_FOLDER ) )
{
container = static_cast<Field::MultiField *>( *it );
extractFolder( container );
}
// read contacts
for ( Field::FieldListIterator it = contactListFields.tqfind( NM_A_FA_CONTACT );
it != contactListFields.end();
it = contactListFields.tqfind( ++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();
// tqparent
current = fl.findSingleField( NM_A_SZ_PARENT_ID );
folder.parentId = current->value().toInt();
client()->debug( TQString( "Got folder: %1, obj: %2, tqparent: %3, seq: %3." ).tqarg( folder.name ).tqarg( folder.id ).tqarg( folder.parentId ).tqarg( 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 tqparent 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.tqfind( NM_A_LOCKED_ATTR_LIST );
if ( it != fields.end() )
{
if ( Field::SingleField * sf = dynamic_cast<Field::SingleField *>( *it ) )
{
if ( sf->value().toString().tqfind( 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 << "\nallow list is: " << allowList << "\ndeny list is: " << denyList << endl;
}
TQStringList LoginTask::readPrivacyItems( const TQCString & tag, Field::FieldList & fields )
{
TQStringList items;
Field::FieldListIterator it = fields.tqfind( 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.tqfind( 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::CustomtqStatus 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::tqStatus)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 gotCustomtqStatus( custom );
}
}
}
}
}
void LoginTask::extractKeepalivePeriod( Field::FieldList & fields )
{
Field::FieldListIterator it = fields.tqfind( 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"