| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import "base/memory/weak_ptr.h" |
| #import "ios/components/security_interstitials/lookalikes/lookalike_url_tab_allow_list.h" |
| #import "ios/web/public/navigation/navigation_manager.h" |
| #import "ios/web_view/internal/cwv_lookalike_url_handler_internal.h" |
| #import "net/base/apple/url_conversions.h" |
| |
| @implementation CWVLookalikeURLHandler { |
| base::WeakPtr<web::WebState> _webState; |
| std::unique_ptr<LookalikeUrlContainer::LookalikeUrlInfo> _lookalikeURLInfo; |
| base::OnceCallback<void(NSString*)> _htmlCallback; |
| } |
| |
| - (instancetype) |
| initWithWebState:(web::WebState*)webState |
| lookalikeURLInfo:(std::unique_ptr<LookalikeUrlContainer::LookalikeUrlInfo>) |
| lookalikeURLInfo |
| htmlCallback:(base::OnceCallback<void(NSString*)>)htmlCallback { |
| self = [super init]; |
| if (self) { |
| _webState = webState->GetWeakPtr(); |
| _lookalikeURLInfo = std::move(lookalikeURLInfo); |
| _htmlCallback = std::move(htmlCallback); |
| } |
| return self; |
| } |
| |
| #pragma mark - Public Methods |
| |
| - (NSURL*)requestURL { |
| return net::NSURLWithGURL(_lookalikeURLInfo->request_url); |
| } |
| |
| - (nullable NSURL*)safeURL { |
| if ([self isSafeURLValid]) { |
| return net::NSURLWithGURL(_lookalikeURLInfo->safe_url); |
| } else { |
| return nil; |
| } |
| } |
| |
| - (void)displayInterstitialPageWithHTML:(NSString*)HTML { |
| if (_htmlCallback) { |
| std::move(_htmlCallback).Run(HTML); |
| } |
| } |
| |
| - (BOOL)commitDecision:(CWVLookalikeURLHandlerDecision)decision { |
| if (!_webState) { |
| return NO; |
| } |
| switch (decision) { |
| case CWVLookalikeURLHandlerDecisionProceedToRequestURL: { |
| LookalikeUrlTabAllowList::FromWebState(_webState.get()) |
| ->AllowDomain(_lookalikeURLInfo->request_url.GetHost()); |
| _webState->GetNavigationManager()->Reload(web::ReloadType::NORMAL, |
| /*check_for_repost=*/true); |
| return YES; |
| } |
| case CWVLookalikeURLHandlerDecisionProceedToSafeURL: { |
| if ([self isSafeURLValid]) { |
| _webState->OpenURL(web::WebState::OpenURLParams( |
| _lookalikeURLInfo->safe_url, web::Referrer(), |
| WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_LINK, |
| /*is_renderer_initiated=*/false)); |
| return YES; |
| } else { |
| return NO; |
| } |
| } |
| case CWVLookalikeURLHandlerDecisionGoBackOrClose: { |
| if (_webState->GetNavigationManager()->CanGoBack()) { |
| _webState->GetNavigationManager()->GoBack(); |
| } else { |
| _webState->CloseWebState(); |
| } |
| return YES; |
| } |
| } |
| } |
| |
| #pragma mark - Private Methods |
| |
| - (BOOL)isSafeURLValid { |
| return _lookalikeURLInfo->safe_url.is_valid(); |
| } |
| |
| @end |