LoggerTest.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <?php
  2. /**
  3. * Copyright (c) 2014 Thomas Müller <thomas.mueller@tmit.eu>
  4. * This file is licensed under the Affero General Public License version 3 or
  5. * later.
  6. * See the COPYING-README file.
  7. */
  8. namespace Test;
  9. use OC\Log;
  10. class LoggerTest extends TestCase {
  11. /** @var \OC\SystemConfig|\PHPUnit_Framework_MockObject_MockObject */
  12. private $config;
  13. /** @var \OCP\Support\CrashReport\IRegistry|\PHPUnit_Framework_MockObject_MockObject */
  14. private $registry;
  15. /** @var \OCP\ILogger */
  16. private $logger;
  17. /** @var array */
  18. static private $logs = array();
  19. protected function setUp() {
  20. parent::setUp();
  21. self::$logs = array();
  22. $this->config = $this->createMock(\OC\SystemConfig::class);
  23. $this->registry = $this->createMock(\OCP\Support\CrashReport\IRegistry::class);
  24. $this->logger = new Log('Test\LoggerTest', $this->config, null, $this->registry);
  25. }
  26. public function testInterpolation() {
  27. $logger = $this->logger;
  28. $logger->warning('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
  29. $expected = array('2 {Message {nothing} Bob Bar a}');
  30. $this->assertEquals($expected, $this->getLogs());
  31. }
  32. public function testAppCondition() {
  33. $this->config->expects($this->any())
  34. ->method('getValue')
  35. ->will(($this->returnValueMap([
  36. ['loglevel', \OCP\Util::WARN, \OCP\Util::WARN],
  37. ['log.condition', [], ['apps' => ['files']]]
  38. ])));
  39. $logger = $this->logger;
  40. $logger->info('Don\'t display info messages');
  41. $logger->info('Show info messages of files app', ['app' => 'files']);
  42. $logger->warning('Show warning messages of other apps');
  43. $expected = [
  44. '1 Show info messages of files app',
  45. '2 Show warning messages of other apps',
  46. ];
  47. $this->assertEquals($expected, $this->getLogs());
  48. }
  49. private function getLogs() {
  50. return self::$logs;
  51. }
  52. public static function write($app, $message, $level) {
  53. self::$logs[]= "$level $message";
  54. }
  55. public function userAndPasswordData() {
  56. return [
  57. ['abc', 'def'],
  58. ['mySpecialUsername', 'MySuperSecretPassword'],
  59. ['my-user', '324324()#ä234'],
  60. ['my-user', ')qwer'],
  61. ['my-user', 'qwer)asdf'],
  62. ['my-user', 'qwer)'],
  63. ['my-user', '(qwer'],
  64. ['my-user', 'qwer(asdf'],
  65. ['my-user', 'qwer('],
  66. ];
  67. }
  68. /**
  69. * @dataProvider userAndPasswordData
  70. */
  71. public function testDetectlogin($user, $password) {
  72. $e = new \Exception('test');
  73. $this->registry->expects($this->once())
  74. ->method('delegateReport')
  75. ->with($e, ['level' => 3]);
  76. $this->logger->logException($e);
  77. $logLines = $this->getLogs();
  78. foreach($logLines as $logLine) {
  79. if (is_array($logLine)) {
  80. $logLine = json_encode($logLine);
  81. }
  82. $this->assertNotContains($user, $logLine);
  83. $this->assertNotContains($password, $logLine);
  84. $this->assertContains('*** sensitive parameters replaced ***', $logLine);
  85. }
  86. }
  87. /**
  88. * @dataProvider userAndPasswordData
  89. */
  90. public function testDetectcheckPassword($user, $password) {
  91. $e = new \Exception('test');
  92. $this->registry->expects($this->once())
  93. ->method('delegateReport')
  94. ->with($e, ['level' => 3]);
  95. $this->logger->logException($e);
  96. $logLines = $this->getLogs();
  97. foreach($logLines as $logLine) {
  98. if (is_array($logLine)) {
  99. $logLine = json_encode($logLine);
  100. }
  101. $this->assertNotContains($user, $logLine);
  102. $this->assertNotContains($password, $logLine);
  103. $this->assertContains('*** sensitive parameters replaced ***', $logLine);
  104. }
  105. }
  106. /**
  107. * @dataProvider userAndPasswordData
  108. */
  109. public function testDetectvalidateUserPass($user, $password) {
  110. $e = new \Exception('test');
  111. $this->registry->expects($this->once())
  112. ->method('delegateReport')
  113. ->with($e, ['level' => 3]);
  114. $this->logger->logException($e);
  115. $logLines = $this->getLogs();
  116. foreach($logLines as $logLine) {
  117. if (is_array($logLine)) {
  118. $logLine = json_encode($logLine);
  119. }
  120. $this->assertNotContains($user, $logLine);
  121. $this->assertNotContains($password, $logLine);
  122. $this->assertContains('*** sensitive parameters replaced ***', $logLine);
  123. }
  124. }
  125. /**
  126. * @dataProvider userAndPasswordData
  127. */
  128. public function testDetecttryLogin($user, $password) {
  129. $e = new \Exception('test');
  130. $this->registry->expects($this->once())
  131. ->method('delegateReport')
  132. ->with($e, ['level' => 3]);
  133. $this->logger->logException($e);
  134. $logLines = $this->getLogs();
  135. foreach($logLines as $logLine) {
  136. if (is_array($logLine)) {
  137. $logLine = json_encode($logLine);
  138. }
  139. $this->assertNotContains($user, $logLine);
  140. $this->assertNotContains($password, $logLine);
  141. $this->assertContains('*** sensitive parameters replaced ***', $logLine);
  142. }
  143. }
  144. /**
  145. * @dataProvider userAndPasswordData
  146. */
  147. public function testDetectclosure($user, $password) {
  148. $a = function($user, $password) {
  149. throw new \Exception('test');
  150. };
  151. $this->registry->expects($this->once())
  152. ->method('delegateReport');
  153. try {
  154. $a($user, $password);
  155. } catch (\Exception $e) {
  156. $this->logger->logException($e);
  157. }
  158. $logLines = $this->getLogs();
  159. foreach($logLines as $logLine) {
  160. if (is_array($logLine)) {
  161. $logLine = json_encode($logLine);
  162. }
  163. $log = explode('\n', $logLine);
  164. unset($log[1]); // Remove `testDetectclosure(` because we are not testing this here, but the closure on stack trace 0
  165. $logLine = implode('\n', $log);
  166. $this->assertNotContains($user, $logLine);
  167. $this->assertNotContains($password, $logLine);
  168. $this->assertContains('*** sensitive parameters replaced ***', $logLine);
  169. }
  170. }
  171. public function dataGetLogClass() {
  172. return [
  173. ['file', \OC\Log\File::class],
  174. ['errorlog', \OC\Log\Errorlog::class],
  175. ['syslog', \OC\Log\Syslog::class],
  176. ['owncloud', \OC\Log\File::class],
  177. ['nextcloud', \OC\Log\File::class],
  178. ['foobar', \OC\Log\File::class],
  179. ];
  180. }
  181. /**
  182. * @dataProvider dataGetLogClass
  183. */
  184. public function testGetLogClass($type, $class) {
  185. $this->assertEquals($class, Log::getLogClass($type));
  186. }
  187. }