Skip to content

Commit

Permalink
Merge pull request #27443 from owncloud/separate-audit-logs-sharidas
Browse files Browse the repository at this point in the history
Separate audit logs from server logs.
  • Loading branch information
Vincent Petry authored Mar 24, 2017
2 parents 5ad0466 + a50b8db commit 6f8bfca
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 29 deletions.
20 changes: 16 additions & 4 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -602,13 +602,25 @@
* this condition is met
* - ``apps``: if the log message is invoked by one of the specified apps,
* this condition is met
* - ``logfile``: the log message invoked by the specified apps get redirected to
* this logfile, this condition is met
* Note: Not applicapable when using syslog.
*
* Defaults to an empty array.
*/
'log.condition' => [
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['sample-user'],
'apps' => ['files'],
'log.conditions' => [
[
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['user1'],
'apps' => ['files_texteditor'],
'logfile' => '/tmp/test.log'
],
[
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['user1'],
'apps' => ['gallery'],
'logfile' => '/tmp/gallery.log'
],
],

/**
Expand Down
59 changes: 37 additions & 22 deletions lib/private/Log.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,11 @@ public function debug($message, array $context = []) {
*/
public function log($level, $message, array $context = []) {
$minLevel = min($this->config->getValue('loglevel', Util::WARN), Util::FATAL);
$logCondition = $this->config->getValue('log.condition', []);
$logConditions = $this->config->getValue('log.conditions', []);
if (empty($logConditions)) {
$logConditions[] = $this->config->getValue('log.condition', []);
}
$logConditionFile = null;

array_walk($context, [$this->normalizer, 'format']);

Expand All @@ -241,10 +245,17 @@ public function log($level, $message, array $context = []) {
* check log condition based on the context of each log message
* once this is met -> change the required log level to debug
*/
if(!empty($logCondition)
&& isset($logCondition['apps'])
&& in_array($app, $logCondition['apps'], true)) {
$minLevel = Util::DEBUG;
if(!empty($logConditions)) {
foreach ($logConditions as $logCondition) {
if(!empty($logCondition['apps'])
&& in_array($app, $logCondition['apps'], true)) {
$minLevel = Util::DEBUG;
if (!empty($logCondition['logfile'])) {
$logConditionFile = $logCondition['logfile'];
break;
}
}
}
}

} else {
Expand All @@ -266,25 +277,29 @@ public function log($level, $message, array $context = []) {
if($this->logConditionSatisfied === null) {
// default to false to just process this once per request
$this->logConditionSatisfied = false;
if(!empty($logCondition)) {

// check for secret token in the request
if(isset($logCondition['shared_secret'])) {
$request = \OC::$server->getRequest();

// if token is found in the request change set the log condition to satisfied
if($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) {
$this->logConditionSatisfied = true;
if(!empty($logConditions)) {
foreach ($logConditions as $logCondition) {

// check for secret token in the request
if (!empty($logCondition['shared_secret'])) {
$request = \OC::$server->getRequest();

// if token is found in the request change set the log condition to satisfied
if ($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) {
$this->logConditionSatisfied = true;
break;
}
}
}

// check for user
if(isset($logCondition['users'])) {
$user = \OC::$server->getUserSession()->getUser();
// check for user
if (!empty($logCondition['users'])) {
$user = \OC::$server->getUserSession()->getUser();

// if the user matches set the log condition to satisfied
if($user !== null && in_array($user->getUID(), $logCondition['users'], true)) {
$this->logConditionSatisfied = true;
// if the user matches set the log condition to satisfied
if ($user !== null && in_array($user->getUID(), $logCondition['users'], true)) {
$this->logConditionSatisfied = true;
break;
}
}
}
}
Expand All @@ -297,7 +312,7 @@ public function log($level, $message, array $context = []) {

if ($level >= $minLevel) {
$logger = $this->logger;
call_user_func([$logger, 'write'], $app, $message, $level);
call_user_func([$logger, 'write'], $app, $message, $level, $logConditionFile);
}
}

Expand Down
12 changes: 9 additions & 3 deletions lib/private/Log/Owncloud.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ public static function init() {
* @param string $app
* @param string $message
* @param int $level
* @param string conditionalLogFile
*/
public static function write($app, $message, $level) {
public static function write($app, $message, $level, $conditionalLogFile = null) {
$config = \OC::$server->getSystemConfig();

// default to ISO8601
Expand Down Expand Up @@ -110,8 +111,13 @@ public static function write($app, $message, $level) {
'user'
);
$entry = json_encode($entry);
$handle = @fopen(self::$logFile, 'a');
@chmod(self::$logFile, 0640);
if (!is_null($conditionalLogFile)) {
$handle = @fopen($conditionalLogFile, 'a');
@chmod($conditionalLogFile, 0640);
} else {
$handle = @fopen(self::$logFile, 'a');
@chmod(self::$logFile, 0640);
}
if ($handle) {
fwrite($handle, $entry."\n");
fclose($handle);
Expand Down
18 changes: 18 additions & 0 deletions tests/lib/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,24 @@ public function testAppCondition() {
$this->assertEquals($expected, $this->getLogs());
}

public function testAppLogCondition() {
$this->config->expects($this->any())
->method('getValue')
->will(($this->returnValueMap([
['loglevel', Util::WARN, Util::WARN],
['log.conditions', [], [['apps' => ['files'], 'logfile' => '/tmp/test.log']]]
])));
$logger = $this->logger;

$logger->info('Don\'t display info messages');
$logger->info('Show info messages of files app', ['app' => 'files']);

$expected = [
'1 Show info messages of files app',
];
$this->assertEquals($expected, $this->getLogs());
}

private function getLogs() {
return self::$logs;
}
Expand Down

0 comments on commit 6f8bfca

Please sign in to comment.