mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 00:28:26 -05:00
23325c135f
Summary of changes: 1. Rename `redisCommand->name` to `redisCommand->declared_name`, it is a const char * for native commands and SDS for module commands. 2. Store the [sub]command fullname in `redisCommand->fullname` (sds). 3. List subcommands in `ACL CAT` 4. List subcommands in `COMMAND LIST` 5. `moduleUnregisterCommands` now will also free the module subcommands. 6. RM_GetCurrentCommandName returns full command name Other changes: 1. Add `addReplyErrorArity` and `addReplyErrorExpireTime` 2. Remove `getFullCommandName` function that now is useless. 3. Some cleanups about `fullname` since now it is SDS. 4. Delete `populateSingleCommand` function from server.h that is useless. 5. Added tests to cover this change. 6. Add some module unload tests and fix the leaks 7. Make error messages uniform, make sure they always contain the full command name and that it's quoted. 7. Fixes some typos see the history in #9504, fixes #10124 Co-authored-by: Oran Agra <oran@redislabs.com> Co-authored-by: guybe7 <guy.benoish@redislabs.com>
101 lines
3.1 KiB
C
101 lines
3.1 KiB
C
#include "redismodule.h"
|
|
|
|
#define UNUSED(V) ((void) V)
|
|
|
|
// A simple global user
|
|
static RedisModuleUser *global = NULL;
|
|
static long long client_change_delta = 0;
|
|
|
|
void UserChangedCallback(uint64_t client_id, void *privdata) {
|
|
REDISMODULE_NOT_USED(privdata);
|
|
REDISMODULE_NOT_USED(client_id);
|
|
client_change_delta++;
|
|
}
|
|
|
|
int Auth_CreateModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
|
REDISMODULE_NOT_USED(argv);
|
|
REDISMODULE_NOT_USED(argc);
|
|
|
|
if (global) {
|
|
RedisModule_FreeModuleUser(global);
|
|
}
|
|
|
|
global = RedisModule_CreateModuleUser("global");
|
|
RedisModule_SetModuleUserACL(global, "allcommands");
|
|
RedisModule_SetModuleUserACL(global, "allkeys");
|
|
RedisModule_SetModuleUserACL(global, "on");
|
|
|
|
return RedisModule_ReplyWithSimpleString(ctx, "OK");
|
|
}
|
|
|
|
int Auth_AuthModuleUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
|
REDISMODULE_NOT_USED(argv);
|
|
REDISMODULE_NOT_USED(argc);
|
|
uint64_t client_id;
|
|
RedisModule_AuthenticateClientWithUser(ctx, global, UserChangedCallback, NULL, &client_id);
|
|
|
|
return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
|
}
|
|
|
|
int Auth_AuthRealUser(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
|
if (argc != 2) return RedisModule_WrongArity(ctx);
|
|
|
|
size_t length;
|
|
uint64_t client_id;
|
|
|
|
RedisModuleString *user_string = argv[1];
|
|
const char *name = RedisModule_StringPtrLen(user_string, &length);
|
|
|
|
if (RedisModule_AuthenticateClientWithACLUser(ctx, name, length,
|
|
UserChangedCallback, NULL, &client_id) == REDISMODULE_ERR) {
|
|
return RedisModule_ReplyWithError(ctx, "Invalid user");
|
|
}
|
|
|
|
return RedisModule_ReplyWithLongLong(ctx, (uint64_t) client_id);
|
|
}
|
|
|
|
int Auth_ChangeCount(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
|
REDISMODULE_NOT_USED(argv);
|
|
REDISMODULE_NOT_USED(argc);
|
|
long long result = client_change_delta;
|
|
client_change_delta = 0;
|
|
return RedisModule_ReplyWithLongLong(ctx, result);
|
|
}
|
|
|
|
/* This function must be present on each Redis module. It is used in order to
|
|
* register the commands into the Redis server. */
|
|
int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
|
|
REDISMODULE_NOT_USED(argv);
|
|
REDISMODULE_NOT_USED(argc);
|
|
|
|
if (RedisModule_Init(ctx,"testacl",1,REDISMODULE_APIVER_1)
|
|
== REDISMODULE_ERR) return REDISMODULE_ERR;
|
|
|
|
if (RedisModule_CreateCommand(ctx,"auth.authrealuser",
|
|
Auth_AuthRealUser,"no-auth",0,0,0) == REDISMODULE_ERR)
|
|
return REDISMODULE_ERR;
|
|
|
|
if (RedisModule_CreateCommand(ctx,"auth.createmoduleuser",
|
|
Auth_CreateModuleUser,"",0,0,0) == REDISMODULE_ERR)
|
|
return REDISMODULE_ERR;
|
|
|
|
if (RedisModule_CreateCommand(ctx,"auth.authmoduleuser",
|
|
Auth_AuthModuleUser,"no-auth",0,0,0) == REDISMODULE_ERR)
|
|
return REDISMODULE_ERR;
|
|
|
|
if (RedisModule_CreateCommand(ctx,"auth.changecount",
|
|
Auth_ChangeCount,"",0,0,0) == REDISMODULE_ERR)
|
|
return REDISMODULE_ERR;
|
|
|
|
return REDISMODULE_OK;
|
|
}
|
|
|
|
int RedisModule_OnUnload(RedisModuleCtx *ctx) {
|
|
UNUSED(ctx);
|
|
|
|
if (global)
|
|
RedisModule_FreeModuleUser(global);
|
|
|
|
return REDISMODULE_OK;
|
|
}
|