00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qstring.h>
00024 #include <qtextstream.h>
00025 #include <qapplication.h>
00026 #include <qdom.h>
00027 #include <qwidgetlist.h>
00028 #include <qwidget.h>
00029 #include <qfile.h>
00030
00031 #include <kurl.h>
00032 #include <kapplication.h>
00033 #include <kdebug.h>
00034 #include <kconfig.h>
00035 #include <dcopclient.h>
00036 #include <kcursor.h>
00037 #include <kmessagebox.h>
00038 #include <klocale.h>
00039
00040 #include <kio/authinfo.h>
00041 #include <kio/davjob.h>
00042 #include <kio/job.h>
00043 #include <kio/netaccess.h>
00044
00045 #include "exchangeaccount.h"
00046 #include "utils.h"
00047
00048 using namespace KPIM;
00049
00050 ExchangeAccount::ExchangeAccount( const QString &host, const QString &port,
00051 const QString &account,
00052 const QString &password,
00053 const QString &mailbox )
00054 : mError( false )
00055 {
00056 KURL url( "webdav://" + host + "/exchange/" + account );
00057
00058 if ( !port.isEmpty() )
00059 {
00060 url.setPort( port.toInt() );
00061 }
00062
00063 mHost = host;
00064 mPort = port;
00065 mAccount = account;
00066 mPassword = password;
00067
00068 if ( mailbox.isEmpty() ) {
00069 mMailbox = url.url();
00070 kdDebug() << "#!#!#!#!#!#!# mailbox url: " << mMailbox << endl;
00071 } else
00072 mMailbox = mailbox;
00073
00074 kdDebug() << "ExchangeAccount: mMailbox: " << mMailbox << endl;
00075
00076 mCalendarURL = 0;
00077 }
00078
00079 ExchangeAccount::ExchangeAccount( const QString& group )
00080 {
00081 load( group );
00082 }
00083
00084 ExchangeAccount::~ExchangeAccount()
00085 {
00086 }
00087
00088 QString endecryptStr( const QString &aStr )
00089 {
00090 QString result;
00091 for (uint i = 0; i < aStr.length(); i++)
00092 result += (aStr[i].unicode() < 0x20) ? aStr[i] :
00093 QChar(0x1001F - aStr[i].unicode());
00094 return result;
00095 }
00096
00097 void ExchangeAccount::save( QString const &group )
00098 {
00099 kapp->config()->setGroup( group );
00100 kapp->config()->writeEntry( "host", mHost );
00101 kapp->config()->writeEntry( "user", mAccount );
00102 kapp->config()->writeEntry( "mailbox", mMailbox );
00103 kapp->config()->writeEntry( "MS-ID", endecryptStr( mPassword ) );
00104 kapp->config()->sync();
00105 }
00106
00107 void ExchangeAccount::load( QString const &group )
00108 {
00109 kapp->config()->setGroup( group );
00110
00111 QString host = kapp->config()->readEntry( "host" );
00112 if ( ! host.isNull() ) {
00113 mHost = host;
00114 } else {
00115 mHost = "mail.company.com";
00116 }
00117
00118 QString user = kapp->config()->readEntry( "user" );
00119 if ( ! user.isNull() ) {
00120 mAccount = user;
00121 } else {
00122 mAccount = "username";
00123 }
00124
00125 QString mailbox = kapp->config()->readEntry( "mailbox" );
00126 if ( ! mailbox.isNull() ) {
00127 mMailbox = mailbox;
00128 } else {
00129 mMailbox = "webdav://" + host + "/exchange/" + mAccount;
00130 }
00131
00132 QString password = endecryptStr( kapp->config()->readEntry( "MS-ID" ) );
00133 if ( ! password.isNull() ) {
00134 mPassword = password;
00135 }
00136 }
00137
00138 KURL ExchangeAccount::baseURL()
00139 {
00140 KURL url = KURL( mMailbox );
00141 return url;
00142 }
00143
00144 KURL ExchangeAccount::calendarURL()
00145 {
00146 if ( mCalendarURL ) {
00147 return *mCalendarURL;
00148 } else {
00149 KURL url = baseURL();
00150 url.addPath( "Calendar" );
00151 return url;
00152 }
00153 }
00154
00155 bool ExchangeAccount::authenticate( QWidget *window )
00156 {
00157 if ( window )
00158 return authenticate( window->winId() );
00159 else
00160 return authenticate();
00161 }
00162
00163 bool ExchangeAccount::authenticate()
00164 {
00165 long windowId;
00166 QWidgetList *widgets = QApplication::topLevelWidgets();
00167 if ( widgets->isEmpty() )
00168 windowId = 0;
00169 else
00170 windowId = widgets->first()->winId();
00171 delete widgets;
00172
00173 return authenticate( windowId );
00174 }
00175
00176 bool ExchangeAccount::authenticate( int windowId )
00177 {
00178 kdDebug() << "Entering ExchangeAccount::authenticate( windowId=" << windowId << " )" << endl;
00179
00180 kdDebug() << "Authenticating to base URL: " << baseURL().prettyURL() << endl;
00181
00182 KIO::AuthInfo info;
00183 info.url = baseURL();
00184 info.username = mAccount;
00185 info.password = mPassword;
00186 info.realmValue = mHost;
00187 info.digestInfo = "Basic";
00188
00189 DCOPClient *dcopClient = new DCOPClient();
00190 dcopClient->attach();
00191
00192 QByteArray params;
00193 QDataStream stream(params, IO_WriteOnly);
00194 stream << info << windowId;
00195
00196 dcopClient->send( "kded", "kpasswdserver",
00197 "addAuthInfo(KIO::AuthInfo, long int)", params );
00198
00199 dcopClient->detach();
00200 delete dcopClient;
00201
00202 mCalendarURL = 0;
00203
00204 calcFolderURLs();
00205
00206
00207 QApplication::setOverrideCursor( KCursor::waitCursor() );
00208 do {
00209 qApp->processEvents();
00210 } while ( !mCalendarURL && !mError );
00211 QApplication::restoreOverrideCursor();
00212
00213 return !mError;
00214 }
00215
00216 void ExchangeAccount::calcFolderURLs()
00217 {
00218 kdDebug() << "ExchangeAccount::calcFolderURLs" << endl;
00219 QDomDocument doc;
00220 QDomElement root = addElement( doc, doc, "DAV:", "propfind" );
00221 QDomElement prop = addElement( doc, root, "DAV:", "prop" );
00222 addElement( doc, prop, "urn:schemas:httpmail:", "calendar" );
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 kdDebug() << "calcFolderUrls(): " << baseURL() << endl;
00237
00238 mError = false;
00239
00240 KIO::DavJob* job = KIO::davPropFind( baseURL(), doc, "0", false );
00241 job->addMetaData( "errorPage", "false" );
00242 connect( job, SIGNAL( result( KIO::Job * ) ),
00243 SLOT( slotFolderResult( KIO::Job * ) ) );
00244 }
00245
00246 void ExchangeAccount::slotFolderResult( KIO::Job *job )
00247 {
00248 kdDebug() << "ExchangeAccount::slotFolderResult()" << endl;
00249 if ( job->error() ) {
00250 kdError() << "Error: Cannot get well-know folder names; " << job->error() << endl;
00251 QString text = i18n("ExchangeAccount\nError accessing '%1': %2")
00252 .arg( baseURL().prettyURL() ).arg( job->errorString() );
00253 KMessageBox::error( 0, text );
00254 mError = true;
00255 return;
00256 }
00257 QDomDocument &response = static_cast<KIO::DavJob *>( job )->response();
00258
00259 QDomElement prop = response.documentElement().namedItem( "response" )
00260 .namedItem( "propstat" ).namedItem( "prop" ).toElement();
00261
00262 QDomElement calElement = prop.namedItem( "calendar" ).toElement();
00263 if ( calElement.isNull() ) {
00264 kdError() << "Error: no calendar URL in Exchange server reply" << endl;
00265 mError = true;
00266 return;
00267 }
00268 QString calendar = calElement.text();
00269
00270 kdDebug() << "ExchangeAccount: response calendarURL: " << calendar << endl;
00271
00272 mCalendarURL = toDAV( new KURL( calendar ) );
00273 kdDebug() << "Calendar URL: " << mCalendarURL->url() << endl;
00274 }
00275
00276 QString ExchangeAccount::tryFindMailbox( const QString& host, const QString& port, const QString& user, const QString& password )
00277 {
00278 kdDebug() << "Entering ExchangeAccount::tryFindMailbox()" << endl;
00279
00280 KURL url("http://" + host + "/exchange");
00281 if (!port.isEmpty()) url.setPort(port.toInt());
00282
00283 QString result = tryMailbox( url.url(), user, password );
00284 if ( result.isNull() )
00285 {
00286 url.setProtocol("https");
00287 result = tryMailbox( url.url(), user, password );
00288 }
00289 return result;
00290 }
00291
00292 QString ExchangeAccount::tryMailbox( const QString &_url, const QString &user,
00293 const QString &password )
00294 {
00295 KURL url = KURL( _url );
00296 url.setUser( user );
00297 url.setPass( password );
00298
00299 QString tmpFile;
00300 if ( !KIO::NetAccess::download( url, tmpFile, 0 ) ) {
00301 kdWarning() << "Trying to find mailbox failed: not able to download " << url.prettyURL() << endl;
00302 return QString::null;
00303 }
00304 QFile file( tmpFile );
00305 if ( !file.open( IO_ReadOnly ) ) {
00306 kdWarning() << "Trying to find mailbox failed: not able to open temp file " << tmpFile << endl;
00307 KIO::NetAccess::removeTempFile( tmpFile );
00308 return QString::null;
00309 }
00310
00311 QTextStream stream( &file );
00312 QString line;
00313 QString result;
00314 while ( !stream.eof() ) {
00315 line = stream.readLine();
00316 int pos = line.find( "<BASE href=\"", 0, FALSE );
00317 if ( pos < 0 )
00318 continue;
00319 int end = line.find( "\"", pos+12, FALSE );
00320 if ( pos < 0 ) {
00321 kdWarning() << "Strange, found no closing quote in " << line << endl;
00322 continue;
00323 }
00324 QString mailboxString = line.mid( pos+12, end-pos-12 );
00325 KURL mailbox( mailboxString );
00326 if ( mailbox.isEmpty() ) {
00327 kdWarning() << "Strange, could not get URL from " << mailboxString << " in line " << line << endl;
00328 continue;
00329 }
00330 result = toDAV( mailbox ).prettyURL( -1 );
00331 kdDebug() << "Found mailbox: " << result << endl;
00332 }
00333 file.close();
00334
00335 KIO::NetAccess::removeTempFile( tmpFile );
00336 return result;
00337 }
00338
00339 #include "exchangeaccount.moc"