diff options
Diffstat (limited to 'libkpimexchange/core/exchangeaccount.cpp')
-rw-r--r-- | libkpimexchange/core/exchangeaccount.cpp | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/libkpimexchange/core/exchangeaccount.cpp b/libkpimexchange/core/exchangeaccount.cpp new file mode 100644 index 000000000..9142c9db3 --- /dev/null +++ b/libkpimexchange/core/exchangeaccount.cpp @@ -0,0 +1,339 @@ +/* + 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" |