CredentialTransformData.cpp [plain text]
#include "config.h"
#include "CredentialTransformData.h"
#include "HTMLFormElement.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "KURL.h"
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
namespace {
static const size_t maxPasswords = 3;
KURL stripURL(const KURL& url)
{
KURL strippedURL = url;
strippedURL.setUser(String());
strippedURL.setPass(String());
strippedURL.setQuery(String());
strippedURL.setFragmentIdentifier(String());
return strippedURL;
}
bool locateSpecificPasswords(Vector<HTMLInputElement*>& passwords,
HTMLInputElement** password)
{
ASSERT(password);
switch (passwords.size()) {
case 1:
*password = passwords[0];
break;
case 2:
if (passwords[0]->value() == passwords[1]->value())
*password = passwords[0];
else {
*password = passwords[1];
}
break;
case 3:
if (passwords[0]->value() == passwords[1]->value()
&& passwords[0]->value() == passwords[2]->value()) {
*password = passwords[0];
} else if (passwords[0]->value() == passwords[1]->value()) {
*password = passwords[2];
} else if (passwords[1]->value() == passwords[2]->value())
*password = passwords[1];
else {
return false;
}
break;
default:
return false;
}
return true;
}
}
CredentialTransformData::CredentialTransformData(HTMLFormElement* form)
: m_userNameElement(0)
, m_passwordElement(0)
, m_isValid(false)
{
ASSERT(form);
KURL fullOrigin(ParsedURLString, form->document()->documentURI());
String action = form->action();
if (action.isNull())
action = ""; KURL fullAction = form->document()->completeURL(action);
if (!fullAction.isValid())
return;
if (!findPasswordFormFields(form))
return;
m_url = stripURL(fullOrigin);
m_action = stripURL(fullAction);
m_protectionSpace = ProtectionSpace(m_url.host(), m_url.port(), ProtectionSpaceServerHTTP, "Form", ProtectionSpaceAuthenticationSchemeHTMLForm);
m_credential = Credential(m_userNameElement->value(), m_passwordElement->value(), CredentialPersistencePermanent);
m_isValid = true;
}
CredentialTransformData::CredentialTransformData(const KURL& url, const ProtectionSpace& protectionSpace, const Credential& credential)
: m_url(url)
, m_protectionSpace(protectionSpace)
, m_credential(credential)
, m_userNameElement(0)
, m_passwordElement(0)
, m_isValid(true)
{
}
KURL CredentialTransformData::url() const
{
if (!m_isValid)
return KURL();
if (m_protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeHTMLForm)
return m_action;
return m_url;
}
Credential CredentialTransformData::credential() const
{
if (m_credential.isEmpty() && m_userNameElement && m_passwordElement)
return m_credential = Credential(m_userNameElement->value(), m_passwordElement->value(), CredentialPersistencePermanent);
return m_credential;
}
void CredentialTransformData::setCredential(const Credential& credential)
{
if (!m_isValid)
return;
m_credential = credential;
m_userNameElement->setValue(credential.user());
m_passwordElement->setValue(credential.password());
}
bool CredentialTransformData::findPasswordFormFields(HTMLFormElement* form)
{
ASSERT(form);
int firstPasswordIndex = 0;
const Vector<FormAssociatedElement*>& formElements = form->associatedElements();
Vector<HTMLInputElement*> passwords;
for (size_t i = 0; i < formElements.size(); i++) {
if (!formElements[i]->isFormControlElement())
continue;
HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]);
if (!formElement->hasLocalName(HTMLNames::inputTag))
continue;
HTMLInputElement* inputElement = formElement->toInputElement();
if (!inputElement->isEnabledFormControl())
continue;
if ((passwords.size() < maxPasswords)
&& inputElement->isPasswordField()
&& inputElement->shouldAutocomplete()) {
if (passwords.isEmpty())
firstPasswordIndex = i;
passwords.append(inputElement);
}
}
if (!passwords.isEmpty()) {
for (int i = firstPasswordIndex - 1; i >= 0; i--) {
if (!formElements[i]->isFormControlElement())
continue;
HTMLFormControlElement* formElement = static_cast<HTMLFormControlElement*>(formElements[i]);
if (!formElement->hasLocalName(HTMLNames::inputTag))
continue;
HTMLInputElement* inputElement = formElement->toInputElement();
if (!inputElement->isEnabledFormControl())
continue;
if ((inputElement->isTextField() && !inputElement->isPasswordField())
&& (inputElement->shouldAutocomplete())) {
m_userNameElement = inputElement;
break;
}
}
}
if (!m_userNameElement)
return false;
if (!locateSpecificPasswords(passwords, &(m_passwordElement)))
return false;
return true;
}
}