TrafficLimiterTest.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. <?php declare(strict_types=1);
  2. use PHPUnit\Framework\TestCase;
  3. use PrivateBin\Data\Filesystem;
  4. use PrivateBin\Persistence\ServerSalt;
  5. use PrivateBin\Persistence\TrafficLimiter;
  6. class TrafficLimiterTest extends TestCase
  7. {
  8. private $_path;
  9. public function setUp(): void
  10. {
  11. /* Setup Routine */
  12. $this->_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'trafficlimit';
  13. $store = new Filesystem(array('dir' => $this->_path));
  14. ServerSalt::setStore($store);
  15. TrafficLimiter::setStore($store);
  16. }
  17. public function tearDown(): void
  18. {
  19. /* Tear Down Routine */
  20. Helper::rmDir($this->_path . DIRECTORY_SEPARATOR);
  21. }
  22. public function testHtaccess()
  23. {
  24. $htaccess = $this->_path . DIRECTORY_SEPARATOR . '.htaccess';
  25. @unlink($htaccess);
  26. $_SERVER['REMOTE_ADDR'] = 'foobar';
  27. TrafficLimiter::canPass();
  28. $this->assertFileExists($htaccess, 'htaccess recreated');
  29. }
  30. public function testTrafficGetsLimited()
  31. {
  32. TrafficLimiter::setLimit(4);
  33. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  34. $this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
  35. sleep(1);
  36. try {
  37. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  38. } catch (Exception $e) {
  39. $this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'second request is to fast, may not pass');
  40. }
  41. sleep(4);
  42. $this->assertTrue(TrafficLimiter::canPass(), 'third request waited long enough and may pass');
  43. $_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
  44. $this->assertTrue(TrafficLimiter::canPass(), 'fourth request has different ip and may pass');
  45. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  46. try {
  47. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  48. } catch (Exception $e) {
  49. $this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'fifth request is to fast, may not pass');
  50. }
  51. }
  52. public function testTrafficLimitExempted()
  53. {
  54. TrafficLimiter::setExempted('1.2.3.4,10.10.10/24,2001:1620:2057::/48');
  55. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  56. $this->assertTrue(TrafficLimiter::canPass(), 'first request may pass');
  57. try {
  58. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  59. } catch (Exception $e) {
  60. $this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'not exempted');
  61. }
  62. $_SERVER['REMOTE_ADDR'] = '10.10.10.10';
  63. $this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in exempted range');
  64. $this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv4 in exempted range');
  65. $_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
  66. $this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in exempted range');
  67. $this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but IPv6 in exempted range');
  68. TrafficLimiter::setExempted('127.*,foobar');
  69. $this->assertTrue(TrafficLimiter::canPass(), 'first cached request may pass');
  70. try {
  71. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  72. } catch (Exception $e) {
  73. $this->assertEquals($e->getMessage(), 'Please wait 4 seconds between each post.', 'request is too fast, invalid range');
  74. }
  75. $_SERVER['REMOTE_ADDR'] = 'foobar';
  76. $this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
  77. $this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but non-IP address matches exempted range');
  78. }
  79. public function testTrafficLimitCreators()
  80. {
  81. TrafficLimiter::setCreators('1.2.3.4,10.10.10/24,2001:1620:2057::/48');
  82. $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
  83. try {
  84. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  85. } catch (Exception $e) {
  86. $this->assertEquals($e->getMessage(), 'Your IP is not authorized to create documents.', 'not a creator');
  87. }
  88. $_SERVER['REMOTE_ADDR'] = '10.10.10.10';
  89. $this->assertTrue(TrafficLimiter::canPass(), 'IPv4 in creator range');
  90. $this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but IPv4 in creator range');
  91. $_SERVER['REMOTE_ADDR'] = '2001:1620:2057:dead:beef::cafe:babe';
  92. $this->assertTrue(TrafficLimiter::canPass(), 'IPv6 in creator range');
  93. $this->assertTrue(TrafficLimiter::canPass(), 'request is too fast, but IPv6 in creator range');
  94. TrafficLimiter::setCreators('127.*,foobar');
  95. try {
  96. $this->assertFalse(TrafficLimiter::canPass(), 'expected an exception');
  97. } catch (Exception $e) {
  98. $this->assertEquals($e->getMessage(), 'Your IP is not authorized to create documents.', 'request is to fast, not a creator');
  99. }
  100. $_SERVER['REMOTE_ADDR'] = 'foobar';
  101. $this->assertTrue(TrafficLimiter::canPass(), 'non-IP address');
  102. $this->assertTrue(TrafficLimiter::canPass(), 'request is to fast, but non-IP address matches creator');
  103. }
  104. }