diff options
-rw-r--r-- | lib/private/log/owncloud.php | 9 | ||||
-rw-r--r-- | lib/public/appframework/http/datadownloadresponse.php | 42 | ||||
-rw-r--r-- | settings/admin.php | 13 | ||||
-rw-r--r-- | settings/ajax/getlog.php | 21 | ||||
-rw-r--r-- | settings/ajax/setloglevel.php | 13 | ||||
-rw-r--r-- | settings/application.php | 10 | ||||
-rw-r--r-- | settings/controller/logsettingscontroller.php | 126 | ||||
-rw-r--r-- | settings/js/admin.js | 2 | ||||
-rw-r--r-- | settings/js/log.js | 12 | ||||
-rw-r--r-- | settings/routes.php | 9 | ||||
-rw-r--r-- | settings/templates/admin.php | 12 | ||||
-rw-r--r-- | tests/settings/controller/logsettingscontrollertest.php | 79 |
12 files changed, 297 insertions, 51 deletions
diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php index d257bd12d2a..c8ae61032aa 100644 --- a/lib/private/log/owncloud.php +++ b/lib/private/log/owncloud.php @@ -111,7 +111,7 @@ class OC_Log_Owncloud { $entriesCount = 0; $lines = 0; // Loop through each character of the file looking for new lines - while ($pos >= 0 && $entriesCount < $limit) { + while ($pos >= 0 && ($limit === null ||$entriesCount < $limit)) { fseek($handle, $pos); $ch = fgetc($handle); if ($ch == "\n" || $pos == 0) { @@ -141,4 +141,11 @@ class OC_Log_Owncloud { } return $entries; } + + /** + * @return string + */ + public static function getLogFilePath() { + return self::$logFile; + } } diff --git a/lib/public/appframework/http/datadownloadresponse.php b/lib/public/appframework/http/datadownloadresponse.php new file mode 100644 index 00000000000..326be927b2e --- /dev/null +++ b/lib/public/appframework/http/datadownloadresponse.php @@ -0,0 +1,42 @@ +<?php +/** + * @author Georg Ehrke + * @copyright 2014 Georg Ehrke <georg@ownCloud.com> + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OCP\AppFramework\Http; + +class DataDownloadResponse extends DownloadResponse { + /** + * @var string + */ + private $data; + + /** + * Creates a response that prompts the user to download the text + * @param string $data text to be downloaded + * @param string $filename the name that the downloaded file should have + * @param string $contentType the mimetype that the downloaded file should have + */ + public function __construct($data, $filename, $contentType) { + $this->data = $data; + parent::__construct($filename, $contentType); + } + + /** + * @param string $data + */ + public function setData($data) { + $this->data = $data; + } + + /** + * @return string + */ + public function render() { + return $this->data; + } +} diff --git a/settings/admin.php b/settings/admin.php index 56484f25b26..24ab428b04c 100644 --- a/settings/admin.php +++ b/settings/admin.php @@ -10,8 +10,14 @@ OC_App::setActiveNavigationEntry("admin"); $template = new OC_Template('settings', 'admin', 'user'); -$entries = OC_Log_Owncloud::getEntries(3); -$entriesRemaining = count(OC_Log_Owncloud::getEntries(4)) > 3; +$showLog = (\OC::$server->getConfig()->getSystemValue('log_type', 'owncloud') === 'owncloud'); +$numEntriesToLoad = 3; +$entries = OC_Log_Owncloud::getEntries($numEntriesToLoad + 1); +$entriesRemaining = count($entries) > $numEntriesToLoad; +$entries = array_slice($entries, 0, $numEntriesToLoad); +$logFilePath = OC_Log_Owncloud::getLogFilePath(); +$doesLogFileExist = file_exists($logFilePath); +$logFileSize = filesize($logFilePath); $config = \OC::$server->getConfig(); $appConfig = \OC::$server->getAppConfig(); @@ -31,6 +37,9 @@ $template->assign('mail_smtpname', $config->getSystemValue("mail_smtpname", '')) $template->assign('mail_smtppassword', $config->getSystemValue("mail_smtppassword", '')); $template->assign('entries', $entries); $template->assign('entriesremain', $entriesRemaining); +$template->assign('logFileSize', $logFileSize); +$template->assign('doesLogFileExist', $doesLogFileExist); +$template->assign('showLog', $showLog); $template->assign('readOnlyConfigEnabled', OC_Helper::isReadOnlyConfigEnabled()); $template->assign('isLocaleWorking', OC_Util::isSetLocaleWorking()); $template->assign('isPhpCharSetUtf8', OC_Util::isPhpCharSetUtf8()); diff --git a/settings/ajax/getlog.php b/settings/ajax/getlog.php deleted file mode 100644 index 34c8d3ce467..00000000000 --- a/settings/ajax/getlog.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php -/** - * Copyright (c) 2012, Robin Appelman <icewind1991@gmail.com> - * This file is licensed under the Affero General Public License version 3 or later. - * See the COPYING-README file. - */ - -OC_JSON::checkAdminUser(); - -$count=(isset($_GET['count']))?$_GET['count']:50; -$offset=(isset($_GET['offset']))?$_GET['offset']:0; - -$entries=OC_Log_Owncloud::getEntries($count, $offset); -$data = array(); - -OC_JSON::success( - array( - "data" => $entries, - "remain" => count(OC_Log_Owncloud::getEntries(1, $offset + $count)) !== 0, - ) -); diff --git a/settings/ajax/setloglevel.php b/settings/ajax/setloglevel.php deleted file mode 100644 index 542219f86c6..00000000000 --- a/settings/ajax/setloglevel.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php -/** - * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com> - * This file is licensed under the Affero General Public License version 3 or later. - * See the COPYING-README file. - */ - -OC_Util::checkAdminUser(); -OCP\JSON::callCheck(); - -OC_Config::setValue( 'loglevel', $_POST['level'] ); - -echo 'true'; diff --git a/settings/application.php b/settings/application.php index 74d021c5bf3..070da8024b2 100644 --- a/settings/application.php +++ b/settings/application.php @@ -12,6 +12,7 @@ namespace OC\Settings; use OC\Settings\Controller\AppSettingsController; use OC\Settings\Controller\GroupsController; +use OC\Settings\Controller\LogSettingsController; use OC\Settings\Controller\MailSettingsController; use OC\Settings\Controller\SecuritySettingsController; use OC\Settings\Controller\UsersController; @@ -91,6 +92,15 @@ class Application extends App { $c->query('URLGenerator') ); }); + $container->registerService('LogSettingsController', function(IContainer $c) { + return new LogSettingsController( + $c->query('AppName'), + $c->query('Request'), + $c->query('Config'), + $c->query('L10N'), + $c->query('TimeFactory') + ); + }); /** * Middleware diff --git a/settings/controller/logsettingscontroller.php b/settings/controller/logsettingscontroller.php new file mode 100644 index 00000000000..759b466682c --- /dev/null +++ b/settings/controller/logsettingscontroller.php @@ -0,0 +1,126 @@ +<?php +/** + * @author Georg Ehrke + * @copyright 2014 Georg Ehrke <georg@ownCloud.com> + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\Settings\Controller; + +use OCP\AppFramework\Controller; +use OCP\AppFramework\Http; +use OCP\AppFramework\Http\JSONResponse; +use OCP\AppFramework\Http\DataDownloadResponse; +use OCP\IL10N; +use OCP\AppFramework\Utility\ITimeFactory; +use OCP\IRequest; +use OCP\IConfig; + +/** + * Class LogSettingsController + * + * @package OC\Settings\Controller + */ +class LogSettingsController extends Controller { + /** + * @var \OCP\IConfig + */ + private $config; + + /** + * @var \OCP\IL10N + */ + private $l10n; + + /** + * @var \OCP\ITimeFactory + */ + private $timefactory; + + /** + * @param string $appName + * @param IRequest $request + * @param IConfig $config + */ + public function __construct($appName, + IRequest $request, + IConfig $config, + IL10N $l10n, + ITimeFactory $timeFactory) { + + parent::__construct($appName, $request); + $this->config = $config; + $this->l10n = $l10n; + $this->timefactory = $timeFactory; + } + + /** + * set log level for logger + * + * @param int $level + * @return JSONResponse + */ + public function setLogLevel($level) { + if ($level < 0 || $level > 4) { + return new JSONResponse([ + 'message' => (string) $this->l10n->t('log-level out of allowed range'), + ], Http::STATUS_BAD_REQUEST); + } + + $this->config->setSystemValue('loglevel', $level); + return new JSONResponse([ + 'level' => $level, + ]); + } + + /** + * get log entries from logfile + * + * @param int $count + * @param int $offset + * @return JSONResponse + */ + public function getEntries($count=50, $offset=0) { + return new JSONResponse([ + 'data' => \OC_Log_Owncloud::getEntries($count, $offset), + 'remain' => count(\OC_Log_Owncloud::getEntries(1, $offset + $count)) !== 0, + ]); + } + + /** + * download logfile + * + * @NoCSRFRequired + * + * @return DataDownloadResponse + */ + public function download() { + return new DataDownloadResponse( + json_encode(\OC_Log_Owncloud::getEntries(null, null)), + $this->getFilenameForDownload(), + 'application/json' + ); + } + + /** + * get filename for the logfile that's being downloaded + * + * @param int $timestamp (defaults to time()) + * @return string + */ + private function getFilenameForDownload($timestamp=null) { + $instanceId = $this->config->getSystemValue('instanceid'); + + $filename = implode([ + 'ownCloud', + $instanceId, + (!is_null($timestamp)) ? $timestamp : $this->timefactory->getTime() + ], '-'); + $filename .= '.log'; + + return $filename; + } +} diff --git a/settings/js/admin.js b/settings/js/admin.js index 059e48ebabe..d00d083407f 100644 --- a/settings/js/admin.js +++ b/settings/js/admin.js @@ -34,7 +34,7 @@ $(document).ready(function(){ $('#loglevel').change(function(){ - $.post(OC.filePath('settings','ajax','setloglevel.php'), { level: $(this).val() },function(){ + $.post(OC.generateUrl('/settings/admin/log/level'), {level: $(this).val()},function(){ OC.Log.reload(); } ); }); diff --git a/settings/js/log.js b/settings/js/log.js index 46d1bfefd5f..c3a9a201e83 100644 --- a/settings/js/log.js +++ b/settings/js/log.js @@ -20,14 +20,12 @@ OC.Log = { loaded: 3,//are initially loaded getMore: function (count) { count = count || 10; - $.get(OC.filePath('settings', 'ajax', 'getlog.php'), {offset: OC.Log.loaded, count: count}, function (result) { - if (result.status === 'success') { - OC.Log.addEntries(result.data); - if (!result.remain) { - $('#moreLog').hide(); - } - $('#lessLog').show(); + $.get(OC.generateUrl('/settings/admin/log/entries'), {offset: OC.Log.loaded, count: count}, function (result) { + OC.Log.addEntries(result.data); + if (!result.remain) { + $('#moreLog').hide(); } + $('#lessLog').show(); }); }, showLess: function (count) { diff --git a/settings/routes.php b/settings/routes.php index 4be7785670b..150746665d3 100644 --- a/settings/routes.php +++ b/settings/routes.php @@ -14,7 +14,7 @@ $application->registerRoutes($this, array( 'groups' => array('url' => '/settings/users/groups'), 'users' => array('url' => '/settings/users/users') ), - 'routes' =>array( + 'routes' => array( array('name' => 'MailSettings#setMailSettings', 'url' => '/settings/admin/mailsettings', 'verb' => 'POST'), array('name' => 'MailSettings#storeCredentials', 'url' => '/settings/admin/mailsettings/credentials', 'verb' => 'POST'), array('name' => 'MailSettings#sendTestMail', 'url' => '/settings/admin/mailtest', 'verb' => 'POST'), @@ -24,6 +24,9 @@ $application->registerRoutes($this, array( array('name' => 'SecuritySettings#enforceSSLForSubdomains', 'url' => '/settings/admin/security/ssl/subdomains', 'verb' => 'POST'), array('name' => 'SecuritySettings#trustedDomains', 'url' => '/settings/admin/security/trustedDomains', 'verb' => 'POST'), array('name' => 'Users#setMailAddress', 'url' => '/settings/users/{id}/mailAddress', 'verb' => 'PUT'), + array('name' => 'LogSettings#setLogLevel', 'url' => '/settings/admin/log/level', 'verb' => 'POST'), + array('name' => 'LogSettings#getEntries', 'url' => '/settings/admin/log/entries', 'verb' => 'GET'), + array('name' => 'LogSettings#download', 'url' => '/settings/admin/log/download', 'verb' => 'GET'), ) )); @@ -87,10 +90,6 @@ $this->create('settings_ajax_uninstallapp', '/settings/ajax/uninstallapp.php') $this->create('settings_ajax_navigationdetect', '/settings/ajax/navigationdetect.php') ->actionInclude('settings/ajax/navigationdetect.php'); // admin -$this->create('settings_ajax_getlog', '/settings/ajax/getlog.php') - ->actionInclude('settings/ajax/getlog.php'); -$this->create('settings_ajax_setloglevel', '/settings/ajax/setloglevel.php') - ->actionInclude('settings/ajax/setloglevel.php'); $this->create('settings_ajax_excludegroups', '/settings/ajax/excludegroups.php') ->actionInclude('settings/ajax/excludegroups.php'); $this->create('settings_ajax_checksetup', '/settings/ajax/checksetup') diff --git a/settings/templates/admin.php b/settings/templates/admin.php index d04351c2d6c..dc800271d5c 100644 --- a/settings/templates/admin.php +++ b/settings/templates/admin.php @@ -462,6 +462,7 @@ if ($_['suggestedOverwriteWebroot']) { <option value='<?php p($i)?>' <?php p($selected) ?>><?php p($levelLabels[$i])?></option> <?php endfor;?> </select> +<?php if ($_['showLog'] && $_['doesLogFileExist']): ?> <table id="log" class="grid"> <?php foreach ($_['entries'] as $entry): ?> <tr> @@ -484,11 +485,20 @@ if ($_['suggestedOverwriteWebroot']) { </tr> <?php endforeach;?> </table> + <?php if ($_['logFileSize'] > 0): ?> + <a href="<?php print_unescaped(OC::$server->getURLGenerator()->linkToRoute('settings.LogSettings.download')); ?>" class="button" id="downloadLog"><?php p($l->t('Download logfile'));?></a> + <?php endif; ?> <?php if ($_['entriesremain']): ?> <input id="moreLog" type="button" value="<?php p($l->t('More'));?>..."> <input id="lessLog" type="button" value="<?php p($l->t('Less'));?>..."> <?php endif; ?> - + <?php if ($_['logFileSize'] > (100 * 1024 * 1024)): ?> + <br> + <em> + <?php p($l->t('The logfile is bigger than 100MB. Downloading it may take some time!')); ?> + </em> + <?php endif; ?> + <?php endif; ?> </div> <div class="section"> diff --git a/tests/settings/controller/logsettingscontrollertest.php b/tests/settings/controller/logsettingscontrollertest.php new file mode 100644 index 00000000000..e80acfa75b5 --- /dev/null +++ b/tests/settings/controller/logsettingscontrollertest.php @@ -0,0 +1,79 @@ +<?php +/** + * @author Georg Ehrke + * @copyright 2014 Georg Ehrke <georg@ownCloud.com> + * + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace Test\Settings\Controller; + +use \OC\Settings\Application; + +/** + * @package OC\Settings\Controller + */ +class LogSettingsControllerTest extends \Test\TestCase { + + /** @var \OCP\AppFramework\IAppContainer */ + private $container; + + /** @var LogSettingsController */ + private $logSettingsController; + + protected function setUp() { + $app = new Application(); + $this->container = $app->getContainer(); + $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig') + ->disableOriginalConstructor()->getMock(); + $this->container['AppName'] = 'settings'; + $this->logSettingsController = $this->container['LogSettingsController']; + } + + /** + * @dataProvider logLevelData + */ + public function testSetLogLevel($level, $inRange) { + if ($inRange) { + $this->container['Config'] + ->expects($this->once()) + ->method('setSystemValue') + ->with('loglevel', $level); + } + + $response = $this->logSettingsController->setLogLevel($level)->getData(); + + if ($inRange) { + $expectedResponse = ['level' => $level]; + } else { + $expectedResponse = ['message' => 'log-level out of allowed range']; + } + + $this->assertSame($expectedResponse, $response); + } + + public function logLevelData() { + return [ + [-1, false], + [0, true], + [1, true], + [2, true], + [3, true], + [4, true], + [5, false], + ]; + } + + public function testGetFilenameForDownload() { + $timestamp = 42; + $this->container['Config'] + ->expects($this->once()) + ->method('getSystemValue') + ->with('instanceid') + ->will($this->returnValue('0xF')); + $filename = \Test_Helper::invokePrivate($this->logSettingsController, 'getFilenameForDownload', [$timestamp]); + + $this->assertSame('ownCloud-0xF-42.log', $filename); + } +} |