• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/ui/webui/chromeos/enterprise_enrollment_ui.h"
6 
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/lazy_instance.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/message_loop.h"
12 #include "base/stringprintf.h"
13 #include "base/values.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
16 #include "chrome/common/jstemplate_builder.h"
17 #include "chrome/common/url_constants.h"
18 #include "content/browser/renderer_host/render_view_host.h"
19 #include "content/browser/tab_contents/tab_contents.h"
20 #include "content/common/bindings_policy.h"
21 #include "content/common/property_bag.h"
22 #include "grit/browser_resources.h"
23 #include "grit/chromium_strings.h"
24 #include "grit/generated_resources.h"
25 #include "ui/base/l10n/l10n_util.h"
26 #include "ui/base/resource/resource_bundle.h"
27 
28 namespace chromeos {
29 
30 static base::LazyInstance<
31     PropertyAccessor<EnterpriseEnrollmentUI::Controller*> >
32         g_enrollment_ui_controller_property(base::LINKER_INITIALIZED);
33 
34 static const char kEnterpriseEnrollmentGaiaLoginPath[] = "gaialogin";
35 
36 // WebUIMessageHandler implementation which handles events occuring on the page,
37 // such as the user pressing the signin button.
38 class EnterpriseEnrollmentMessageHandler : public WebUIMessageHandler {
39  public:
40   EnterpriseEnrollmentMessageHandler();
41   virtual ~EnterpriseEnrollmentMessageHandler();
42 
43   // WebUIMessageHandler implementation.
44   virtual void RegisterMessages() OVERRIDE;
45 
46  private:
47   // Handlers for WebUI messages.
48   void HandleSubmitAuth(const ListValue* args);
49   void HandleCancelAuth(const ListValue* args);
50   void HandleConfirmationClose(const ListValue* args);
51 
52   // Gets the currently installed enrollment controller (if any).
53   EnterpriseEnrollmentUI::Controller* GetController();
54 
55   DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentMessageHandler);
56 };
57 
58 // A data source that provides the resources for the enterprise enrollment page.
59 // The enterprise enrollment page requests the HTML and other resources from
60 // this source.
61 class EnterpriseEnrollmentDataSource : public ChromeURLDataManager::DataSource {
62  public:
63   EnterpriseEnrollmentDataSource();
64 
65   // DataSource implementation.
66   virtual void StartDataRequest(const std::string& path,
67                                 bool is_off_the_record,
68                                 int request_id) OVERRIDE;
69   virtual std::string GetMimeType(const std::string& path) const OVERRIDE;
70 
71  private:
72   virtual ~EnterpriseEnrollmentDataSource();
73 
74   // Saves i18n string for |resource_id| to the |key| property of |dictionary|.
75   static void AddString(DictionaryValue* dictionary,
76                         const std::string& key,
77                         int resource_id);
78   static void AddString(DictionaryValue* dictionary,
79                         const std::string& key,
80                         int resource_id,
81                         const string16& arg1);
82 
83   DISALLOW_COPY_AND_ASSIGN(EnterpriseEnrollmentDataSource);
84 };
85 
EnterpriseEnrollmentMessageHandler()86 EnterpriseEnrollmentMessageHandler::EnterpriseEnrollmentMessageHandler() {}
87 
~EnterpriseEnrollmentMessageHandler()88 EnterpriseEnrollmentMessageHandler::~EnterpriseEnrollmentMessageHandler() {}
89 
RegisterMessages()90 void EnterpriseEnrollmentMessageHandler::RegisterMessages() {
91   web_ui_->RegisterMessageCallback(
92       "SubmitAuth",
93       NewCallback(
94           this, &EnterpriseEnrollmentMessageHandler::HandleSubmitAuth));
95   web_ui_->RegisterMessageCallback(
96       "DialogClose",
97       NewCallback(
98           this, &EnterpriseEnrollmentMessageHandler::HandleCancelAuth));
99   web_ui_->RegisterMessageCallback(
100       "confirmationClose",
101       NewCallback(
102           this, &EnterpriseEnrollmentMessageHandler::HandleConfirmationClose));
103 }
104 
HandleSubmitAuth(const ListValue * value)105 void EnterpriseEnrollmentMessageHandler::HandleSubmitAuth(
106     const ListValue* value) {
107   EnterpriseEnrollmentUI::Controller* controller = GetController();
108   if (!controller) {
109     NOTREACHED();
110     return;
111   }
112 
113   // Value carries single list entry, which is a json-encoded string that
114   // contains the auth parameters (see gaia_login.js).
115   std::string json_params;
116   if (!value->GetString(0, &json_params)) {
117     NOTREACHED();
118     return;
119   }
120 
121   // Check the value type.
122   scoped_ptr<Value> params(base::JSONReader::Read(json_params, false));
123   if (!params.get() || !params->IsType(Value::TYPE_DICTIONARY)) {
124     NOTREACHED();
125     return;
126   }
127 
128   // Read the parameters.
129   DictionaryValue* params_dict = static_cast<DictionaryValue*>(params.get());
130   std::string user;
131   std::string pass;
132   std::string captcha;
133   std::string access_code;
134   if (!params_dict->GetString("user", &user) ||
135       !params_dict->GetString("pass", &pass) ||
136       !params_dict->GetString("captcha", &captcha) ||
137       !params_dict->GetString("access_code", &access_code)) {
138     NOTREACHED();
139     return;
140   }
141 
142   controller->OnAuthSubmitted(user, pass, captcha, access_code);
143 }
144 
HandleCancelAuth(const ListValue * value)145 void EnterpriseEnrollmentMessageHandler::HandleCancelAuth(
146     const ListValue* value) {
147   EnterpriseEnrollmentUI::Controller* controller = GetController();
148   if (!controller) {
149     NOTREACHED();
150     return;
151   }
152 
153   controller->OnAuthCancelled();
154 }
155 
HandleConfirmationClose(const ListValue * value)156 void EnterpriseEnrollmentMessageHandler::HandleConfirmationClose(
157     const ListValue* value) {
158   EnterpriseEnrollmentUI::Controller* controller = GetController();
159   if (!controller) {
160     NOTREACHED();
161     return;
162   }
163 
164   controller->OnConfirmationClosed();
165 }
166 
167 EnterpriseEnrollmentUI::Controller*
GetController()168     EnterpriseEnrollmentMessageHandler::GetController() {
169   return EnterpriseEnrollmentUI::GetController(web_ui_);
170 }
171 
EnterpriseEnrollmentDataSource()172 EnterpriseEnrollmentDataSource::EnterpriseEnrollmentDataSource()
173     : DataSource(chrome::kChromeUIEnterpriseEnrollmentHost,
174                  MessageLoop::current()) {}
175 
StartDataRequest(const std::string & path,bool is_off_the_record,int request_id)176 void EnterpriseEnrollmentDataSource::StartDataRequest(const std::string& path,
177                                                       bool is_off_the_record,
178                                                       int request_id) {
179   ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
180 
181   DictionaryValue strings;
182   std::string response;
183   if (path.empty()) {
184     AddString(&strings, "loginHeader",
185               IDS_ENTERPRISE_ENROLLMENT_LOGIN_HEADER),
186     AddString(&strings, "loginExplain",
187               IDS_ENTERPRISE_ENROLLMENT_LOGIN_EXPLAIN,
188               l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
189     AddString(&strings, "cloudHeader",
190               IDS_ENTERPRISE_ENROLLMENT_CLOUD_HEADER),
191     AddString(&strings, "cloudExplain",
192               IDS_ENTERPRISE_ENROLLMENT_CLOUD_EXPLAIN);
193     AddString(&strings, "accesscontrolHeader",
194               IDS_ENTERPRISE_ENROLLMENT_ACCESSCONTROL_HEADER),
195     AddString(&strings, "accesscontrolExplain",
196               IDS_ENTERPRISE_ENROLLMENT_ACCESSCONTROL_EXPLAIN);
197     AddString(&strings, "confirmationHeader",
198               IDS_ENTERPRISE_ENROLLMENT_CONFIRMATION_HEADER);
199     AddString(&strings, "confirmationMessage",
200               IDS_ENTERPRISE_ENROLLMENT_CONFIRMATION_MESSAGE);
201     AddString(&strings, "confirmationClose",
202               IDS_ENTERPRISE_ENROLLMENT_CONFIRMATION_CLOSE);
203 
204     static const base::StringPiece html(
205         resource_bundle.GetRawDataResource(IDR_ENTERPRISE_ENROLLMENT_HTML));
206     SetFontAndTextDirection(&strings);
207     response = jstemplate_builder::GetI18nTemplateHtml(html, &strings);
208   } else if (path == kEnterpriseEnrollmentGaiaLoginPath) {
209     strings.SetString("invalidpasswordhelpurl", "");
210     strings.SetString("invalidaccessaccounturl", "");
211     strings.SetString("cannotaccessaccount", "");
212     strings.SetString("cannotaccessaccounturl", "");
213     strings.SetString("createaccount", "");
214     strings.SetString("createnewaccounturl", "");
215     strings.SetString("getaccesscodehelp", "");
216     strings.SetString("getaccesscodeurl", "");
217 
218     // None of the strings used here currently have sync-specific wording in
219     // them.  We have a unit test to catch if that happens.
220     strings.SetString("introduction", "");
221     AddString(&strings, "signinprefix", IDS_SYNC_LOGIN_SIGNIN_PREFIX);
222     AddString(&strings, "signinsuffix", IDS_SYNC_LOGIN_SIGNIN_SUFFIX);
223     AddString(&strings, "cannotbeblank", IDS_SYNC_CANNOT_BE_BLANK);
224     AddString(&strings, "emaillabel", IDS_SYNC_LOGIN_EMAIL);
225     AddString(&strings, "passwordlabel", IDS_SYNC_LOGIN_PASSWORD);
226     AddString(&strings, "invalidcredentials",
227               IDS_SYNC_INVALID_USER_CREDENTIALS);
228     AddString(&strings, "signin", IDS_SYNC_SIGNIN);
229     AddString(&strings, "couldnotconnect", IDS_SYNC_LOGIN_COULD_NOT_CONNECT);
230     AddString(&strings, "cancel", IDS_CANCEL);
231     AddString(&strings, "settingup", IDS_SYNC_LOGIN_SETTING_UP);
232     AddString(&strings, "success", IDS_SYNC_SUCCESS);
233     AddString(&strings, "errorsigningin", IDS_SYNC_ERROR_SIGNING_IN);
234     AddString(&strings, "captchainstructions",
235               IDS_SYNC_GAIA_CAPTCHA_INSTRUCTIONS);
236     AddString(&strings, "invalidaccesscode",
237               IDS_SYNC_INVALID_ACCESS_CODE_LABEL);
238     AddString(&strings, "enteraccesscode", IDS_SYNC_ENTER_ACCESS_CODE_LABEL);
239 
240     static const base::StringPiece html(resource_bundle.GetRawDataResource(
241         IDR_GAIA_LOGIN_HTML));
242     SetFontAndTextDirection(&strings);
243     response = jstemplate_builder::GetI18nTemplateHtml(html, &strings);
244   }
245 
246   // Send the response.
247   scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes());
248   html_bytes->data.resize(response.size());
249   std::copy(response.begin(), response.end(), html_bytes->data.begin());
250   SendResponse(request_id, html_bytes);
251 }
252 
GetMimeType(const std::string & path) const253 std::string EnterpriseEnrollmentDataSource::GetMimeType(
254     const std::string& path) const {
255   return "text/html";
256 }
257 
~EnterpriseEnrollmentDataSource()258 EnterpriseEnrollmentDataSource::~EnterpriseEnrollmentDataSource() {}
259 
AddString(DictionaryValue * dictionary,const std::string & key,int resource_id)260 void EnterpriseEnrollmentDataSource::AddString(DictionaryValue* dictionary,
261                                                const std::string& key,
262                                                int resource_id) {
263   dictionary->SetString(key, l10n_util::GetStringUTF16(resource_id));
264 }
265 
AddString(DictionaryValue * dictionary,const std::string & key,int resource_id,const string16 & arg1)266 void EnterpriseEnrollmentDataSource::AddString(DictionaryValue* dictionary,
267                                                const std::string& key,
268                                                int resource_id,
269                                                const string16& arg1) {
270   dictionary->SetString(key, l10n_util::GetStringFUTF16(resource_id, arg1));
271 }
272 
EnterpriseEnrollmentUI(TabContents * contents)273 EnterpriseEnrollmentUI::EnterpriseEnrollmentUI(TabContents* contents)
274     : WebUI(contents) {}
275 
~EnterpriseEnrollmentUI()276 EnterpriseEnrollmentUI::~EnterpriseEnrollmentUI() {}
277 
RenderViewCreated(RenderViewHost * render_view_host)278 void EnterpriseEnrollmentUI::RenderViewCreated(
279     RenderViewHost* render_view_host) {
280   // Bail out early if the controller doesn't exist or web ui is disabled.
281   if (!GetController(this) || !(bindings_ & BindingsPolicy::WEB_UI))
282     return;
283 
284   WebUIMessageHandler* handler = new EnterpriseEnrollmentMessageHandler();
285   AddMessageHandler(handler->Attach(this));
286 
287   // Set up the data source, so the enrollment page can be loaded.
288   tab_contents()->profile()->GetChromeURLDataManager()->AddDataSource(
289       new EnterpriseEnrollmentDataSource());
290 
291   std::string user;
292   bool has_init_user = GetController(this)->GetInitialUser(&user);
293   if (!has_init_user)
294     user = "";
295   // Set the arguments for showing the gaia login page.
296   DictionaryValue args;
297   args.SetString("user", user);
298   args.SetInteger("error", 0);
299   args.SetBoolean("editable_user", !has_init_user);
300   args.SetString("initialScreen", "login-screen");
301   std::string json_args;
302   base::JSONWriter::Write(&args, false, &json_args);
303   render_view_host->SetWebUIProperty("dialogArguments", json_args);
304 }
305 
306 // static
GetController(WebUI * ui)307 EnterpriseEnrollmentUI::Controller* EnterpriseEnrollmentUI::GetController(
308     WebUI* ui) {
309   Controller** controller =
310       g_enrollment_ui_controller_property.Get().GetProperty(
311           ui->tab_contents()->property_bag());
312 
313   return controller ? *controller : NULL;
314 }
315 
316 // static
SetController(TabContents * contents,EnterpriseEnrollmentUI::Controller * controller)317 void EnterpriseEnrollmentUI::SetController(
318     TabContents* contents,
319     EnterpriseEnrollmentUI::Controller* controller) {
320   g_enrollment_ui_controller_property.Get().SetProperty(
321       contents->property_bag(),
322       controller);
323 }
324 
325 }  // namespace chromeos
326