Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'username' auth option to Redis driver #413

Merged
merged 1 commit into from
May 28, 2022

Conversation

okiedork
Copy link
Contributor

This PR implements an additional option username to be used with Redis clusters that have ACL rules (Redis 6+) with non-default users.

I have changed the auth method parameters to use associative arrays, because I thought it would be less confusing to someone reading the code. More info on parameter styles here.

How I tested it:

  • Start a Redis container without authentication enabled.

    • Try to connect and get something, without setting username or password.
    • Result: "cache miss" (OK).
    • Try to connect and get something, setting only the password option.
    • Result:Fatal error: Uncaught RedisException: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct? in /usr/src/src/Stash/Driver/Redis.php:137 (followed by a stack trace).
      • Observation: this is already the default behavior of this library.
    • Try to connect and get something, setting username and password.
    • Result: Fatal error: Uncaught RedisException: WRONGPASS invalid username-password pair or user is disabled. in /usr/src/src/Stash/Driver/Redis.php:133 (followed by a stack trace).
  • Start a Redis container and change the authentication password for the default user.

    • Use this command: ACL SETUSER default >somepassword
    • Try to connect and get something, without setting username or password.
    • Result: Caught exception: NOAUTH Authentication required. (I used a try-catch block of code).
    • Try to connect and get something, setting only the password option.
    • Result: "cache miss" (OK).
    • Try to connect and get something, setting username and password.
    • Result: Fatal error: Uncaught RedisException: WRONGPASS invalid username-password pair or user is disabled. in /usr/src/src/Stash/Driver/Redis.php:133 (followed by a stack trace).
  • Start a Redis container and create a new user, disabling the default user.

    • Use the commands:
      • ACL SETUSER default off
      • ACL SETUSER someuser on allkeys allcommands allchannels >somepasshere
    • Try to connect and get something, without setting username or password.
    • Result: Caught exception: NOAUTH Authentication required. (I used a try-catch block of code).
    • Try to connect and get something, setting only the password option.
    • Result: Fatal error: Uncaught RedisException: ERR AUTH <password> called without any password configured for the default user. Are you sure your configuration is correct? in /usr/src/src/Stash/Driver/Redis.php:137 (followed by a stack trace).
    • Try to connect and get something, setting username and password options.
    • Result: "cache miss" (OK).

Closes #412

@okiedork
Copy link
Contributor Author

Adding here the code I've used to to do the tests. Redis on port 6379 is the server without authentication. Redis on port 6380 is the server with authentication. Containers were restarted before each test to avoid problems with ACL misconfiguration.

<?php

require __DIR__ . '/autoload.php';
require __DIR__ .'/vendor/autoload.php';

$driver_nopass = new Stash\Driver\Redis(
    [
        'servers' => [
            [
              'server'   => '172.17.0.1',
              'port'     => 6379
            ]
        ]
    ]
);

$driver_yespass = new Stash\Driver\Redis(
    [
        'servers' => [
            [
              'server'   => '172.17.0.1',
              'port'     => 6380
            ]
        ],
        'password' => 'somepasshere',
        'username' => 'someuser'
    ]
);

$pool_nopass = new Stash\Pool($driver_nopass);
$pool_yespass = new Stash\Pool($driver_yespass);

try {
    $item = $pool_nopass->getItem('/someitem');

    if($item->isHit()) {
       echo "Cache hit.\n";
    } else {
       echo "Cache miss.\n";
    }
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
}

try {
    $item = $pool_yespass->getItem('/someitem');

    if($item->isHit()) {
       echo "Cache hit.\n";
    } else {
       echo "Cache miss.\n";
    }
} catch (Exception $e) {
    echo 'Caught exception: ', $e->getMessage(), "\n";
}

@tedivm tedivm merged commit e6d5534 into tedious:main May 28, 2022
@tedivm
Copy link
Member

tedivm commented May 28, 2022

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Redis] Option to authenticate using name and password
2 participants