Home | History | Annotate | Download | only in chromeos
      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 
     86 EnterpriseEnrollmentMessageHandler::EnterpriseEnrollmentMessageHandler() {}
     87 
     88 EnterpriseEnrollmentMessageHandler::~EnterpriseEnrollmentMessageHandler() {}
     89 
     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 
    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 
    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 
    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*
    168     EnterpriseEnrollmentMessageHandler::GetController() {
    169   return EnterpriseEnrollmentUI::GetController(web_ui_);
    170 }
    171 
    172 EnterpriseEnrollmentDataSource::EnterpriseEnrollmentDataSource()
    173     : DataSource(chrome::kChromeUIEnterpriseEnrollmentHost,
    174                  MessageLoop::current()) {}
    175 
    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 
    253 std::string EnterpriseEnrollmentDataSource::GetMimeType(
    254     const std::string& path) const {
    255   return "text/html";
    256 }
    257 
    258 EnterpriseEnrollmentDataSource::~EnterpriseEnrollmentDataSource() {}
    259 
    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 
    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 
    273 EnterpriseEnrollmentUI::EnterpriseEnrollmentUI(TabContents* contents)
    274     : WebUI(contents) {}
    275 
    276 EnterpriseEnrollmentUI::~EnterpriseEnrollmentUI() {}
    277 
    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
    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
    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