[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: [PATCH] Add multiple account saving support to KHTML/Konqueror
From:       Filip Brcic <brcha () gna ! org>
Date:       2010-08-01 14:58:47
Message-ID: 201008011659.06451.brcha () gna ! org
[Download RAW message or body]

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday, 29. July 2010. 15.53.19 Maksim Orlovich wrote:
> Thanks for this... I'll try to take a look at this, but I feel like I
> should do my planned refactoring of the KWallet code in KHTML first,
> as it should make fixing the remaining things easier, too.

You are welcome.

I ran this patch for a week, found some errors (1: system offered to save 
password always, not only when it is new or changed + 2: you had to click on 
the password field so that it gets filled with the password because I didn't 
"setFocusNode" before setting the value) and fixed them. Also, I added support 
for writing password values using KHTMLWalletQueue as well.

What did you have in mind about refactoring KWallet in KHTML? I read (and 
changed) almost all KWallet related code in KHTML, so maybe I could be of some 
assistance.

- -- 
Filip Brcic <brcha@gna.org>
WWWeb: http://www.brcha.iz.rs
Jabber  : brcha@kdetalk.net 
GPG 0x2537C379
Fingerprint: 287D 5F24 50AA A36C 977F AC9A F1FD C7EB 2537 C379
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.14 (GNU/Linux)

iQIcBAEBAgAGBQJMVYu5AAoJEPH9x+slN8N588MP/iTVJgObjXu8snXEBxvoWXG0
EJF+8OTpY25PNE4P7BqMGV2HUbDCa7In/C9ZQWM47lF3jytPocJ0HrDmzpnNgSwK
vpJPQkS4SUFLIGJkTA5FjwDlL6aLA72qCU3ZtkBfO86TkgTWwkJjzQ+8T+ferD2k
jTOzmmWFgbAyZxB9RhZWgUwgYgidrOo5NKF0d4mjd8F9UV8mH56Gz+KKSjBQCuEC
ZCy3Rk1aeVFftOTHXcRQNv61LzG8bhTK+zS1aI8qo62mb9MHejkcv+zqXHyqdKVG
UU7mlbH9Cy5s6zoTOY0B4GiAOZ6ZqYOdwIMxXXmldCUzOGAYgqNKIapcFHlnYWZO
L6OjpgvXYKzuYlz3gmExUCE+yqHV6zjgbp5M53lv0G8FZ4X5IIjG8j/IHoMNardk
BVyUbzlm1N2BNjUVmMVcob5INOpxt1k6QcEJWIpkV9VZMuNYJ8+Pq+Vg0VSAZTtM
zMqHU1Fn6TAz1UGZ9YpQu66hKzym68fjftjZ0fhGIxpp8D1tx8okz3Dc7biB94oh
WB14A/vSLpWEc881SoBLbO7Vc5utrjWWCUxSofIVhzVx9EV9O3Y1NxbejzIybbly
oyCvz/2guU5G90i1gok20gZlFY0FHALOstRQLVC4n0Mwz13kwooXrwb6Z8Xa98wm
MnMzZwba/xmxhuyE/Ev1
=TA5i
-----END PGP SIGNATURE-----

["kdelibs--khtml--enable_multiaccount_saving-2.diff" (text/x-patch)]

Index: khtml/khtml_part.h
===================================================================
--- khtml/khtml_part.h	(revision 1152611)
+++ khtml/khtml_part.h	(working copy)
@@ -7,6 +7,7 @@
  *                     2000-2001 Simon Hausmann <hausmann@kde.org>
  *                     2000-2001 Dirk Mueller <mueller@kde.org>
  *                     2000 Stefan Schimanski <1Stein@gmx.de>
+ *                     2010 Filip Brcic <brcha@gna.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -1676,8 +1677,14 @@
 
   void openWallet(DOM::HTMLFormElementImpl*);
   void saveToWallet(const QString& key, const QMap<QString,QString>& data);
+  // BEGIN CHANGE [BRCHA]: Save/get password to/from wallet
+  void savePasswordToWallet(const QString& key, const QString& password);
+  QString getPasswordFromWallet(const QString& key);
+  // END CHANGE [BRCHA]
   void dequeueWallet(DOM::HTMLFormElementImpl*);
   void saveLoginInformation(const QString& host, const QString& key, const \
QMap<QString, QString>& walletMap); +  // BEGIN CHANGE [BRCHA]: Save username & \
password to wallet +  void saveAccount(const QString& host, const QString& \
accountKey, const QString& accountsKey, const QString& username, const QString& \
password);  
   void enableFindAheadActions(bool);
 
Index: khtml/khtml_wallet_p.h
===================================================================
--- khtml/khtml_wallet_p.h	(revision 1152611)
+++ khtml/khtml_wallet_p.h	(working copy)
@@ -57,6 +57,9 @@
     typedef QList<Caller> CallerList;
     CallerList callers;
     QList<QPair<QString, QMap<QString, QString> > > savers;
+    // BEGIN CHANGE [BRCHA]: support password savers
+    QList<QPair<QString, QString> > pwd_savers;
+    // END CHANGE [BRCHA]
 
   Q_SIGNALS:
     void walletOpened(KWallet::Wallet*);
@@ -81,9 +84,17 @@
         for (QList<QPair<QString, QMap<QString, QString> > >::Iterator i = \
savers.begin(); i != savers.end(); ++i) {  wallet->writeMap((*i).first, (*i).second);
         }
+        // BEGIN CHANGE [BRCHA]: Password savers
+        for (QList<QPair<QString, QString> >::Iterator i = pwd_savers.begin(); i != \
pwd_savers.end(); ++i) { +            wallet->writePassword((*i).first, (*i).second);
       }
+        // END CHANGE [BRCHA]
+      }
       callers.clear();
       savers.clear();
+      // BEGIN CHANGE [BRCHA]: Password savers
+      pwd_savers.clear();
+      // END CHANGE [BRCHA]
       wallet = 0L; // gave it away
     }
 };
Index: khtml/khtml_part.cpp
===================================================================
--- khtml/khtml_part.cpp	(revision 1152611)
+++ khtml/khtml_part.cpp	(working copy)
@@ -10,6 +10,7 @@
  *                     2000-2005 David Faure <faure@kde.org>
  *                     2002 Apple Computer, Inc.
  *                     2010 Maksim Orlovich (maksim@kde.org)
+ *                     2010 Filip Brcic <brcha@gna.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -7071,7 +7072,81 @@
 #endif // KHTML_NO_WALLET
 }
 
+// BEGIN CHANGE [BRCHA]: Save/get password to/from the wallet
+void KHTMLPart::savePasswordToWallet(const QString& key, const QString& password)
+{
+#ifndef KHTML_NO_WALLET
+  KHTMLPart *p;
 
+  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
+  }
+
+  if (p) {
+    p->savePasswordToWallet(key, password);
+    return;
+  }
+
+  if (d->m_wallet) {
+    if (d->m_bWalletOpened) {
+      if (d->m_wallet->isOpen()) {
+        if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder())) {
+          d->m_wallet->createFolder(KWallet::Wallet::FormDataFolder());
+        }
+        d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
+        d->m_wallet->writePassword(key, password);
+        return;
+      }
+      d->m_wallet->deleteLater();
+      d->m_wallet = 0L;
+      d->m_bWalletOpened = false;
+    }
+  }
+
+  if (!d->m_wq) {
+    KWallet::Wallet *wallet = \
KWallet::Wallet::openWallet(KWallet::Wallet::NetworkWallet(), widget() ? \
widget()->topLevelWidget()->winId() : 0, KWallet::Wallet::Asynchronous); +    d->m_wq \
= new KHTMLWalletQueue(this); +    d->m_wq->wallet = wallet;
+    connect(wallet, SIGNAL(walletOpened(bool)), d->m_wq, SLOT(walletOpened(bool)));
+    connect(d->m_wq, SIGNAL(walletOpened(KWallet::Wallet*)), this, \
SLOT(walletOpened(KWallet::Wallet*))); +  }
+  d->m_wq->pwd_savers.append(qMakePair(key, password));
+#endif // KHTML_NO_WALLET
+}
+
+QString KHTMLPart::getPasswordFromWallet(const QString& key)
+{
+#ifndef KHTML_NO_WALLET
+  KHTMLPart *p;
+
+  for (p = parentPart(); p && p->parentPart(); p = p->parentPart()) {
+  }
+
+  if (p) {
+      return p->getPasswordFromWallet(key);
+  }
+
+  if (d->m_wallet) {
+    if (d->m_bWalletOpened) {
+      if (d->m_wallet->isOpen()) {
+        if (!d->m_wallet->hasFolder(KWallet::Wallet::FormDataFolder()))
+            return QString( "" );
+        d->m_wallet->setFolder(KWallet::Wallet::FormDataFolder());
+        QString password;
+        if ( d->m_wallet->readPassword(key,  password) == 0 )
+            return password;
+        return QString( "" );
+      }
+      d->m_wallet->deleteLater();
+      d->m_wallet = 0L;
+      d->m_bWalletOpened = false;
+    }
+  }
+
+#endif // KHTML_NO_WALLET
+  return QString( "" );
+}
+// END CHANGE [BRCHA]
+
 void KHTMLPart::dequeueWallet(DOM::HTMLFormElementImpl *form) {
 #ifndef KHTML_NO_WALLET
   KHTMLPart *p;
@@ -7252,6 +7327,15 @@
 #endif // KHTML_NO_WALLET
 }
 
+// BEGIN CHANGE [BRCHA]: Save username & password to kwallet
+void KHTMLPart::saveAccount(const QString& host, const QString& accountKey,  const \
QString& accountsKey, const QString& username,  const QString& password ) +{
+#ifndef KHTML_NO_WALLET
+  d->m_storePass.saveAccount(host, accountKey, accountsKey, username, password);
+#endif // KHTML_NO_WALLET
+}
+// END CHANGE [BRCHA]
+
 void KHTMLPart::slotToggleCaretMode()
 {
   setCaretMode(d->m_paToggleCaretMode->isChecked());
Index: khtml/html/html_formimpl.cpp
===================================================================
--- khtml/html/html_formimpl.cpp	(revision 1152611)
+++ khtml/html/html_formimpl.cpp	(working copy)
@@ -5,6 +5,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  *           (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *           (C) 2010 Filip Brcic (brcha@gna.org)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -495,11 +496,19 @@
 {
 #ifndef KHTML_NO_WALLET
     const QString key = calculateAutoFillKey(*this);
+    // BEGIN CHANGE [BRCHA]: Auto fill with new data model
+    const KUrl formUrl( document()->URL() );
+    const QString accountsKey = QString( "accounts_" ) + formUrl.host();
 
     if (KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(),
                                          KWallet::Wallet::FormDataFolder(),
-                                         key))
+                                         key) &&
+        KWallet::Wallet::keyDoesNotExist( KWallet::Wallet::NetworkWallet(),
+                                          KWallet::Wallet::FormDataFolder(),
+                                          accountsKey )
+        )
         return;
+    // END CHANGE [BRCHA]
 
     // assert(view())
     document()->view()->part()->openWallet(this);
@@ -511,22 +520,88 @@
 #ifndef KHTML_NO_WALLET
     assert(w);
     const QString key = calculateAutoFillKey(*this);
+    // BEGIN CHANGE [BRCHA]: Autofill with new data model
+    const KUrl formUrl( document()->URL() );
+    const QString accountKeyTmpl = QString( "account_" ) + formUrl.host() + "_%1";
+    const QString accountsKey = QString( "accounts_" ) + formUrl.host();
+    // END CHANGE [BRCHA]
     if (!w->hasFolder(KWallet::Wallet::FormDataFolder())) {
         return; // failed
     }
     w->setFolder(KWallet::Wallet::FormDataFolder());
+    // BEGIN CHANGE [BRCHA]
     QMap<QString, QString> map;
-    if (w->readMap(key, map))
+    bool isAccountSaved = false;
+    QStringList accounts;
+    if ( w->hasEntry( accountsKey ) ) {
+        isAccountSaved = true;
+        QString accountsStr;
+        if ( w->readPassword( accountsKey,  accountsStr ) )
         return; // failed, abort
+        accounts = accountsStr.split( "\n" );
 
+        for ( int i = 0; i < accounts.size(); i++ ) {
+            QString password;
+            if ( ! w->readPassword( accountKeyTmpl.arg( accounts[i] ), password ) )
+                map[accounts[i]] = password;
+        }
+    }
+    else if (w->readMap(key, map))
+        return; // failed, abort
+    // END CHANGE [BRCHA]
+
     if(document()->view())
     {
         document()->view()->part()->addWalletFormKey(key);
     }
+    // BEGIN CHANGE [BRCHA]: Possible username
+    QString possibleUsername;
+    // Doesn't have multiple password & username fields
+    // The new way
+    if ( isAccountSaved ) {
+        HTMLInputElementImpl* usernameField = NULL;
+        HTMLInputElementImpl* passwordField = NULL;
+        bool fill = true;
+        // Find username and password fields
     for (QListIterator<HTMLGenericFormElementImpl*> it(formElements); it.hasNext();) \
{  HTMLGenericFormElementImpl* const cur = it.next();
         if (cur->id() == ID_INPUT) {
             HTMLInputElementImpl* const current = \
static_cast<HTMLInputElementImpl*>(cur); +                if ( ( current->inputType() \
== HTMLInputElementImpl::TEXT ) && +                     ! current->readOnly() &&
+                     fill ) {
+                    if ( usernameField == NULL )
+                        usernameField = current;
+                    else
+                        fill = false;
+                }
+                else if ( ( current->inputType() == HTMLInputElementImpl::PASSWORD ) \
&& +                          ! current->readOnly() &&
+                          fill ) {
+                    if ( passwordField == NULL )
+                        passwordField = current;
+                    else
+                        fill = false;
+                }
+            }
+        }
+
+        // Ok, now check if we found username and password fields
+        if ( fill &&
+             ( usernameField != NULL ) &&
+             ( passwordField != NULL ) ) {
+            // I guess so, now fill this up
+            usernameField->setPasswordCompanion( passwordField );
+            usernameField->setAccounts( map );
+            document()->setFocusNode( usernameField );
+        }
+    }
+    else {
+        // The old way (just copied)
+        for (QListIterator<HTMLGenericFormElementImpl*> it(formElements); \
it.hasNext();) { +            HTMLGenericFormElementImpl* const cur = it.next();
+            if (cur->id() == ID_INPUT) {
+                HTMLInputElementImpl* const current = \
                static_cast<HTMLInputElementImpl*>(cur);
             if ((current->inputType() == HTMLInputElementImpl::PASSWORD ||
                     current->inputType() == HTMLInputElementImpl::TEXT) &&
                     !current->readOnly() &&
@@ -536,6 +611,8 @@
             }
         }
     }
+    }
+    // END CHANGE [BRCHA]
 #endif // KHTML_NO_WALLET
 }
 
@@ -587,10 +664,34 @@
     m_haveTextarea = false;
     const KUrl formUrl(document()->URL());
     if (view && !view->nonPasswordStorableSite(formUrl.host())) {
+        // BEGIN CHANGE [BRCHA]: initialize store as password variables
+	m_hasMultipleNonPasswordFields = false;
+	m_hasMultiplePasswordFields = false;
+	m_username.clear();
+	m_password.clear();
+	// END CHANGE [BRCHA]
         for (QListIterator<HTMLGenericFormElementImpl*> it(formElements); \
it.hasNext();) {  HTMLGenericFormElementImpl* const cur = it.next();
             if (cur->id() == ID_INPUT)  {
                 HTMLInputElementImpl* const c = static_cast<HTMLInputElementImpl*> \
(cur); +		// BEGIN CHANGE [BRCHA]: Store username & password
+		if (!m_hasMultipleNonPasswordFields &&
+		    c->inputType() == HTMLInputElementImpl::TEXT &&
+		    !c->readOnly()) {
+		    if (m_username.isEmpty())
+		        m_username = c->value().string();
+		    else
+		        m_hasMultipleNonPasswordFields = true;
+		}
+		if (!m_hasMultipleNonPasswordFields &&
+		    c->inputType() == HTMLInputElementImpl::PASSWORD &&
+		    !c->readOnly()) {
+		  if (m_password.isEmpty())
+		      m_password = c->value().string();
+		  else
+		      m_hasMultiplePasswordFields = true;
+                }
+		// END CHANGE [BRCHA]
                 if ((c->inputType() == HTMLInputElementImpl::TEXT ||
                         c->inputType() == HTMLInputElementImpl::PASSWORD) &&
                         !c->readOnly())  {
@@ -653,7 +754,49 @@
             gatherWalletData();
         }
 #ifndef KHTML_NO_WALLET
-        if (m_havePassword && !m_haveTextarea && KWallet::Wallet::isEnabled()) {
+        // BEGIN CHANGE [BRCHA]: Add support for password storing first
+        if ( !m_hasMultipleNonPasswordFields && !m_hasMultiplePasswordFields &&
+             !m_username.isEmpty() && !m_password.isEmpty() &&
+             KWallet::Wallet::isEnabled()) {
+            // Store as username/password pair instead of form data
+            // Now key should be account_HOSTNAME_USERNAME and value=password
+            // Also, save "password" accounts_HOSTNAME with value=\n separated \
username list +            const QString accountKey = QString( "account_" ) + \
formUrl.host() + "_" + m_username; +            const QString accountsKey = QString( \
"accounts_" ) + formUrl.host(); +            const bool doesnotexist =
+                KWallet::Wallet::keyDoesNotExist(
+                    KWallet::Wallet::NetworkWallet(),
+                    KWallet::Wallet::FormDataFolder(),
+                    accountsKey ) ||
+                KWallet::Wallet::keyDoesNotExist(
+                    KWallet::Wallet::NetworkWallet(),
+                    KWallet::Wallet::FormDataFolder(),
+                    accountKey ); // doesnotexist
+            KWallet::Wallet* const w = view->part()->wallet();
+            bool login_changed = false;
+            if ( !doesnotexist && w ) {
+                // Check if password was changed
+                if ( w->hasFolder( KWallet::Wallet::FormDataFolder() ) ) {
+                    w->setFolder( KWallet::Wallet::FormDataFolder() );
+                    QString password;
+                    if ( !w->readPassword( accountKey, password ) ) {
+                        if ( password != m_password )
+                            login_changed = true;
+                    }
+                    else
+                        login_changed = true;
+                }
+            }
+            if ( login_changed || !w || doesnotexist )
+                if ( view->part() )
+                    view->part()->saveAccount( formUrl.host(),
+                                               accountKey,
+                                               accountsKey,
+                                               m_username,
+                                               m_password );
+        }
+        else if (m_havePassword && !m_haveTextarea && KWallet::Wallet::isEnabled()) \
{ +        // END CHANGE [BRCHA]
             const QString key = calculateAutoFillKey(*this);
             const bool doesnotexist = \
KWallet::Wallet::keyDoesNotExist(KWallet::Wallet::NetworkWallet(), \
KWallet::Wallet::FormDataFolder(), key);  KWallet::Wallet* const w = \
view->part()->wallet(); @@ -706,6 +849,11 @@
     m_walletMap.clear(); // done with it
     m_havePassword = m_haveTextarea= false;
     m_doingsubmit = m_insubmit = false;
+    // BEGIN CHANGE [BRCHA]: Clear additional data
+    m_hasMultiplePasswordFields = m_hasMultipleNonPasswordFields = false;
+    m_username.clear();
+    m_password.clear();
+    // END CHANGE [BRCHA]
 }
 
 void HTMLFormElementImpl::reset(  )
@@ -1292,6 +1440,9 @@
     xPos = 0;
     yPos = 0;
 
+    m_passwordField = 0;
+    m_accounts.clear();
+
     if ( m_form )
         m_autocomplete = f->autoComplete();
 }
@@ -1388,7 +1539,17 @@
     case RADIO:
         return QLatin1String(checked() ? "on" : "off");
     case TEXT:
-        if (autoComplete() && value() != getAttribute(ATTR_VALUE) && \
document()->view()) +        // BEGIN CHANGE [BRCHA]: New account autocomplete method
+        if ( autoComplete() && !m_accounts.isEmpty() ) {
+            QMap<QString,  QString>::const_iterator accIterator;
+            for ( accIterator = m_accounts.constBegin();
+                  accIterator != m_accounts.constEnd();
+                  ++accIterator )
+                document()->view()->addFormCompletionItem( name().string(),
+                                                           accIterator.key() );
+        }
+        // END CHANGE [BRCHA]
+        else if (autoComplete() && value() != getAttribute(ATTR_VALUE) && \
                document()->view())
             document()->view()->addFormCompletionItem(name().string(), \
value().string());  /* nobreak */
     default:
@@ -2009,6 +2170,43 @@
     static_cast<RenderLineEdit*>(m_render)->setSelectionRange(start, end);
 }
 
+// BEGIN CHANGE [BRCHA]: Add password companion field & account completion
+void HTMLInputElementImpl::setPasswordCompanion( HTMLInputElementImpl* passwordField \
) +{
+    if ( m_type != TEXT )
+        return;
+    if ( passwordField->m_type != PASSWORD )
+        return;
+    m_passwordField = passwordField;
+}
+
+void HTMLInputElementImpl::setAccounts( QMap<QString, QString> & accounts )
+{
+    if ( m_type != TEXT )
+        return;
+    m_accounts = accounts;
+}
+
+bool HTMLInputElementImpl::hasPasswordCompanion()
+{
+    if ( m_type == TEXT &&
+         !m_accounts.isEmpty() &&
+         m_passwordField )
+        return true;
+    return false;
+}
+
+void HTMLInputElementImpl::completePassword()
+{
+    if ( !hasPasswordCompanion() )
+        return;
+
+    document()->setFocusNode( m_passwordField );
+    m_passwordField->setValue( m_accounts[m_value.string()] );
+}
+
+// END CHANGE [BRCHA]
+
 // -------------------------------------------------------------------------
 
 HTMLLabelElementImpl::HTMLLabelElementImpl(DocumentImpl *doc)
Index: khtml/html/html_formimpl.h
===================================================================
--- khtml/html/html_formimpl.h	(revision 1152611)
+++ khtml/html/html_formimpl.h	(working copy)
@@ -5,6 +5,7 @@
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2000 Dirk Mueller (mueller@kde.org)
  *           (C) 2004, 2005, 2006 Apple Computer, Inc.
+ *           (C) 2010  Filip Brcic <brcha@gna.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -130,6 +131,12 @@
     bool m_malformed : 1;
     bool m_haveTextarea : 1; // for wallet storage
     bool m_havePassword : 1; // for wallet storage
+    // BEGIN CHANGE [BRCHA]: Add username/password pair + \
hasMultiple{,Non}PasswordFields bools +    bool m_hasMultipleNonPasswordFields : 1; \
// for wallet storage +    bool m_hasMultiplePasswordFields : 1; // for wallet \
storage +    QString m_username; // for wallet storage
+    QString m_password; // for wallet storage
+    // END CHANGE [BRCHA]:
     DOMString m_name;        // our name
     QMap<QString, QString> m_walletMap; // for wallet storage
 };
@@ -293,6 +300,13 @@
     DOMString value() const;
     void setValue(DOMString val);
 
+    // BEGIN CHANGE [BRCHA]: Add support for companion password field & account \
completion +    void setPasswordCompanion(HTMLInputElementImpl* passwordField);
+    void setAccounts(QMap<QString, QString> & accounts);
+    bool hasPasswordCompanion();
+    void completePassword(); // called from the renderer to do the completion
+    // END CHANGE [BRCHA]
+
     DOMString valueWithDefault() const;
 
     virtual bool maintainsState() { return true; }
@@ -351,6 +365,10 @@
     bool m_autocomplete : 1;
     bool m_inited : 1;
     bool m_unsubmittedFormChange : 1;
+    // BEGIN CHANGE [BRCHA]: Add password companion and accounts list
+    HTMLInputElementImpl * m_passwordField;
+    QMap<QString, QString> m_accounts;
+    // END CHANGE [BRCHA]
 };
 
 // -------------------------------------------------------------------------
Index: khtml/rendering/render_form.cpp
===================================================================
--- khtml/rendering/render_form.cpp	(revision 1152611)
+++ khtml/rendering/render_form.cpp	(working copy)
@@ -8,6 +8,7 @@
  *           (C) 2007-2009 Germain Garand (germain@ebooksfrance.org)
  *           (C) 2007 Mitz Pettel (mitz@webkit.org)
  *           (C) 2007 Charles Samuels (charles@kde.org)
+ *           (C) 2010 Filip Brcic (brcha@gna.org)
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -1156,6 +1157,10 @@
     // don't use setValue here!
     element()->m_value = string;
     element()->m_unsubmittedFormChange = true;
+    // BEGIN CHANGE [BRCHA]: Enable multi-account user-pass completion
+    if ( element()->hasPasswordCompanion() )
+        element()->completePassword();
+    // END CHANGE [BRCHA]
 }
 
 void RenderLineEdit::select()
Index: khtml/ui/passwordbar/storepassbar.cpp
===================================================================
--- khtml/ui/passwordbar/storepassbar.cpp	(revision 1152611)
+++ khtml/ui/passwordbar/storepassbar.cpp	(working copy)
@@ -1,6 +1,7 @@
 /* This file is part of the KDE project
  *
  * Copyright (C) 2009 Eduardo Robles Elvira <edulix at gmail dot com>
+ *           (C) 2010 Filip Brcic <brcha@gna.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
 #include "khtml_part.h"
 #include "khtmlview.h"
 #include <kcolorscheme.h>
+#include <kwallet.h>
 #include <QPalette>
 
 StorePassBar::StorePassBar( QWidget *parent ) :
@@ -84,22 +86,70 @@
   m_key = key;
   m_walletMap = walletMap;
   m_storePassBar.setHost(host);
+  // BEGIN CHANGE [BRCHA]: Save as map
+  m_saveAsAccount = false;
+  // END CHANGE [BRCHA]
   
   m_part->pTopViewBar()->addBarWidget( &m_storePassBar );
   m_part->pTopViewBar()->showBarWidget( &m_storePassBar );
 }
 
+// BEGIN CHANGE [BRCHA]: Save username & password to kwallet
+void StorePass::saveAccount(const QString& host,
+                            const QString& accountKey,
+                            const QString& accountsKey,
+                            const QString& username,
+                            const QString& password )
+{
+  m_host = host;
+  m_accountKey = accountKey;
+  m_accountsKey = accountsKey;
+  m_username = username;
+  m_password = password;
+  m_saveAsAccount = true;
+  m_storePassBar.setHost(host);
+
+  m_part->pTopViewBar()->addBarWidget( &m_storePassBar );
+  m_part->pTopViewBar()->showBarWidget( &m_storePassBar );
+}
+// END CHANGE [BRCHA]
+
 void StorePass::removeBar()
 {
   m_part->pTopViewBar()->hideCurrentBarWidget();
   m_walletMap.clear();
+  // BEGIN CHANGE [BRCHA]
+  m_username.clear();
+  m_password.clear();
+  m_accountKey.clear();
+  m_accountsKey.clear();
+  m_saveAsAccount = false;
+  // END CHANGE [BRCHA]
   m_host = m_key = "";
   m_storePassBar.setHost(m_host);
 }
 
 void StorePass::slotStoreClicked()
 {
+  // BEGIN CHANGE [BRCHA]: Save as u-p pair or as std. wallet map
+  if ( m_saveAsAccount ) {
+      // First check if there are existing accounts on the site
+      QStringList accounts;
+      if ( ! KWallet::Wallet::keyDoesNotExist( KWallet::Wallet::NetworkWallet(),
+                                               KWallet::Wallet::FormDataFolder(),
+                                               m_accountsKey ) ) {
+          accounts = m_part->getPasswordFromWallet( m_accountsKey ).split( "\n" );
+      }
+      if ( !accounts.contains( m_username ) )
+      {
+          accounts.append( m_username );
+          m_part->savePasswordToWallet( m_accountsKey,  accounts.join( "\n" ) );
+      }
+      m_part->savePasswordToWallet( m_accountKey, m_password );
+  }
+  else
   m_part->saveToWallet(m_key, m_walletMap);
+  // END CHANGE [BRCHA]
   removeBar();
 }
 
Index: khtml/ui/passwordbar/storepassbar.h
===================================================================
--- khtml/ui/passwordbar/storepassbar.h	(revision 1152611)
+++ khtml/ui/passwordbar/storepassbar.h	(working copy)
@@ -1,6 +1,7 @@
 /* This file is part of the KDE project
  *
  * Copyright (C) 2009 Eduardo Robles Elvira <edulix at gmail dot com>
+ *           (C) 2010 Filip Brcic <brcha@gna.org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -51,6 +52,13 @@
     
   void saveLoginInformation(const QString& host, const QString& key,
     const QMap<QString, QString>& walletMap);
+  // BEGIN CHANGE [BRCHA]: Save username & password to kwallet
+  void saveAccount(const QString& host,
+                   const QString& accountKey,
+                   const QString& accountsKey,
+                   const QString& username,
+                   const QString& password);
+  // END CHANGE [BRCHA]
   void removeBar();
 
 private slots:
@@ -65,5 +73,12 @@
   QString m_host;
   QString m_key;
   QMap<QString, QString> m_walletMap;
+  // BEGIN CHANGE [BRCHA]: Save password to wallet
+  QString m_accountKey;
+  QString m_accountsKey;
+  QString m_username;
+  QString m_password;
+  bool    m_saveAsAccount : 1;
+  // END CHANGE [BRCHA]
 };
 #endif



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic