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.
tdepim/libkpimexchange/core/exchangeaccount.cpp

340 lines
9.4 KiB

/*
This file is part of libkpimexchange
Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <qstring.h>
#include <qtextstream.h>
#include <qapplication.h>
#include <qdom.h>
#include <qwidgetlist.h>
#include <qwidget.h>
#include <qfile.h>
#include <kurl.h>
#include <kapplication.h>
#include <kdebug.h>
#include <kconfig.h>
#include <dcopclient.h>
#include <kcursor.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kio/authinfo.h>
#include <kio/davjob.h>
#include <kio/job.h>
#include <kio/netaccess.h>
#include "exchangeaccount.h"
#include "utils.h"
using namespace KPIM;
ExchangeAccount::ExchangeAccount( const QString &host, const QString &port,
const QString &account,
const QString &password,
const QString &mailbox )
: mError( false )
{
KURL url( "webdav://" + host + "/exchange/" + account );
if ( !port.isEmpty() )
{
url.setPort( port.toInt() );
}
mHost = host;
mPort = port;
mAccount = account;
mPassword = password;
if ( mailbox.isEmpty() ) {
mMailbox = url.url();
kdDebug() << "#!#!#!#!#!#!# mailbox url: " << mMailbox << endl;
} else
mMailbox = mailbox;
kdDebug() << "ExchangeAccount: mMailbox: " << mMailbox << endl;
mCalendarURL = 0;
}
ExchangeAccount::ExchangeAccount( const QString& group )
{
load( group );
}
ExchangeAccount::~ExchangeAccount()
{
}
QString endecryptStr( const QString &aStr )
{
QString result;
for (uint i = 0; i < aStr.length(); i++)
result += (aStr[i].unicode() < 0x20) ? aStr[i] :
QChar(0x1001F - aStr[i].unicode());
return result;
}
void ExchangeAccount::save( QString const &group )
{
kapp->config()->setGroup( group );
kapp->config()->writeEntry( "host", mHost );
kapp->config()->writeEntry( "user", mAccount );
kapp->config()->writeEntry( "mailbox", mMailbox );
kapp->config()->writeEntry( "MS-ID", endecryptStr( mPassword ) );
kapp->config()->sync();
}
void ExchangeAccount::load( QString const &group )
{
kapp->config()->setGroup( group );
QString host = kapp->config()->readEntry( "host" );
if ( ! host.isNull() ) {
mHost = host;
} else {
mHost = "mail.company.com";
}
QString user = kapp->config()->readEntry( "user" );
if ( ! user.isNull() ) {
mAccount = user;
} else {
mAccount = "username";
}
QString mailbox = kapp->config()->readEntry( "mailbox" );
if ( ! mailbox.isNull() ) {
mMailbox = mailbox;
} else {
mMailbox = "webdav://" + host + "/exchange/" + mAccount;
}
QString password = endecryptStr( kapp->config()->readEntry( "MS-ID" ) );
if ( ! password.isNull() ) {
mPassword = password;
}
}
KURL ExchangeAccount::baseURL()
{
KURL url = KURL( mMailbox );
return url;
}
KURL ExchangeAccount::calendarURL()
{
if ( mCalendarURL ) {
return *mCalendarURL;
} else {
KURL url = baseURL();
url.addPath( "Calendar" );
return url;
}
}
bool ExchangeAccount::authenticate( QWidget *window )
{
if ( window )
return authenticate( window->winId() );
else
return authenticate();
}
bool ExchangeAccount::authenticate()
{
long windowId;
QWidgetList *widgets = QApplication::topLevelWidgets();
if ( widgets->isEmpty() )
windowId = 0;
else
windowId = widgets->first()->winId();
delete widgets;
return authenticate( windowId );
}
bool ExchangeAccount::authenticate( int windowId )
{
kdDebug() << "Entering ExchangeAccount::authenticate( windowId=" << windowId << " )" << endl;
kdDebug() << "Authenticating to base URL: " << baseURL().prettyURL() << endl;
KIO::AuthInfo info;
info.url = baseURL();
info.username = mAccount;
info.password = mPassword;
info.realmValue = mHost;
info.digestInfo = "Basic";
DCOPClient *dcopClient = new DCOPClient();
dcopClient->attach();
QByteArray params;
QDataStream stream(params, IO_WriteOnly);
stream << info << windowId;
dcopClient->send( "kded", "kpasswdserver",
"addAuthInfo(KIO::AuthInfo, long int)", params );
dcopClient->detach();
delete dcopClient;
mCalendarURL = 0;
calcFolderURLs();
// TODO: Remove this busy loop
QApplication::setOverrideCursor( KCursor::waitCursor() );
do {
qApp->processEvents();
} while ( !mCalendarURL && !mError );
QApplication::restoreOverrideCursor();
return !mError;
}
void ExchangeAccount::calcFolderURLs()
{
kdDebug() << "ExchangeAccount::calcFolderURLs" << endl;
QDomDocument doc;
QDomElement root = addElement( doc, doc, "DAV:", "propfind" );
QDomElement prop = addElement( doc, root, "DAV:", "prop" );
addElement( doc, prop, "urn:schemas:httpmail:", "calendar" );
// For later use:
// urn:schemas:httpmail:contacts Contacts
// urn:schemas:httpmail:deleteditems Deleted Items
// urn:schemas:httpmail:drafts Drafts
// urn:schemas:httpmail:inbox Inbox
// urn:schemas:httpmail:journal Journal
// urn:schemas:httpmail:notes Notes
// urn:schemas:httpmail:outbox Outbox
// urn:schemas:httpmail:sentitems Sent Items
// urn:schemas:httpmail:tasks Tasks
// urn:schemas:httpmail:sendmsg Exchange Mail Submission URI
// urn:schemas:httpmail:msgfolderroot Mailbox folder (root)
kdDebug() << "calcFolderUrls(): " << baseURL() << endl;
mError = false;
KIO::DavJob* job = KIO::davPropFind( baseURL(), doc, "1", false );
job->addMetaData( "errorPage", "false" );
connect( job, SIGNAL( result( KIO::Job * ) ),
SLOT( slotFolderResult( KIO::Job * ) ) );
}
void ExchangeAccount::slotFolderResult( KIO::Job *job )
{
kdDebug() << "ExchangeAccount::slotFolderResult()" << endl;
if ( job->error() ) {
kdError() << "Error: Cannot get well-know folder names; " << job->error() << endl;
QString text = i18n("ExchangeAccount\nError accessing '%1': %2")
.arg( baseURL().prettyURL() ).arg( job->errorString() );
KMessageBox::error( 0, text );
mError = true;
return;
}
QDomDocument &response = static_cast<KIO::DavJob *>( job )->response();
QDomElement prop = response.documentElement().namedItem( "response" )
.namedItem( "propstat" ).namedItem( "prop" ).toElement();
QDomElement calElement = prop.namedItem( "calendar" ).toElement();
if ( calElement.isNull() ) {
kdError() << "Error: no calendar URL in Exchange server reply" << endl;
mError = true;
return;
}
QString calendar = calElement.text();
kdDebug() << "ExchangeAccount: response calendarURL: " << calendar << endl;
mCalendarURL = toDAV( new KURL( calendar ) );
kdDebug() << "Calendar URL: " << mCalendarURL->url() << endl;
}
QString ExchangeAccount::tryFindMailbox( const QString& host, const QString& port, const QString& user, const QString& password )
{
kdDebug() << "Entering ExchangeAccount::tryFindMailbox()" << endl;
KURL url("http://" + host + "/exchange");
if (!port.isEmpty()) url.setPort(port.toInt());
QString result = tryMailbox( url.url(), user, password );
if ( result.isNull() )
{
url.setProtocol("https");
result = tryMailbox( url.url(), user, password );
}
return result;
}
QString ExchangeAccount::tryMailbox( const QString &_url, const QString &user,
const QString &password )
{
KURL url = KURL( _url );
url.setUser( user );
url.setPass( password );
QString tmpFile;
if ( !KIO::NetAccess::download( url, tmpFile, 0 ) ) {
kdWarning() << "Trying to find mailbox failed: not able to download " << url.prettyURL() << endl;
return QString::null;
}
QFile file( tmpFile );
if ( !file.open( IO_ReadOnly ) ) {
kdWarning() << "Trying to find mailbox failed: not able to open temp file " << tmpFile << endl;
KIO::NetAccess::removeTempFile( tmpFile );
return QString::null;
}
QTextStream stream( &file );
QString line;
QString result;
while ( !stream.eof() ) {
line = stream.readLine(); // line of text excluding '\n'
int pos = line.find( "<BASE href=\"", 0, FALSE );
if ( pos < 0 )
continue;
int end = line.find( "\"", pos+12, FALSE );
if ( pos < 0 ) {
kdWarning() << "Strange, found no closing quote in " << line << endl;
continue;
}
QString mailboxString = line.mid( pos+12, end-pos-12 );
KURL mailbox( mailboxString );
if ( mailbox.isEmpty() ) {
kdWarning() << "Strange, could not get URL from " << mailboxString << " in line " << line << endl;
continue;
}
result = toDAV( mailbox ).prettyURL( -1 ); // Strip ending slash from URL, if present
kdDebug() << "Found mailbox: " << result << endl;
}
file.close();
KIO::NetAccess::removeTempFile( tmpFile );
return result;
}
#include "exchangeaccount.moc"