Permissions issue writing to redis
Redis is running on an external service (AWS) and I'm having trouble configuring cacheops to talk to it without getting this error:
redis.exceptions.NoPermissionError: this user has no permissions to access one of the keys used as arguments
I had no trouble setting up Django's main cache to use my prefix:
CACHES = {
"default": {
...
"KEY_PREFIX": config.REDIS_PREFIX, # loaded from an env var
...
}
}
# Then from a Django shell:
from django.core.cache import cache
cache.set("foo", "bar")
cache.get("foo")
'bar'
I'm having trouble wiring up cacheops to work the same way. Docs say we cannot use a simple string, but must reference a function or lambda:
CACHEOPS_PREFIX = lambda query: ...
# or
CACHEOPS_PREFIX = 'some.module.cacheops_prefix'
So, two questions:
-
Why can't we use a simple string here? I'm not following the point of requiring a lambda or function to set this var, when a string works fine for the main Django cache settings.
-
Even when I do set it up as a callable, still get the permissions error.
If I don't create the setting CACHEOPS_PREFIX , I get the permissions error. If I do set it, I get the permissions error.
def get_cacheops_prefix():
return config.REDIS_PREFIX
# Neither of these work
#CACHEOPS_PREFIX = "myapp.settings.get_cacheops_prefix"
#CACHEOPS_PREFIX = lambda query: get_cacheops_prefix()
Since Django's main cache works fine, it feels like the Permissions error is red herring or mistake in my configuration, but I can't see what. Maybe this isn't about the prefix? But if not that, then what? Thanks for a clue.
Django cache does not support callable prefix, so it's just string, here things are different.
CACHEOPS_PREFIX = lambda _: "your_prefix"
Should work. If not then need to look at particular key you get permission error on.
I dug into this a bit more and found the issue. If you are using Redis' ACL to restrict a user to a specific key namespace, you can replicate the problem. In Redis add a user like this:
ACL SETUSER user on nopass ~user/* +@all
Now set CACHEOPS_PREFIX = lambda _: "user/" and connect to redis://user@localhost:6379/0.
When you query the database the cache_thing.lua script will get called with 3 keys:
-
"user/" -
"user/q:..." -
""
Redis won't run the script because the last key cannot be accessed by this user and you'll get this error:
NOPERM this user has no permissions to access one of the keys used as arguments
I'm not deeply familiar with how this library works, but I submitted a PR which seems to fix the issue in #423
Thanks very much for the PR @ipmb and thanks for the speedy merge @Suor . Just need to get this into pypi and we'll be off and running.