Skip to content

Commit 10a7a56

Browse files
committed
#RI-4699 - 500 error on connecting to user with -@dangerous rule
1 parent ff85235 commit 10a7a56

File tree

3 files changed

+45
-25
lines changed

3 files changed

+45
-25
lines changed

redisinsight/api/src/constants/error-messages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ export default {
6868
INVALID_WINDOW_ID: 'Invalid window id.',
6969
UNDEFINED_WINDOW_ID: 'Undefined window id.',
7070
LIBRARY_NOT_EXIST: 'This library does not exist.',
71+
NO_PERMISSION_COMMAND_INFO: 'This user has no permissions to run the \'info\' command.',
7172
};

redisinsight/api/src/modules/database/providers/database-info.provider.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,19 @@ describe('DatabaseInfoProvider', () => {
370370
nodes: [mockRedisGeneralInfo, mockRedisGeneralInfo],
371371
});
372372
});
373+
it('should throw an error if no permission to run \'info\' command', async () => {
374+
mockIORedisClient.info.mockRejectedValue({
375+
message: 'NOPERM this user has no permissions to run the \'info\' command'
376+
});
377+
378+
try {
379+
await service.getRedisGeneralInfo(mockIORedisClient);
380+
fail('Should throw an error');
381+
} catch (err) {
382+
expect(err).toBeInstanceOf(ForbiddenException);
383+
expect(err.message).toEqual(ERROR_MESSAGES.NO_PERMISSION_COMMAND_INFO);
384+
}
385+
});
373386
});
374387

375388
describe('getMasterEndpoints', () => {

redisinsight/api/src/modules/database/providers/database-info.provider.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { BadRequestException, Injectable } from '@nestjs/common';
1+
import { BadRequestException, Injectable, ForbiddenException } from '@nestjs/common';
22
import * as IORedis from 'ioredis';
33
import {
44
IRedisClusterInfo,
@@ -216,30 +216,36 @@ export class DatabaseInfoProvider {
216216
private async getRedisNodeGeneralInfo(
217217
client: IORedis.Redis,
218218
): Promise<RedisDatabaseInfoResponse> {
219-
const info = convertRedisInfoReplyToObject(
220-
await client.info(),
221-
);
222-
const serverInfo = info['server'];
223-
const memoryInfo = info['memory'];
224-
const keyspaceInfo = info['keyspace'];
225-
const clientsInfo = info['clients'];
226-
const statsInfo = info['stats'];
227-
const replicationInfo = info['replication'];
228-
const databases = await this.getDatabasesCount(client, keyspaceInfo);
229-
return {
230-
version: serverInfo?.redis_version,
231-
databases,
232-
role: get(replicationInfo, 'role') || undefined,
233-
totalKeys: this.getRedisNodeTotalKeysCount(keyspaceInfo),
234-
usedMemory: parseInt(get(memoryInfo, 'used_memory'), 10) || undefined,
235-
connectedClients:
236-
parseInt(get(clientsInfo, 'connected_clients'), 10) || undefined,
237-
uptimeInSeconds:
238-
parseInt(get(serverInfo, 'uptime_in_seconds'), 10) || undefined,
239-
hitRatio: this.getRedisHitRatio(statsInfo),
240-
cashedScripts: parseInt(get(memoryInfo, 'number_of_cached_scripts'), 10) || undefined,
241-
server: serverInfo,
242-
};
219+
try {
220+
const info = convertRedisInfoReplyToObject(
221+
await client.info(),
222+
);
223+
const serverInfo = info['server'];
224+
const memoryInfo = info['memory'];
225+
const keyspaceInfo = info['keyspace'];
226+
const clientsInfo = info['clients'];
227+
const statsInfo = info['stats'];
228+
const replicationInfo = info['replication'];
229+
const databases = await this.getDatabasesCount(client, keyspaceInfo);
230+
return {
231+
version: serverInfo?.redis_version,
232+
databases,
233+
role: get(replicationInfo, 'role') || undefined,
234+
totalKeys: this.getRedisNodeTotalKeysCount(keyspaceInfo),
235+
usedMemory: parseInt(get(memoryInfo, 'used_memory'), 10) || undefined,
236+
connectedClients:
237+
parseInt(get(clientsInfo, 'connected_clients'), 10) || undefined,
238+
uptimeInSeconds:
239+
parseInt(get(serverInfo, 'uptime_in_seconds'), 10) || undefined,
240+
hitRatio: this.getRedisHitRatio(statsInfo),
241+
cashedScripts: parseInt(get(memoryInfo, 'number_of_cached_scripts'), 10) || undefined,
242+
server: serverInfo,
243+
};
244+
} catch (error) {
245+
if (error.message.includes('NOPERM this user has no permissions to run the \'info\' command')) {
246+
throw new ForbiddenException(ERROR_MESSAGES.NO_PERMISSION_COMMAND_INFO);
247+
}
248+
}
243249
}
244250

245251
private async getRedisMasterNodesGeneralInfo(

0 commit comments

Comments
 (0)