| Index: chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
|
| diff --git a/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..78ea7729b9e9b2f1fe84f0752c8e7d94667242ec
|
| --- /dev/null
|
| +++ b/chrome/browser/chromeos/login/saml/saml_offline_signin_limiter.cc
|
| @@ -0,0 +1,151 @@
|
| +// Copyright 2014 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/chromeos/login/saml/saml_offline_signin_limiter.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/bind_helpers.h"
|
| +#include "base/location.h"
|
| +#include "base/logging.h"
|
| +#include "base/prefs/pref_service.h"
|
| +#include "base/time/clock.h"
|
| +#include "base/time/time.h"
|
| +#include "chrome/browser/chromeos/login/user_manager.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "components/user_prefs/pref_registry_syncable.h"
|
| +
|
| +namespace chromeos {
|
| +
|
| +namespace {
|
| +
|
| +const int kDefaultSAMLOfflineSigninTimeLimit = 14 * 24 * 60 * 60; // 14 days.
|
| +
|
| +} // namespace
|
| +
|
| +// static
|
| +void SAMLOfflineSigninLimiter::RegisterProfilePrefs(
|
| + user_prefs::PrefRegistrySyncable* registry) {
|
| + registry->RegisterIntegerPref(
|
| + prefs::kSAMLOfflineSigninTimeLimit,
|
| + kDefaultSAMLOfflineSigninTimeLimit,
|
| + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
|
| + registry->RegisterInt64Pref(
|
| + prefs::kSAMLLastGAIASignInTime,
|
| + 0,
|
| + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
|
| +}
|
| +
|
| +void SAMLOfflineSigninLimiter::SignedIn(UserContext::AuthFlow auth_flow) {
|
| + PrefService* prefs = profile_->GetPrefs();
|
| + const User* user = UserManager::Get()->GetUserByProfile(profile_);
|
| + if (!user) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| + const std::string& user_id = user->email();
|
| +
|
| + if (auth_flow == UserContext::AUTH_FLOW_GAIA_WITHOUT_SAML) {
|
| + // The user went through online authentication and GAIA did not redirect to
|
| + // a SAML IdP. No limit applies in this case. Clear the time of last login
|
| + // with SAML and the flag enforcing online login, then return.
|
| + prefs->ClearPref(prefs::kSAMLLastGAIASignInTime);
|
| + UserManager::Get()->SaveForceOnlineSignin(user_id, false);
|
| + return;
|
| + }
|
| +
|
| + if (auth_flow == UserContext::AUTH_FLOW_GAIA_WITH_SAML) {
|
| + // The user went through online authentication and GAIA did redirect to a
|
| + // SAML IdP. Update the time of last login with SAML and clear the flag
|
| + // enforcing online login. The flag will be set again when the limit
|
| + // expires. If the limit already expired (e.g. because it was set to zero),
|
| + // the flag will be set again immediately.
|
| + UserManager::Get()->SaveForceOnlineSignin(user_id, false);
|
| + prefs->SetInt64(prefs::kSAMLLastGAIASignInTime,
|
| + clock_->Now().ToInternalValue());
|
| + }
|
| +
|
| + // Start listening for pref changes.
|
| + pref_change_registrar_.Init(prefs);
|
| + pref_change_registrar_.Add(prefs::kSAMLOfflineSigninTimeLimit,
|
| + base::Bind(&SAMLOfflineSigninLimiter::UpdateLimit,
|
| + base::Unretained(this)));
|
| +
|
| + // Arm the |offline_signin_limit_timer_| if a limit is in force.
|
| + UpdateLimit();
|
| +}
|
| +
|
| +void SAMLOfflineSigninLimiter::Shutdown() {
|
| + pref_change_registrar_.RemoveAll();
|
| + offline_signin_limit_timer_.reset();
|
| +}
|
| +
|
| +SAMLOfflineSigninLimiter::SAMLOfflineSigninLimiter(Profile* profile,
|
| + base::Clock* clock)
|
| + : profile_(profile),
|
| + clock_(clock ? clock : &default_clock_) {
|
| +}
|
| +
|
| +SAMLOfflineSigninLimiter::~SAMLOfflineSigninLimiter() {
|
| +}
|
| +
|
| +void SAMLOfflineSigninLimiter::UpdateLimit() {
|
| + // Stop the |offline_signin_limit_timer_|.
|
| + offline_signin_limit_timer_.reset();
|
| +
|
| + PrefService* prefs = pref_change_registrar_.prefs();
|
| + const base::TimeDelta offline_signin_time_limit =
|
| + base::TimeDelta::FromSeconds(
|
| + prefs->GetInteger(prefs::kSAMLOfflineSigninTimeLimit));
|
| + base::Time last_gaia_signin_time = base::Time::FromInternalValue(
|
| + prefs->GetInt64(prefs::kSAMLLastGAIASignInTime));
|
| + if (offline_signin_time_limit < base::TimeDelta() ||
|
| + last_gaia_signin_time.is_null()) {
|
| + // If no limit is in force, return.
|
| + return;
|
| + }
|
| +
|
| + const base::Time now = clock_->Now();
|
| + if (last_gaia_signin_time > now) {
|
| + // If the time of last login with SAML lies in the future, set it to the
|
| + // current time.
|
| + NOTREACHED();
|
| + last_gaia_signin_time = now;
|
| + prefs->SetInt64(prefs::kSAMLLastGAIASignInTime, now.ToInternalValue());
|
| + }
|
| +
|
| + const base::TimeDelta time_since_last_gaia_signin =
|
| + now - last_gaia_signin_time;
|
| + if (time_since_last_gaia_signin >= offline_signin_time_limit) {
|
| + // If the limit already expired, set the flag enforcing online login
|
| + // immediately and return.
|
| + ForceOnlineLogin();
|
| + return;
|
| + }
|
| +
|
| + // Arm |offline_signin_limit_timer_| so that it sets the flag enforcing online
|
| + // login when the limit expires.
|
| + offline_signin_limit_timer_.reset(
|
| + new base::OneShotTimer<SAMLOfflineSigninLimiter>);
|
| + offline_signin_limit_timer_->Start(
|
| + FROM_HERE,
|
| + offline_signin_time_limit - time_since_last_gaia_signin,
|
| + this,
|
| + &SAMLOfflineSigninLimiter::ForceOnlineLogin);
|
| +}
|
| +
|
| +void SAMLOfflineSigninLimiter::ForceOnlineLogin() {
|
| + User* user = UserManager::Get()->GetUserByProfile(profile_);
|
| + if (!user) {
|
| + NOTREACHED();
|
| + return;
|
| + }
|
| +
|
| + UserManager::Get()->SaveForceOnlineSignin(user->email(), true);
|
| + offline_signin_limit_timer_.reset();
|
| +}
|
| +
|
| +} // namespace chromeos
|
|
|