Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / enrollment_dialog_view.cc
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 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
6
7 #include "base/bind.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/chromeos/profiles/profile_helper.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/profiles/profile_manager.h"
12 #include "chrome/browser/ui/browser_finder.h"
13 #include "chrome/browser/ui/browser_navigator.h"
14 #include "chrome/grit/generated_resources.h"
15 #include "chromeos/network/client_cert_util.h"
16 #include "chromeos/network/managed_network_configuration_handler.h"
17 #include "chromeos/network/network_event_log.h"
18 #include "chromeos/network/network_state.h"
19 #include "chromeos/network/network_state_handler.h"
20 #include "extensions/browser/extension_host.h"
21 #include "extensions/common/constants.h"
22 #include "ui/base/l10n/l10n_util.h"
23 #include "ui/base/page_transition_types.h"
24 #include "ui/views/controls/label.h"
25 #include "ui/views/layout/grid_layout.h"
26 #include "ui/views/layout/layout_constants.h"
27 #include "ui/views/widget/widget.h"
28 #include "ui/views/window/dialog_delegate.h"
29
30 namespace chromeos {
31
32 namespace {
33
34 // Default width/height of the dialog.
35 const int kDefaultWidth = 350;
36 const int kDefaultHeight = 100;
37
38 ////////////////////////////////////////////////////////////////////////////////
39 // Dialog for certificate enrollment. This displays the content from the
40 // certificate enrollment URI.
41 class EnrollmentDialogView : public views::DialogDelegateView {
42  public:
43   virtual ~EnrollmentDialogView();
44
45   static void ShowDialog(gfx::NativeWindow owning_window,
46                          const std::string& network_name,
47                          Profile* profile,
48                          const GURL& target_uri,
49                          const base::Closure& connect);
50
51   // views::DialogDelegateView overrides
52   virtual int GetDialogButtons() const override;
53   virtual bool Accept() override;
54   virtual void OnClosed() override;
55   virtual base::string16 GetDialogButtonLabel(
56       ui::DialogButton button) const override;
57
58   // views::WidgetDelegate overrides
59   virtual ui::ModalType GetModalType() const override;
60   virtual base::string16 GetWindowTitle() const override;
61
62   // views::View overrides
63   virtual gfx::Size GetPreferredSize() const override;
64
65  private:
66   EnrollmentDialogView(const std::string& network_name,
67                        Profile* profile,
68                        const GURL& target_uri,
69                        const base::Closure& connect);
70   void InitDialog();
71
72   bool accepted_;
73   std::string network_name_;
74   Profile* profile_;
75   GURL target_uri_;
76   base::Closure connect_;
77   bool added_cert_;
78 };
79
80 ////////////////////////////////////////////////////////////////////////////////
81 // EnrollmentDialogView implementation.
82
83 EnrollmentDialogView::EnrollmentDialogView(const std::string& network_name,
84                                            Profile* profile,
85                                            const GURL& target_uri,
86                                            const base::Closure& connect)
87     : accepted_(false),
88       network_name_(network_name),
89       profile_(profile),
90       target_uri_(target_uri),
91       connect_(connect),
92       added_cert_(false) {
93 }
94
95 EnrollmentDialogView::~EnrollmentDialogView() {
96 }
97
98 // static
99 void EnrollmentDialogView::ShowDialog(gfx::NativeWindow owning_window,
100                                       const std::string& network_name,
101                                       Profile* profile,
102                                       const GURL& target_uri,
103                                       const base::Closure& connect) {
104   EnrollmentDialogView* dialog_view =
105       new EnrollmentDialogView(network_name, profile, target_uri, connect);
106   views::DialogDelegate::CreateDialogWidget(dialog_view, NULL, owning_window);
107   dialog_view->InitDialog();
108   views::Widget* widget = dialog_view->GetWidget();
109   DCHECK(widget);
110   widget->Show();
111 }
112
113 int EnrollmentDialogView::GetDialogButtons() const {
114   return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
115 }
116
117 bool EnrollmentDialogView::Accept() {
118   accepted_ = true;
119   return true;
120 }
121
122 void EnrollmentDialogView::OnClosed() {
123   if (!accepted_)
124     return;
125   chrome::NavigateParams params(profile_,
126                                 GURL(target_uri_),
127                                 ui::PAGE_TRANSITION_LINK);
128   params.disposition = NEW_FOREGROUND_TAB;
129   params.window_action = chrome::NavigateParams::SHOW_WINDOW;
130   chrome::Navigate(&params);
131 }
132
133 base::string16 EnrollmentDialogView::GetDialogButtonLabel(
134     ui::DialogButton button) const {
135   if (button == ui::DIALOG_BUTTON_OK)
136     return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_BUTTON);
137   return views::DialogDelegateView::GetDialogButtonLabel(button);
138 }
139
140 ui::ModalType EnrollmentDialogView::GetModalType() const {
141   return ui::MODAL_TYPE_SYSTEM;
142 }
143
144 base::string16 EnrollmentDialogView::GetWindowTitle() const {
145   return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE);
146 }
147
148 gfx::Size EnrollmentDialogView::GetPreferredSize() const {
149   return gfx::Size(kDefaultWidth, kDefaultHeight);
150 }
151
152 void EnrollmentDialogView::InitDialog() {
153   added_cert_ = false;
154   // Create the views and layout manager and set them up.
155   views::Label* label = new views::Label(
156       l10n_util::GetStringFUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_INSTRUCTIONS,
157                                  base::UTF8ToUTF16(network_name_)));
158   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
159   label->SetMultiLine(true);
160   label->SetAllowCharacterBreak(true);
161
162   views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
163   SetLayoutManager(grid_layout);
164
165   views::ColumnSet* columns = grid_layout->AddColumnSet(0);
166   columns->AddColumn(views::GridLayout::FILL,  // Horizontal resize.
167                      views::GridLayout::FILL,  // Vertical resize.
168                      1,   // Resize weight.
169                      views::GridLayout::USE_PREF,  // Size type.
170                      0,   // Ignored for USE_PREF.
171                      0);  // Minimum size.
172   columns = grid_layout->AddColumnSet(1);
173   columns->AddPaddingColumn(
174       0, views::kUnrelatedControlHorizontalSpacing);
175   columns->AddColumn(views::GridLayout::LEADING,  // Horizontal leading.
176                      views::GridLayout::FILL,     // Vertical resize.
177                      1,   // Resize weight.
178                      views::GridLayout::USE_PREF,  // Size type.
179                      0,   // Ignored for USE_PREF.
180                      0);  // Minimum size.
181
182   grid_layout->StartRow(0, 0);
183   grid_layout->AddView(label);
184   grid_layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
185   grid_layout->Layout(this);
186 }
187
188 ////////////////////////////////////////////////////////////////////////////////
189 // Handler for certificate enrollment.
190
191 class DialogEnrollmentDelegate {
192  public:
193   // |owning_window| is the window that will own the dialog.
194   DialogEnrollmentDelegate(gfx::NativeWindow owning_window,
195                            const std::string& network_name,
196                            Profile* profile);
197   ~DialogEnrollmentDelegate();
198
199   // EnrollmentDelegate overrides
200   bool Enroll(const std::vector<std::string>& uri_list,
201               const base::Closure& connect);
202
203  private:
204   gfx::NativeWindow owning_window_;
205   std::string network_name_;
206   Profile* profile_;
207
208   DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate);
209 };
210
211 DialogEnrollmentDelegate::DialogEnrollmentDelegate(
212     gfx::NativeWindow owning_window,
213     const std::string& network_name,
214     Profile* profile) : owning_window_(owning_window),
215                         network_name_(network_name),
216                         profile_(profile) {}
217
218 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
219
220 bool DialogEnrollmentDelegate::Enroll(const std::vector<std::string>& uri_list,
221                                       const base::Closure& post_action) {
222   // Keep the closure for later activation if we notice that
223   // a certificate has been added.
224
225   // TODO(gspencer): Do something smart with the closure.  At the moment it is
226   // being ignored because we don't know when the enrollment tab is closed.
227   // http://crosbug.com/30422
228   for (std::vector<std::string>::const_iterator iter = uri_list.begin();
229        iter != uri_list.end(); ++iter) {
230     GURL uri(*iter);
231     if (uri.IsStandard() || uri.scheme() == extensions::kExtensionScheme) {
232       // If this is a "standard" scheme, like http, ftp, etc., then open that in
233       // the enrollment dialog.
234       NET_LOG_EVENT("Showing enrollment dialog", network_name_);
235       EnrollmentDialogView::ShowDialog(owning_window_,
236                                        network_name_,
237                                        profile_,
238                                        uri, post_action);
239       return true;
240     }
241     NET_LOG_DEBUG("Nonstandard URI: " + uri.spec(), network_name_);
242   }
243
244   // No appropriate scheme was found.
245   NET_LOG_ERROR("No usable enrollment URI", network_name_);
246   return false;
247 }
248
249 void EnrollmentComplete(const std::string& service_path) {
250   NET_LOG_USER("Enrollment Complete", service_path);
251 }
252
253 }  // namespace
254
255 ////////////////////////////////////////////////////////////////////////////////
256 // Factory function.
257
258 namespace enrollment {
259
260 bool CreateDialog(const std::string& service_path,
261                   gfx::NativeWindow owning_window) {
262   const NetworkState* network = NetworkHandler::Get()->network_state_handler()->
263       GetNetworkState(service_path);
264   if (!network) {
265     NET_LOG_ERROR("Enrolling Unknown network", service_path);
266     return false;
267   }
268   Browser* browser = chrome::FindBrowserWithWindow(owning_window);
269   Profile* profile =
270       browser ? browser->profile() : ProfileManager::GetPrimaryUserProfile();
271   std::string username_hash = ProfileHelper::GetUserIdHashFromProfile(profile);
272
273   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
274   const base::DictionaryValue* policy =
275       NetworkHandler::Get()
276           ->managed_network_configuration_handler()
277           ->FindPolicyByGUID(username_hash, network->guid(), &onc_source);
278
279   // We skip certificate patterns for device policy ONC so that an unmanaged
280   // user can't get to the place where a cert is presented for them
281   // involuntarily.
282   if (!policy || onc_source == onc::ONC_SOURCE_DEVICE_POLICY)
283     return false;
284
285   client_cert::ClientCertConfig cert_config;
286   OncToClientCertConfig(*policy, &cert_config);
287
288   if (cert_config.client_cert_type != onc::client_cert::kPattern)
289     return false;
290
291   if (cert_config.pattern.Empty())
292     NET_LOG_ERROR("Certificate pattern is empty", service_path);
293
294   if (cert_config.pattern.enrollment_uri_list().empty()) {
295     NET_LOG_EVENT("No enrollment URIs", service_path);
296     return false;
297   }
298
299   NET_LOG_USER("Enrolling", service_path);
300
301   DialogEnrollmentDelegate* enrollment =
302       new DialogEnrollmentDelegate(owning_window, network->name(), profile);
303   return enrollment->Enroll(cert_config.pattern.enrollment_uri_list(),
304                             base::Bind(&EnrollmentComplete, service_path));
305 }
306
307 }  // namespace enrollment
308
309 }  // namespace chromeos