WebKit/chromium/src/WebPasswordFormData.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 /*
       
     2  * Copyright (C) 2009 Google Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions are
       
     6  * met:
       
     7  *
       
     8  *     * Redistributions of source code must retain the above copyright
       
     9  * notice, this list of conditions and the following disclaimer.
       
    10  *     * Redistributions in binary form must reproduce the above
       
    11  * copyright notice, this list of conditions and the following disclaimer
       
    12  * in the documentation and/or other materials provided with the
       
    13  * distribution.
       
    14  *     * Neither the name of Google Inc. nor the names of its
       
    15  * contributors may be used to endorse or promote products derived from
       
    16  * this software without specific prior written permission.
       
    17  *
       
    18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
       
    19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
       
    20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
       
    21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
       
    22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
       
    25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
       
    26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
       
    28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    29  */
       
    30 
       
    31 #include "config.h"
       
    32 #include "WebPasswordFormData.h"
       
    33 
       
    34 #include "Document.h"
       
    35 #include "DocumentLoader.h"
       
    36 #include "Frame.h"
       
    37 #include "FrameLoader.h"
       
    38 #include "HTMLFormElement.h"
       
    39 #include "HTMLInputElement.h"
       
    40 #include "HTMLNames.h"
       
    41 #include "KURL.h"
       
    42 
       
    43 #include "DOMUtilitiesPrivate.h"
       
    44 #include "WebPasswordFormUtils.h"
       
    45 
       
    46 using namespace WebCore;
       
    47 
       
    48 namespace WebKit {
       
    49 
       
    50 namespace {
       
    51 
       
    52 // Helper to determine which password is the main one, and which is
       
    53 // an old password (e.g on a "make new password" form), if any.
       
    54 bool locateSpecificPasswords(PasswordFormFields* fields,
       
    55                              HTMLInputElement** password,
       
    56                              HTMLInputElement** oldPassword)
       
    57 {
       
    58     ASSERT(fields);
       
    59     ASSERT(password);
       
    60     ASSERT(oldPassword);
       
    61     switch (fields->passwords.size()) {
       
    62     case 1:
       
    63         // Single password, easy.
       
    64         *password = fields->passwords[0];
       
    65         break;
       
    66     case 2:
       
    67         if (fields->passwords[0]->value() == fields->passwords[1]->value())
       
    68             // Treat two identical passwords as a single password.
       
    69             *password = fields->passwords[0];
       
    70         else {
       
    71             // Assume first is old password, second is new (no choice but to guess).
       
    72             *oldPassword = fields->passwords[0];
       
    73             *password = fields->passwords[1];
       
    74         }
       
    75         break;
       
    76     case 3:
       
    77         if (fields->passwords[0]->value() == fields->passwords[1]->value()
       
    78             && fields->passwords[0]->value() == fields->passwords[2]->value()) {
       
    79             // All three passwords the same? Just treat as one and hope.
       
    80             *password = fields->passwords[0];
       
    81         } else if (fields->passwords[0]->value() == fields->passwords[1]->value()) {
       
    82             // Two the same and one different -> old password is duplicated one.
       
    83             *oldPassword = fields->passwords[0];
       
    84             *password = fields->passwords[2];
       
    85         } else if (fields->passwords[1]->value() == fields->passwords[2]->value()) {
       
    86             *oldPassword = fields->passwords[0];
       
    87             *password = fields->passwords[1];
       
    88         } else {
       
    89             // Three different passwords, or first and last match with middle
       
    90             // different. No idea which is which, so no luck.
       
    91             return false;
       
    92         }
       
    93         break;
       
    94     default:
       
    95         return false;
       
    96     }
       
    97     return true;
       
    98 }
       
    99 
       
   100 // Helped method to clear url of unneeded parts.
       
   101 KURL stripURL(const KURL& url)
       
   102 {
       
   103     KURL strippedURL = url;
       
   104     strippedURL.setUser(String());
       
   105     strippedURL.setPass(String());
       
   106     strippedURL.setQuery(String());
       
   107     strippedURL.setFragmentIdentifier(String());
       
   108     return strippedURL;
       
   109 }
       
   110 
       
   111 // Helper to gather up the final form data and create a PasswordForm.
       
   112 void assemblePasswordFormResult(const KURL& fullOrigin,
       
   113                                 const KURL& fullAction,
       
   114                                 HTMLFormControlElement* submit,
       
   115                                 HTMLInputElement* userName,
       
   116                                 HTMLInputElement* oldPassword,
       
   117                                 HTMLInputElement* password,
       
   118                                 WebPasswordFormData* result)
       
   119 {
       
   120     // We want to keep the path but strip any authentication data, as well as
       
   121     // query and ref portions of URL, for the form action and form origin.
       
   122     result->action = stripURL(fullAction);
       
   123     result->origin = stripURL(fullOrigin);
       
   124 
       
   125     // Naming is confusing here because we have both the HTML form origin URL
       
   126     // the page where the form was seen), and the "origin" components of the url
       
   127     // (scheme, host, and port).
       
   128     KURL signonRealmURL = stripURL(fullOrigin);
       
   129     signonRealmURL.setPath("");
       
   130     result->signonRealm = signonRealmURL;
       
   131 
       
   132     if (submit)
       
   133         result->submitElement = submit->name();
       
   134     if (userName) {
       
   135         result->userNameElement = userName->name();
       
   136         result->userNameValue = userName->value();
       
   137     }
       
   138     if (password) {
       
   139         result->passwordElement = password->name();
       
   140         result->passwordValue = password->value();
       
   141     }
       
   142     if (oldPassword) {
       
   143         result->oldPasswordElement = oldPassword->name();
       
   144         result->oldPasswordValue = oldPassword->value();
       
   145     }
       
   146 }
       
   147 
       
   148 } // namespace
       
   149 
       
   150 WebPasswordFormData::WebPasswordFormData(const WebFormElement& webForm)
       
   151 {
       
   152     RefPtr<HTMLFormElement> form = webForm.operator PassRefPtr<HTMLFormElement>();
       
   153 
       
   154     Frame* frame = form->document()->frame();
       
   155     if (!frame)
       
   156         return;
       
   157 
       
   158     PasswordFormFields fields;
       
   159     findPasswordFormFields(form.get(), &fields);
       
   160 
       
   161     // Get the document URL
       
   162     KURL fullOrigin(ParsedURLString, form->document()->documentURI());
       
   163 
       
   164     // Calculate the canonical action URL
       
   165     String action = form->action();
       
   166     if (action.isNull())
       
   167         action = ""; // missing 'action' attribute implies current URL
       
   168     KURL fullAction = frame->loader()->completeURL(action);
       
   169     if (!fullAction.isValid())
       
   170         return;
       
   171 
       
   172     // Determine the types of the password fields
       
   173     HTMLInputElement* password = 0;
       
   174     HTMLInputElement* oldPassword = 0;
       
   175     if (!locateSpecificPasswords(&fields, &password, &oldPassword))
       
   176         return;
       
   177 
       
   178     assemblePasswordFormResult(fullOrigin, fullAction,
       
   179                                fields.submit, fields.userName,
       
   180                                oldPassword, password, this);
       
   181 }
       
   182 
       
   183 } // namespace WebKit