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.
340 lines
9.4 KiB
340 lines
9.4 KiB
15 years ago
|
/*
|
||
|
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"
|