Merge pull request #2112 from nextcloud/downstream-26206

Introduce an event for first time login based on the last login time …
This commit is contained in:
Roeland Jago Douma 2016-11-14 16:13:16 +01:00 committed by GitHub
commit 04f8521b2c
11 changed files with 57 additions and 41 deletions

View 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) {

View 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) {

View 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');

View 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() {

View File

@ -24,8 +24,10 @@
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);

View 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);

View 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;

View 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();
});
}
/**

View 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;
}

View 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;
}
/**

View 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);