1// Copyright 2015 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#import "ios/chrome/browser/passwords/ios_chrome_password_manager_client.h"
6
7#include <memory>
8#include <utility>
9
10#include "base/bind.h"
11#include "base/no_destructor.h"
12#include "components/autofill/core/browser/logging/log_manager.h"
13#include "components/autofill/core/browser/logging/log_router.h"
14#include "components/keyed_service/core/service_access_type.h"
15#include "components/password_manager/core/browser/password_form.h"
16#include "components/password_manager/core/browser/password_form_manager_for_ui.h"
17#include "components/password_manager/core/browser/password_manager.h"
18#include "components/password_manager/core/browser/password_manager_constants.h"
19#include "components/password_manager/core/browser/password_manager_driver.h"
20#include "components/password_manager/core/browser/password_manager_util.h"
21#include "components/password_manager/core/browser/password_requirements_service.h"
22#include "components/password_manager/core/browser/store_metrics_reporter.h"
23#include "components/password_manager/core/common/password_manager_pref_names.h"
24#include "components/password_manager/ios/password_manager_ios_util.h"
25#include "components/sync/driver/sync_service.h"
26#include "components/translate/core/browser/translate_manager.h"
27#import "components/ukm/ios/ukm_url_recorder.h"
28#include "ios/chrome/browser/application_context.h"
29#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
30#include "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
31#include "ios/chrome/browser/passwords/ios_password_requirements_service_factory.h"
32#include "ios/chrome/browser/passwords/password_manager_log_router_factory.h"
33#include "ios/chrome/browser/signin/identity_manager_factory.h"
34#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
35#include "ios/chrome/browser/system_flags.h"
36#include "ios/chrome/browser/translate/chrome_ios_translate_client.h"
37#import "ios/chrome/browser/ui/ui_feature_flags.h"
38#include "net/cert/cert_status_flags.h"
39#include "services/metrics/public/cpp/ukm_recorder.h"
40#include "services/network/public/cpp/shared_url_loader_factory.h"
41#include "url/gurl.h"
42
43#if !defined(__has_feature) || !__has_feature(objc_arc)
44#error "This file requires ARC support."
45#endif
46
47using password_manager::metrics_util::PasswordType;
48using password_manager::PasswordFormManagerForUI;
49using password_manager::PasswordManagerMetricsRecorder;
50using password_manager::PasswordStore;
51using password_manager::SyncState;
52
53namespace {
54
55const syncer::SyncService* GetSyncService(ChromeBrowserState* browser_state) {
56  return ProfileSyncServiceFactory::GetForBrowserStateIfExists(browser_state);
57}
58
59}  // namespace
60
61IOSChromePasswordManagerClient::IOSChromePasswordManagerClient(
62    id<IOSChromePasswordManagerClientBridge> bridge)
63    : bridge_(bridge),
64      password_feature_manager_(GetPrefs(),
65                                GetSyncService(bridge_.browserState)),
66      credentials_filter_(
67          this,
68          base::BindRepeating(&GetSyncService, bridge_.browserState)),
69      helper_(this) {
70  saving_passwords_enabled_.Init(
71      password_manager::prefs::kCredentialsEnableService, GetPrefs());
72  static base::NoDestructor<password_manager::StoreMetricsReporter> reporter(
73      this, GetSyncService(bridge_.browserState), GetIdentityManager(),
74      GetPrefs());
75  log_manager_ = autofill::LogManager::Create(
76      ios::PasswordManagerLogRouterFactory::GetForBrowserState(
77          bridge_.browserState),
78      base::RepeatingClosure());
79}
80
81IOSChromePasswordManagerClient::~IOSChromePasswordManagerClient() = default;
82
83SyncState IOSChromePasswordManagerClient::GetPasswordSyncState() const {
84  syncer::SyncService* sync_service =
85      ProfileSyncServiceFactory::GetForBrowserState(bridge_.browserState);
86  return password_manager_util::GetPasswordSyncState(sync_service);
87}
88
89bool IOSChromePasswordManagerClient::PromptUserToChooseCredentials(
90    std::vector<std::unique_ptr<password_manager::PasswordForm>> local_forms,
91    const url::Origin& origin,
92    CredentialsCallback callback) {
93  NOTIMPLEMENTED();
94  return false;
95}
96
97bool IOSChromePasswordManagerClient::PromptUserToSaveOrUpdatePassword(
98    std::unique_ptr<PasswordFormManagerForUI> form_to_save,
99    bool update_password) {
100  if (form_to_save->IsBlacklisted())
101    return false;
102
103  [bridge_ removePasswordInfoBarManualFallback:YES];
104
105  if (update_password) {
106    [bridge_ showUpdatePasswordInfoBar:std::move(form_to_save) manual:NO];
107  } else {
108    [bridge_ showSavePasswordInfoBar:std::move(form_to_save) manual:NO];
109  }
110
111  return true;
112}
113
114void IOSChromePasswordManagerClient::PromptUserToMovePasswordToAccount(
115    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_move) {
116  NOTIMPLEMENTED();
117}
118
119bool IOSChromePasswordManagerClient::RequiresReauthToFill() {
120  return true;
121}
122
123void IOSChromePasswordManagerClient::ShowManualFallbackForSaving(
124    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_to_save,
125    bool has_generated_password,
126    bool is_update) {
127  if (is_update) {
128    [bridge_ showUpdatePasswordInfoBar:std::move(form_to_save) manual:YES];
129  } else {
130    [bridge_ showSavePasswordInfoBar:std::move(form_to_save) manual:YES];
131  }
132}
133
134void IOSChromePasswordManagerClient::HideManualFallbackForSaving() {
135  [bridge_ removePasswordInfoBarManualFallback:YES];
136}
137
138void IOSChromePasswordManagerClient::FocusedInputChanged(
139    password_manager::PasswordManagerDriver* driver,
140    autofill::mojom::FocusedFieldType focused_field_type) {
141  NOTIMPLEMENTED();
142}
143
144void IOSChromePasswordManagerClient::AutomaticPasswordSave(
145    std::unique_ptr<PasswordFormManagerForUI> saved_form_manager) {
146  NOTIMPLEMENTED();
147}
148
149void IOSChromePasswordManagerClient::PromptUserToEnableAutosignin() {
150  // TODO(crbug.com/435048): Implement this method.
151  NOTIMPLEMENTED();
152}
153
154bool IOSChromePasswordManagerClient::IsIncognito() const {
155  return (bridge_.browserState)->IsOffTheRecord();
156}
157
158const password_manager::PasswordManager*
159IOSChromePasswordManagerClient::GetPasswordManager() const {
160  return bridge_.passwordManager;
161}
162
163const password_manager::PasswordFeatureManager*
164IOSChromePasswordManagerClient::GetPasswordFeatureManager() const {
165  return &password_feature_manager_;
166}
167
168PrefService* IOSChromePasswordManagerClient::GetPrefs() const {
169  return (bridge_.browserState)->GetPrefs();
170}
171
172PasswordStore* IOSChromePasswordManagerClient::GetProfilePasswordStore() const {
173  return IOSChromePasswordStoreFactory::GetForBrowserState(
174             bridge_.browserState, ServiceAccessType::EXPLICIT_ACCESS)
175      .get();
176}
177
178PasswordStore* IOSChromePasswordManagerClient::GetAccountPasswordStore() const {
179  // AccountPasswordStore is currenly not supported on iOS.
180  return nullptr;
181}
182
183void IOSChromePasswordManagerClient::NotifyUserAutoSignin(
184    std::vector<std::unique_ptr<password_manager::PasswordForm>> local_forms,
185    const url::Origin& origin) {
186  DCHECK(!local_forms.empty());
187  helper_.NotifyUserAutoSignin();
188  [bridge_ showAutosigninNotification:std::move(local_forms[0])];
189}
190
191void IOSChromePasswordManagerClient::NotifyUserCouldBeAutoSignedIn(
192    std::unique_ptr<password_manager::PasswordForm> form) {
193  helper_.NotifyUserCouldBeAutoSignedIn(std::move(form));
194}
195
196void IOSChromePasswordManagerClient::NotifySuccessfulLoginWithExistingPassword(
197    std::unique_ptr<password_manager::PasswordFormManagerForUI>
198        submitted_manager) {
199  helper_.NotifySuccessfulLoginWithExistingPassword(
200      std::move(submitted_manager));
201}
202
203void IOSChromePasswordManagerClient::NotifyStorePasswordCalled() {
204  helper_.NotifyStorePasswordCalled();
205}
206
207void IOSChromePasswordManagerClient::NotifyUserCredentialsWereLeaked(
208    password_manager::CredentialLeakType leak_type,
209    password_manager::CompromisedSitesCount saved_sites,
210    const GURL& origin,
211    const base::string16& username) {
212  [bridge_ showPasswordBreachForLeakType:leak_type URL:origin];
213}
214
215bool IOSChromePasswordManagerClient::IsSavingAndFillingEnabled(
216    const GURL& url) const {
217  return *saving_passwords_enabled_ && !IsIncognito() &&
218         !net::IsCertStatusError(GetMainFrameCertStatus()) &&
219         IsFillingEnabled(url);
220}
221
222bool IOSChromePasswordManagerClient::IsFillingEnabled(const GURL& url) const {
223  return url.GetOrigin() !=
224         GURL(password_manager::kPasswordManagerAccountDashboardURL);
225}
226
227bool IOSChromePasswordManagerClient::IsCommittedMainFrameSecure() const {
228  return password_manager::WebStateContentIsSecureHtml(bridge_.webState);
229}
230
231const GURL& IOSChromePasswordManagerClient::GetLastCommittedURL() const {
232  return bridge_.lastCommittedURL;
233}
234
235url::Origin IOSChromePasswordManagerClient::GetLastCommittedOrigin() const {
236  return url::Origin::Create(bridge_.lastCommittedURL);
237}
238
239std::string IOSChromePasswordManagerClient::GetPageLanguage() const {
240  // TODO(crbug.com/912597): Add WebState to the IOSChromePasswordManagerClient
241  // to be able to get the pages LanguageState from the TranslateManager.
242  return std::string();
243}
244
245const password_manager::CredentialsFilter*
246IOSChromePasswordManagerClient::GetStoreResultFilter() const {
247  return &credentials_filter_;
248}
249
250const autofill::LogManager* IOSChromePasswordManagerClient::GetLogManager()
251    const {
252  return log_manager_.get();
253}
254
255ukm::SourceId IOSChromePasswordManagerClient::GetUkmSourceId() {
256  return bridge_.webState
257             ? ukm::GetSourceIdForWebStateDocument(bridge_.webState)
258             : ukm::kInvalidSourceId;
259}
260
261PasswordManagerMetricsRecorder*
262IOSChromePasswordManagerClient::GetMetricsRecorder() {
263  if (!metrics_recorder_) {
264    metrics_recorder_.emplace(GetUkmSourceId(),
265                              /*navigation_metric_recorder=*/nullptr);
266  }
267  return base::OptionalOrNullptr(metrics_recorder_);
268}
269
270signin::IdentityManager* IOSChromePasswordManagerClient::GetIdentityManager() {
271  return IdentityManagerFactory::GetForBrowserState(bridge_.browserState);
272}
273
274scoped_refptr<network::SharedURLLoaderFactory>
275IOSChromePasswordManagerClient::GetURLLoaderFactory() {
276  return (bridge_.browserState)->GetSharedURLLoaderFactory();
277}
278
279password_manager::PasswordRequirementsService*
280IOSChromePasswordManagerClient::GetPasswordRequirementsService() {
281  return IOSPasswordRequirementsServiceFactory::GetForBrowserState(
282      bridge_.browserState, ServiceAccessType::EXPLICIT_ACCESS);
283}
284
285bool IOSChromePasswordManagerClient::IsIsolationForPasswordSitesEnabled()
286    const {
287  return false;
288}
289
290bool IOSChromePasswordManagerClient::IsNewTabPage() const {
291  return false;
292}
293
294password_manager::FieldInfoManager*
295IOSChromePasswordManagerClient::GetFieldInfoManager() const {
296  return nullptr;
297}
298
299bool IOSChromePasswordManagerClient::IsAutofillAssistantUIVisible() const {
300  return false;
301}
302
303safe_browsing::PasswordProtectionService*
304IOSChromePasswordManagerClient::GetPasswordProtectionService() const {
305  // TODO(crbug.com/1147967): This is no-op until the password protection
306  // service is enabled.
307  return nullptr;
308}
309
310void IOSChromePasswordManagerClient::CheckProtectedPasswordEntry(
311    PasswordType password_type,
312    const std::string& username,
313    const std::vector<password_manager::MatchingReusedCredential>&
314        matching_reused_credentials,
315    bool password_field_exists) {
316  // TODO(crbug.com/1147967): This is no-op until the password protection
317  // service is enabled.
318}
319