diff --git a/apps/updatenotification/appinfo/app.php b/apps/updatenotification/appinfo/app.php index 9148b6e6ef..f257cba697 100644 --- a/apps/updatenotification/appinfo/app.php +++ b/apps/updatenotification/appinfo/app.php @@ -31,9 +31,11 @@ if(\OC::$server->getConfig()->getSystemValue('updatechecker', true) === true) { $userObject = \OC::$server->getUserSession()->getUser(); if($userObject !== null) { - if(\OC::$server->getGroupManager()->isAdmin($userObject->getUID()) && $updateChecker->getUpdateState() !== []) { - \OCP\Util::addScript('updatenotification', 'notification'); - OC_Hook::connect('\OCP\Config', 'js', $updateChecker, 'getJavaScript'); + if(\OC::$server->getGroupManager()->isAdmin($userObject->getUID())) { + if($updateChecker->getUpdateState() !== []) { + \OCP\Util::addScript('updatenotification', 'notification'); + OC_Hook::connect('\OCP\Config', 'js', $updateChecker, 'getJavaScript'); + } \OC_App::registerAdmin('updatenotification', 'admin'); } } diff --git a/apps/updatenotification/appinfo/application.php b/apps/updatenotification/appinfo/application.php index ae3317c1b5..24c0a11af6 100644 --- a/apps/updatenotification/appinfo/application.php +++ b/apps/updatenotification/appinfo/application.php @@ -22,7 +22,9 @@ namespace OCA\UpdateNotification\AppInfo; use OC\AppFramework\Utility\TimeFactory; +use OC\Updater; use OCA\UpdateNotification\Controller\AdminController; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\App; use OCP\AppFramework\IAppContainer; @@ -32,13 +34,21 @@ class Application extends App { $container = $this->getContainer(); $container->registerService('AdminController', function(IAppContainer $c) { + $updater = new \OC\Updater( + \OC::$server->getHTTPHelper(), + \OC::$server->getConfig(), + \OC::$server->getIntegrityCodeChecker() + ); return new AdminController( $c->query('AppName'), $c->query('Request'), $c->getServer()->getJobList(), $c->getServer()->getSecureRandom(), $c->getServer()->getConfig(), - new TimeFactory() + new TimeFactory(), + $c->getServer()->getL10N($c->query('AppName')), + new UpdateChecker($updater), + $c->getServer()->getDateTimeFormatter() ); }); } diff --git a/apps/updatenotification/appinfo/routes.php b/apps/updatenotification/appinfo/routes.php index 2cf43c8976..9021d381b1 100644 --- a/apps/updatenotification/appinfo/routes.php +++ b/apps/updatenotification/appinfo/routes.php @@ -24,4 +24,5 @@ namespace OCA\UpdateNotification\AppInfo; $application = new Application(); $application->registerRoutes($this, ['routes' => [ ['name' => 'Admin#createCredentials', 'url' => '/credentials', 'verb' => 'GET'], + ['name' => 'Admin#setChannel', 'url' => '/channel', 'verb' => 'POST'], ]]); diff --git a/apps/updatenotification/controller/admincontroller.php b/apps/updatenotification/controller/admincontroller.php index 505ea01edd..cb0c6409d7 100644 --- a/apps/updatenotification/controller/admincontroller.php +++ b/apps/updatenotification/controller/admincontroller.php @@ -21,12 +21,15 @@ namespace OCA\UpdateNotification\Controller; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\IConfig; +use OCP\IDateTimeFormatter; +use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; @@ -39,6 +42,12 @@ class AdminController extends Controller { private $config; /** @var ITimeFactory */ private $timeFactory; + /** @var UpdateChecker */ + private $updateChecker; + /** @var IL10N */ + private $l10n; + /** @var IDateTimeFormatter */ + private $dateTimeFormatter; /** * @param string $appName @@ -47,25 +56,70 @@ class AdminController extends Controller { * @param ISecureRandom $secureRandom * @param IConfig $config * @param ITimeFactory $timeFactory + * @param IL10N $l10n + * @param UpdateChecker $updateChecker + * @param IDateTimeFormatter $dateTimeFormatter */ public function __construct($appName, IRequest $request, IJobList $jobList, ISecureRandom $secureRandom, IConfig $config, - ITimeFactory $timeFactory) { + ITimeFactory $timeFactory, + IL10N $l10n, + UpdateChecker $updateChecker, + IDateTimeFormatter $dateTimeFormatter) { parent::__construct($appName, $request); $this->jobList = $jobList; $this->secureRandom = $secureRandom; $this->config = $config; $this->timeFactory = $timeFactory; + $this->l10n = $l10n; + $this->updateChecker = $updateChecker; + $this->dateTimeFormatter = $dateTimeFormatter; } /** * @return TemplateResponse */ public function displayPanel() { - return new TemplateResponse($this->appName, 'admin', [], ''); + $lastUpdateCheck = $this->dateTimeFormatter->formatDateTime( + $this->config->getAppValue('core', 'lastupdatedat') + ); + + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $params = [ + 'isNewVersionAvailable' => ($this->updateChecker->getUpdateState() === []) ? false : true, + 'lastChecked' => $lastUpdateCheck, + 'currentChannel' => $currentChannel, + 'channels' => $channels, + ]; + + return new TemplateResponse($this->appName, 'admin', $params, ''); + } + + /** + * @UseSession + * + * @param string $channel + * @return DataResponse + */ + public function setChannel($channel) { + \OCP\Util::setChannel($channel); + $this->config->setAppValue('core', 'lastupdatedat', 0); + return new DataResponse(['status' => 'success', 'data' => ['message' => $this->l10n->t('Updated channel')]]); } /** diff --git a/apps/updatenotification/js/admin.js b/apps/updatenotification/js/admin.js index df021fe2e9..2fc8c9d99b 100644 --- a/apps/updatenotification/js/admin.js +++ b/apps/updatenotification/js/admin.js @@ -15,7 +15,7 @@ */ var loginToken = ''; $(document).ready(function(){ - $('#oca_updatenotification').click(function() { + $('#oca_updatenotification_button').click(function() { // Load the new token $.ajax({ url: OC.generateUrl('/apps/updatenotification/credentials') @@ -39,4 +39,16 @@ $(document).ready(function(){ }); }); }); + $('#release-channel').change(function() { + var newChannel = $('#release-channel').find(":selected").val(); + $.post( + OC.generateUrl('/apps/updatenotification/channel'), + { + 'channel': newChannel + }, + function(data){ + OC.msg.finishedAction('#channel_save_msg', data); + } + ); + }); }); diff --git a/apps/updatenotification/templates/admin.php b/apps/updatenotification/templates/admin.php index 647c88dea1..c1adc8d0d3 100644 --- a/apps/updatenotification/templates/admin.php +++ b/apps/updatenotification/templates/admin.php @@ -1,8 +1,42 @@ - -
+ +

t('Updater')); ?>

+ + + t('A new version is available: %s', [$newVersionString])); ?> + + + t('Your version is up to date.')); ?> + + +

- t('For security reasons the built-in ownCloud updater is using additional credentials. To visit the updater page please click the following button.')) ?> + + + +

+

+ t('You can always update to a newer version / experimental channel. But you can never downgrade to a more stable channel.')); ?>

-
diff --git a/apps/updatenotification/tests/controller/AdminControllerTest.php b/apps/updatenotification/tests/controller/AdminControllerTest.php index 5a0f9d2146..50adcd2028 100644 --- a/apps/updatenotification/tests/controller/AdminControllerTest.php +++ b/apps/updatenotification/tests/controller/AdminControllerTest.php @@ -22,11 +22,14 @@ namespace OCA\UpdateNotification\Tests\Controller; use OCA\UpdateNotification\Controller\AdminController; +use OCA\UpdateNotification\UpdateChecker; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\AppFramework\Utility\ITimeFactory; use OCP\BackgroundJob\IJobList; use OCP\IConfig; +use OCP\IDateTimeFormatter; +use OCP\IL10N; use OCP\IRequest; use OCP\Security\ISecureRandom; use Test\TestCase; @@ -44,6 +47,12 @@ class AdminControllerTest extends TestCase { private $adminController; /** @var ITimeFactory */ private $timeFactory; + /** @var IL10N */ + private $l10n; + /** @var UpdateChecker */ + private $updateChecker; + /** @var IDateTimeFormatter */ + private $dateTimeFormatter; public function setUp() { parent::setUp(); @@ -53,6 +62,10 @@ class AdminControllerTest extends TestCase { $this->secureRandom = $this->getMock('\\OCP\\Security\\ISecureRandom'); $this->config = $this->getMock('\\OCP\\IConfig'); $this->timeFactory = $this->getMock('\\OCP\\AppFramework\\Utility\\ITimeFactory'); + $this->l10n = $this->getMock('\\OCP\\IL10N'); + $this->updateChecker = $this->getMockBuilder('\\OCA\\UpdateNotification\\UpdateChecker') + ->disableOriginalConstructor()->getMock(); + $this->dateTimeFormatter = $this->getMock('\\OCP\\IDateTimeFormatter'); $this->adminController = new AdminController( 'updatenotification', @@ -60,15 +73,94 @@ class AdminControllerTest extends TestCase { $this->jobList, $this->secureRandom, $this->config, - $this->timeFactory + $this->timeFactory, + $this->l10n, + $this->updateChecker, + $this->dateTimeFormatter ); } - public function testDisplayPanel() { - $expected = new TemplateResponse('updatenotification', 'admin', [], ''); + public function testDisplayPanelWithUpdate() { + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->willReturn('12345'); + $this->dateTimeFormatter + ->expects($this->once()) + ->method('formatDateTime') + ->with('12345') + ->willReturn('LastCheckedReturnValue'); + $this->updateChecker + ->expects($this->once()) + ->method('getUpdateState') + ->willReturn(['foo' => 'bar']); + + $params = [ + 'isNewVersionAvailable' => true, + 'lastChecked' => 'LastCheckedReturnValue', + 'currentChannel' => \OCP\Util::getChannel(), + 'channels' => $channels, + ]; + + $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); $this->assertEquals($expected, $this->adminController->displayPanel()); } + public function testDisplayPanelWithoutUpdate() { + $channels = [ + 'daily', + 'beta', + 'stable', + 'production', + ]; + $currentChannel = \OCP\Util::getChannel(); + + // Remove the currently used channel from the channels list + if(($key = array_search($currentChannel, $channels)) !== false) { + unset($channels[$key]); + } + + $this->config + ->expects($this->once()) + ->method('getAppValue') + ->with('core', 'lastupdatedat') + ->willReturn('12345'); + $this->dateTimeFormatter + ->expects($this->once()) + ->method('formatDateTime') + ->with('12345') + ->willReturn('LastCheckedReturnValue'); + $this->updateChecker + ->expects($this->once()) + ->method('getUpdateState') + ->willReturn([]); + + $params = [ + 'isNewVersionAvailable' => false, + 'lastChecked' => 'LastCheckedReturnValue', + 'currentChannel' => \OCP\Util::getChannel(), + 'channels' => $channels, + ]; + + $expected = new TemplateResponse('updatenotification', 'admin', $params, ''); + $this->assertEquals($expected, $this->adminController->displayPanel()); + } + + public function testCreateCredentials() { $this->jobList ->expects($this->once())