• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/browser/password_manager/password_store_default.h"
6 
7 #include <set>
8 
9 #include "base/logging.h"
10 #include "base/stl_util-inl.h"
11 #include "chrome/browser/password_manager/password_store_change.h"
12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/webdata/web_data_service.h"
15 #include "chrome/common/chrome_constants.h"
16 #include "chrome/common/pref_names.h"
17 #include "content/browser/browser_thread.h"
18 #include "content/common/notification_service.h"
19 
20 using webkit_glue::PasswordForm;
21 
22 // MigrateHelper handles migration from WebDB to PasswordStore. It runs
23 // entirely on the UI thread and is owned by PasswordStoreDefault.
24 class PasswordStoreDefault::MigrateHelper : public WebDataServiceConsumer {
25  public:
MigrateHelper(Profile * profile,WebDataService * web_data_service,PasswordStore * password_store)26   MigrateHelper(Profile* profile,
27                 WebDataService* web_data_service,
28                 PasswordStore* password_store)
29       : profile_(profile),
30         web_data_service_(web_data_service),
31         password_store_(password_store) {
32   }
33   ~MigrateHelper();
34 
35   void Init();
36 
37   // WebDataServiceConsumer:
38   virtual void OnWebDataServiceRequestDone(
39       WebDataService::Handle handle,
40       const WDTypedResult *result) OVERRIDE;
41 
42  private:
43   typedef std::set<WebDataService::Handle> Handles;
44 
45   Profile* profile_;
46 
47   scoped_refptr<WebDataService> web_data_service_;
48 
49   // This creates a cycle between us and PasswordStore. The cycle is broken
50   // from PasswordStoreDefault::Shutdown, which deletes us.
51   scoped_refptr<PasswordStore> password_store_;
52 
53   // Set of handles from requesting data from the WebDB.
54   Handles handles_;
55 
56   DISALLOW_COPY_AND_ASSIGN(MigrateHelper);
57 };
58 
~MigrateHelper()59 PasswordStoreDefault::MigrateHelper::~MigrateHelper() {
60   for (Handles::const_iterator i = handles_.begin(); i != handles_.end(); ++i)
61     web_data_service_->CancelRequest(*i);
62   handles_.clear();
63 }
64 
Init()65 void PasswordStoreDefault::MigrateHelper::Init() {
66   handles_.insert(web_data_service_->GetAutofillableLogins(this));
67   handles_.insert(web_data_service_->GetBlacklistLogins(this));
68 }
69 
OnWebDataServiceRequestDone(WebDataService::Handle handle,const WDTypedResult * result)70 void PasswordStoreDefault::MigrateHelper::OnWebDataServiceRequestDone(
71     WebDataService::Handle handle,
72     const WDTypedResult* result) {
73   typedef std::vector<const PasswordForm*> PasswordForms;
74 
75   DCHECK(handles_.end() != handles_.find(handle));
76   DCHECK(password_store_);
77 
78   handles_.erase(handle);
79   if (!result)
80     return;
81 
82   if (PASSWORD_RESULT != result->GetType()) {
83     NOTREACHED();
84     return;
85   }
86 
87   const PasswordForms& forms =
88       static_cast<const WDResult<PasswordForms>*>(result)->GetValue();
89   for (PasswordForms::const_iterator it = forms.begin();
90        it != forms.end(); ++it) {
91     password_store_->AddLogin(**it);
92     web_data_service_->RemoveLogin(**it);
93     delete *it;
94   }
95   if (handles_.empty()) {
96     profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated,
97                                               true);
98   }
99 }
100 
PasswordStoreDefault(LoginDatabase * login_db,Profile * profile,WebDataService * web_data_service)101 PasswordStoreDefault::PasswordStoreDefault(LoginDatabase* login_db,
102                                            Profile* profile,
103                                            WebDataService* web_data_service)
104     : web_data_service_(web_data_service),
105       login_db_(login_db), profile_(profile) {
106   DCHECK(login_db);
107   DCHECK(profile);
108   DCHECK(web_data_service);
109   MigrateIfNecessary();
110 }
111 
~PasswordStoreDefault()112 PasswordStoreDefault::~PasswordStoreDefault() {
113   // MigrateHelper should always be NULL as Shutdown should be invoked before
114   // the destructor.
115   DCHECK(!migrate_helper_.get());
116 }
117 
Shutdown()118 void PasswordStoreDefault::Shutdown() {
119   migrate_helper_.reset();
120 }
121 
ReportMetricsImpl()122 void PasswordStoreDefault::ReportMetricsImpl() {
123   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
124   login_db_->ReportMetrics();
125 }
126 
AddLoginImpl(const PasswordForm & form)127 void PasswordStoreDefault::AddLoginImpl(const PasswordForm& form) {
128   if (login_db_->AddLogin(form)) {
129     PasswordStoreChangeList changes;
130     changes.push_back(PasswordStoreChange(PasswordStoreChange::ADD, form));
131     NotificationService::current()->Notify(
132         NotificationType::LOGINS_CHANGED,
133         Source<PasswordStore>(this),
134         Details<PasswordStoreChangeList>(&changes));
135   }
136 }
137 
UpdateLoginImpl(const PasswordForm & form)138 void PasswordStoreDefault::UpdateLoginImpl(const PasswordForm& form) {
139   if (login_db_->UpdateLogin(form, NULL)) {
140     PasswordStoreChangeList changes;
141     changes.push_back(PasswordStoreChange(PasswordStoreChange::UPDATE, form));
142     NotificationService::current()->Notify(
143         NotificationType::LOGINS_CHANGED,
144         Source<PasswordStore>(this),
145         Details<PasswordStoreChangeList>(&changes));
146   }
147 }
148 
RemoveLoginImpl(const PasswordForm & form)149 void PasswordStoreDefault::RemoveLoginImpl(const PasswordForm& form) {
150   if (login_db_->RemoveLogin(form)) {
151     PasswordStoreChangeList changes;
152     changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE, form));
153     NotificationService::current()->Notify(
154         NotificationType::LOGINS_CHANGED,
155         Source<PasswordStore>(this),
156         Details<PasswordStoreChangeList>(&changes));
157   }
158 }
159 
RemoveLoginsCreatedBetweenImpl(const base::Time & delete_begin,const base::Time & delete_end)160 void PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl(
161     const base::Time& delete_begin, const base::Time& delete_end) {
162   std::vector<PasswordForm*> forms;
163   if (login_db_->GetLoginsCreatedBetween(delete_begin, delete_end, &forms)) {
164     if (login_db_->RemoveLoginsCreatedBetween(delete_begin, delete_end)) {
165       PasswordStoreChangeList changes;
166       for (std::vector<PasswordForm*>::const_iterator it = forms.begin();
167            it != forms.end(); ++it) {
168         changes.push_back(PasswordStoreChange(PasswordStoreChange::REMOVE,
169                                               **it));
170       }
171       NotificationService::current()->Notify(
172           NotificationType::LOGINS_CHANGED,
173           Source<PasswordStore>(this),
174           Details<PasswordStoreChangeList>(&changes));
175     }
176   }
177   STLDeleteElements(&forms);
178 }
179 
GetLoginsImpl(GetLoginsRequest * request,const webkit_glue::PasswordForm & form)180 void PasswordStoreDefault::GetLoginsImpl(
181     GetLoginsRequest* request, const webkit_glue::PasswordForm& form) {
182   login_db_->GetLogins(form, &request->value);
183   ForwardLoginsResult(request);
184 }
185 
GetAutofillableLoginsImpl(GetLoginsRequest * request)186 void PasswordStoreDefault::GetAutofillableLoginsImpl(
187     GetLoginsRequest* request) {
188   FillAutofillableLogins(&request->value);
189   ForwardLoginsResult(request);
190 }
191 
GetBlacklistLoginsImpl(GetLoginsRequest * request)192 void PasswordStoreDefault::GetBlacklistLoginsImpl(
193     GetLoginsRequest* request) {
194   FillBlacklistLogins(&request->value);
195   ForwardLoginsResult(request);
196 }
197 
FillAutofillableLogins(std::vector<PasswordForm * > * forms)198 bool PasswordStoreDefault::FillAutofillableLogins(
199          std::vector<PasswordForm*>* forms) {
200   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
201   return login_db_->GetAutofillableLogins(forms);
202 }
203 
FillBlacklistLogins(std::vector<PasswordForm * > * forms)204 bool PasswordStoreDefault::FillBlacklistLogins(
205          std::vector<PasswordForm*>* forms) {
206   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
207   return login_db_->GetBlacklistLogins(forms);
208 }
209 
MigrateIfNecessary()210 void PasswordStoreDefault::MigrateIfNecessary() {
211   PrefService* prefs = profile_->GetPrefs();
212   if (prefs->FindPreference(prefs::kLoginDatabaseMigrated))
213     return;
214   DCHECK(!migrate_helper_.get());
215   migrate_helper_.reset(new MigrateHelper(profile_, web_data_service_, this));
216   migrate_helper_->Init();
217 }
218