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.
5 #include "chrome/browser/chromeos/enrollment_dialog_view.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"
34 // Default width/height of the dialog.
35 const int kDefaultWidth
= 350;
36 const int kDefaultHeight
= 100;
38 ////////////////////////////////////////////////////////////////////////////////
39 // Dialog for certificate enrollment. This displays the content from the
40 // certificate enrollment URI.
41 class EnrollmentDialogView
: public views::DialogDelegateView
{
43 ~EnrollmentDialogView() override
;
45 static void ShowDialog(gfx::NativeWindow owning_window
,
46 const std::string
& network_name
,
48 const GURL
& target_uri
,
49 const base::Closure
& connect
);
51 // views::DialogDelegateView overrides
52 int GetDialogButtons() const override
;
53 bool Accept() override
;
54 void OnClosed() override
;
55 base::string16
GetDialogButtonLabel(ui::DialogButton button
) const override
;
57 // views::WidgetDelegate overrides
58 ui::ModalType
GetModalType() const override
;
59 base::string16
GetWindowTitle() const override
;
61 // views::View overrides
62 gfx::Size
GetPreferredSize() const override
;
65 EnrollmentDialogView(const std::string
& network_name
,
67 const GURL
& target_uri
,
68 const base::Closure
& connect
);
72 std::string network_name_
;
75 base::Closure connect_
;
79 ////////////////////////////////////////////////////////////////////////////////
80 // EnrollmentDialogView implementation.
82 EnrollmentDialogView::EnrollmentDialogView(const std::string
& network_name
,
84 const GURL
& target_uri
,
85 const base::Closure
& connect
)
87 network_name_(network_name
),
89 target_uri_(target_uri
),
94 EnrollmentDialogView::~EnrollmentDialogView() {
98 void EnrollmentDialogView::ShowDialog(gfx::NativeWindow owning_window
,
99 const std::string
& network_name
,
101 const GURL
& target_uri
,
102 const base::Closure
& connect
) {
103 EnrollmentDialogView
* dialog_view
=
104 new EnrollmentDialogView(network_name
, profile
, target_uri
, connect
);
105 views::DialogDelegate::CreateDialogWidget(dialog_view
, NULL
, owning_window
);
106 dialog_view
->InitDialog();
107 views::Widget
* widget
= dialog_view
->GetWidget();
112 int EnrollmentDialogView::GetDialogButtons() const {
113 return ui::DIALOG_BUTTON_CANCEL
| ui::DIALOG_BUTTON_OK
;
116 bool EnrollmentDialogView::Accept() {
121 void EnrollmentDialogView::OnClosed() {
124 chrome::NavigateParams
params(profile_
,
126 ui::PAGE_TRANSITION_LINK
);
127 params
.disposition
= NEW_FOREGROUND_TAB
;
128 params
.window_action
= chrome::NavigateParams::SHOW_WINDOW
;
129 chrome::Navigate(¶ms
);
132 base::string16
EnrollmentDialogView::GetDialogButtonLabel(
133 ui::DialogButton button
) const {
134 if (button
== ui::DIALOG_BUTTON_OK
)
135 return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_BUTTON
);
136 return views::DialogDelegateView::GetDialogButtonLabel(button
);
139 ui::ModalType
EnrollmentDialogView::GetModalType() const {
140 return ui::MODAL_TYPE_SYSTEM
;
143 base::string16
EnrollmentDialogView::GetWindowTitle() const {
144 return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE
);
147 gfx::Size
EnrollmentDialogView::GetPreferredSize() const {
148 return gfx::Size(kDefaultWidth
, kDefaultHeight
);
151 void EnrollmentDialogView::InitDialog() {
153 // Create the views and layout manager and set them up.
154 views::Label
* label
= new views::Label(
155 l10n_util::GetStringFUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_INSTRUCTIONS
,
156 base::UTF8ToUTF16(network_name_
)));
157 label
->SetHorizontalAlignment(gfx::ALIGN_LEFT
);
158 label
->SetMultiLine(true);
159 label
->SetAllowCharacterBreak(true);
161 views::GridLayout
* grid_layout
= views::GridLayout::CreatePanel(this);
162 SetLayoutManager(grid_layout
);
164 views::ColumnSet
* columns
= grid_layout
->AddColumnSet(0);
165 columns
->AddColumn(views::GridLayout::FILL
, // Horizontal resize.
166 views::GridLayout::FILL
, // Vertical resize.
168 views::GridLayout::USE_PREF
, // Size type.
169 0, // Ignored for USE_PREF.
171 columns
= grid_layout
->AddColumnSet(1);
172 columns
->AddPaddingColumn(
173 0, views::kUnrelatedControlHorizontalSpacing
);
174 columns
->AddColumn(views::GridLayout::LEADING
, // Horizontal leading.
175 views::GridLayout::FILL
, // Vertical resize.
177 views::GridLayout::USE_PREF
, // Size type.
178 0, // Ignored for USE_PREF.
181 grid_layout
->StartRow(0, 0);
182 grid_layout
->AddView(label
);
183 grid_layout
->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing
);
184 grid_layout
->Layout(this);
187 ////////////////////////////////////////////////////////////////////////////////
188 // Handler for certificate enrollment.
190 class DialogEnrollmentDelegate
{
192 // |owning_window| is the window that will own the dialog.
193 DialogEnrollmentDelegate(gfx::NativeWindow owning_window
,
194 const std::string
& network_name
,
196 ~DialogEnrollmentDelegate();
198 // EnrollmentDelegate overrides
199 bool Enroll(const std::vector
<std::string
>& uri_list
,
200 const base::Closure
& connect
);
203 gfx::NativeWindow owning_window_
;
204 std::string network_name_
;
207 DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate
);
210 DialogEnrollmentDelegate::DialogEnrollmentDelegate(
211 gfx::NativeWindow owning_window
,
212 const std::string
& network_name
,
213 Profile
* profile
) : owning_window_(owning_window
),
214 network_name_(network_name
),
217 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
219 bool DialogEnrollmentDelegate::Enroll(const std::vector
<std::string
>& uri_list
,
220 const base::Closure
& post_action
) {
221 // Keep the closure for later activation if we notice that
222 // a certificate has been added.
224 // TODO(gspencer): Do something smart with the closure. At the moment it is
225 // being ignored because we don't know when the enrollment tab is closed.
226 // http://crosbug.com/30422
227 for (std::vector
<std::string
>::const_iterator iter
= uri_list
.begin();
228 iter
!= uri_list
.end(); ++iter
) {
230 if (uri
.IsStandard() || uri
.scheme() == extensions::kExtensionScheme
) {
231 // If this is a "standard" scheme, like http, ftp, etc., then open that in
232 // the enrollment dialog.
233 NET_LOG_EVENT("Showing enrollment dialog", network_name_
);
234 EnrollmentDialogView::ShowDialog(owning_window_
,
240 NET_LOG_DEBUG("Nonstandard URI: " + uri
.spec(), network_name_
);
243 // No appropriate scheme was found.
244 NET_LOG_ERROR("No usable enrollment URI", network_name_
);
248 void EnrollmentComplete(const std::string
& service_path
) {
249 NET_LOG_USER("Enrollment Complete", service_path
);
254 ////////////////////////////////////////////////////////////////////////////////
257 namespace enrollment
{
259 bool CreateDialog(const std::string
& service_path
,
260 gfx::NativeWindow owning_window
) {
261 const NetworkState
* network
= NetworkHandler::Get()->network_state_handler()->
262 GetNetworkState(service_path
);
264 NET_LOG_ERROR("Enrolling Unknown network", service_path
);
267 Browser
* browser
= chrome::FindBrowserWithWindow(owning_window
);
269 browser
? browser
->profile() : ProfileManager::GetPrimaryUserProfile();
270 std::string username_hash
= ProfileHelper::GetUserIdHashFromProfile(profile
);
272 onc::ONCSource onc_source
= onc::ONC_SOURCE_NONE
;
273 const base::DictionaryValue
* policy
=
274 NetworkHandler::Get()
275 ->managed_network_configuration_handler()
276 ->FindPolicyByGUID(username_hash
, network
->guid(), &onc_source
);
278 // We skip certificate patterns for device policy ONC so that an unmanaged
279 // user can't get to the place where a cert is presented for them
281 if (!policy
|| onc_source
== onc::ONC_SOURCE_DEVICE_POLICY
)
284 client_cert::ClientCertConfig cert_config
;
285 OncToClientCertConfig(*policy
, &cert_config
);
287 if (cert_config
.client_cert_type
!= onc::client_cert::kPattern
)
290 if (cert_config
.pattern
.Empty())
291 NET_LOG_ERROR("Certificate pattern is empty", service_path
);
293 if (cert_config
.pattern
.enrollment_uri_list().empty()) {
294 NET_LOG_EVENT("No enrollment URIs", service_path
);
298 NET_LOG_USER("Enrolling", service_path
);
300 DialogEnrollmentDelegate
* enrollment
=
301 new DialogEnrollmentDelegate(owning_window
, network
->name(), profile
);
302 return enrollment
->Enroll(cert_config
.pattern
.enrollment_uri_list(),
303 base::Bind(&EnrollmentComplete
, service_path
));
306 } // namespace enrollment
308 } // namespace chromeos