summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/tests/modules/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/tests/modules/auth.c')
-rw-r--r--examples/redis-unstable/tests/modules/auth.c286
1 files changed, 0 insertions, 286 deletions
diff --git a/examples/redis-unstable/tests/modules/auth.c b/examples/redis-unstable/tests/modules/auth.c
deleted file mode 100644
index cc2378e..0000000
--- a/examples/redis-unstable/tests/modules/auth.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* define macros for having usleep */
-#define _BSD_SOURCE
-#define _DEFAULT_SOURCE
-
-#include "redismodule.h"
-
-#include <string.h>
-#include <unistd.h>
-#include <pthread.h>
-
-#define UNUSED(V) ((void) V)
-
-// A simple global user
-static RedisModuleUser *global = NULL;
-static long long client_change_delta = 0;
-static pthread_t tid;
-
-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);
-}
-
-/* This command redacts every other arguments and returns OK */
-int Auth_RedactedAPI(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
- REDISMODULE_NOT_USED(argv);
- for(int i = argc - 1; i > 0; i -= 2) {
- int result = RedisModule_RedactClientCommandArgument(ctx, i);
- RedisModule_Assert(result == REDISMODULE_OK);
- }
- return RedisModule_ReplyWithSimpleString(ctx, "OK");
-}
-
-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);
-}
-
-/* The Module functionality below validates that module authentication callbacks can be registered
- * to support both non-blocking and blocking module based authentication. */
-
-/* Non Blocking Module Auth callback / implementation. */
-int auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
- const char *user = RedisModule_StringPtrLen(username, NULL);
- const char *pwd = RedisModule_StringPtrLen(password, NULL);
- if (!strcmp(user,"foo") && !strcmp(pwd,"allow")) {
- RedisModule_AuthenticateClientWithACLUser(ctx, "foo", 3, NULL, NULL, NULL);
- return REDISMODULE_AUTH_HANDLED;
- }
- else if (!strcmp(user,"foo") && !strcmp(pwd,"deny")) {
- RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
- RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
- RedisModule_FreeString(ctx, log);
- const char *err_msg = "Auth denied by Misc Module.";
- *err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
- return REDISMODULE_AUTH_HANDLED;
- }
- return REDISMODULE_AUTH_NOT_HANDLED;
-}
-
-int test_rm_register_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
- REDISMODULE_NOT_USED(argv);
- REDISMODULE_NOT_USED(argc);
- RedisModule_RegisterAuthCallback(ctx, auth_cb);
- RedisModule_ReplyWithSimpleString(ctx, "OK");
- return REDISMODULE_OK;
-}
-
-/*
- * The thread entry point that actually executes the blocking part of the AUTH command.
- * This function sleeps for 0.5 seconds and then unblocks the client which will later call
- * `AuthBlock_Reply`.
- * `arg` is expected to contain the RedisModuleBlockedClient, username, and password.
- */
-void *AuthBlock_ThreadMain(void *arg) {
- usleep(500000);
- void **targ = arg;
- RedisModuleBlockedClient *bc = targ[0];
- int result = 2;
- const char *user = RedisModule_StringPtrLen(targ[1], NULL);
- const char *pwd = RedisModule_StringPtrLen(targ[2], NULL);
- if (!strcmp(user,"foo") && !strcmp(pwd,"block_allow")) {
- result = 1;
- }
- else if (!strcmp(user,"foo") && !strcmp(pwd,"block_deny")) {
- result = 0;
- }
- else if (!strcmp(user,"foo") && !strcmp(pwd,"block_abort")) {
- RedisModule_BlockedClientMeasureTimeEnd(bc);
- RedisModule_AbortBlock(bc);
- goto cleanup;
- }
- /* Provide the result to the blocking reply cb. */
- void **replyarg = RedisModule_Alloc(sizeof(void*));
- replyarg[0] = (void *) (uintptr_t) result;
- RedisModule_BlockedClientMeasureTimeEnd(bc);
- RedisModule_UnblockClient(bc, replyarg);
-cleanup:
- /* Free the username and password and thread / arg data. */
- RedisModule_FreeString(NULL, targ[1]);
- RedisModule_FreeString(NULL, targ[2]);
- RedisModule_Free(targ);
- return NULL;
-}
-
-/*
- * Reply callback for a blocking AUTH command. This is called when the client is unblocked.
- */
-int AuthBlock_Reply(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
- REDISMODULE_NOT_USED(password);
- void **targ = RedisModule_GetBlockedClientPrivateData(ctx);
- int result = (uintptr_t) targ[0];
- size_t userlen = 0;
- const char *user = RedisModule_StringPtrLen(username, &userlen);
- /* Handle the success case by authenticating. */
- if (result == 1) {
- RedisModule_AuthenticateClientWithACLUser(ctx, user, userlen, NULL, NULL, NULL);
- return REDISMODULE_AUTH_HANDLED;
- }
- /* Handle the Error case by denying auth */
- else if (result == 0) {
- RedisModuleString *log = RedisModule_CreateString(ctx, "Module Auth", 11);
- RedisModule_ACLAddLogEntryByUserName(ctx, username, log, REDISMODULE_ACL_LOG_AUTH);
- RedisModule_FreeString(ctx, log);
- const char *err_msg = "Auth denied by Misc Module.";
- *err = RedisModule_CreateString(ctx, err_msg, strlen(err_msg));
- return REDISMODULE_AUTH_HANDLED;
- }
- /* "Skip" Authentication */
- return REDISMODULE_AUTH_NOT_HANDLED;
-}
-
-/* Private data freeing callback for Module Auth. */
-void AuthBlock_FreeData(RedisModuleCtx *ctx, void *privdata) {
- REDISMODULE_NOT_USED(ctx);
- RedisModule_Free(privdata);
-}
-
-/* Callback triggered when the engine attempts module auth
- * Return code here is one of the following: Auth succeeded, Auth denied,
- * Auth not handled, Auth blocked.
- * The Module can have auth succeed / denied here itself, but this is an example
- * of blocking module auth.
- */
-int blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString *username, RedisModuleString *password, RedisModuleString **err) {
- REDISMODULE_NOT_USED(username);
- REDISMODULE_NOT_USED(password);
- REDISMODULE_NOT_USED(err);
- /* Block the client from the Module. */
- RedisModuleBlockedClient *bc = RedisModule_BlockClientOnAuth(ctx, AuthBlock_Reply, AuthBlock_FreeData);
- int ctx_flags = RedisModule_GetContextFlags(ctx);
- if (ctx_flags & REDISMODULE_CTX_FLAGS_MULTI || ctx_flags & REDISMODULE_CTX_FLAGS_LUA) {
- /* Clean up by using RedisModule_UnblockClient since we attempted blocking the client. */
- RedisModule_UnblockClient(bc, NULL);
- return REDISMODULE_AUTH_HANDLED;
- }
-
- /* Another blocking auth cb may have spawned a thread, we'll just wait for it
- * to finish here */
- if (tid) pthread_join(tid, NULL);
-
- RedisModule_BlockedClientMeasureTimeStart(bc);
-
- /* Allocate memory for information needed. */
- void **targ = RedisModule_Alloc(sizeof(void*)*3);
- targ[0] = bc;
- targ[1] = RedisModule_CreateStringFromString(NULL, username);
- targ[2] = RedisModule_CreateStringFromString(NULL, password);
-
- /* Create bg thread and pass the blockedclient, username and password to it. */
- if (pthread_create(&tid, NULL, AuthBlock_ThreadMain, targ) != 0) {
- RedisModule_AbortBlock(bc);
-
- /* These are freed in AuthBlock_ThreadMain but since we failed to spawn
- * the thread need to free them here. */
- RedisModule_FreeString(NULL, targ[1]);
- RedisModule_FreeString(NULL, targ[2]);
- RedisModule_Free(targ);
- }
-
- return REDISMODULE_AUTH_HANDLED;
-}
-
-int test_rm_register_blocking_auth_cb(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
- REDISMODULE_NOT_USED(argv);
- REDISMODULE_NOT_USED(argc);
- RedisModule_RegisterAuthCallback(ctx, blocking_auth_cb);
- RedisModule_ReplyWithSimpleString(ctx, "OK");
- return REDISMODULE_OK;
-}
-
-/* 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;
-
- if (RedisModule_CreateCommand(ctx,"auth.redact",
- Auth_RedactedAPI,"",0,0,0) == REDISMODULE_ERR)
- return REDISMODULE_ERR;
-
- if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_auth_cb",
- test_rm_register_auth_cb,"",0,0,0) == REDISMODULE_ERR)
- return REDISMODULE_ERR;
-
- if (RedisModule_CreateCommand(ctx,"testmoduleone.rm_register_blocking_auth_cb",
- test_rm_register_blocking_auth_cb,"",0,0,0) == REDISMODULE_ERR)
- return REDISMODULE_ERR;
-
- return REDISMODULE_OK;
-}
-
-int RedisModule_OnUnload(RedisModuleCtx *ctx) {
- UNUSED(ctx);
-
- if (tid) pthread_join(tid, NULL);
-
- if (global)
- RedisModule_FreeModuleUser(global);
-
- return REDISMODULE_OK;
-}