Skip to content

Commit

Permalink
feat(admin): Show an error when the admin is throttled
Browse files Browse the repository at this point in the history
Signed-off-by: Joas Schilling <[email protected]>
  • Loading branch information
nickvergessen committed Aug 21, 2023
1 parent 124588d commit bed3ffb
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 0 deletions.
7 changes: 7 additions & 0 deletions apps/settings/lib/Controller/CheckSetupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
use OCP\IURLGenerator;
use OCP\Lock\ILockingProvider;
use OCP\Notification\IManager;
use OCP\Security\Bruteforce\IThrottler;
use OCP\Security\ISecureRandom;
use Psr\Log\LoggerInterface;

Expand Down Expand Up @@ -123,6 +124,8 @@ class CheckSetupController extends Controller {
private $iniGetWrapper;
/** @var IDBConnection */
private $connection;
/** @var IThrottler */
private $throttler;
/** @var ITempManager */
private $tempManager;
/** @var IManager */
Expand All @@ -148,6 +151,7 @@ public function __construct($AppName,
ISecureRandom $secureRandom,
IniGetWrapper $iniGetWrapper,
IDBConnection $connection,
IThrottler $throttler,
ITempManager $tempManager,
IManager $manager,
IAppManager $appManager,
Expand All @@ -162,6 +166,7 @@ public function __construct($AppName,
$this->logger = $logger;
$this->dispatcher = $dispatcher;
$this->db = $db;
$this->throttler = $throttler;
$this->lockingProvider = $lockingProvider;
$this->dateTimeFormatter = $dateTimeFormatter;
$this->memoryInfo = $memoryInfo;
Expand Down Expand Up @@ -920,6 +925,8 @@ public function check() {
'cronInfo' => $this->getLastCronInfo(),
'cronErrors' => $this->getCronErrors(),
'isFairUseOfFreePushService' => $this->isFairUseOfFreePushService(),
'isBruteforceThrottled' => $this->throttler->getAttempts($this->request->getRemoteAddress()) !== 0,
'bruteforceRemoteAddress' => $this->request->getRemoteAddress(),
'serverHasInternetConnectionProblems' => $this->hasInternetConnectivityProblems(),
'isMemcacheConfigured' => $this->isMemcacheConfigured(),
'memcacheDocs' => $this->urlGenerator->linkToDocs('admin-performance'),
Expand Down
8 changes: 8 additions & 0 deletions apps/settings/tests/Controller/CheckSetupControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
use OCP\IURLGenerator;
use OCP\Lock\ILockingProvider;
use OCP\Notification\IManager;
use OCP\Security\Bruteforce\IThrottler;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -143,6 +144,7 @@ protected function setUp(): void {
$this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
$this->db = $this->getMockBuilder(Connection::class)
->disableOriginalConstructor()->getMock();
$this->throttler = $this->createMock(IThrottler::class);
$this->lockingProvider = $this->getMockBuilder(ILockingProvider::class)->getMock();
$this->dateTimeFormatter = $this->getMockBuilder(IDateTimeFormatter::class)->getMock();
$this->memoryInfo = $this->getMockBuilder(MemoryInfo::class)
Expand Down Expand Up @@ -174,6 +176,7 @@ protected function setUp(): void {
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
$this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
Expand Down Expand Up @@ -659,6 +662,8 @@ public function testCheck() {
'isFairUseOfFreePushService' => false,
'temporaryDirectoryWritable' => false,
\OCA\Settings\SetupChecks\LdapInvalidUuids::class => ['pass' => true, 'description' => 'Invalid UUIDs of LDAP users or groups have been found. Please review your "Override UUID detection" settings in the Expert part of the LDAP configuration and use "occ ldap:update-uuid" to update them.', 'severity' => 'warning'],
'isBruteforceThrottled' => false,
'bruteforceRemoteAddress' => '',
]
);
$this->assertEquals($expected, $this->checkSetupController->check());
Expand All @@ -683,6 +688,7 @@ public function testGetCurlVersion() {
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
$this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
Expand Down Expand Up @@ -1410,6 +1416,7 @@ public function testIsMysqlUsedWithoutUTF8MB4(string $db, bool $useUTF8MB4, bool
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
$this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
Expand Down Expand Up @@ -1464,6 +1471,7 @@ public function testIsEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed(string $m
$this->secureRandom,
$this->iniGetWrapper,
$this->connection,
$this->throttler,
$this->tempManager,
$this->notificationManager,
$this->appManager,
Expand Down
8 changes: 8 additions & 0 deletions core/js/setupchecks.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@
type: OC.SetupChecks.MESSAGE_TYPE_INFO
});
}
if (data.isBruteforceThrottled) {
messages.push({
msg: t('core', 'Your remote address was identified as "{remoteAddress}" and is bruteforce throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly. Further information can be found in the {linkstart}documentation ↗{linkend}.', { remoteAddress: data.bruteforceRemoteAddress })
.replace('{linkstart}', '<a target="_blank" rel="noreferrer noopener" class="external" href="' + data.reverseProxyDocs + '">')
.replace('{linkend}', '</a>'),
type: OC.SetupChecks.MESSAGE_TYPE_ERROR
});
}
if(!data.hasWorkingFileLocking) {
messages.push({
msg: t('core', 'Transactional file locking is disabled, this might lead to issues with race conditions. Enable "filelocking.enabled" in config.php to avoid these problems. See the {linkstart}documentation ↗{linkend} for more information.')
Expand Down
61 changes: 61 additions & 0 deletions core/js/tests/specs/setupchecksSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,67 @@ describe('OC.SetupChecks tests', function() {
});
});

it('should return an error if the admin IP is bruteforce throttled', function(done) {
var async = OC.SetupChecks.checkSetup();

suite.server.requests[0].respond(
200,
{
'Content-Type': 'application/json',
},
JSON.stringify({
hasFileinfoInstalled: true,
isGetenvServerWorking: true,
isReadOnlyConfig: false,
wasEmailTestSuccessful: true,
hasWorkingFileLocking: true,
hasDBFileLocking: false,
hasValidTransactionIsolationLevel: true,
suggestedOverwriteCliURL: '',
isRandomnessSecure: true,
isFairUseOfFreePushService: true,
isBruteforceThrottled: true,
bruteforceRemoteAddress: '::1',
serverHasInternetConnectionProblems: false,
isMemcacheConfigured: true,
forwardedForHeadersWorking: true,
reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html',
isCorrectMemcachedPHPModuleInstalled: true,
hasPassedCodeIntegrityCheck: true,
OpcacheSetupRecommendations: [],
isSettimelimitAvailable: true,
hasFreeTypeSupport: true,
missingIndexes: [],
missingPrimaryKeys: [],
missingColumns: [],
cronErrors: [],
cronInfo: {
diffInSeconds: 0
},
isMemoryLimitSufficient: true,
appDirsWithDifferentOwner: [],
isImagickEnabled: true,
areWebauthnExtensionsEnabled: true,
is64bit: true,
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
temporaryDirectoryWritable: true,
})
);

async.done(function( data, s, x ){
expect(data).toEqual([{
msg: 'Your remote address was identified as "::1" and is bruteforce throttled at the moment slowing down the performance of various requests. If the remote address is not your address this can be an indication that a proxy is not configured correctly. Further information can be found in the <a target="_blank" rel="noreferrer noopener" class="external" href="https://docs.nextcloud.com/foo/bar.html">documentation ↗</a>.',
type: OC.SetupChecks.MESSAGE_TYPE_ERROR
}]);
done();
});
});

it('should return an error if set_time_limit is unavailable', function(done) {
var async = OC.SetupChecks.checkSetup();

Expand Down

0 comments on commit bed3ffb

Please sign in to comment.