Commit d26f388a authored by Anastasiia N's avatar Anastasiia N Committed by Commit Bot

Implement getAccounts API

Support |getAccounts| Gaia request - send |accountsListed| message with
list of emails of accounts in session.

Bug: b/123630392
Change-Id: I2e920bf8a1303a17d70d74f0069a6ad9298aa86d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353348Reviewed-by: default avatarKush Sinha <sinhak@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Anastasiia N <anastasiian@chromium.org>
Cr-Commit-Position: refs/heads/master@{#798569}
parent d2cec01c
...@@ -61,6 +61,13 @@ export class EduAccountLoginBrowserProxy { ...@@ -61,6 +61,13 @@ export class EduAccountLoginBrowserProxy {
*/ */
completeLogin(credentials, eduLoginParams) {} completeLogin(credentials, eduLoginParams) {}
/**
* Send 'getAccounts' message to the handler. The promise will be resolved
* with the list of emails of accounts in session.
* @return {Promise<Array<string>>}
*/
getAccounts() {}
/** Send 'dialogClose' message to close the login dialog. */ /** Send 'dialogClose' message to close the login dialog. */
dialogClose() {} dialogClose() {}
} }
...@@ -109,6 +116,11 @@ export class EduAccountLoginBrowserProxyImpl { ...@@ -109,6 +116,11 @@ export class EduAccountLoginBrowserProxyImpl {
chrome.send('completeLogin', [credentials, eduLoginParams]); chrome.send('completeLogin', [credentials, eduLoginParams]);
} }
/** @override */
getAccounts() {
return sendWithPromise('getAccounts');
}
/** @override */ /** @override */
dialogClose() { dialogClose() {
chrome.send('dialogClose'); chrome.send('dialogClose');
......
...@@ -85,6 +85,8 @@ Polymer({ ...@@ -85,6 +85,8 @@ Polymer({
this.authExtHost_.addEventListener( this.authExtHost_.addEventListener(
'authCompleted', e => this.onAuthCompleted_( 'authCompleted', e => this.onAuthCompleted_(
/** @type {!CustomEvent<!AuthCompletedCredentials>} */(e))); /** @type {!CustomEvent<!AuthCompletedCredentials>} */(e)));
this.authExtHost_.addEventListener(
'getAccounts', () => this.onGetAccounts_());
}, },
/** /**
...@@ -129,6 +131,13 @@ Polymer({ ...@@ -129,6 +131,13 @@ Polymer({
this.loading_ = true; this.loading_ = true;
}, },
/** @private */
onGetAccounts_() {
this.browserProxy_.getAccounts().then(result => {
this.authExtHost_.getAccountsResponse(result);
});
},
/** /**
* Loads auth extension. * Loads auth extension.
* @param {!AuthParams} data Parameters for auth extension. * @param {!AuthParams} data Parameters for auth extension.
......
...@@ -207,6 +207,9 @@ cr.define('cr.login', function() { ...@@ -207,6 +207,9 @@ cr.define('cr.login', function() {
'backButton'(msg) { 'backButton'(msg) {
this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show})); this.dispatchEvent(new CustomEvent('backButton', {detail: msg.show}));
}, },
'getAccounts'(msg) {
this.dispatchEvent(new Event('getAccounts'));
},
'showView'(msg) { 'showView'(msg) {
this.dispatchEvent(new Event('showView')); this.dispatchEvent(new Event('showView'));
}, },
...@@ -595,6 +598,14 @@ cr.define('cr.login', function() { ...@@ -595,6 +598,14 @@ cr.define('cr.login', function() {
this.isLoaded_ = true; this.isLoaded_ = true;
} }
/**
* Called in response to 'getAccounts' event.
* @param {Array<string>} accounts list of emails
*/
getAccountsResponse(accounts) {
this.sendMessageToWebview('accountsListed', accounts);
}
constructInitialFrameUrl_(data) { constructInitialFrameUrl_(data) {
if (data.doSamlRedirect) { if (data.doSamlRedirect) {
let url = this.idpOrigin_ + SAML_REDIRECTION_PATH; let url = this.idpOrigin_ + SAML_REDIRECTION_PATH;
...@@ -860,11 +871,22 @@ cr.define('cr.login', function() { ...@@ -860,11 +871,22 @@ cr.define('cr.login', function() {
} }
/** /**
* Invoked to send a HTML5 message to the webview element. * Invoked to send a HTML5 message with attached data to the webview
* @param {*} payload Payload of the HTML5 message. * element.
* @param {string} messageType Type of the HTML5 message.
* @param {Object=} messageData Data to be attached to the message.
*/ */
sendMessageToWebview(payload) { sendMessageToWebview(messageType, messageData = null) {
const currentUrl = this.webview_.src; const currentUrl = this.webview_.src;
let payload = undefined;
if (messageData) {
payload = {type: messageType, data: messageData};
} else {
// TODO(crbug.com/1116343): Use new message format when it will be
// available in production.
payload = messageType;
}
this.webview_.contentWindow.postMessage(payload, currentUrl); this.webview_.contentWindow.postMessage(payload, currentUrl);
} }
......
...@@ -105,6 +105,8 @@ Polymer({ ...@@ -105,6 +105,8 @@ Polymer({
/** @type {!CustomEvent<!AuthCompletedCredentials>} */ (e))); /** @type {!CustomEvent<!AuthCompletedCredentials>} */ (e)));
this.authExtHost_.addEventListener( this.authExtHost_.addEventListener(
'showIncognito', () => this.onShowIncognito_()); 'showIncognito', () => this.onShowIncognito_());
this.authExtHost_.addEventListener(
'getAccounts', () => this.onGetAccounts_());
}, },
/** /**
...@@ -156,6 +158,13 @@ Polymer({ ...@@ -156,6 +158,13 @@ Polymer({
this.browserProxy_.showIncognito(); this.browserProxy_.showIncognito();
}, },
/** @private */
onGetAccounts_() {
this.browserProxy_.getAccounts().then(result => {
this.authExtHost_.getAccountsResponse(result);
});
},
/** /**
* Loads auth extension. * Loads auth extension.
* @param {!AuthParams} data Parameters for auth extension. * @param {!AuthParams} data Parameters for auth extension.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import {addSingletonGetter} from 'chrome://resources/js/cr.m.js'; import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
import {AuthCompletedCredentials} from '../gaia_auth_host/authenticator.m.js'; import {AuthCompletedCredentials} from '../gaia_auth_host/authenticator.m.js';
...@@ -46,6 +46,13 @@ export class InlineLoginBrowserProxy { ...@@ -46,6 +46,13 @@ export class InlineLoginBrowserProxy {
/** Send 'showIncognito' message to the handler */ /** Send 'showIncognito' message to the handler */
showIncognito() {} showIncognito() {}
/**
* Send 'getAccounts' message to the handler. The promise will be resolved
* with the list of emails of accounts in session.
* @return {Promise<Array<string>>}
*/
getAccounts() {}
/** Send 'dialogClose' message to close the login dialog. */ /** Send 'dialogClose' message to close the login dialog. */
dialogClose() {} dialogClose() {}
} }
...@@ -87,6 +94,11 @@ export class InlineLoginBrowserProxyImpl { ...@@ -87,6 +94,11 @@ export class InlineLoginBrowserProxyImpl {
chrome.send('showIncognito'); chrome.send('showIncognito');
} }
/** @override */
getAccounts() {
return sendWithPromise('getAccounts');
}
/** @override */ /** @override */
dialogClose() { dialogClose() {
chrome.send('dialogClose'); chrome.send('dialogClose');
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h" #include "chrome/browser/ui/webui/signin/inline_login_dialog_chromeos.h"
#include "chrome/browser/ui/webui/signin/inline_login_handler.h" #include "chrome/browser/ui/webui/signin/inline_login_handler.h"
#include "chromeos/components/account_manager/account_manager.h"
#include "chromeos/components/account_manager/account_manager_factory.h" #include "chromeos/components/account_manager/account_manager_factory.h"
#include "chromeos/constants/chromeos_features.h" #include "chromeos/constants/chromeos_features.h"
#include "components/signin/public/identity_manager/account_info.h" #include "components/signin/public/identity_manager/account_info.h"
...@@ -38,6 +37,12 @@ namespace { ...@@ -38,6 +37,12 @@ namespace {
constexpr char kCrosAddAccountFlow[] = "crosAddAccount"; constexpr char kCrosAddAccountFlow[] = "crosAddAccount";
constexpr char kCrosAddAccountEduFlow[] = "crosAddAccountEdu"; constexpr char kCrosAddAccountEduFlow[] = "crosAddAccountEdu";
std::string AnonymizeAccountEmail(const std::string& email) {
std::string result;
base::Base64Encode(crypto::SHA256HashString(email), &result);
return result + "@example.com";
}
bool GaiaActionButtonsEnabled() { bool GaiaActionButtonsEnabled() {
return base::FeatureList::IsEnabled(chromeos::features::kGaiaActionButtons); return base::FeatureList::IsEnabled(chromeos::features::kGaiaActionButtons);
} }
...@@ -252,6 +257,10 @@ void InlineLoginHandlerChromeOS::RegisterMessages() { ...@@ -252,6 +257,10 @@ void InlineLoginHandlerChromeOS::RegisterMessages() {
base::BindRepeating( base::BindRepeating(
&InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog, &InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog,
base::Unretained(this))); base::Unretained(this)));
web_ui()->RegisterMessageCallback(
"getAccounts",
base::BindRepeating(&InlineLoginHandlerChromeOS::GetAccountsInSession,
base::Unretained(this)));
} }
void InlineLoginHandlerChromeOS::SetExtraInitParams( void InlineLoginHandlerChromeOS::SetExtraInitParams(
...@@ -347,4 +356,36 @@ void InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog( ...@@ -347,4 +356,36 @@ void InlineLoginHandlerChromeOS::ShowIncognitoAndCloseDialog(
close_dialog_closure_.Run(); close_dialog_closure_.Run();
} }
void InlineLoginHandlerChromeOS::GetAccountsInSession(
const base::ListValue* args) {
const std::string& callback_id = args->GetList()[0].GetString();
const Profile* profile = Profile::FromWebUI(web_ui());
chromeos::AccountManager* account_manager =
g_browser_process->platform_part()
->GetAccountManagerFactory()
->GetAccountManager(profile->GetPath().value());
account_manager->GetAccounts(
base::BindOnce(&InlineLoginHandlerChromeOS::OnGetAccounts,
weak_factory_.GetWeakPtr(), callback_id));
}
void InlineLoginHandlerChromeOS::OnGetAccounts(
const std::string& callback_id,
const std::vector<AccountManager::Account>& accounts) {
base::ListValue account_emails;
for (const auto& account : accounts) {
if (account.key.account_type ==
account_manager::AccountType::ACCOUNT_TYPE_ACTIVE_DIRECTORY) {
// Don't send Active Directory account email to Gaia.
account_emails.Append(AnonymizeAccountEmail(account.raw_email));
} else {
account_emails.Append(account.raw_email);
}
}
ResolveJavascriptCallback(base::Value(callback_id),
std::move(account_emails));
}
} // namespace chromeos } // namespace chromeos
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "chrome/browser/ui/webui/signin/inline_login_handler.h" #include "chrome/browser/ui/webui/signin/inline_login_handler.h"
#include "chromeos/components/account_manager/account_manager.h"
#include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h" #include "google_apis/gaia/gaia_auth_fetcher.h"
...@@ -36,8 +37,12 @@ class InlineLoginHandlerChromeOS : public InlineLoginHandler { ...@@ -36,8 +37,12 @@ class InlineLoginHandlerChromeOS : public InlineLoginHandler {
private: private:
void ShowIncognitoAndCloseDialog(const base::ListValue* args); void ShowIncognitoAndCloseDialog(const base::ListValue* args);
void GetAccountsInSession(const base::ListValue* args);
void OnGetAccounts(const std::string& callback_id,
const std::vector<AccountManager::Account>& accounts);
base::RepeatingClosure close_dialog_closure_; base::RepeatingClosure close_dialog_closure_;
base::WeakPtrFactory<InlineLoginHandlerChromeOS> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerChromeOS); DISALLOW_COPY_AND_ASSIGN(InlineLoginHandlerChromeOS);
}; };
......
...@@ -11,7 +11,7 @@ import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; ...@@ -11,7 +11,7 @@ import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js'; import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_target.m.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {TestEduAccountLoginBrowserProxy} from './edu_login_test_util.js'; import {getFakeAccountsList, TestEduAccountLoginBrowserProxy} from './edu_login_test_util.js';
window.edu_login_signin_tests = {}; window.edu_login_signin_tests = {};
edu_login_signin_tests.suiteName = 'EduLoginSigninTest'; edu_login_signin_tests.suiteName = 'EduLoginSigninTest';
...@@ -45,6 +45,10 @@ suite(edu_login_signin_tests.suiteName, function() { ...@@ -45,6 +45,10 @@ suite(edu_login_signin_tests.suiteName, function() {
this.loadCalls = 0; this.loadCalls = 0;
/** @type {Number} */ /** @type {Number} */
this.resetStatesCalls = 0; this.resetStatesCalls = 0;
/** @type {number} */
this.getAccountsResponseCalls = 0;
/** @type {Array<string>} */
this.getAccountsResponseResult = null;
} }
/** /**
...@@ -60,6 +64,14 @@ suite(edu_login_signin_tests.suiteName, function() { ...@@ -60,6 +64,14 @@ suite(edu_login_signin_tests.suiteName, function() {
resetStates() { resetStates() {
this.resetStatesCalls++; this.resetStatesCalls++;
} }
/**
* @param {Array<string>} accounts list of emails.
*/
getAccountsResponse(accounts) {
this.getAccountsResponseCalls++;
this.getAccountsResponseResult = accounts;
}
} }
setup(function() { setup(function() {
...@@ -119,6 +131,15 @@ suite(edu_login_signin_tests.suiteName, function() { ...@@ -119,6 +131,15 @@ suite(edu_login_signin_tests.suiteName, function() {
assertEquals(fakeCredentials, result[0]); assertEquals(fakeCredentials, result[0]);
assertDeepEquals(fakeLoginParams, result[1]); assertDeepEquals(fakeLoginParams, result[1]);
}); });
testAuthenticator.dispatchEvent(new Event('getAccounts'));
assertEquals(1, testBrowserProxy.getCallCount('getAccounts'));
testBrowserProxy.whenCalled('getAccounts').then(function() {
assertEquals(1, testAuthenticator.getAccountsResponseCalls);
assertDeepEquals(
getFakeAccountsList(),
testAuthenticator.getAccountsResponseResult);
});
}); });
test(assert(edu_login_signin_tests.TestNames.GoBackInWebview), function() { test(assert(edu_login_signin_tests.TestNames.GoBackInWebview), function() {
......
...@@ -29,6 +29,11 @@ export function getFakeParentsList() { ...@@ -29,6 +29,11 @@ export function getFakeParentsList() {
]; ];
} }
/** @return {!Array<string>} */
export function getFakeAccountsList() {
return ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com'];
}
/** @implements {EduAccountLoginBrowserProxy} */ /** @implements {EduAccountLoginBrowserProxy} */
export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy { export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy {
constructor() { constructor() {
...@@ -40,6 +45,7 @@ export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy { ...@@ -40,6 +45,7 @@ export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy {
'authExtensionReady', 'authExtensionReady',
'switchToFullTab', 'switchToFullTab',
'completeLogin', 'completeLogin',
'getAccounts',
'dialogClose', 'dialogClose',
]); ]);
...@@ -106,6 +112,12 @@ export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy { ...@@ -106,6 +112,12 @@ export class TestEduAccountLoginBrowserProxy extends TestBrowserProxy {
this.methodCalled('completeLogin', [credentials, eduLoginParams]); this.methodCalled('completeLogin', [credentials, eduLoginParams]);
} }
/** @override */
getAccounts() {
this.methodCalled('getAccounts');
return Promise.resolve(getFakeAccountsList());
}
/** @override */ /** @override */
dialogClose() { dialogClose() {
this.methodCalled('dialogClose'); this.methodCalled('dialogClose');
......
...@@ -10,8 +10,9 @@ import {isChromeOS} from 'chrome://resources/js/cr.m.js'; ...@@ -10,8 +10,9 @@ import {isChromeOS} from 'chrome://resources/js/cr.m.js';
import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js'; import {webUIListenerCallback} from 'chrome://resources/js/cr.m.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assertEquals, assertFalse, assertTrue} from '../chai_assert.js'; import {assertDeepEquals, assertEquals, assertFalse, assertTrue} from '../chai_assert.js';
import {TestAuthenticator, TestInlineLoginBrowserProxy} from './inline_login_test_util.js';
import {getFakeAccountsList, TestAuthenticator, TestInlineLoginBrowserProxy} from './inline_login_test_util.js';
window.inline_login_test = {}; window.inline_login_test = {};
inline_login_test.suiteName = 'InlineLoginTest'; inline_login_test.suiteName = 'InlineLoginTest';
...@@ -97,6 +98,14 @@ suite(inline_login_test.suiteName, () => { ...@@ -97,6 +98,14 @@ suite(inline_login_test.suiteName, () => {
testAuthenticator.dispatchEvent(new Event('showIncognito')); testAuthenticator.dispatchEvent(new Event('showIncognito'));
assertEquals(1, testBrowserProxy.getCallCount('showIncognito')); assertEquals(1, testBrowserProxy.getCallCount('showIncognito'));
testAuthenticator.dispatchEvent(new Event('getAccounts'));
assertEquals(1, testBrowserProxy.getCallCount('getAccounts'));
testBrowserProxy.whenCalled('getAccounts').then(function() {
assertEquals(1, testAuthenticator.getAccountsResponseCalls);
assertDeepEquals(
getFakeAccountsList(), testAuthenticator.getAccountsResponseResult);
});
}); });
test(assert(inline_login_test.TestNames.BackButton), () => { test(assert(inline_login_test.TestNames.BackButton), () => {
......
...@@ -8,6 +8,11 @@ import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_t ...@@ -8,6 +8,11 @@ import {NativeEventTarget as EventTarget} from 'chrome://resources/js/cr/event_t
import {TestBrowserProxy} from '../test_browser_proxy.m.js'; import {TestBrowserProxy} from '../test_browser_proxy.m.js';
/** @return {!Array<string>} */
export function getFakeAccountsList() {
return ['test@gmail.com', 'test2@gmail.com', 'test3@gmail.com'];
}
export class TestAuthenticator extends EventTarget { export class TestAuthenticator extends EventTarget {
constructor() { constructor() {
super(); super();
...@@ -17,6 +22,10 @@ export class TestAuthenticator extends EventTarget { ...@@ -17,6 +22,10 @@ export class TestAuthenticator extends EventTarget {
this.data = null; this.data = null;
/** @type {number} */ /** @type {number} */
this.loadCalls = 0; this.loadCalls = 0;
/** @type {number} */
this.getAccountsResponseCalls = 0;
/** @type {Array<string>} */
this.getAccountsResponseResult = null;
} }
/** /**
...@@ -28,6 +37,14 @@ export class TestAuthenticator extends EventTarget { ...@@ -28,6 +37,14 @@ export class TestAuthenticator extends EventTarget {
this.authMode = authMode; this.authMode = authMode;
this.data = data; this.data = data;
} }
/**
* @param {Array<string>} accounts list of emails.
*/
getAccountsResponse(accounts) {
this.getAccountsResponseCalls++;
this.getAccountsResponseResult = accounts;
}
} }
/** @implements {InlineLoginBrowserProxy} */ /** @implements {InlineLoginBrowserProxy} */
...@@ -41,6 +58,7 @@ export class TestInlineLoginBrowserProxy extends TestBrowserProxy { ...@@ -41,6 +58,7 @@ export class TestInlineLoginBrowserProxy extends TestBrowserProxy {
'lstFetchResults', 'lstFetchResults',
'metricsHandler:recordAction', 'metricsHandler:recordAction',
'showIncognito', 'showIncognito',
'getAccounts',
'dialogClose', 'dialogClose',
]); ]);
} }
...@@ -80,6 +98,12 @@ export class TestInlineLoginBrowserProxy extends TestBrowserProxy { ...@@ -80,6 +98,12 @@ export class TestInlineLoginBrowserProxy extends TestBrowserProxy {
this.methodCalled('showIncognito'); this.methodCalled('showIncognito');
} }
/** @override */
getAccounts() {
this.methodCalled('getAccounts');
return Promise.resolve(getFakeAccountsList());
}
/** @override */ /** @override */
dialogClose() { dialogClose() {
this.methodCalled('dialogClose'); this.methodCalled('dialogClose');
......
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