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:
commit
04f8521b2c
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue