15d010aa50a0694d498e8317fd8044e56474ce7edChris Masone# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
25d010aa50a0694d498e8317fd8044e56474ce7edChris Masone# Use of this source code is governed by a BSD-style license that can be
35d010aa50a0694d498e8317fd8044e56474ce7edChris Masone# found in the LICENSE file.
45d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
55d010aa50a0694d498e8317fd8044e56474ce7edChris Masoneimport gobject, os
664170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masonefrom dbus.mainloop.glib import DBusGMainLoop
75d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
85d010aa50a0694d498e8317fd8044e56474ce7edChris Masonefrom autotest_lib.client.bin import test, utils
9c9acf25744b9f267fd334662d2dd3655e139e55cChris Masonefrom autotest_lib.client.common_lib import error
105d010aa50a0694d498e8317fd8044e56474ce7edChris Masonefrom autotest_lib.client.common_lib.cros import policy, session_manager
115d010aa50a0694d498e8317fd8044e56474ce7edChris Masonefrom autotest_lib.client.cros import cros_ui, cryptohome, ownership
125d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
135d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
145d010aa50a0694d498e8317fd8044e56474ce7edChris Masoneclass login_MultipleSessions(test.test):
155d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    """Ensure that the session_manager can handle multiple calls to StartSession
165d010aa50a0694d498e8317fd8044e56474ce7edChris Masone       correctly.
175d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    """
185d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    version = 1
195d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
205d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    def setup(self):
215d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        os.chdir(self.srcdir)
225d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        utils.make('OUT_DIR=.')
235d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
245d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
255d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    def initialize(self):
265d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        super(login_MultipleSessions, self).initialize()
275d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # Ensure a clean beginning.
28a2b32851e8716f188dde273c73f4c76058bbd289Chris Masone        ownership.restart_ui_to_clear_ownership_files()
295d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
3064170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone        self._bus_loop = DBusGMainLoop(set_as_default=True)
3164170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone        self._session_manager = session_manager.connect(self._bus_loop)
32c9acf25744b9f267fd334662d2dd3655e139e55cChris Masone        self._listener = session_manager.OwnershipSignalListener(
33c9acf25744b9f267fd334662d2dd3655e139e55cChris Masone                gobject.MainLoop())
345d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self._listener.listen_for_new_key_and_policy()
355d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
3664170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone        self._cryptohome_proxy = cryptohome.CryptohomeProxy(self._bus_loop)
3764170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone
385d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
395d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    def run_once(self):
405d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        expected_owner = 'first_user@nowhere.com'
415d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        other_user = 'second_user@nowhere.com'
425d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self.__start_session_for(expected_owner)
435d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self.__start_session_for(other_user)
445d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self._listener.wait_for_signals(desc='Initial policy push complete.')
455d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
465d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # Ensure that the first user got to be the owner.
475d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        retrieved_policy = policy.get_policy(self._session_manager)
485d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        if retrieved_policy is None: raise error.TestFail('Policy not found')
495d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        policy.compare_policy_response(self.srcdir, retrieved_policy,
505d010aa50a0694d498e8317fd8044e56474ce7edChris Masone                                       owner=expected_owner)
515d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # bounce the session manager and wait for it to come back up before
525d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # reconnecting.
535d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        cros_ui.restart()
5464170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone        self._session_manager = session_manager.connect(self._bus_loop)
555d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
565d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # Destroy the owner's cryptohome and start sessions again in a
575d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # different order
585d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self.__start_session_for(other_user)
595d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self.__start_session_for(expected_owner)
605d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
615d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        self._listener.wait_for_signals(desc='Re-taking of ownership complete.')
625d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
635d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        # Ensure that the first user still gets to be the owner.
645d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        retrieved_policy = policy.get_policy(self._session_manager)
655d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        if retrieved_policy is None: raise error.TestFail('Policy not found')
665d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        policy.compare_policy_response(self.srcdir, retrieved_policy,
675d010aa50a0694d498e8317fd8044e56474ce7edChris Masone                                       owner=expected_owner)
685d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
695d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
705d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    def __start_session_for(self, user):
715d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        """Call StartSession() for user, ensure he has clean on-device state
725d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
735d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        Make a fresh cryptohome for user, and then start a session for him
745d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        with the session manager.
755d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
765d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        @param user: the user to start a session for.
775d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
785d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        @raises error.TestFail: if the session cannot be started.
795d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        """
8064170f8e7053f92f4bbad501c61a352fdabf6d82Chris Masone        self._cryptohome_proxy.ensure_clean_cryptohome_for(user)
815d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        if not self._session_manager.StartSession(user, ''):
825d010aa50a0694d498e8317fd8044e56474ce7edChris Masone            raise error.TestFail('Could not start session for ' + user)
835d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
845d010aa50a0694d498e8317fd8044e56474ce7edChris Masone
855d010aa50a0694d498e8317fd8044e56474ce7edChris Masone    def cleanup(self):
861e3510a040383790a25e8e54dbcc0e43fc440741Chris Masone        # Bounce UI, without waiting for the browser to come back. Best effort.
871e3510a040383790a25e8e54dbcc0e43fc440741Chris Masone        cros_ui.stop(allow_fail=True)
885d010aa50a0694d498e8317fd8044e56474ce7edChris Masone        cros_ui.start(allow_fail=True, wait_for_login_prompt=False)
89