Commit 8171be71 authored by Maksim Ivanov's avatar Maksim Ivanov Committed by Commit Bot

Chrome OS Login: known_user for SAML API usage

Store in the Local State (as a known_user preference) the boolean flag
whether the SAML Credentials Passing API (a.k.a. the principals API) was
used during the authentication of this user.

Bug: 971795
Test: browser_tests --gtest_filter="SamlTest.*:OobeTest.*"
Change-Id: I92a7e2c9c029cb02df8b51e581cb6e0f34e3e6f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1662552
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Reviewed-by: default avatarAchuith Bhandarkar <achuith@chromium.org>
Cr-Commit-Position: refs/heads/master@{#670057}
parent 79534f5f
......@@ -20,6 +20,10 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/constants/chromeos_switches.h"
#include "components/account_id/account_id.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user.h"
#include "content/public/browser/notification_details.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "google_apis/gaia/gaia_switches.h"
......@@ -85,6 +89,12 @@ IN_PROC_BROWSER_TEST_F(OobeTest, NewUser) {
FakeGaiaMixin::kEmptyUserServices);
session_start_waiter.Wait();
const AccountId account_id =
content::Details<const user_manager::User>(session_start_waiter.details())
->GetAccountId();
EXPECT_FALSE(
user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(account_id));
}
IN_PROC_BROWSER_TEST_F(OobeTest, Accelerator) {
......
......@@ -85,6 +85,7 @@
#include "components/policy/policy_constants.h"
#include "components/policy/proto/chrome_device_policy.pb.h"
#include "components/policy/proto/device_management_backend.pb.h"
#include "components/user_manager/known_user.h"
#include "components/user_manager/user.h"
#include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_task_traits.h"
......@@ -536,6 +537,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, CredentialPassingAPI) {
SystemSaltGetter::ConvertRawSaltToHexString(
FakeCryptohomeClient::GetStubSystemSalt()));
EXPECT_EQ(key.GetSecret(), cryptohome_client_->salted_hashed_secret());
EXPECT_TRUE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
}
// Tests the single password scraped flow.
......@@ -568,6 +573,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedSingle) {
} while (message != "\"fake_password\"");
session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
}
// Tests password scraping from a dynamically created password field.
......@@ -594,6 +603,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedDynamic) {
content::NotificationService::AllSources());
SigninFrameJS().TapOn("Submit");
session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
}
// Tests the multiple password scraped flow.
......@@ -619,6 +632,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedMultiple) {
content::NotificationService::AllSources());
SendConfirmPassword("password1");
session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
}
// Tests the no password scraped flow.
......@@ -645,6 +662,10 @@ IN_PROC_BROWSER_TEST_F(SamlTest, ScrapedNone) {
content::NotificationService::AllSources());
SetManualPasswords("Test1", "Test1");
session_start_waiter.Wait();
EXPECT_FALSE(user_manager::known_user::GetIsUsingSAMLPrincipalsAPI(
AccountId::FromUserEmailGaiaId(kFirstSAMLUserEmail,
kFirstSAMLUserGaiaId)));
}
// Types |bob@corp.example.com| into the GAIA login form but then authenticates
......
......@@ -1516,9 +1516,13 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
if (user_manager->IsLoggedInAsUserWithGaiaAccount()) {
if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML)
if (user_context_.GetAuthFlow() == UserContext::AUTH_FLOW_GAIA_WITH_SAML) {
user_manager::known_user::UpdateUsingSAML(user_context_.GetAccountId(),
true);
user_manager::known_user::UpdateIsUsingSAMLPrincipalsAPI(
user_context_.GetAccountId(),
user_context_.IsUsingSamlPrincipalsApi());
}
SAMLOfflineSigninLimiter* saml_offline_signin_limiter =
SAMLOfflineSigninLimiterFactory::GetForProfile(profile);
if (saml_offline_signin_limiter)
......
......@@ -831,6 +831,8 @@ void GaiaScreenHandler::OnGetCookiesForCompleteAuthentication(
user_context.SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML
: UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
if (using_saml)
user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_);
user_context.SetGAPSCookie(gaps_cookie);
if (using_saml && ExtractSamlPasswordAttributesEnabled()) {
user_context.SetSamlPasswordAttributes(password_attributes);
......@@ -983,6 +985,8 @@ void GaiaScreenHandler::DoCompleteLogin(
user_context.SetAuthFlow(using_saml
? UserContext::AUTH_FLOW_GAIA_WITH_SAML
: UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML);
if (using_saml)
user_context.SetIsUsingSamlPrincipalsApi(using_saml_api_);
if (using_saml && ExtractSamlPasswordAttributesEnabled()) {
user_context.SetSamlPasswordAttributes(password_attributes);
......
......@@ -334,6 +334,10 @@ class GaiaScreenHandler : public BaseScreenHandler,
// If the user authenticated via SAML, this indicates whether the principals
// API was used.
// TODO(emaxx): This is also currently set when the user authenticated via
// Gaia, since Gaia uses the same API for passing the password to Chrome.
// Either fix this behavior, or change the naming and the comments to reflect
// it.
bool using_saml_api_ = false;
// Test credentials.
......
......@@ -113,6 +113,10 @@ UserContext::AuthFlow UserContext::GetAuthFlow() const {
return auth_flow_;
}
bool UserContext::IsUsingSamlPrincipalsApi() const {
return is_using_saml_principals_api_;
}
user_manager::UserType UserContext::GetUserType() const {
return user_type_;
}
......@@ -196,6 +200,11 @@ void UserContext::SetAuthFlow(AuthFlow auth_flow) {
auth_flow_ = auth_flow;
}
void UserContext::SetIsUsingSamlPrincipalsApi(
bool is_using_saml_principals_api) {
is_using_saml_principals_api_ = is_using_saml_principals_api;
}
void UserContext::SetPublicSessionLocale(const std::string& locale) {
public_session_locale_ = locale;
}
......
......@@ -79,6 +79,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
bool IsUsingPin() const;
bool IsForcingDircrypto() const;
AuthFlow GetAuthFlow() const;
bool IsUsingSamlPrincipalsApi() const;
user_manager::UserType GetUserType() const;
const std::string& GetPublicSessionLocale() const;
const std::string& GetPublicSessionInputMethod() const;
......@@ -105,6 +106,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
void SetIsUsingPin(bool is_using_pin);
void SetIsForcingDircrypto(bool is_forcing_dircrypto);
void SetAuthFlow(AuthFlow auth_flow);
void SetIsUsingSamlPrincipalsApi(bool is_using_saml_principals_api);
void SetPublicSessionLocale(const std::string& locale);
void SetPublicSessionInputMethod(const std::string& input_method);
void SetDeviceId(const std::string& device_id);
......@@ -130,6 +132,7 @@ class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) UserContext {
bool is_using_pin_ = false;
bool is_forcing_dircrypto_ = false;
AuthFlow auth_flow_ = AUTH_FLOW_OFFLINE;
bool is_using_saml_principals_api_ = false;
user_manager::UserType user_type_ = user_manager::USER_TYPE_REGULAR;
std::string public_session_locale_;
std::string public_session_input_method_;
......
......@@ -43,6 +43,9 @@ const char kAccountTypeKey[] = "account_type";
// Key of whether this user ID refers to a SAML user.
const char kUsingSAMLKey[] = "using_saml";
// Key of whether this user authenticated via SAML using the principals API.
const char kIsUsingSAMLPrincipalsAPI[] = "using_saml_principals_api";
// Key of Device Id.
const char kDeviceId[] = "device_id";
......@@ -72,6 +75,7 @@ const char* kReservedKeys[] = {kCanonicalEmail,
kObjGuidKey,
kAccountTypeKey,
kUsingSAMLKey,
kIsUsingSAMLPrincipalsAPI,
kDeviceId,
kGAPSCookie,
kReauthReasonKey,
......@@ -519,6 +523,23 @@ bool IsUsingSAML(const AccountId& account_id) {
return false;
}
void USER_MANAGER_EXPORT
UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id,
bool is_using_saml_principals_api) {
SetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI,
is_using_saml_principals_api);
}
bool USER_MANAGER_EXPORT
GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id) {
bool is_using_saml_principals_api;
if (GetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI,
&is_using_saml_principals_api)) {
return is_using_saml_principals_api;
}
return false;
}
void SetProfileRequiresPolicy(const AccountId& account_id,
ProfileRequiresPolicy required) {
DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
......
......@@ -152,6 +152,15 @@ void USER_MANAGER_EXPORT UpdateUsingSAML(const AccountId& account_id,
// returns false.
bool USER_MANAGER_EXPORT IsUsingSAML(const AccountId& account_id);
// Setter and getter for the known user preference that stores whether the user
// authenticated via SAML using the principals API.
void USER_MANAGER_EXPORT
UpdateIsUsingSAMLPrincipalsAPI(const AccountId& account_id,
bool is_using_saml_principals_api);
bool USER_MANAGER_EXPORT
GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id);
// Enum describing whether a user's profile requires policy. If kPolicyRequired,
// the profile initialization code will ensure that valid policy is loaded
// before session initialization completes.
......
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