Implemented consumer management unenrollment.
[chromium-blink-merge.git] / chrome / browser / chromeos / enrollment_dialog_view.cc
blob5f81a147b11a01bfbbbdc359020e01ad74ece900
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"
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"
30 namespace chromeos {
32 namespace {
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 {
42 public:
43 virtual ~EnrollmentDialogView();
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);
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;
58 // views::WidgetDelegate overrides
59 virtual ui::ModalType GetModalType() const override;
60 virtual base::string16 GetWindowTitle() const override;
62 // views::View overrides
63 virtual gfx::Size GetPreferredSize() const override;
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();
72 bool accepted_;
73 std::string network_name_;
74 Profile* profile_;
75 GURL target_uri_;
76 base::Closure connect_;
77 bool added_cert_;
80 ////////////////////////////////////////////////////////////////////////////////
81 // EnrollmentDialogView implementation.
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) {
95 EnrollmentDialogView::~EnrollmentDialogView() {
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();
113 int EnrollmentDialogView::GetDialogButtons() const {
114 return ui::DIALOG_BUTTON_CANCEL | ui::DIALOG_BUTTON_OK;
117 bool EnrollmentDialogView::Accept() {
118 accepted_ = true;
119 return true;
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);
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);
140 ui::ModalType EnrollmentDialogView::GetModalType() const {
141 return ui::MODAL_TYPE_SYSTEM;
144 base::string16 EnrollmentDialogView::GetWindowTitle() const {
145 return l10n_util::GetStringUTF16(IDS_NETWORK_ENROLLMENT_HANDLER_TITLE);
148 gfx::Size EnrollmentDialogView::GetPreferredSize() const {
149 return gfx::Size(kDefaultWidth, kDefaultHeight);
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);
162 views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
163 SetLayoutManager(grid_layout);
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.
182 grid_layout->StartRow(0, 0);
183 grid_layout->AddView(label);
184 grid_layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
185 grid_layout->Layout(this);
188 ////////////////////////////////////////////////////////////////////////////////
189 // Handler for certificate enrollment.
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();
199 // EnrollmentDelegate overrides
200 bool Enroll(const std::vector<std::string>& uri_list,
201 const base::Closure& connect);
203 private:
204 gfx::NativeWindow owning_window_;
205 std::string network_name_;
206 Profile* profile_;
208 DISALLOW_COPY_AND_ASSIGN(DialogEnrollmentDelegate);
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) {}
218 DialogEnrollmentDelegate::~DialogEnrollmentDelegate() {}
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.
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;
241 NET_LOG_DEBUG("Nonstandard URI: " + uri.spec(), network_name_);
244 // No appropriate scheme was found.
245 NET_LOG_ERROR("No usable enrollment URI", network_name_);
246 return false;
249 void EnrollmentComplete(const std::string& service_path) {
250 NET_LOG_USER("Enrollment Complete", service_path);
253 } // namespace
255 ////////////////////////////////////////////////////////////////////////////////
256 // Factory function.
258 namespace enrollment {
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;
268 Browser* browser = chrome::FindBrowserWithWindow(owning_window);
269 Profile* profile =
270 browser ? browser->profile() : ProfileManager::GetPrimaryUserProfile();
271 std::string username_hash = ProfileHelper::GetUserIdHashFromProfile(profile);
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);
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;
285 client_cert::ClientCertConfig cert_config;
286 OncToClientCertConfig(*policy, &cert_config);
288 if (cert_config.client_cert_type != onc::client_cert::kPattern)
289 return false;
291 if (cert_config.pattern.Empty())
292 NET_LOG_ERROR("Certificate pattern is empty", service_path);
294 if (cert_config.pattern.enrollment_uri_list().empty()) {
295 NET_LOG_EVENT("No enrollment URIs", service_path);
296 return false;
299 NET_LOG_USER("Enrolling", service_path);
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));
307 } // namespace enrollment
309 } // namespace chromeos