1 // Copyright (c) 2012 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 #ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_WEB_AUTH_FLOW_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_WEB_AUTH_FLOW_H_ 7 8 #include <string> 9 10 #include "base/macros.h" 11 #include "content/public/browser/notification_observer.h" 12 #include "content/public/browser/notification_registrar.h" 13 #include "content/public/browser/storage_partition_config.h" 14 #include "content/public/browser/web_contents_observer.h" 15 #include "extensions/browser/app_window/app_window_registry.h" 16 #include "ui/gfx/geometry/rect.h" 17 #include "url/gurl.h" 18 19 class Profile; 20 class WebAuthFlowTest; 21 22 namespace content { 23 class NotificationDetails; 24 class NotificationSource; 25 class StoragePartition; 26 } 27 28 namespace extensions { 29 30 // Controller class for web based auth flows. The WebAuthFlow creates 31 // a dialog window in the scope approval component app by firing an 32 // event. A webview embedded in the dialog will navigate to the 33 // |provider_url| passed to the WebAuthFlow constructor. 34 // 35 // The WebAuthFlow monitors the WebContents of the webview, and 36 // notifies its delegate interface any time the WebContents navigates 37 // to a new URL or changes title. The delegate is expected to delete 38 // the flow when navigation reaches a known target location. 39 // 40 // The window is not displayed until the first page load 41 // completes. This allows the flow to complete without flashing a 42 // window on screen if the provider immediately redirects to the 43 // target URL. 44 // 45 // A WebAuthFlow can be started in Mode::SILENT, which never displays 46 // a window. If a window would be required, the flow fails. 47 class WebAuthFlow : public content::NotificationObserver, 48 public content::WebContentsObserver, 49 public AppWindowRegistry::Observer { 50 public: 51 enum Mode { 52 INTERACTIVE, // Show UI to the user if necessary. 53 SILENT // No UI should be shown. 54 }; 55 56 enum Partition { 57 GET_AUTH_TOKEN, // Use the getAuthToken() partition. 58 LAUNCH_WEB_AUTH_FLOW // Use the launchWebAuthFlow() partition. 59 }; 60 61 enum Failure { 62 WINDOW_CLOSED, // Window closed by user. 63 INTERACTION_REQUIRED, // Non-redirect page load in silent mode. 64 LOAD_FAILED 65 }; 66 67 class Delegate { 68 public: 69 // Called when the auth flow fails. This means that the flow did not result 70 // in a successful redirect to a valid redirect URL. 71 virtual void OnAuthFlowFailure(Failure failure) = 0; 72 // Called on redirects and other navigations to see if the URL should stop 73 // the flow. OnAuthFlowURLChange(const GURL & redirect_url)74 virtual void OnAuthFlowURLChange(const GURL& redirect_url) {} 75 // Called when the title of the current page changes. OnAuthFlowTitleChange(const std::string & title)76 virtual void OnAuthFlowTitleChange(const std::string& title) {} 77 78 protected: ~Delegate()79 virtual ~Delegate() {} 80 }; 81 82 // Creates an instance with the given parameters. 83 // Caller owns |delegate|. 84 WebAuthFlow(Delegate* delegate, 85 Profile* profile, 86 const GURL& provider_url, 87 Mode mode, 88 Partition partition); 89 90 ~WebAuthFlow() override; 91 92 // Starts the flow. 93 virtual void Start(); 94 95 // Prevents further calls to the delegate and deletes the flow. 96 void DetachDelegateAndDelete(); 97 98 // Returns a StoragePartition of the guest webview. Used to inject cookies 99 // into Gaia page. Can override for testing. 100 virtual content::StoragePartition* GetGuestPartition(); 101 102 // Returns an ID string attached to the window. Can override for testing. 103 virtual const std::string& GetAppWindowKey() const; 104 105 // Returns the StoragePartitionConfig for a given |partition| used in the 106 // WebAuthFlow. 107 static content::StoragePartitionConfig GetWebViewPartitionConfig( 108 Partition partition, 109 content::BrowserContext* browser_context); 110 111 private: 112 friend class ::WebAuthFlowTest; 113 114 // ::AppWindowRegistry::Observer implementation. 115 void OnAppWindowAdded(AppWindow* app_window) override; 116 void OnAppWindowRemoved(AppWindow* app_window) override; 117 118 // NotificationObserver implementation. 119 void Observe(int type, 120 const content::NotificationSource& source, 121 const content::NotificationDetails& details) override; 122 123 // WebContentsObserver implementation. 124 void DidStopLoading() override; 125 void RenderProcessGone(base::TerminationStatus status) override; 126 void TitleWasSet(content::NavigationEntry* entry) override; 127 void DidStartNavigation( 128 content::NavigationHandle* navigation_handle) override; 129 void DidRedirectNavigation( 130 content::NavigationHandle* navigation_handle) override; 131 void DidFinishNavigation( 132 content::NavigationHandle* navigation_handle) override; 133 134 void BeforeUrlLoaded(const GURL& url); 135 void AfterUrlLoaded(); 136 137 Delegate* delegate_; 138 Profile* profile_; 139 GURL provider_url_; 140 Mode mode_; 141 Partition partition_; 142 143 AppWindow* app_window_; 144 std::string app_window_key_; 145 bool embedded_window_created_; 146 147 content::NotificationRegistrar registrar_; 148 149 DISALLOW_COPY_AND_ASSIGN(WebAuthFlow); 150 }; 151 152 } // namespace extensions 153 154 #endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_WEB_AUTH_FLOW_H_ 155