| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_MANAGER_H_ |
| #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_MANAGER_H_ |
| |
| #include <stdint.h> |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/optional.h" |
| #include "base/strings/string16.h" |
| #include "build/build_config.h" |
| #include "components/autofill/core/browser/field_types.h" |
| #include "components/autofill/core/browser/form_structure.h" |
| #include "components/autofill/core/common/password_form.h" |
| #include "components/password_manager/core/browser/form_fetcher.h" |
| #include "components/password_manager/core/browser/password_manager_driver.h" |
| #include "components/password_manager/core/browser/password_store.h" |
| |
| using autofill::FormData; |
| using autofill::FormStructure; |
| |
| namespace password_manager { |
| |
| class FormSaver; |
| class PasswordManager; |
| class PasswordManagerClient; |
| |
| // A map from field names to field types. |
| using FieldTypeMap = std::map<base::string16, autofill::ServerFieldType>; |
| |
| // This class helps with filling the observed form (both HTML and from HTTP |
| // auth) and with saving/updating the stored information about it. |
| class PasswordFormManager : public FormFetcher::Consumer { |
| public: |
| // |password_manager| owns |this|, |client| and |driver| serve to |
| // communicate with embedder, |observed_form| is the associated form |this| |
| // is managing, |form_saver| is used to save/update the form and |
| // |form_fetcher| to get saved data about the form. |form_fetcher| must not be |
| // destroyed before |this|. |
| // |
| // TODO(crbug.com/621355): So far, |form_fetcher| can be null. In that case |
| // |this| creates an instance of it itself (meant for production code). Once |
| // the fetcher is shared between PasswordFormManager instances, it will be |
| // required that |form_fetcher| is not null. |
| PasswordFormManager(PasswordManager* password_manager, |
| PasswordManagerClient* client, |
| const base::WeakPtr<PasswordManagerDriver>& driver, |
| const autofill::PasswordForm& observed_form, |
| std::unique_ptr<FormSaver> form_saver, |
| FormFetcher* form_fetcher); |
| ~PasswordFormManager() override; |
| |
| // Flags describing the result of comparing two forms as performed by |
| // DoesMatch. Individual flags are only relevant for HTML forms, but |
| // RESULT_COMPLETE_MATCH will also be returned to indicate non-HTML forms |
| // completely matching. |
| // The ordering of these flags is important. Larger matches are more |
| // preferred than lower matches. That is, since RESULT_HTML_ATTRIBUTES_MATCH |
| // is greater than RESULT_ACTION_MATCH, a match of only attributes and not |
| // actions will be preferred to one of actions and not attributes. |
| enum MatchResultFlags { |
| RESULT_NO_MATCH = 0, |
| RESULT_ACTION_MATCH = 1 << 0, |
| RESULT_HTML_ATTRIBUTES_MATCH = 1 << 1, |
| RESULT_ORIGINS_OR_FRAMES_MATCH = 1 << 2, |
| RESULT_COMPLETE_MATCH = RESULT_ACTION_MATCH | RESULT_HTML_ATTRIBUTES_MATCH | |
| RESULT_ORIGINS_OR_FRAMES_MATCH |
| }; |
| // Use MatchResultMask to contain combinations of MatchResultFlags values. |
| // It's a signed int rather than unsigned to avoid signed/unsigned mismatch |
| // caused by the enum values implicitly converting to signed int. |
| typedef int MatchResultMask; |
| |
| enum OtherPossibleUsernamesAction { |
| ALLOW_OTHER_POSSIBLE_USERNAMES, |
| IGNORE_OTHER_POSSIBLE_USERNAMES |
| }; |
| |
| // Chooses between the current and new password value which one to save. This |
| // is whichever is non-empty, with the preference being given to the new one. |
| static base::string16 PasswordToSave(const autofill::PasswordForm& form); |
| |
| // Compares basic data of |observed_form_| with |form| and returns how much |
| // they match. The return value is a MatchResultMask bitmask. |
| // |driver| is optional and if it's given it should be a driver that |
| // corresponds to a frame from which |form| comes from. |
| MatchResultMask DoesManage( |
| const autofill::PasswordForm& form, |
| const password_manager::PasswordManagerDriver* driver) const; |
| |
| // Update |this| with the |form| that was actually submitted. Used to |
| // determine what type the submitted form is for |
| // IsIgnorableChangePasswordForm() and UMA stats. |
| void SetSubmittedForm(const autofill::PasswordForm& form); |
| |
| // Determines if the user opted to 'never remember' passwords for this form. |
| bool IsBlacklisted() const; |
| |
| // Used by PasswordManager to determine whether or not to display |
| // a SavePasswordBar when given the green light to save the PasswordForm |
| // managed by this. |
| bool IsNewLogin() const; |
| |
| // Returns true if the current pending credentials were found using |
| // origin matching of the public suffix, instead of the signon realm of the |
| // form. |
| bool IsPendingCredentialsPublicSuffixMatch() const; |
| |
| // Through |driver|, supply the associated frame with appropriate information |
| // (fill data, whether to allow password generation, etc.). If this is called |
| // before |this| has data from the PasswordStore, the execution will be |
| // delayed until the data arrives. |
| void ProcessFrame(const base::WeakPtr<PasswordManagerDriver>& driver); |
| |
| // A user opted to 'never remember' passwords for this form. |
| // Blacklist it so that from now on when it is seen we ignore it. |
| // TODO(vasilii): remove the 'virtual' specifier. |
| virtual void PermanentlyBlacklist(); |
| |
| // If the user has submitted observed_form_, provisionally hold on to |
| // the submitted credentials until we are told by PasswordManager whether |
| // or not the login was successful. |action| describes how we deal with |
| // possible usernames. If |action| is ALLOW_OTHER_POSSIBLE_USERNAMES we will |
| // treat a possible usernames match as a sign that our original heuristics |
| // were wrong and that the user selected the correct username from the |
| // Autofill UI. |
| void ProvisionallySave(const autofill::PasswordForm& credentials, |
| OtherPossibleUsernamesAction action); |
| |
| // Handles save-as-new or update of the form managed by this manager. |
| // Note the basic data of updated_credentials must match that of |
| // observed_form_ (e.g DoesManage(pending_credentials_) == true). |
| void Save(); |
| |
| // Update the password store entry for |credentials_to_update|, using the |
| // password from |pending_credentials_|. It modifies |pending_credentials_|. |
| // |credentials_to_update| should be one of |best_matches_| or |
| // |pending_credentials_|. |
| void Update(const autofill::PasswordForm& credentials_to_update); |
| |
| // Call these if/when we know the form submission worked or failed. |
| // These routines are used to update internal statistics ("ActionsTaken"). |
| void LogSubmitPassed(); |
| void LogSubmitFailed(); |
| |
| // These functions are used to determine if this form has had it's password |
| // auto generated by the browser. |
| bool has_generated_password() const { return has_generated_password_; } |
| void set_has_generated_password(bool generated_password) { |
| has_generated_password_ = generated_password; |
| } |
| |
| bool is_manual_generation() { return is_manual_generation_; } |
| void set_is_manual_generation(bool is_manual_generation) { |
| is_manual_generation_ = is_manual_generation; |
| } |
| |
| const base::string16& generation_element() { return generation_element_; } |
| void set_generation_element(const base::string16& generation_element) { |
| generation_element_ = generation_element; |
| } |
| |
| bool get_generation_popup_was_shown() const { |
| return generation_popup_was_shown_; |
| } |
| void set_generation_popup_was_shown(bool generation_popup_was_shown) { |
| generation_popup_was_shown_ = generation_popup_was_shown; |
| } |
| |
| bool password_overridden() const { return password_overridden_; } |
| |
| bool retry_password_form_password_update() const { |
| return retry_password_form_password_update_; |
| } |
| |
| // Called if the user could generate a password for this form. |
| void MarkGenerationAvailable() { generation_available_ = true; } |
| |
| // Returns the provisionally saved form, if it exists, otherwise nullptr. |
| const autofill::PasswordForm* submitted_form() const { |
| return submitted_form_.get(); |
| } |
| |
| // Returns the pending credentials. |
| const autofill::PasswordForm& pending_credentials() const { |
| return pending_credentials_; |
| } |
| |
| // Returns the best matches. |
| const std::map<base::string16, const autofill::PasswordForm*>& best_matches() |
| const { |
| return best_matches_; |
| } |
| |
| const autofill::PasswordForm* preferred_match() const { |
| return preferred_match_; |
| } |
| |
| const std::vector<const autofill::PasswordForm*>& blacklisted_matches() |
| const { |
| return blacklisted_matches_; |
| } |
| |
| const autofill::PasswordForm& observed_form() const { return observed_form_; } |
| |
| bool is_possible_change_password_form_without_username() const { |
| return is_possible_change_password_form_without_username_; |
| } |
| |
| FormFetcher* form_fetcher() { return form_fetcher_; } |
| |
| // Use this to wipe copies of |pending_credentials_| from the password store |
| // (and |best_matches_| as well. It will only wipe if: |
| // 1. The stored password differs from the one in |pending_credentials_|. |
| // 2. And the store already returned results for the observed form. |
| // This is designed for use with sync credentials, so it will use GAIA utils |
| // to catch equivalent usernames (e.g., if |pending_credentials_| have |
| // username 'test', and the store also contains outdated entries for |
| // 'test@gmail.com' and 'test@googlemail.com', those will be wiped). |
| void WipeStoreCopyIfOutdated(); |
| |
| // Called when the user chose not to update password. |
| void OnNopeUpdateClicked(); |
| |
| // Called when the user clicked "Never" button in the "save password" prompt. |
| void OnNeverClicked(); |
| |
| // Called when the user didn't interact with UI. |is_update| is true iff |
| // it was the update UI. |
| void OnNoInteraction(bool is_update); |
| |
| // Saves the outcome of HTML parsing based form classifier to upload proto. |
| void SaveGenerationFieldDetectedByClassifier( |
| const base::string16& generation_field); |
| |
| FormSaver* form_saver() { return form_saver_.get(); } |
| |
| // Clears references to matches derived from the associated FormFetcher data. |
| // After calling this, the PasswordFormManager holds no references to objects |
| // owned by the associated FormFetcher. This does not cause removing |this| as |
| // a consumer of |form_fetcher_|. |
| void ResetStoredMatches(); |
| |
| // Takes ownership of |fetcher|. If |fetcher| is different from the current |
| // |form_fetcher_| then also resets matches stored from the old fetcher and |
| // adds itself as a consumer of the new one. |
| void GrabFetcher(std::unique_ptr<FormFetcher> fetcher); |
| |
| protected: |
| // FormFetcher::Consumer: |
| void ProcessMatches( |
| const std::vector<const autofill::PasswordForm*>& non_federated, |
| size_t filtered_count) override; |
| |
| private: |
| // ManagerAction - What does the manager do with this form? Either it |
| // fills it, or it doesn't. If it doesn't fill it, that's either |
| // because it has no match or it is disabled via the AUTOCOMPLETE=off |
| // attribute. Note that if we don't have an exact match, we still provide |
| // candidates that the user may end up choosing. |
| enum ManagerAction { |
| kManagerActionNone = 0, |
| kManagerActionAutofilled, |
| kManagerActionBlacklisted_Obsolete, |
| kManagerActionMax |
| }; |
| |
| // Same as above, without the obsoleted 'Blacklisted' action. |
| enum ManagerActionNew { |
| kManagerActionNewNone, |
| kManagerActionNewAutofilled, |
| kManagerActionNewMax |
| }; |
| |
| // UserAction - What does the user do with this form? If they do nothing |
| // (either by accepting what the password manager did, or by simply (not |
| // typing anything at all), you get None. If there were multiple choices and |
| // the user selects one other than the default, you get Choose, if user |
| // selects an entry from matching against the Public Suffix List you get |
| // ChoosePslMatch, if the user types in a new value for just the password you |
| // get OverridePassword, and if the user types in a new value for the |
| // username and password you get OverrideUsernameAndPassword. |
| enum UserAction { |
| kUserActionNone = 0, |
| kUserActionChoose, |
| kUserActionChoosePslMatch, |
| kUserActionOverridePassword, |
| kUserActionOverrideUsernameAndPassword, |
| kUserActionMax |
| }; |
| |
| // Result - What happens to the form? |
| enum SubmitResult { |
| kSubmitResultNotSubmitted = 0, |
| kSubmitResultFailed, |
| kSubmitResultPassed, |
| kSubmitResultMax |
| }; |
| |
| // What the form is used for. kFormTypeUnspecified is only set before |
| // the SetSubmittedForm() is called, and should never be actually uploaded. |
| enum FormType { |
| kFormTypeLogin, |
| kFormTypeLoginNoUsername, |
| kFormTypeChangePasswordEnabled, |
| kFormTypeChangePasswordDisabled, |
| kFormTypeChangePasswordNoUsername, |
| kFormTypeSignup, |
| kFormTypeSignupNoUsername, |
| kFormTypeLoginAndSignup, |
| kFormTypeUnspecified, |
| kFormTypeMax |
| }; |
| |
| // The outcome of the form classifier. |
| enum FormClassifierOutcome { |
| kNoOutcome, |
| kNoGenerationElement, |
| kFoundGenerationElement |
| }; |
| |
| // The maximum number of combinations of the three preceding enums. |
| // This is used when recording the actions taken by the form in UMA. |
| static const int kMaxNumActionsTaken = |
| kManagerActionMax * kUserActionMax * kSubmitResultMax; |
| |
| // Enumerates whether there were `suppressed` credentials. These are stored |
| // credentials that were not filled, even though they might be related to the |
| // |observed_form_|. See FormFetcher::GetSuppressed* for details. |
| // |
| // If suppressed credentials exist, it is also recorded whether their username |
| // and/or password matched those submitted. |
| enum SuppressedAccountExistence { |
| kSuppressedAccountNone, |
| // Recorded when there exists a suppressed account, but there was no |
| // submitted form to compare its username and password to. |
| kSuppressedAccountExists, |
| // Recorded when there was a submitted form. |
| kSuppressedAccountExistsDifferentUsername, |
| kSuppressedAccountExistsSameUsername, |
| kSuppressedAccountExistsSameUsernameAndPassword, |
| kSuppressedAccountExistenceMax, |
| }; |
| |
| // The maximum number of combinations recorded into histograms in the |
| // PasswordManager.SuppressedAccount.* family. |
| static constexpr int kMaxSuppressedAccountStats = |
| kSuppressedAccountExistenceMax * kManagerActionNewMax * kUserActionMax * |
| kSubmitResultMax; |
| |
| // Through |driver|, supply the associated frame with appropriate information |
| // (fill data, whether to allow password generation, etc.). |
| void ProcessFrameInternal(const base::WeakPtr<PasswordManagerDriver>& driver); |
| |
| // Trigger filling of HTTP auth dialog and update |manager_action_|. |
| void ProcessLoginPrompt(); |
| |
| // Given all non-blacklisted |matches|, computes their score and populates |
| // |best_matches_|, |preferred_match_| and |non_best_matches_| accordingly. |
| void ScoreMatches(const std::vector<const autofill::PasswordForm*>& matches); |
| |
| // Helper for Save in the case that best_matches.size() == 0, meaning |
| // we have no prior record of this form/username/password and the user |
| // has opted to 'Save Password'. The previously preferred login from |
| // |best_matches_| will be reset. |
| void SaveAsNewLogin(); |
| |
| // Helper for OnGetPasswordStoreResults to score an individual result |
| // against the observed_form_. |
| uint32_t ScoreResult(const autofill::PasswordForm& candidate) const; |
| |
| // Returns true iff |form| is a non-blacklisted match for |observed_form_|. |
| bool IsMatch(const autofill::PasswordForm& form) const; |
| |
| // Returns true iff |form| blacklists |observed_form_|. |
| bool IsBlacklistMatch(const autofill::PasswordForm& form) const; |
| |
| // Helper for Save in the case there is at least one match for the pending |
| // credentials. This sends needed signals to the autofill server, and also |
| // triggers some UMA reporting. |
| void ProcessUpdate(); |
| |
| // Check to see if |pending| corresponds to an account creation form. If we |
| // think that it does, we label it as such and upload this state to the |
| // Autofill server to vote for the correct username field, and also so that |
| // we will trigger password generation in the future. This function will |
| // update generation_upload_status of |pending| if an upload is performed. |
| void SendVoteOnCredentialsReuse(const autofill::PasswordForm& observed, |
| autofill::PasswordForm* pending); |
| |
| // Update all login matches to reflect new preferred state - preferred flag |
| // will be reset on all matched logins that different than the current |
| // |pending_credentials_|. |
| void UpdatePreferredLoginState(PasswordStore* password_store); |
| |
| // Returns true if |username| is one of the other possible usernames for a |
| // password form in |best_matches_| and sets |pending_credentials_| to the |
| // match which had this username. |
| bool UpdatePendingCredentialsIfOtherPossibleUsername( |
| const base::string16& username); |
| |
| // Searches for |username| in |other_possible_usernames| of |best_matches_| |
| // and |not_best_matches_|. If the username value is found in |
| // |other_possible_usernames| and the password value of the match is equal to |
| // |password|, the match is saved to |username_correction_vote_|. |
| void FindCorrectedUsernameElement(const base::string16& username, |
| const base::string16& password); |
| |
| // Searches for |username| in |other_possible_usernames| of |match|. If the |
| // username value is found, the match is saved to |username_correction_vote_| |
| // and the function returns true. |
| bool FindUsernameInOtherPossibleUsernames(const autofill::PasswordForm& match, |
| const base::string16& username); |
| |
| // Returns true if |form| is a username update of a credential already in |
| // |best_matches_|. Sets |pending_credentials_| to the appropriate |
| // PasswordForm if it returns true. |
| bool UpdatePendingCredentialsIfUsernameChanged( |
| const autofill::PasswordForm& form); |
| |
| // Converts the "ActionsTaken" fields into an int so they can be logged to |
| // UMA. |
| int GetActionsTaken() const; |
| |
| // When supplied with the list of all |suppressed_forms| that belong to |
| // certain suppressed credential type (see FormFetcher::GetSuppressed*), |
| // filters that list down to forms that are either |manual_or_generated|, and |
| // based on that, computes the histogram sample that is a mixed-based |
| // representation of a combination of four attributes: |
| // -- whether there were suppressed credentials (and if so, their relation to |
| // the submitted username/password). |
| // -- whether the |observed_form_| got ultimately submitted |
| // -- what action the password manager performed (|manager_action_|), |
| // -- and what action the user performed (|user_action_|_). |
| int GetHistogramSampleForSuppressedAccounts( |
| const std::vector<const autofill::PasswordForm*> suppressed_forms, |
| autofill::PasswordForm::Type manual_or_generated) const; |
| |
| // Records all histograms in the PasswordManager.SuppressedAccount.* family. |
| void RecordHistogramsOnSuppressedAccounts() const; |
| |
| // Tries to set all votes (e.g. autofill field types, generation vote) to |
| // a |FormStructure| and upload it to the server. Returns true on success. |
| bool UploadPasswordVote(const autofill::PasswordForm& form_to_upload, |
| const autofill::ServerFieldType& password_type, |
| const std::string& login_form_signature); |
| |
| // Adds a vote on password generation usage to |form_structure|. |
| void AddGeneratedVote(autofill::FormStructure* form_structure); |
| |
| // Adds a vote from HTML parsing based form classifier to |form_structure|. |
| void AddFormClassifierVote(autofill::FormStructure* form_structure); |
| |
| // Create pending credentials from provisionally saved form and forms received |
| // from password store. |
| void CreatePendingCredentials(); |
| |
| // Create pending credentials from provisionally saved form when this form |
| // represents credentials that were not previosly saved. |
| void CreatePendingCredentialsForNewCredentials(); |
| |
| // If |best_matches| contains only one entry then return this entry. Otherwise |
| // for empty |password| return nullptr and for non-empty |password| returns |
| // the unique entry in |best_matches_| with the same password, if it exists, |
| // and nullptr otherwise. |
| const autofill::PasswordForm* FindBestMatchForUpdatePassword( |
| const base::string16& password) const; |
| |
| // Try to find best matched to |form| from |best_matches_| by the rules: |
| // 1. If there is an element in |best_matches_| with the same username then |
| // return it; |
| // 2. If |form| is created with Credential API return nullptr, i.e. we match |
| // Credentials API forms only by username; |
| // 3. If |form| has no |username_element| and no |new_password_element| (i.e. |
| // a form contains only one field which is a password) and there is an element |
| // from |best_matches_| with the same password as in |form| then return it; |
| // 4. Otherwise return nullptr. |
| const autofill::PasswordForm* FindBestSavedMatch( |
| const autofill::PasswordForm* form) const; |
| |
| // Send appropriate votes based on what is currently being saved. |
| void SendVotesOnSave(); |
| |
| // Send a vote for sign-in forms with autofill types for a username field. |
| void SendSignInVote(const FormData& form_data); |
| |
| // Sets |user_action_| and records some metrics. |
| void SetUserAction(UserAction user_action); |
| |
| // Edits some fields in |pending_credentials_| before it can be used to |
| // update the password store. It also goes through |not_best_matches|, |
| // updates the password of those which share the old password and username |
| // with |pending_credentials_| to the new password of |pending_credentials_|, |
| // and adds copies of all such modified credentials to |
| // |credentials_to_update|. If needed, this also returns a PasswordForm to be |
| // used as the old primary key during the store update. |
| base::Optional<autofill::PasswordForm> UpdatePendingAndGetOldKey( |
| std::vector<autofill::PasswordForm>* credentials_to_update); |
| |
| // Set of nonblacklisted PasswordForms from the DB that best match the form |
| // being managed by |this|, indexed by username. They are owned by |
| // |form_fetcher_|. |
| std::map<base::string16, const autofill::PasswordForm*> best_matches_; |
| |
| // Set of forms from PasswordStore that correspond to the current site and |
| // that are not in |best_matches_|. They are owned by |form_fetcher_|. |
| std::vector<const autofill::PasswordForm*> not_best_matches_; |
| |
| // Set of blacklisted forms from the PasswordStore that best match the current |
| // form. They are owned by |form_fetcher_|, with the exception that if |
| // |new_blacklisted_| is not null, the address of that form is also inside |
| // |blacklisted_matches_|. |
| std::vector<const autofill::PasswordForm*> blacklisted_matches_; |
| |
| // If the observed form gets blacklisted through |this|, the blacklist entry |
| // gets stored in |new_blacklisted_| until data is potentially refreshed by |
| // reading from PasswordStore again. |blacklisted_matches_| will contain |
| // |new_blacklisted_.get()| in that case. The PasswordForm will usually get |
| // accessed via |blacklisted_matches_|, this unique_ptr is only used to store |
| // it (unlike the rest of forms being pointed to in |blacklisted_matches_|, |
| // which are owned by |form_fetcher_|. |
| std::unique_ptr<autofill::PasswordForm> new_blacklisted_; |
| |
| // The PasswordForm from the page or dialog managed by |this|. |
| const autofill::PasswordForm observed_form_; |
| |
| // Stores a submitted form. |
| std::unique_ptr<const autofill::PasswordForm> submitted_form_; |
| |
| // Stores if for creating |pending_credentials_| other possible usernames |
| // option should apply. |
| OtherPossibleUsernamesAction other_possible_username_action_; |
| |
| // If the user typed username that doesn't match any saved credentials, but |
| // matches an entry from |other_possible_usernames| of a saved credential, |
| // then |username_correction_vote_| stores the credential with matched |
| // username. The matched credential is copied to |username_correction_vote_|, |
| // but |username_correction_vote_.username_element| is set to the name of the |
| // field where matched username was found. |
| std::unique_ptr<autofill::PasswordForm> username_correction_vote_; |
| |
| // The origin url path of observed_form_ tokenized, for convenience when |
| // scoring. |
| const std::vector<std::string> form_path_segments_; |
| |
| // Stores updated credentials when the form was submitted but success is still |
| // unknown. This variable contains credentials that are ready to be written |
| // (saved or updated) to a password store. It is calculated based on |
| // |submitted_form_| and |best_matches_|. |
| autofill::PasswordForm pending_credentials_; |
| |
| // Whether pending_credentials_ stores a new login or is an update |
| // to an existing one. |
| bool is_new_login_; |
| |
| // Whether this form has an auto generated password. |
| bool has_generated_password_; |
| |
| // Whether password generation was manually triggered. |
| bool is_manual_generation_; |
| |
| // A password field name that is used for generation. |
| base::string16 generation_element_; |
| |
| // Whether generation popup was shown at least once. |
| bool generation_popup_was_shown_; |
| |
| // The outcome of HTML parsing based form classifier. |
| FormClassifierOutcome form_classifier_outcome_; |
| |
| // If |form_classifier_outcome_| == kFoundGenerationElement, the field |
| // contains the name of the detected generation element. |
| base::string16 generation_element_detected_by_classifier_; |
| |
| // Whether the saved password was overridden. |
| bool password_overridden_; |
| |
| // A form is considered to be "retry" password if it has only one field which |
| // is a current password field. |
| // This variable is true if the password passed through ProvisionallySave() is |
| // a password that is not part of any password form stored for this origin |
| // and it was entered on a retry password form. |
| bool retry_password_form_password_update_; |
| |
| // Whether the user can choose to generate a password for this form. |
| bool generation_available_; |
| |
| // Set if the user has selected one of the other possible usernames in |
| // |pending_credentials_|. |
| base::string16 selected_username_; |
| |
| // PasswordManager owning this. |
| PasswordManager* const password_manager_; |
| |
| // Convenience pointer to entry in best_matches_ that is marked |
| // as preferred. This is only allowed to be null if there are no best matches |
| // at all, since there will always be one preferred login when there are |
| // multiple matches (when first saved, a login is marked preferred). |
| const autofill::PasswordForm* preferred_match_; |
| |
| // True if we consider this form to be a change password form without username |
| // field. We use only client heuristics, so it could include signup forms. |
| // The value of this variable is calculated based not only on information from |
| // |observed_form_| but also on the credentials that the user submitted. |
| bool is_possible_change_password_form_without_username_; |
| |
| // True if |submitted_form_| looks like SignUp form according to |
| // local heuristics. |
| bool does_look_like_signup_form_ = false; |
| |
| // The client which implements embedder-specific PasswordManager operations. |
| PasswordManagerClient* client_; |
| |
| // |this| is created for a form in some frame, which is represented by a |
| // driver. Similar form can appear in more frames, represented with more |
| // drivers. The drivers are needed to perform frame-specific operations |
| // (filling etc.). These drivers are kept in |drivers_| to allow updating of |
| // the filling information when needed. |
| std::vector<base::WeakPtr<PasswordManagerDriver>> drivers_; |
| |
| // These three fields record the "ActionsTaken" by the browser and |
| // the user with this form, and the result. They are combined and |
| // recorded in UMA when the manager is destroyed. |
| ManagerAction manager_action_; |
| UserAction user_action_; |
| SubmitResult submit_result_; |
| |
| // Form type of the form that |this| is managing. Set after SetSubmittedForm() |
| // as our classification of the form can change depending on what data the |
| // user has entered. |
| FormType form_type_; |
| |
| // FormSaver instance used by |this| to all tasks related to storing |
| // credentials. |
| std::unique_ptr<FormSaver> form_saver_; |
| |
| // When not null, then this is the object which |form_fetcher_| points to. |
| std::unique_ptr<FormFetcher> owned_form_fetcher_; |
| |
| // FormFetcher instance which owns the login data from PasswordStore. |
| FormFetcher* form_fetcher_; |
| |
| // True if the main frame's visible URL, at the time this PasswordFormManager |
| // was created, is secure. |
| bool is_main_frame_secure_ = false; |
| |
| DISALLOW_COPY_AND_ASSIGN(PasswordFormManager); |
| }; |
| |
| } // namespace password_manager |
| |
| #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_FORM_MANAGER_H_ |