Commit cdd46b0b authored by Vadym Doroshenko's avatar Vadym Doroshenko Committed by Commit Bot

[Bling Password Manager] Unifying treating of password form action

Normalizing of password form action is done in 2 different cases with different code:
 1.On Load, in Obj-C code in password_controller.mm
 2.On fill in JS in password_controller.js

That's bad, as any duplicating code, because in some cases it generates different canonical actions (for example when the action is empty). This CL unifying canonical action calculation. As a model for canonical action calculation GetCanonicalActionForForm from Desktop/Android implementation is taken.

Bug: 710438, 708602
Change-Id: I1ea879c60d01cf02bed6ea9715089221971ff4a0
Reviewed-on: https://chromium-review.googlesource.com/596031
Commit-Queue: Vadym Doroshenko <dvadym@chromium.org>
Reviewed-by: default avatarVasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491434}
parent 2491c29c
......@@ -686,12 +686,8 @@ bool GetPageURLAndCheckTrustLevel(web::WebState* web_state, GURL* page_url) {
form->signon_realm = form->origin.ReplaceComponents(remove_path).spec();
std::string action;
// Not checking the return value, as empty action is valid.
dictionary->GetString("action", &action);
GURL actionUrl = action.empty() ? originUrl : originUrl.Resolve(action);
if (!actionUrl.is_valid())
return NO;
form->action = stripURL(actionUrl);
form->action = GURL(action);
if (!dictionary->GetString("usernameElement", &form->username_element) ||
!dictionary->GetString("usernameValue", &form->username_value) ||
......
......@@ -209,7 +209,7 @@ TEST_F(PasswordControllerJsTest,
const std::string base_url = BaseUrl();
NSString* result = [NSString
stringWithFormat:
@"[{\"action\":\"/generic_submit\","
@"[{\"action\":\"https://chromium.test/generic_submit\","
"\"method\":\"post\","
"\"name\":\"login_form\","
"\"origin\":\"%s\","
......@@ -244,7 +244,7 @@ TEST_F(PasswordControllerJsTest,
const std::string base_url = BaseUrl();
NSString* result = [NSString
stringWithFormat:
@"[{\"action\":\"/generic_submit\","
@"[{\"action\":\"https://chromium.test/generic_submit\","
"\"method\":\"post\","
"\"name\":\"login_form1\","
"\"origin\":\"%s\","
......@@ -254,7 +254,7 @@ TEST_F(PasswordControllerJsTest,
"\"usernameElement\":\"name\","
"\"usernameValue\":\"\","
"\"passwords\":[{\"element\":\"password\",\"value\":\"\"}]},"
"{\"action\":\"/generic_s2\","
"{\"action\":\"https://chromium.test/generic_s2\","
"\"method\":\"post\","
"\"name\":\"login_form2\","
"\"origin\":\"%s\","
......@@ -284,7 +284,7 @@ TEST_F(PasswordControllerJsTest, GetPasswordFormData) {
NSString* parameter = @"window.document.getElementsByTagName('form')[0]";
NSString* result = [NSString
stringWithFormat:
@"{\"action\":\"/generic_submit\","
@"{\"action\":\"https://chromium.test/generic_submit\","
"\"method\":\"post\","
"\"name\":\"np\","
"\"origin\":\"%s\","
......@@ -301,4 +301,34 @@ TEST_F(PasswordControllerJsTest, GetPasswordFormData) {
@"__gCrWeb.stringify(__gCrWeb.getPasswordFormData(%@))", parameter));
};
// Check that if a form action is not set then the action is parsed to the
// current url.
TEST_F(PasswordControllerJsTest, FormActionIsNotSet) {
LoadHtmlAndInject(
@"<html><body>"
"<form name='login_form'>"
" Name: <input type='text' name='name'>"
" Password: <input type='password' name='password'>"
" <input type='submit' value='Submit'>"
"</form>"
"</body></html>");
const std::string base_url = BaseUrl();
NSString* result = [NSString
stringWithFormat:
@"[{\"action\":\"https://chromium.test/\","
"\"method\":null,"
"\"name\":\"login_form\","
"\"origin\":\"%s\","
"\"fields\":[{\"element\":\"name\",\"type\":\"text\"},"
"{\"element\":\"password\",\"type\":\"password\"},"
"{\"element\":\"\",\"type\":\"submit\"}],"
"\"usernameElement\":\"name\","
"\"usernameValue\":\"\","
"\"passwords\":[{\"element\":\"password\",\"value\":\"\"}]}]",
base_url.c_str()];
EXPECT_NSEQ(result,
ExecuteJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()"));
};
} // namespace
......@@ -268,7 +268,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// to be stripped off. The password is recognized as an old password.
{
"http://john:doe@fakedomain.com/foo/bar?baz=quz#foobar",
"{ \"action\": \"some/action?to=be&or=not#tobe\","
"{ \"action\": \"http://fakedomain.com/foo/some/action\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......@@ -289,7 +289,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// due to an origin mismatch.
{
"http://john:doe@fakedomain.com/foo/bar?baz=quz#foobar",
"{ \"action\": \"some/action?to=be&or=not#tobe\","
"{ \"action\": \"\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......@@ -334,7 +334,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// to enter the old password and new password.
{
"http://fakedomain.com/foo",
"{ \"action\": \"\","
"{ \"action\": \"http://fakedomain.com/foo\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......@@ -357,7 +357,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// does not make sense.
{
"http://fakedomain.com",
"{ \"action\": \"\","
"{ \"action\": \"http://fakedomain.com/\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......@@ -381,7 +381,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// password is the old one.
{
"http://fakedomain.com",
"{ \"action\": \"\","
"{ \"action\": \"http://fakedomain.com/\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......@@ -405,7 +405,7 @@ TEST_F(PasswordControllerTest, PopulatePasswordFormWithDictionary) {
// password is the new one.
{
"http://fakedomain.com",
"{ \"action\": \"\","
"{ \"action\": \"http://fakedomain.com/\","
"\"usernameElement\": \"account\","
"\"usernameValue\": \"fakeaccount\","
"\"name\": \"signup\","
......
......@@ -79,6 +79,19 @@ if (__gCrWeb && !__gCrWeb['fillPasswordForm']) {
return result;
};
/**
* Returns a canonical action for |formElement|. It works the same as upstream
* function GetCanonicalActionForForm.
* @param {Form} formElement.
* @return {string} Canonical action.
*/
var getCanonicalActionForForm_ = function(formElement) {
var raw_action = formElement.getAttribute('action') || "";
var absolute_url = __gCrWeb.common.absoluteURL(
formElement.ownerDocument, raw_action);
return __gCrWeb.common.removeQueryAndReferenceFromURL(absolute_url);
};
/**
* Returns the password form with the given |name| as a JSON string.
* @param {string} name The name of the form to extract.
......@@ -111,8 +124,7 @@ if (__gCrWeb && !__gCrWeb['fillPasswordForm']) {
for (var i = 0; i < forms.length; i++) {
var form = forms[i];
var normalizedFormAction = opt_normalizedAction ||
__gCrWeb.common.removeQueryAndReferenceFromURL(
__gCrWeb.common.absoluteURL(doc, form.action));
getCanonicalActionForForm_(form);
if (formData.action != normalizedFormAction) {
continue;
}
......@@ -455,7 +467,7 @@ if (__gCrWeb && !__gCrWeb['fillPasswordForm']) {
formElement.ownerDocument.location.href);
return {
'action': formElement.getAttribute('action'),
'action': getCanonicalActionForForm_(formElement),
'method': formElement.getAttribute('method'),
'name': __gCrWeb.common.getFormIdentifier(formElement),
'origin': origin,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment