// Copyright (c) 2012 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 "components/signin/core/browser/signin_manager.h"

#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/compiler_specific.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/testing_pref_service.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/notification_source.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "net/cookies/cookie_monster.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

KeyedService* SigninManagerBuild(content::BrowserContext* context) {
  SigninManager* service = NULL;
  Profile* profile = static_cast<Profile*>(context);
  service = new SigninManager(
      ChromeSigninClientFactory::GetInstance()->GetForProfile(profile),
      ProfileOAuth2TokenServiceFactory::GetForProfile(profile));
  service->Initialize(NULL);
  return service;
}

class TestSigninManagerObserver : public SigninManagerBase::Observer {
 public:
  TestSigninManagerObserver() : num_failed_signins_(0),
                                num_successful_signins_(0),
                                num_signouts_(0) {
  }

  virtual ~TestSigninManagerObserver() {}

  int num_failed_signins_;
  int num_successful_signins_;
  int num_signouts_;

 private:
  // SigninManagerBase::Observer:
  virtual void GoogleSigninFailed(
      const GoogleServiceAuthError& error) OVERRIDE {
    num_failed_signins_++;
  }

  virtual void GoogleSigninSucceeded(
      const std::string& username, const std::string& password) OVERRIDE {
    num_successful_signins_++;
  }

  virtual void GoogleSignedOut(const std::string& username) OVERRIDE {
    num_signouts_++;
  }
};

}  // namespace


class SigninManagerTest : public testing::Test {
 public:
  SigninManagerTest() : manager_(NULL) {}
  virtual ~SigninManagerTest() {}

  virtual void SetUp() OVERRIDE {
    manager_ = NULL;
    prefs_.reset(new TestingPrefServiceSimple);
    chrome::RegisterLocalState(prefs_->registry());
    TestingBrowserProcess::GetGlobal()->SetLocalState(
        prefs_.get());
    TestingProfile::Builder builder;
    builder.AddTestingFactory(ProfileOAuth2TokenServiceFactory::GetInstance(),
                              BuildFakeProfileOAuth2TokenService);
    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
                              SigninManagerBuild);
    profile_ = builder.Build();
  }

  virtual void TearDown() OVERRIDE {
    if (manager_)
      manager_->RemoveObserver(&test_observer_);

    // Destroy the SigninManager here, because it relies on profile() which is
    // freed in the base class.
    if (naked_manager_) {
      naked_manager_->Shutdown();
      naked_manager_.reset(NULL);
    }
    TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);

    // Manually destroy PrefService and Profile so that they are shutdown
    // in the correct order.  Both need to be destroyed before the
    // |thread_bundle_| member.
    profile_.reset();
    prefs_.reset();  // LocalState needs to outlive the profile.
  }

  TestingProfile* profile() { return profile_.get(); }

  // Sets up the signin manager as a service if other code will try to get it as
  // a PKS.
  void SetUpSigninManagerAsService() {
    DCHECK(!manager_);
    DCHECK(!naked_manager_);
    manager_ = static_cast<SigninManager*>(
        SigninManagerFactory::GetForProfile(profile()));
    manager_->AddObserver(&test_observer_);
  }

  // Create a naked signin manager if integration with PKSs is not needed.
  void CreateNakedSigninManager() {
    DCHECK(!manager_);
    naked_manager_.reset(new SigninManager(
        ChromeSigninClientFactory::GetInstance()->GetForProfile(profile()),
        ProfileOAuth2TokenServiceFactory::GetForProfile(profile())));

    manager_ = naked_manager_.get();
    manager_->AddObserver(&test_observer_);
  }

  // Shuts down |manager_|.
  void ShutDownManager() {
    DCHECK(manager_);
    manager_->RemoveObserver(&test_observer_);
    manager_->Shutdown();
    if (naked_manager_)
      naked_manager_.reset(NULL);
    manager_ = NULL;
  }

  void ExpectSignInWithRefreshTokenSuccess() {
    EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty());

    ProfileOAuth2TokenService* token_service =
        ProfileOAuth2TokenServiceFactory::GetForProfile(profile());
    EXPECT_TRUE(token_service->RefreshTokenIsAvailable(
        manager_->GetAuthenticatedUsername()));

    // Should go into token service and stop.
    EXPECT_EQ(1, test_observer_.num_successful_signins_);
    EXPECT_EQ(0, test_observer_.num_failed_signins_);
  }

  void CompleteSigninCallback(const std::string& oauth_token) {
    oauth_tokens_fetched_.push_back(oauth_token);
    manager_->CompletePendingSignin();
  }

  content::TestBrowserThreadBundle thread_bundle_;
  net::TestURLFetcherFactory factory_;
  scoped_ptr<SigninManager> naked_manager_;
  SigninManager* manager_;
  TestSigninManagerObserver test_observer_;
  scoped_ptr<TestingProfile> profile_;
  std::vector<std::string> oauth_tokens_fetched_;
  scoped_ptr<TestingPrefServiceSimple> prefs_;
  std::vector<std::string> cookies_;
};

TEST_F(SigninManagerTest, SignInWithRefreshToken) {
  SetUpSigninManagerAsService();
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());

  manager_->StartSignInWithRefreshToken(
      "rt1",
      "user@gmail.com",
      "password",
      SigninManager::OAuthTokenFetchedCallback());

  ExpectSignInWithRefreshTokenSuccess();

  // Should persist across resets.
  ShutDownManager();
  CreateNakedSigninManager();
  manager_->Initialize(NULL);
  EXPECT_EQ("user@gmail.com", manager_->GetAuthenticatedUsername());
}

TEST_F(SigninManagerTest, SignInWithRefreshTokenCallbackComplete) {
  SetUpSigninManagerAsService();
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());

  // Since the password is empty, must verify the gaia cookies first.
  SigninManager::OAuthTokenFetchedCallback callback =
      base::Bind(&SigninManagerTest::CompleteSigninCallback,
                 base::Unretained(this));
  manager_->StartSignInWithRefreshToken(
      "rt1",
      "user@gmail.com",
      "password",
      callback);

  ExpectSignInWithRefreshTokenSuccess();
  ASSERT_EQ(1U, oauth_tokens_fetched_.size());
  EXPECT_EQ(oauth_tokens_fetched_[0], "rt1");
}

TEST_F(SigninManagerTest, SignOut) {
  SetUpSigninManagerAsService();
  manager_->StartSignInWithRefreshToken(
      "rt1",
      "user@gmail.com",
      "password",
      SigninManager::OAuthTokenFetchedCallback());
  manager_->SignOut(signin_metrics::SIGNOUT_TEST);
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
  // Should not be persisted anymore
  ShutDownManager();
  CreateNakedSigninManager();
  manager_->Initialize(NULL);
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
}

TEST_F(SigninManagerTest, SignOutWhileProhibited) {
  SetUpSigninManagerAsService();
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());

  manager_->SetAuthenticatedUsername("user@gmail.com");
  manager_->ProhibitSignout(true);
  manager_->SignOut(signin_metrics::SIGNOUT_TEST);
  EXPECT_FALSE(manager_->GetAuthenticatedUsername().empty());
  manager_->ProhibitSignout(false);
  manager_->SignOut(signin_metrics::SIGNOUT_TEST);
  EXPECT_TRUE(manager_->GetAuthenticatedUsername().empty());
}

TEST_F(SigninManagerTest, TestIsWebBasedSigninFlowURL) {
  EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
      GURL("http://www.google.com")));
  EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
      GURL("https://accounts.google.com/ServiceLogin?service=chromiumsync")));
  EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
      GURL("http://accounts.google.com/ServiceLogin?service=chromiumsync")));
  // http, not https, should not be treated as web based signin.
  EXPECT_FALSE(SigninManager::IsWebBasedSigninFlowURL(
      GURL("http://accounts.google.com/ServiceLogin?service=googlemail")));
  // chromiumsync is double-embedded in a continue query param.
  EXPECT_TRUE(SigninManager::IsWebBasedSigninFlowURL(
      GURL("https://accounts.google.com/CheckCookie?"
           "continue=https%3A%2F%2Fwww.google.com%2Fintl%2Fen-US%2Fchrome"
           "%2Fblank.html%3Fsource%3D3%26nonadv%3D1&service=chromiumsync")));
}

TEST_F(SigninManagerTest, Prohibited) {
  g_browser_process->local_state()->SetString(
      prefs::kGoogleServicesUsernamePattern, ".*@google.com");
  CreateNakedSigninManager();
  manager_->Initialize(g_browser_process->local_state());
  EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
  EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
}

TEST_F(SigninManagerTest, TestAlternateWildcard) {
  // Test to make sure we accept "*@google.com" as a pattern (treat it as if
  // the admin entered ".*@google.com").
  g_browser_process->local_state()->SetString(
      prefs::kGoogleServicesUsernamePattern, "*@google.com");
  CreateNakedSigninManager();
  manager_->Initialize(g_browser_process->local_state());
  EXPECT_TRUE(manager_->IsAllowedUsername("test@google.com"));
  EXPECT_TRUE(manager_->IsAllowedUsername("happy@google.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername("test@invalid.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername("test@notgoogle.com"));
  EXPECT_FALSE(manager_->IsAllowedUsername(std::string()));
}

TEST_F(SigninManagerTest, ProhibitedAtStartup) {
  profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
                                   "monkey@invalid.com");
  g_browser_process->local_state()->SetString(
      prefs::kGoogleServicesUsernamePattern, ".*@google.com");
  CreateNakedSigninManager();
  manager_->Initialize(g_browser_process->local_state());
  // Currently signed in user is prohibited by policy, so should be signed out.
  EXPECT_EQ("", manager_->GetAuthenticatedUsername());
}

TEST_F(SigninManagerTest, ProhibitedAfterStartup) {
  std::string user("monkey@invalid.com");
  profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
  CreateNakedSigninManager();
  manager_->Initialize(g_browser_process->local_state());
  EXPECT_EQ(user, manager_->GetAuthenticatedUsername());
  // Update the profile - user should be signed out.
  g_browser_process->local_state()->SetString(
      prefs::kGoogleServicesUsernamePattern, ".*@google.com");
  EXPECT_EQ("", manager_->GetAuthenticatedUsername());
}

TEST_F(SigninManagerTest, ExternalSignIn) {
  CreateNakedSigninManager();
  manager_->Initialize(g_browser_process->local_state());
  EXPECT_EQ("",
            profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
  EXPECT_EQ("", manager_->GetAuthenticatedUsername());
  EXPECT_EQ(0, test_observer_.num_successful_signins_);

  manager_->OnExternalSigninCompleted("external@example.com");
  EXPECT_EQ(1, test_observer_.num_successful_signins_);
  EXPECT_EQ(0, test_observer_.num_failed_signins_);
  EXPECT_EQ("external@example.com",
            profile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername));
  EXPECT_EQ("external@example.com", manager_->GetAuthenticatedUsername());
}

TEST_F(SigninManagerTest, SigninNotAllowed) {
  std::string user("user@google.com");
  profile()->GetPrefs()->SetString(prefs::kGoogleServicesUsername, user);
  profile()->GetPrefs()->SetBoolean(prefs::kSigninAllowed, false);
  SetUpSigninManagerAsService();
}
