Commit 121fc1fd authored by Lutz Justen's avatar Lutz Justen Committed by Commit Bot

Add Kerberos Accounts handler

Adds a handler for the Kerberos Accounts settings page. Some methods
are already implemented like HandleRemoveKerberosAccount(), but others
are stubs, e.g. HandleAddKerberosAccount() does not have the UI yet to
enter credentials for a new account.

The code is largely similar to AccountManagerUIHandler. PS1 in the code
review tool contains the vanilla Account Manager code. Please diff to
PS1 for the code review.

BUG=chromium:952237
TEST=None

Change-Id: I521eac1a8aa6733a6b643971d75a555694f74e1d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1590096
Commit-Queue: Lutz Justen <ljusten@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#658477}
parent d8699589
......@@ -54,39 +54,22 @@ cr.define('settings', function() {
class KerberosAccountsBrowserProxyImpl {
/** @override */
getAccounts() {
// TODO(https://crbug.com/952232): Implement
return new Promise(function(resolve, reject) {
resolve([
{
principalName: 'user@REALM',
isSignedIn: true,
pic: 'chrome://theme/IDR_LOGIN_DEFAULT_USER_2',
},
{
principalName: 'user2@REALM2',
isSignedIn: false,
pic: 'chrome://theme/IDR_LOGIN_DEFAULT_USER_2',
}
]);
});
return cr.sendWithPromise('getKerberosAccounts');
}
/** @override */
addAccount() {
// TODO(https://crbug.com/952232): Implement
console.log('addKerberosAccount');
chrome.send('addKerberosAccount');
}
/** @override */
reauthenticateAccount(principalName) {
// TODO(https://crbug.com/952232): Implement
console.log('reauthenticateKerberosAccount');
chrome.send('reauthenticateKerberosAccount', [principalName]);
}
/** @override */
removeAccount(account) {
// TODO(https://crbug.com/952232): Implement
console.log('removeKerberosAccount');
chrome.send('removeKerberosAccount', [account.principalName]);
}
}
......
......@@ -1773,6 +1773,8 @@ jumbo_split_static_library("ui") {
"webui/settings/chromeos/google_assistant_handler.h",
"webui/settings/chromeos/internet_handler.cc",
"webui/settings/chromeos/internet_handler.h",
"webui/settings/chromeos/kerberos_accounts_handler.cc",
"webui/settings/chromeos/kerberos_accounts_handler.h",
"webui/settings/chromeos/multidevice_handler.cc",
"webui/settings/chromeos/multidevice_handler.h",
"webui/settings/chromeos/os_settings_ui.cc",
......@@ -1816,6 +1818,7 @@ jumbo_split_static_library("ui") {
"//chromeos/dbus/audio",
"//chromeos/dbus/cryptohome",
"//chromeos/dbus/cryptohome:cryptohome_proto",
"//chromeos/dbus/kerberos:kerberos_proto",
"//chromeos/dbus/power",
"//chromeos/dbus/session_manager",
"//chromeos/dbus/system_clock",
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h"
#include <utility>
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/chromeos/resources/grit/ui_chromeos_resources.h"
#include "ui/gfx/image/image_skia.h"
namespace chromeos {
namespace settings {
namespace {
KerberosCredentialsManager::ResultCallback EmptyResultCallback() {
return base::BindOnce([](kerberos::ErrorType error) {
// Do nothing.
});
}
} // namespace
KerberosAccountsHandler::KerberosAccountsHandler()
: credentials_manager_observer_(this), weak_factory_(this) {}
KerberosAccountsHandler::~KerberosAccountsHandler() = default;
void KerberosAccountsHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(
"getKerberosAccounts",
base::BindRepeating(&KerberosAccountsHandler::HandleGetKerberosAccounts,
weak_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"addKerberosAccount",
base::BindRepeating(&KerberosAccountsHandler::HandleAddKerberosAccount,
weak_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"reauthenticateKerberosAccount",
base::BindRepeating(
&KerberosAccountsHandler::HandleReauthenticateKerberosAccount,
weak_factory_.GetWeakPtr()));
web_ui()->RegisterMessageCallback(
"removeKerberosAccount",
base::BindRepeating(&KerberosAccountsHandler::HandleRemoveKerberosAccount,
weak_factory_.GetWeakPtr()));
}
void KerberosAccountsHandler::HandleGetKerberosAccounts(
const base::ListValue* args) {
AllowJavascript();
CHECK(!args->GetList().empty());
base::Value callback_id = args->GetList()[0].Clone();
KerberosCredentialsManager::Get().ListAccounts(
base::BindOnce(&KerberosAccountsHandler::OnListAccounts,
weak_factory_.GetWeakPtr(), std::move(callback_id)));
}
void KerberosAccountsHandler::OnListAccounts(
base::Value callback_id,
const kerberos::ListAccountsResponse& response) {
base::ListValue accounts;
// Default icon is a briefcase.
gfx::ImageSkia skia_default_icon =
*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
IDR_LOGIN_DEFAULT_USER_2);
std::string default_icon = webui::GetBitmapDataUrl(
skia_default_icon.GetRepresentation(1.0f).GetBitmap());
for (int n = 0; n < response.accounts_size(); ++n) {
const kerberos::Account& account = response.accounts(n);
base::DictionaryValue account_dict;
account_dict.SetString("principalName", account.principal_name());
account_dict.SetString("krb5conf", account.krb5conf());
account_dict.SetBoolean("isSignedIn", account.tgt_validity_seconds() > 0);
account_dict.SetString("pic", default_icon);
accounts.GetList().push_back(std::move(account_dict));
}
ResolveJavascriptCallback(callback_id, accounts);
}
void KerberosAccountsHandler::HandleAddKerberosAccount(
const base::ListValue* args) {
AllowJavascript();
// TODO(https://crbug.com/961246):
// - Prevent account changes when Kerberos is disabled.
// - Remove all accounts when Kerberos is disabled.
// TODO(ljusten): Call KerberosAddAccountDialog::Show() instead when that's
// implemented.
static int count = 0;
KerberosCredentialsManager::Get().AddAccountAndAuthenticate(
base::StringPrintf("user%i@realm", ++count), "password",
EmptyResultCallback());
}
void KerberosAccountsHandler::HandleReauthenticateKerberosAccount(
const base::ListValue* args) {
AllowJavascript();
CHECK(!args->GetList().empty());
// TODO(ljusten): Add KerberosAddAccountDialog::Show(principal_name) when
// that's implemented.
}
void KerberosAccountsHandler::HandleRemoveKerberosAccount(
const base::ListValue* args) {
AllowJavascript();
CHECK(!args->GetList().empty());
const std::string& principal_name = args->GetList()[0].GetString();
// Note that we're observing the credentials manager, so OnAccountsChanged()
// is called when an account is removed, which calls RefreshUI(). Thus, it's
// fine to pass an EmptyResultCallback() in here and not something that calls
// RefreshUI().
KerberosCredentialsManager::Get().RemoveAccount(principal_name,
EmptyResultCallback());
}
void KerberosAccountsHandler::OnJavascriptAllowed() {
credentials_manager_observer_.Add(&KerberosCredentialsManager::Get());
}
void KerberosAccountsHandler::OnJavascriptDisallowed() {
credentials_manager_observer_.RemoveAll();
}
void KerberosAccountsHandler::OnAccountsChanged() {
RefreshUI();
}
void KerberosAccountsHandler::RefreshUI() {
FireWebUIListener("kerberos-accounts-changed");
}
} // namespace settings
} // namespace chromeos
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_KERBEROS_ACCOUNTS_HANDLER_H_
#define CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_KERBEROS_ACCOUNTS_HANDLER_H_
#include <string>
#include <vector>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/scoped_observer.h"
#include "chrome/browser/chromeos/kerberos/kerberos_credentials_manager.h"
#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h"
#include "chromeos/dbus/kerberos/kerberos_service.pb.h"
#include "services/identity/public/cpp/identity_manager.h"
namespace kerberos {
class ListAccountsResponse;
}
namespace chromeos {
namespace settings {
class KerberosAccountsHandler : public ::settings::SettingsPageUIHandler,
public KerberosCredentialsManager::Observer {
public:
KerberosAccountsHandler();
~KerberosAccountsHandler() override;
// WebUIMessageHandler:
void RegisterMessages() override;
void OnJavascriptAllowed() override;
void OnJavascriptDisallowed() override;
// KerberosCredentialsManager::Observer:
void OnAccountsChanged() override;
private:
// WebUI "getKerberosAccounts" message callback.
void HandleGetKerberosAccounts(const base::ListValue* args);
// WebUI "addKerberosAccount" message callback.
void HandleAddKerberosAccount(const base::ListValue* args);
// WebUI "reauthenticateKerberosAccount" message callback.
void HandleReauthenticateKerberosAccount(const base::ListValue* args);
// WebUI "removeKerberosAccount" message callback.
void HandleRemoveKerberosAccount(const base::ListValue* args);
// Callback for the Kerberos daemon's ListAccounts D-Bus method.
void OnListAccounts(base::Value callback_id,
const kerberos::ListAccountsResponse& response);
// Fires the "kerberos-accounts-changed" event, which refreshes the Kerberos
// Accounts UI.
void RefreshUI();
// This instance can be added as observer to KerberosCredentialsManager.
// This class keeps track of that and removes this instance on destruction.
ScopedObserver<KerberosCredentialsManager,
KerberosCredentialsManager::Observer>
credentials_manager_observer_;
base::WeakPtrFactory<KerberosAccountsHandler> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(KerberosAccountsHandler);
};
} // namespace settings
} // namespace chromeos
#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_CHROMEOS_KERBEROS_ACCOUNTS_HANDLER_H_
......@@ -1964,6 +1964,7 @@ void AddPeopleStrings(content::WebUIDataSource* html_source, Profile* profile) {
chromeos::IsAccountManagerAvailable(profile));
// Toggles the Chrome OS Kerberos Accounts submenu in the People section.
// Note that the handler is also dependent on this pref.
html_source->AddBoolean(
"isKerberosEnabled",
g_browser_process->local_state()->GetBoolean(prefs::kKerberosEnabled));
......
......@@ -104,6 +104,7 @@
#include "chrome/browser/ui/webui/settings/chromeos/fingerprint_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/google_assistant_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/internet_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/kerberos_accounts_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/multidevice_handler.h"
#include "chrome/browser/ui/webui/settings/chromeos/plugin_vm_handler.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
......@@ -384,6 +385,11 @@ void SettingsUI::InitOSWebUIHandlers(Profile* profile,
web_ui->AddMessageHandler(
std::make_unique<chromeos::settings::GoogleAssistantHandler>(profile));
}
if (g_browser_process->local_state()->GetBoolean(prefs::kKerberosEnabled)) {
// Note that UI is also dependent on this pref.
web_ui->AddMessageHandler(
std::make_unique<chromeos::settings::KerberosAccountsHandler>());
}
web_ui->AddMessageHandler(
std::make_unique<chromeos::settings::KeyboardHandler>());
if (plugin_vm::IsPluginVmEnabled(profile)) {
......
......@@ -22,12 +22,12 @@ cr.define('settings_people_page_kerberos_accounts', function() {
{
principalName: 'user@REALM',
isSignedIn: true,
pic: 'chrome://theme/IDR_LOGIN_DEFAULT_USER_2',
pic: 'pic',
},
{
principalName: 'user2@REALM2',
isSignedIn: false,
pic: 'chrome://theme/IDR_LOGIN_DEFAULT_USER_2',
pic: 'pic2',
}
]);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment