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