]> source.dussan.org Git - nextcloud-server.git/commitdiff
Introduce an event for first time login based on the last login time stamp 2112/head
authorThomas Müller <thomas.mueller@tmit.eu>
Fri, 23 Sep 2016 15:21:07 +0000 (17:21 +0200)
committerMorris Jobke <hey@morrisjobke.de>
Mon, 14 Nov 2016 13:50:10 +0000 (14:50 +0100)
Use firstLogin event to trigger creation of default calendar and default address book

Delay login of admin user after setup so that firstLogin event can properly be processed for the admin

Fixing tests ...

Skeleton files are not copied over -> only 3 cache entries are remaining

Use updateLastLoginTimestamp to properly setup lastLogin value for a test user

apps/dav/lib/AppInfo/Application.php
apps/dav/lib/HookManager.php
apps/dav/tests/unit/Connector/Sabre/RequestTest/UploadTest.php
apps/dav/tests/unit/DAV/HookManagerTest.php
apps/files/tests/Command/DeleteOrphanedFilesTest.php
lib/private/Files/Node/Root.php
lib/private/Setup.php
lib/private/User/Manager.php
lib/private/User/Session.php
lib/private/User/User.php
tests/lib/TestCase.php

index c777f5e5a352e487467bad83a609d847b5366ab4..844e0780ffb923bb84558961a58f97a0e6a79fec 100644 (file)
@@ -33,6 +33,7 @@ use OCA\DAV\CardDAV\SyncService;
 use OCA\DAV\HookManager;
 use \OCP\AppFramework\App;
 use OCP\Contacts\IManager;
+use OCP\IUser;
 use Symfony\Component\EventDispatcher\GenericEvent;
 
 class Application extends App {
@@ -65,6 +66,16 @@ class Application extends App {
                $hm = $this->getContainer()->query(HookManager::class);
                $hm->setup();
 
+               $dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
+
+               // first time login event setup
+               $dispatcher->addListener(IUser::class . '::firstLogin', function ($event) use ($hm) {
+                       if ($event instanceof GenericEvent) {
+                               $hm->firstLogin($event->getSubject());
+                       }
+               });
+
+               // carddav/caldav sync event setup
                $listener = function($event) {
                        if ($event instanceof GenericEvent) {
                                /** @var BirthdayService $b */
@@ -77,7 +88,6 @@ class Application extends App {
                        }
                };
 
-               $dispatcher = $this->getContainer()->getServer()->getEventDispatcher();
                $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::createCard', $listener);
                $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::updateCard', $listener);
                $dispatcher->addListener('\OCA\DAV\CardDAV\CardDavBackend::deleteCard', function($event) {
index 92aa4fce7fa371de76607eb34b65c9b104954055..247d4b291af1595f67b9e29ca392298a7d80ef8f 100644 (file)
@@ -78,10 +78,6 @@ class HookManager {
                        'changeUser',
                        $this,
                        'changeUser');
-               Util::connectHook('OC_User',
-                       'post_login',
-                       $this,
-                       'postLogin');
        }
 
        public function postCreateUser($params) {
@@ -117,8 +113,7 @@ class HookManager {
                $this->syncService->updateUser($user);
        }
 
-       public function postLogin($params) {
-               $user = $this->userManager->get($params['uid']);
+       public function firstLogin(IUser $user = null) {
                if (!is_null($user)) {
                        $principal = 'principals/users/' . $user->getUID();
                        if ($this->calDav->getCalendarsForUserCount($principal) === 0) {
index f22da14a0d8cd83c76a94ae7964e1edd32aff047..1db85b1bcaf5be29f173a2c894b3f19856228fb2 100644 (file)
@@ -88,6 +88,7 @@ class UploadTest extends RequestTest {
        public function testUploadOverWriteWriteLocked() {
                $user = $this->getUniqueID();
                $view = $this->setupUser($user, 'pass');
+               $this->loginAsUser($user);
 
                $view->file_put_contents('foo.txt', 'bar');
 
index 5b7d4700a5f871b2b6b465f452ef2dab58abc727..f980e595bf9174733284b69b5f6ef1e66b391747 100644 (file)
@@ -58,7 +58,6 @@ class HookManagerTest extends TestCase {
                $userManager = $this->getMockBuilder(IUserManager::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $userManager->expects($this->once())->method('get')->willReturn($user);
 
                /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */
                $syncService = $this->getMockBuilder(SyncService::class)
@@ -84,7 +83,7 @@ class HookManagerTest extends TestCase {
                        'contacts', ['{DAV:}displayname' => 'Contacts']);
 
                $hm = new HookManager($userManager, $syncService, $cal, $card);
-               $hm->postLogin(['uid' => 'newUser']);
+               $hm->firstLogin($user);
        }
 
        public function testWithExisting() {
@@ -97,7 +96,6 @@ class HookManagerTest extends TestCase {
                $userManager = $this->getMockBuilder(IUserManager::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $userManager->expects($this->once())->method('get')->willReturn($user);
 
                /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */
                $syncService = $this->getMockBuilder(SyncService::class)
@@ -119,7 +117,7 @@ class HookManagerTest extends TestCase {
                $card->expects($this->never())->method('createAddressBook');
 
                $hm = new HookManager($userManager, $syncService, $cal, $card);
-               $hm->postLogin(['uid' => 'newUser']);
+               $hm->firstLogin($user);
        }
 
        public function testWithBirthdayCalendar() {
@@ -132,7 +130,6 @@ class HookManagerTest extends TestCase {
                $userManager = $this->getMockBuilder(IUserManager::class)
                        ->disableOriginalConstructor()
                        ->getMock();
-               $userManager->expects($this->once())->method('get')->willReturn($user);
 
                /** @var SyncService | \PHPUnit_Framework_MockObject_MockObject $syncService */
                $syncService = $this->getMockBuilder(SyncService::class)
@@ -158,7 +155,7 @@ class HookManagerTest extends TestCase {
                        'contacts', ['{DAV:}displayname' => 'Contacts']);
 
                $hm = new HookManager($userManager, $syncService, $cal, $card);
-               $hm->postLogin(['uid' => 'newUser']);
+               $hm->firstLogin($user);
        }
 
        public function testDeleteCalendar() {
index b4d16e546176dd9fad870376af77fa95329bc96b..32c8d628a809ebdd485b6bf31ffbf3fee2ea2218 100644 (file)
 
 namespace OCA\Files\Tests\Command;
 
+use OC\Files\View;
 use OCA\Files\Command\DeleteOrphanedFiles;
 use OCP\Files\StorageNotAvailableException;
+use Test\TestCase;
 
 /**
  * Class DeleteOrphanedFilesTest
@@ -34,7 +36,7 @@ use OCP\Files\StorageNotAvailableException;
  *
  * @package OCA\Files\Tests\Command
  */
-class DeleteOrphanedFilesTest extends \Test\TestCase {
+class DeleteOrphanedFilesTest extends TestCase {
 
        /**
         * @var DeleteOrphanedFiles
@@ -94,7 +96,7 @@ class DeleteOrphanedFilesTest extends \Test\TestCase {
 
                $this->loginAsUser($this->user1);
 
-               $view = new \OC\Files\View('/' . $this->user1 . '/');
+               $view = new View('/' . $this->user1 . '/');
                $view->mkdir('files/test');
 
                $fileInfo = $view->getFileInfo('files/test');
@@ -115,7 +117,7 @@ class DeleteOrphanedFilesTest extends \Test\TestCase {
                $output
                        ->expects($this->once())
                        ->method('writeln')
-                       ->with('4 orphaned file cache entries deleted');
+                       ->with('3 orphaned file cache entries deleted');
 
                $this->command->execute($input, $output);
 
index 515a795d6e023f73859cdef5a49d645e7cfdb667..175cb4f914f035377e95208bced71658dacc4347 100644 (file)
@@ -378,7 +378,6 @@ class Root extends Folder implements IRootFolder {
                                        $this->newFolder('/' . $userId);
                                }
                                $folder = $this->newFolder('/' . $userId . '/files');
-                               \OC_Util::copySkeleton($userId, $folder);
                        }
 
                        $this->userFolderCache->set($userId, $folder);
index 4c72fbc962342d8452ea8a63b8f9a4ae009cfeaa..81a5343fe2103b1412128ff0419f5efbb9c18ac7 100644 (file)
@@ -363,15 +363,6 @@ class Setup {
                        $group =\OC::$server->getGroupManager()->createGroup('admin');
                        $group->addUser($user);
 
-                       // Create a session token for the newly created user
-                       // The token provider requires a working db, so it's not injected on setup
-                       /* @var $userSession User\Session */
-                       $userSession = \OC::$server->getUserSession();
-                       $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
-                       $userSession->setTokenProvider($defaultTokenProvider);
-                       $userSession->login($username, $password);
-                       $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
-
                        //guess what this does
                        Installer::installShippedApps();
 
@@ -392,6 +383,15 @@ class Setup {
 
                        //and we are done
                        $config->setSystemValue('installed', true);
+
+                       // Create a session token for the newly created user
+                       // The token provider requires a working db, so it's not injected on setup
+                       /* @var $userSession User\Session */
+                       $userSession = \OC::$server->getUserSession();
+                       $defaultTokenProvider = \OC::$server->query('OC\Authentication\Token\DefaultTokenProvider');
+                       $userSession->setTokenProvider($defaultTokenProvider);
+                       $userSession->login($username, $password);
+                       $userSession->createSessionToken($request, $userSession->getUser()->getUID(), $username, $password);
                }
 
                return $error;
index c3fb8737420031328b805285818e2c078159677e..43e09cdabcfc3a610ef7c58b5340b3f9fa14317b 100644 (file)
@@ -79,14 +79,6 @@ class Manager extends PublicEmitter implements IUserManager {
                        /** @var \OC\User\User $user */
                        unset($cachedUsers[$user->getUID()]);
                });
-               $this->listen('\OC\User', 'postLogin', function ($user) {
-                       /** @var \OC\User\User $user */
-                       $user->updateLastLoginTimestamp();
-               });
-               $this->listen('\OC\User', 'postRememberedLogin', function ($user) {
-                       /** @var \OC\User\User $user */
-                       $user->updateLastLoginTimestamp();
-               });
        }
 
        /**
index 7215cbe418886a64b36b1dad004b01c95eb8fa8e..ef408aa40776bb43e520e907e3906f1888d42abf 100644 (file)
@@ -51,6 +51,7 @@ use OCP\IUserSession;
 use OCP\Security\ISecureRandom;
 use OCP\Session\Exceptions\SessionNotAvailableException;
 use OCP\Util;
+use Symfony\Component\EventDispatcher\GenericEvent;
 
 /**
  * Class Session
@@ -396,15 +397,25 @@ class Session implements IUserSession, Emitter {
                }
        }
 
-       protected function prepareUserLogin() {
+       protected function prepareUserLogin($firstTimeLogin) {
                // TODO: mock/inject/use non-static
                // Refresh the token
                \OC::$server->getCsrfTokenManager()->refreshToken();
                //we need to pass the user name, which may differ from login name
                $user = $this->getUser()->getUID();
                OC_Util::setupFS($user);
-               //trigger creation of user home and /files folder
-               \OC::$server->getUserFolder($user);
+
+               if ($firstTimeLogin) {
+                       // TODO: lock necessary?
+                       //trigger creation of user home and /files folder
+                       $userFolder = \OC::$server->getUserFolder($user);
+
+                       // copy skeleton
+                       \OC_Util::copySkeleton($user, $userFolder);
+
+                       // trigger any other initialization
+                       \OC::$server->getEventDispatcher()->dispatch(IUser::class . '::firstLogin', new GenericEvent($this->getUser()));
+               }
        }
 
        /**
@@ -457,9 +468,10 @@ class Session implements IUserSession, Emitter {
                if ($user->isEnabled()) {
                        $this->setUser($user);
                        $this->setLoginName($uid);
-                       $this->manager->emit('\OC\User', 'postLogin', array($user, $password));
+                       $firstTimeLogin = $user->updateLastLoginTimestamp();
+                       $this->manager->emit('\OC\User', 'postLogin', [$user, $password]);
                        if ($this->isLoggedIn()) {
-                               $this->prepareUserLogin();
+                               $this->prepareUserLogin($firstTimeLogin);
                                return true;
                        } else {
                                // injecting l10n does not work - there is a circular dependency between session and \OCP\L10N\IFactory
@@ -725,7 +737,8 @@ class Session implements IUserSession, Emitter {
 
                //login
                $this->setUser($user);
-               $this->manager->emit('\OC\User', 'postRememberedLogin', array($user));
+               $user->updateLastLoginTimestamp();
+               $this->manager->emit('\OC\User', 'postRememberedLogin', [$user]);
                return true;
        }
 
index 68787ce60f8753e12feb2834f711d0b2a6df8051..3cc6dc3b7ed62f2b1f95d8fdf0fcf5d12e84e2da 100644 (file)
@@ -180,9 +180,12 @@ class User implements IUser {
         * updates the timestamp of the most recent login of this user
         */
        public function updateLastLoginTimestamp() {
+               $firstTimeLogin = ($this->lastLogin === 0);
                $this->lastLogin = time();
-               \OC::$server->getConfig()->setUserValue(
+               $this->config->setUserValue(
                        $this->uid, 'login', 'lastLogin', $this->lastLogin);
+
+               return $firstTimeLogin;
        }
 
        /**
index c1fe9c382faffb51bc4283b0acb184001018aec9..42b2273e11929d6fa5394808bba94999bd58a5ca 100644 (file)
@@ -377,6 +377,10 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
                self::logout();
                \OC\Files\Filesystem::tearDown();
                \OC_User::setUserId($user);
+               $userObject = \OC::$server->getUserManager()->get($user);
+               if (!is_null($userObject)) {
+                       $userObject->updateLastLoginTimestamp();
+               }
                \OC_Util::setupFS($user);
                if (\OC_User::userExists($user)) {
                        \OC::$server->getUserFolder($user);