// Copyright (c) 2012 The Chromium OS 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 "login_manager/session_manager_impl.h"

#include <glib.h>
#include <signal.h>
#include <unistd.h>

#include <algorithm>
#include <map>
#include <string>
#include <vector>

#include <base/basictypes.h>
#include <base/command_line.h>
#include <base/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/memory/ref_counted.h>
#include <base/message_loop.h>
#include <base/message_loop_proxy.h>
#include <base/string_util.h>
#include <chromeos/cryptohome.h>
#include <chromeos/dbus/dbus.h>
#include <chromeos/dbus/error_constants.h>
#include <chromeos/dbus/service_constants.h>
#include <chromeos/glib/object.h>
#include <crypto/scoped_nss_types.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "login_manager/device_local_account_policy_service.h"
#include "login_manager/device_management_backend.pb.h"
#include "login_manager/file_checker.h"
#include "login_manager/matchers.h"
#include "login_manager/mock_device_policy_service.h"
#include "login_manager/mock_file_checker.h"
#include "login_manager/mock_key_generator.h"
#include "login_manager/mock_metrics.h"
#include "login_manager/mock_nss_util.h"
#include "login_manager/mock_policy_service.h"
#include "login_manager/mock_process_manager_service.h"
#include "login_manager/mock_system_utils.h"
#include "login_manager/mock_upstart_signal_emitter.h"
#include "login_manager/mock_user_policy_service_factory.h"

using ::testing::AnyNumber;
using ::testing::AtMost;
using ::testing::DoAll;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::HasSubstr;
using ::testing::InvokeWithoutArgs;
using ::testing::Mock;
using ::testing::Return;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::_;

using chromeos::Resetter;
using chromeos::cryptohome::home::kGuestUserName;
using chromeos::cryptohome::home::SanitizeUserName;
using chromeos::cryptohome::home::SetSystemSalt;
using chromeos::glib::ScopedError;

using std::map;
using std::string;
using std::vector;

namespace login_manager {

class SessionManagerImplTest : public ::testing::Test {
 public:
  SessionManagerImplTest()
      : upstart_(new MockUpstartSignalEmitter),
        device_policy_service_(new MockDevicePolicyService),
        impl_(scoped_ptr<UpstartSignalEmitter>(upstart_),
              &manager_,
              &metrics_,
              &nss_,
              &utils_),
        fake_salt_("fake salt") {
  }

  virtual ~SessionManagerImplTest() {}

  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(tmpdir_.CreateUniqueTempDir());
    SetSystemSalt(&fake_salt_);

    MockUserPolicyServiceFactory* factory = new MockUserPolicyServiceFactory;
    EXPECT_CALL(*factory, Create(_))
        .WillRepeatedly(
            Invoke(this, &SessionManagerImplTest::CreateUserPolicyService));
    scoped_ptr<DeviceLocalAccountPolicyService> device_local_account_policy(
        new DeviceLocalAccountPolicyService(tmpdir_.path(), NULL, NULL));
    impl_.InjectPolicyServices(
        scoped_ptr<DevicePolicyService>(device_policy_service_),
        scoped_ptr<UserPolicyServiceFactory>(factory),
        device_local_account_policy.Pass());
  }

  virtual void TearDown() OVERRIDE {
    SetSystemSalt(NULL);
  }

 protected:
  void ExpectStartSession(const string& email_string) {
    ExpectSessionBoilerplate(email_string, false, false);
  }

  void ExpectGuestSession() {
    ExpectSessionBoilerplate(kGuestUserName, true, false);
  }

  void ExpectStartOwnerSession(const string& email_string) {
    ExpectSessionBoilerplate(email_string, false, true);
  }

  void ExpectStartSessionUnowned(const string& email_string) {
    ExpectStartSessionUnownedBoilerplate(email_string, false, false);
  }

  void ExpectStartSessionOwningInProcess(const string& email_string) {
    ExpectStartSessionUnownedBoilerplate(email_string, false, true);
  }

  void ExpectStartSessionOwnerLost(const string& email_string) {
    ExpectStartSessionUnownedBoilerplate(email_string, true, false);
  }

  void ExpectStorePolicy(MockDevicePolicyService* service,
                         const string& policy,
                         int flags) {
    EXPECT_CALL(*service, Store(CastEq(policy), policy.size(), _, flags))
        .WillOnce(Return(true));
  }

  void ExpectAndRunStartSession(const string& const_email) {
    gboolean out;
    // Need a non-const gchar*.
    gchar* email = g_strdup(const_email.c_str());
    gchar nothing[] = "";

    ExpectStartSession(email);
    EXPECT_EQ(TRUE, impl_.StartSession(email, nothing, &out, NULL));
    g_free(email);
  }

  void ExpectAndRunGuestSession() {
    gboolean out;
    // Need a non-const gchar*.
    gchar* incognito = g_strdup(kGuestUserName);
    gchar nothing[] = "";

    ExpectGuestSession();
    EXPECT_EQ(TRUE, impl_.StartSession(incognito, nothing, &out, NULL));
    g_free(incognito);
  }

  PolicyService* CreateUserPolicyService(const string& username) {
    user_policy_services_[username] = new MockPolicyService();
    return user_policy_services_[username];
  }

  void VerifyAndClearExpectations() {
    Mock::VerifyAndClearExpectations(upstart_);
    Mock::VerifyAndClearExpectations(device_policy_service_);
    for (map<string, MockPolicyService*>::iterator it =
             user_policy_services_.begin();
         it != user_policy_services_.end();
         ++it) {
      Mock::VerifyAndClearExpectations(it->second);
    }
    Mock::VerifyAndClearExpectations(&manager_);
    Mock::VerifyAndClearExpectations(&metrics_);
    Mock::VerifyAndClearExpectations(&nss_);
    Mock::VerifyAndClearExpectations(&utils_);
  }

  // Caller takes ownership.
  GArray* CreateArray(const char* input, const int len) {
    GArray* output = g_array_new(FALSE, FALSE, 1);
    g_array_append_vals(output, input, len);
    return output;
  }

  // These are bare pointers, not scoped_ptrs, because we need to give them
  // to a SessionManagerImpl instance, but also be able to set expectations
  // on them after we hand them off.
  MockUpstartSignalEmitter* upstart_;
  MockDevicePolicyService* device_policy_service_;
  map<string, MockPolicyService*> user_policy_services_;

  MockProcessManagerService manager_;
  MockMetrics metrics_;
  MockNssUtil nss_;
  MockSystemUtils utils_;

  SessionManagerImpl impl_;
  base::ScopedTempDir tmpdir_;

  static const pid_t kDummyPid;
 private:
  void ExpectSessionBoilerplate(const string& email_string,
                                bool guest,
                                bool for_owner) {
    EXPECT_CALL(manager_,
                SetBrowserSessionForUser(StrEq(email_string),
                                         StrEq(SanitizeUserName(email_string))))
        .Times(1);
    // Expect initialization of the device policy service, return success.
    EXPECT_CALL(*device_policy_service_,
                CheckAndHandleOwnerLogin(StrEq(email_string), _, _, _))
        .WillOnce(DoAll(SetArgumentPointee<2>(for_owner),
                        Return(true)));
    // Confirm that the key is present.
    EXPECT_CALL(*device_policy_service_, KeyMissing())
        .WillOnce(Return(false));

    EXPECT_CALL(metrics_, SendLoginUserType(false, guest, for_owner))
        .Times(1);
    EXPECT_CALL(utils_,
                EmitSignalWithStringArgs(
                    StrEq(login_manager::kSessionStateChangedSignal),
                    ElementsAre(SessionManagerImpl::kStarted)))
        .Times(1);
    EXPECT_CALL(utils_, IsDevMode())
        .WillOnce(Return(false));
  }

  void ExpectStartSessionUnownedBoilerplate(const string& email_string,
                                            bool mitigating,
                                            bool owning_in_progress) {
    EXPECT_CALL(manager_,
                SetBrowserSessionForUser(StrEq(email_string),
                                         StrEq(SanitizeUserName(email_string))))
        .Times(1);

    // Expect initialization of the device policy service, return success.
    EXPECT_CALL(*device_policy_service_,
                CheckAndHandleOwnerLogin(StrEq(email_string), _, _, _))
        .WillOnce(DoAll(SetArgumentPointee<2>(false),
                        Return(true)));

    // Indicate that there is no owner key in order to trigger a new one to be
    // generated.
    EXPECT_CALL(*device_policy_service_, KeyMissing())
        .WillOnce(Return(true));
    EXPECT_CALL(*device_policy_service_, Mitigating())
        .WillRepeatedly(Return(mitigating));
    if (!mitigating && !owning_in_progress)
      EXPECT_CALL(manager_, RunKeyGenerator(StrEq(email_string))).Times(1);
    else
      EXPECT_CALL(manager_, RunKeyGenerator(_)).Times(0);

    EXPECT_CALL(utils_,
                EmitSignalWithStringArgs(
                    StrEq(login_manager::kSessionStateChangedSignal),
                    ElementsAre(SessionManagerImpl::kStarted)))
        .Times(1);
    EXPECT_CALL(utils_, IsDevMode())
        .WillOnce(Return(false));
  }

  DISALLOW_COPY_AND_ASSIGN(SessionManagerImplTest);

  string fake_salt_;
};

const pid_t SessionManagerImplTest::kDummyPid = 4;

TEST_F(SessionManagerImplTest, EmitLoginPromptVisible) {
  const char event_name[] = "login-prompt-visible";
  EXPECT_CALL(metrics_, RecordStats(StrEq(event_name))).Times(1);
  EXPECT_CALL(utils_,
              EmitSignal(StrEq(login_manager::kLoginPromptVisibleSignal)))
      .Times(1);
  EXPECT_TRUE(impl_.EmitLoginPromptVisible(NULL));
}

TEST_F(SessionManagerImplTest, EnableChromeTesting) {
  // DBus arrays are null-terminated.
  const gchar* args1[] = {"--repeat-arg", "--one-time-arg", NULL};
  gchar* testing_path = NULL;

  base::FilePath expected = utils_.GetUniqueFilename();
  ASSERT_FALSE(expected.empty());
  string expected_testing_path = expected.value();

  EXPECT_CALL(manager_,
              RestartBrowserWithArgs(
                  ElementsAre(args1[0], args1[1],
                              HasSubstr(expected_testing_path)),
                  true))
      .Times(1);

  EXPECT_TRUE(impl_.EnableChromeTesting(false, args1, &testing_path, NULL));
  ASSERT_TRUE(testing_path != NULL);
  EXPECT_TRUE(EndsWith(testing_path, expected_testing_path, false));

  // Calling again, without forcing relaunch, should not do anything.
  testing_path = NULL;
  EXPECT_TRUE(impl_.EnableChromeTesting(false, args1, &testing_path, NULL));
  ASSERT_TRUE(testing_path != NULL);
  EXPECT_TRUE(EndsWith(testing_path, expected_testing_path, false));

  // Force relaunch.  Should go through the whole path again.
  const gchar* args2[] = {"--dummy", "--repeat-arg", NULL};
  testing_path = NULL;
  EXPECT_CALL(manager_,
              RestartBrowserWithArgs(
                  ElementsAre(args2[0], args2[1],
                              HasSubstr(expected_testing_path)),
                  true))
      .Times(1);

  EXPECT_TRUE(impl_.EnableChromeTesting(true, args2, &testing_path, NULL));
  ASSERT_TRUE(testing_path != NULL);
  EXPECT_TRUE(EndsWith(testing_path, expected_testing_path, false));
}

TEST_F(SessionManagerImplTest, StartSession) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSession(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StartSession_New) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSessionUnowned(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StartSession_InvalidUser) {
  gboolean out;
  gchar email[] = "user";
  gchar nothing[] = "";
  ScopedError error;
  EXPECT_EQ(FALSE, impl_.StartSession(email,
                                      nothing,
                                      &out,
                                      &Resetter(&error).lvalue()));
  EXPECT_EQ(CHROMEOS_LOGIN_ERROR_INVALID_EMAIL, error->code);
}

TEST_F(SessionManagerImplTest, StartSession_Twice) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSession(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));

  EXPECT_EQ(FALSE, impl_.StartSession(email,
                                      nothing,
                                      &out,
                                      &Resetter(&error).lvalue()));
  EXPECT_EQ(CHROMEOS_LOGIN_ERROR_SESSION_EXISTS, error->code);
}

TEST_F(SessionManagerImplTest, StartSession_TwoUsers) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSession(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));
  VerifyAndClearExpectations();

  gchar email2[] = "user2@somewhere";
  ExpectStartSession(email2);
  EXPECT_EQ(TRUE, impl_.StartSession(email2,
                                      nothing,
                                      &out,
                                      &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StartSession_OwnerAndOther) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSessionUnowned(email);

  EXPECT_EQ(TRUE, impl_.StartSession(email, nothing, &out, NULL));
  VerifyAndClearExpectations();

  gchar email2[] = "user2@somewhere";
  ExpectStartSession(email2);
  EXPECT_EQ(TRUE, impl_.StartSession(email2, nothing, &out, NULL));
}

TEST_F(SessionManagerImplTest, StartSession_OwnerRace) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSessionUnowned(email);

  EXPECT_EQ(TRUE, impl_.StartSession(email, nothing, &out, NULL));
  VerifyAndClearExpectations();

  gchar email2[] = "user2@somewhere";
  ExpectStartSessionOwningInProcess(email2);
  EXPECT_EQ(TRUE, impl_.StartSession(email2, nothing, &out, NULL));
}

TEST_F(SessionManagerImplTest, StartSession_BadNssDB) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ScopedError error;

  nss_.MakeBadDB();
  EXPECT_EQ(FALSE, impl_.StartSession(email,
                                      nothing,
                                      &out,
                                      &Resetter(&error).lvalue()));
  EXPECT_EQ(CHROMEOS_LOGIN_ERROR_NO_USER_NSSDB, error->code);
}

TEST_F(SessionManagerImplTest, StartSession_DevicePolicyFailure) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ScopedError error;

  // Upon the owner login check, return an error.
  EXPECT_CALL(*device_policy_service_,
              CheckAndHandleOwnerLogin(StrEq(email), _, _, _))
      .WillOnce(Return(false));

  EXPECT_EQ(FALSE, impl_.StartSession(email,
                                      nothing,
                                      &out,
                                      &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StartSession_Owner) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartOwnerSession(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StartSession_KeyMitigation) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartSessionOwnerLost(email);

  ScopedError error;
  EXPECT_EQ(TRUE, impl_.StartSession(email,
                                     nothing,
                                     &out,
                                     &Resetter(&error).lvalue()));
}

TEST_F(SessionManagerImplTest, StopSession) {
  gboolean out;
  gchar nothing[] = "";
  EXPECT_CALL(manager_, ScheduleShutdown()).Times(1);
  impl_.StopSession(nothing, &out, NULL);
}

TEST_F(SessionManagerImplTest, StorePolicy_NoSession) {
  const string fake_policy("fake policy");
  GArray* policy_blob = CreateArray(fake_policy.c_str(), fake_policy.size());
  ExpectStorePolicy(device_policy_service_,
                    fake_policy,
                    PolicyService::KEY_ROTATE |
                    PolicyService::KEY_INSTALL_NEW |
                    PolicyService::KEY_CLOBBER);
  EXPECT_EQ(TRUE, impl_.StorePolicy(policy_blob, NULL));
  g_array_free(policy_blob, TRUE);
}

TEST_F(SessionManagerImplTest, StorePolicy_SessionStarted) {
  ExpectAndRunStartSession("user@somewhere");
  const string fake_policy("fake policy");
  GArray* policy_blob = CreateArray(fake_policy.c_str(), fake_policy.size());
  ExpectStorePolicy(device_policy_service_,
                    fake_policy,
                    PolicyService::KEY_ROTATE);
  EXPECT_EQ(TRUE, impl_.StorePolicy(policy_blob, NULL));
  g_array_free(policy_blob, TRUE);
}

TEST_F(SessionManagerImplTest, RetrievePolicy) {
  const string fake_policy("fake policy");
  const vector<uint8> policy_data(fake_policy.begin(), fake_policy.end());
  EXPECT_CALL(*device_policy_service_, Retrieve(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(policy_data),
                      Return(true)));
  GArray* out_blob;
  ScopedError error;
  EXPECT_EQ(TRUE, impl_.RetrievePolicy(&out_blob,
                                       &Resetter(&error).lvalue()));
  EXPECT_EQ(fake_policy.size(), out_blob->len);
  EXPECT_TRUE(
      std::equal(fake_policy.begin(), fake_policy.end(), out_blob->data));
  g_array_free(out_blob, TRUE);
}

TEST_F(SessionManagerImplTest, StoreUserPolicy_NoSession) {
  EXPECT_CALL(utils_, SetAndSendGError(_, _, _));

  gchar username[] = "user@somewhere.com";
  const string fake_policy("fake policy");
  GArray* policy_blob = CreateArray(fake_policy.c_str(), fake_policy.size());
  EXPECT_EQ(FALSE, impl_.StorePolicyForUser(username, policy_blob, NULL));
  g_array_free(policy_blob, TRUE);
}

TEST_F(SessionManagerImplTest, StoreUserPolicy_SessionStarted) {
  gchar username[] = "user@somewhere.com";
  ExpectAndRunStartSession(username);
  const string fake_policy("fake policy");
  GArray* policy_blob = CreateArray(fake_policy.c_str(), fake_policy.size());
  EXPECT_CALL(*user_policy_services_[username],
              Store(CastEq(fake_policy),
                    fake_policy.size(),
                    _,
                    PolicyService::KEY_ROTATE |
                    PolicyService::KEY_INSTALL_NEW))
      .WillOnce(Return(true));
  EXPECT_EQ(TRUE, impl_.StorePolicyForUser(username, policy_blob, NULL));
  g_array_free(policy_blob, TRUE);
}

TEST_F(SessionManagerImplTest, StoreUserPolicy_SecondSession) {
  EXPECT_CALL(utils_, SetAndSendGError(_, _, _));

  gchar user1[] = "user1@somewhere.com";
  ExpectAndRunStartSession(user1);
  ASSERT_TRUE(user_policy_services_[user1]);

  // Store policy for the signed-in user.
  const std::string fake_policy("fake policy");
  GArray* policy_blob = CreateArray(fake_policy.c_str(), fake_policy.size());
  EXPECT_CALL(*user_policy_services_[user1],
              Store(CastEq(fake_policy),
                    fake_policy.size(),
                    _,
                    PolicyService::KEY_ROTATE |
                    PolicyService::KEY_INSTALL_NEW))
      .WillOnce(Return(true));
  EXPECT_EQ(TRUE, impl_.StorePolicyForUser(user1, policy_blob, NULL));
  Mock::VerifyAndClearExpectations(user_policy_services_[user1]);

  // Storing policy for another username fails before his session starts.
  gchar user2[] = "user2@somewhere.com";
  EXPECT_EQ(FALSE, impl_.StorePolicyForUser(user2, policy_blob, NULL));

  // Now start another session for the 2nd user.
  ExpectAndRunStartSession(user2);
  ASSERT_TRUE(user_policy_services_[user2]);

  // Storing policy for that user now succeeds.
  EXPECT_CALL(*user_policy_services_[user2],
              Store(CastEq(fake_policy),
                    fake_policy.size(),
                    _,
                    PolicyService::KEY_ROTATE |
                    PolicyService::KEY_INSTALL_NEW))
      .WillOnce(Return(true));
  EXPECT_EQ(TRUE, impl_.StorePolicyForUser(user2, policy_blob, NULL));
  Mock::VerifyAndClearExpectations(user_policy_services_[user2]);

  // Cleanup.
  g_array_free(policy_blob, TRUE);
}

TEST_F(SessionManagerImplTest, RetrieveUserPolicy_NoSession) {
  gchar username[] = "user@somewhere.com";
  GArray* out_blob = NULL;
  ScopedError error;
  EXPECT_EQ(FALSE, impl_.RetrievePolicyForUser(username,
                                               &out_blob,
                                               &Resetter(&error).lvalue()));
  EXPECT_FALSE(out_blob);
}

TEST_F(SessionManagerImplTest, RetrieveUserPolicy_SessionStarted) {
  gchar username[] = "user@somewhere.com";
  ExpectAndRunStartSession(username);
  const string fake_policy("fake policy");
  const vector<uint8> policy_data(fake_policy.begin(), fake_policy.end());
  EXPECT_CALL(*user_policy_services_[username], Retrieve(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(policy_data),
                      Return(true)));
  GArray* out_blob = NULL;
  ScopedError error;
  EXPECT_EQ(TRUE, impl_.RetrievePolicyForUser(username,
                                              &out_blob,
                                              &Resetter(&error).lvalue()));
  EXPECT_EQ(fake_policy.size(), out_blob->len);
  EXPECT_TRUE(
      std::equal(fake_policy.begin(), fake_policy.end(), out_blob->data));
  g_array_free(out_blob, TRUE);
}

TEST_F(SessionManagerImplTest, RetrieveUserPolicy_SecondSession) {
  gchar user1[] = "user1@somewhere.com";
  ExpectAndRunStartSession(user1);
  ASSERT_TRUE(user_policy_services_[user1]);

  // Retrieve policy for the signed-in user.
  const std::string fake_policy("fake policy");
  const std::vector<uint8> policy_data(fake_policy.begin(), fake_policy.end());
  EXPECT_CALL(*user_policy_services_[user1], Retrieve(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(policy_data),
                      Return(true)));
  GArray* out_blob = NULL;
  ScopedError error;
  EXPECT_EQ(TRUE, impl_.RetrievePolicyForUser(user1,
                                              &out_blob,
                                              &Resetter(&error).lvalue()));
  Mock::VerifyAndClearExpectations(user_policy_services_[user1]);
  EXPECT_EQ(fake_policy.size(), out_blob->len);
  EXPECT_TRUE(
      std::equal(fake_policy.begin(), fake_policy.end(), out_blob->data));
  g_array_free(out_blob, TRUE);

  // Retrieving policy for another username fails before his session starts.
  gchar user2[] = "user2@somewhere.com";
  out_blob = NULL;
  error.reset();
  EXPECT_EQ(FALSE, impl_.RetrievePolicyForUser(user2,
                                               &out_blob,
                                               &Resetter(&error).lvalue()));

  // Now start another session for the 2nd user.
  ExpectAndRunStartSession(user2);
  ASSERT_TRUE(user_policy_services_[user2]);

  // Retrieving policy for that user now succeeds.
  EXPECT_CALL(*user_policy_services_[user2], Retrieve(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(policy_data),
                      Return(true)));
  out_blob = NULL;
  error.reset();
  EXPECT_EQ(TRUE, impl_.RetrievePolicyForUser(user2,
                                              &out_blob,
                                              &Resetter(&error).lvalue()));
  Mock::VerifyAndClearExpectations(user_policy_services_[user2]);
  EXPECT_EQ(fake_policy.size(), out_blob->len);
  EXPECT_TRUE(
      std::equal(fake_policy.begin(), fake_policy.end(), out_blob->data));
  g_array_free(out_blob, TRUE);
}

TEST_F(SessionManagerImplTest, RetrieveActiveSessions) {
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";

  ExpectStartSession(email);
  EXPECT_EQ(TRUE, impl_.StartSession(email, nothing, &out, NULL));
  GHashTable* active_users = impl_.RetrieveActiveSessions();
  EXPECT_EQ(g_hash_table_size(active_users), 1);
  EXPECT_EQ(reinterpret_cast<char*>(g_hash_table_lookup(active_users, email)),
            SanitizeUserName(email));
  g_hash_table_unref(active_users);
  VerifyAndClearExpectations();

  gchar email2[] = "user2@somewhere";
  ExpectStartSession(email2);
  EXPECT_EQ(TRUE, impl_.StartSession(email2, nothing, &out, NULL));
  active_users = impl_.RetrieveActiveSessions();
  EXPECT_EQ(g_hash_table_size(active_users), 2);
  EXPECT_EQ(reinterpret_cast<char*>(g_hash_table_lookup(active_users, email)),
            SanitizeUserName(email));
  EXPECT_EQ(reinterpret_cast<char*>(g_hash_table_lookup(active_users, email2)),
            SanitizeUserName(email2));
  g_hash_table_unref(active_users);
}

TEST_F(SessionManagerImplTest, RestartJob_UnknownPid) {
  gboolean out;
  gint pid = kDummyPid;
  gchar arguments[] = "";
  ScopedError error;
  EXPECT_CALL(manager_, IsBrowser(pid)).WillOnce(Return(false));

  EXPECT_EQ(FALSE, impl_.RestartJob(pid, arguments, &out,
                                    &Resetter(&error).lvalue()));
  EXPECT_EQ(CHROMEOS_LOGIN_ERROR_UNKNOWN_PID, error->code);
  EXPECT_EQ(FALSE, out);
}

TEST_F(SessionManagerImplTest, RestartJob) {
  gboolean out;
  gint pid = kDummyPid;
  gchar arguments[] = "dummy";

  EXPECT_CALL(manager_, IsBrowser(pid)).WillOnce(Return(true));
  EXPECT_CALL(manager_, RestartBrowserWithArgs(ElementsAre(arguments), false))
      .Times(1);
  ExpectGuestSession();

  EXPECT_EQ(TRUE, impl_.RestartJob(pid, arguments, &out, NULL));
  EXPECT_EQ(TRUE, out);
}

TEST_F(SessionManagerImplTest, RestartJobWithAuth_BadCookie) {
  gboolean out;
  gint pid = kDummyPid;
  gchar cookie[] = "bogus-cookie";
  gchar arguments[] = "dummy";

  // Ensure there's no browser restarting.
  EXPECT_CALL(manager_, RestartBrowserWithArgs(_, _)).Times(0);
  EXPECT_EQ(FALSE, impl_.RestartJobWithAuth(pid, cookie, arguments, &out,
                                            NULL));
  EXPECT_EQ(FALSE, out);
}

TEST_F(SessionManagerImplTest, LockScreen) {
  ExpectAndRunStartSession("user@somewhere");
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(1);
  GError *error = NULL;
  EXPECT_EQ(TRUE, impl_.LockScreen(&error));
  EXPECT_EQ(TRUE, impl_.ScreenIsLocked());
}

TEST_F(SessionManagerImplTest, LockScreen_MultiSession) {
  ExpectAndRunStartSession("user@somewhere");
  ExpectAndRunStartSession("user2@somewhere");
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(1);
  GError *error = NULL;
  EXPECT_EQ(TRUE, impl_.LockScreen(&error));
  EXPECT_EQ(TRUE, impl_.ScreenIsLocked());
}

TEST_F(SessionManagerImplTest, LockScreen_NoSession) {
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(0);
  GError *error = NULL;
  EXPECT_EQ(FALSE, impl_.LockScreen(&error));
}

TEST_F(SessionManagerImplTest, LockScreen_Guest) {
  ExpectAndRunGuestSession();
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(0);
  GError *error = NULL;
  EXPECT_EQ(FALSE, impl_.LockScreen(&error));
}

TEST_F(SessionManagerImplTest, LockScreen_UserAndGuest) {
  ExpectAndRunStartSession("user@somewhere");
  ExpectAndRunGuestSession();
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(1);
  GError *error = NULL;
  EXPECT_EQ(TRUE, impl_.LockScreen(&error));
  EXPECT_EQ(TRUE, impl_.ScreenIsLocked());
}

TEST_F(SessionManagerImplTest, LockUnlockScreen) {
  ExpectAndRunStartSession("user@somewhere");
  EXPECT_CALL(utils_, EmitSignal(StrEq(chromium::kLockScreenSignal))).Times(1);
  GError *error = NULL;
  EXPECT_EQ(TRUE, impl_.LockScreen(&error));
  EXPECT_EQ(TRUE, impl_.ScreenIsLocked());

  EXPECT_CALL(utils_, EmitSignal(StrEq(login_manager::kScreenIsLockedSignal)))
      .Times(1);
  EXPECT_EQ(TRUE, impl_.HandleLockScreenShown(&error));
  EXPECT_EQ(TRUE, impl_.ScreenIsLocked());

  EXPECT_CALL(utils_, EmitSignal(StrEq(login_manager::kScreenIsUnlockedSignal)))
      .Times(1);
  EXPECT_EQ(TRUE, impl_.HandleLockScreenDismissed(&error));
  EXPECT_EQ(FALSE, impl_.ScreenIsLocked());
}

TEST_F(SessionManagerImplTest, StartDeviceWipe_AlreadyLoggedIn) {
  FilePath logged_in_path(SessionManagerImpl::kLoggedInFlag);
  ASSERT_FALSE(utils_.Exists(logged_in_path));
  ASSERT_TRUE(utils_.AtomicFileWrite(logged_in_path, "1", 1));
  GError *error = NULL;
  gboolean done = FALSE;
  EXPECT_EQ(FALSE, impl_.StartDeviceWipe(&done, &error));
}

TEST_F(SessionManagerImplTest, StartDeviceWipe) {
  FilePath logged_in_path(SessionManagerImpl::kLoggedInFlag);
  FilePath reset_path(SessionManagerImpl::kResetFile);
  ASSERT_TRUE(utils_.RemoveFile(logged_in_path));
  EXPECT_CALL(utils_, CallMethodOnPowerManager(_)).Times(1);
  gboolean done = FALSE;
  EXPECT_EQ(TRUE, impl_.StartDeviceWipe(&done, NULL));
  EXPECT_TRUE(done);
}

TEST_F(SessionManagerImplTest, ImportValidateAndStoreGeneratedKey) {
  base::ScopedTempDir tmpdir;
  FilePath key_file_path;
  string key("key_contents");
  ASSERT_TRUE(tmpdir.CreateUniqueTempDir());
  ASSERT_TRUE(file_util::CreateTemporaryFileInDir(tmpdir.path(),
                                                  &key_file_path));
  ASSERT_EQ(file_util::WriteFile(key_file_path, key.c_str(), key.size()),
            key.size());

  // Start a session, to set up NSSDB for the user.
  gboolean out;
  gchar email[] = "user@somewhere";
  gchar nothing[] = "";
  ExpectStartOwnerSession(email);
  ASSERT_EQ(TRUE, impl_.StartSession(email, nothing, &out, NULL));

  EXPECT_CALL(*device_policy_service_,
              ValidateAndStoreOwnerKey(StrEq(email),
                                       StrEq(key),
                                       nss_.GetSlot()))
      .WillOnce(Return(true));

  impl_.ImportValidateAndStoreGeneratedKey(email, key_file_path);
  EXPECT_FALSE(file_util::PathExists(key_file_path));
}

class SessionManagerImplStaticTest : public ::testing::Test {
 public:
  SessionManagerImplStaticTest() {}
  virtual ~SessionManagerImplStaticTest() {}

  bool ValidateEmail(const string& email_address) {
    return SessionManagerImpl::ValidateEmail(email_address);
  }
 };

TEST_F(SessionManagerImplStaticTest, EmailAddressTest) {
  const char valid[] = "user_who+we.like@some-where.com";
  EXPECT_TRUE(ValidateEmail(valid));
}

TEST_F(SessionManagerImplStaticTest, EmailAddressNonAsciiTest) {
  char invalid[4] = "a@m";
  invalid[2] = 254;
  EXPECT_FALSE(ValidateEmail(invalid));
}

TEST_F(SessionManagerImplStaticTest, EmailAddressNoAtTest) {
  const char no_at[] = "user";
  EXPECT_FALSE(ValidateEmail(no_at));
}

TEST_F(SessionManagerImplStaticTest, EmailAddressTooMuchAtTest) {
  const char extra_at[] = "user@what@where";
  EXPECT_FALSE(ValidateEmail(extra_at));
}

}  // namespace login_manager
