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