mirror of
https://github.com/jazzband/django-defender.git
synced 2026-03-16 22:10:32 +00:00
FIX: support for special character in redis password(such like '@') (#155)
* FIX: if special character in redis password, we can set DEFENDER_REDIS_PASSWORD_QUOTE to True, and use quote password * MOD:add test cases with password_quota = True
This commit is contained in:
parent
8daa2d168d
commit
71312eb841
4 changed files with 34 additions and 10 deletions
|
|
@ -357,6 +357,8 @@ These should be defined in your ``settings.py`` file.
|
|||
* ``DEFENDER_REDIS_URL``\ : String: the redis url for defender.
|
||||
[Default: ``redis://localhost:6379/0``\ ]
|
||||
(Example with password: ``redis://:mypassword@localhost:6379/0``\ )
|
||||
* ``DEFENDER_REDIS_PASSWORD_QUOTE``\ : Boolean: if special character in redis password(like '@'), we can quote password(urllib.quote_plus("password!@#")), and set to True.
|
||||
[Default: ``False``\ ]
|
||||
* ``DEFENDER_REDIS_NAME``\ : String: the name of your cache client on the CACHES django setting. If set, ``DEFENDER_REDIS_URL`` will be ignored.
|
||||
[Default: ``None``\ ]
|
||||
* ``DEFENDER_STORE_ACCESS_ATTEMPTS``\ : Boolean: If you want to store the login
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ def get_setting(variable, default=None):
|
|||
# redis server host
|
||||
DEFENDER_REDIS_URL = get_setting("DEFENDER_REDIS_URL")
|
||||
|
||||
# redis password quote for special character
|
||||
DEFENDER_REDIS_PASSWORD_QUOTE = get_setting("DEFENDER_REDIS_PASSWORD_QUOTE", False)
|
||||
|
||||
# reuse declared cache from django settings
|
||||
DEFENDER_REDIS_NAME = get_setting("DEFENDER_REDIS_NAME")
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ def get_redis_connection():
|
|||
# django_redis.cache.RedisCache case (django-redis package)
|
||||
return cache.client.get_client(True)
|
||||
else: # pragma: no cover
|
||||
redis_config = parse_redis_url(config.DEFENDER_REDIS_URL)
|
||||
redis_config = parse_redis_url(
|
||||
config.DEFENDER_REDIS_URL, config.DEFENDER_REDIS_PASSWORD_QUOTE)
|
||||
return redis.StrictRedis(
|
||||
host=redis_config.get("HOST"),
|
||||
port=redis_config.get("PORT"),
|
||||
|
|
@ -45,7 +46,7 @@ def get_redis_connection():
|
|||
)
|
||||
|
||||
|
||||
def parse_redis_url(url):
|
||||
def parse_redis_url(url, password_quote):
|
||||
"""Parses a redis URL."""
|
||||
|
||||
# create config with some sane defaults
|
||||
|
|
@ -68,7 +69,10 @@ def parse_redis_url(url):
|
|||
if path:
|
||||
redis_config.update({"DB": int(path)})
|
||||
if url.password:
|
||||
redis_config.update({"PASSWORD": url.password})
|
||||
password = url.password
|
||||
if password_quote:
|
||||
password = urlparse.unquote(password)
|
||||
redis_config.update({"PASSWORD": password})
|
||||
if url.hostname:
|
||||
redis_config.update({"HOST": url.hostname})
|
||||
if url.port:
|
||||
|
|
|
|||
|
|
@ -491,54 +491,69 @@ class AccessAttemptTest(DefenderTestCase):
|
|||
def test_parse_redis_url(self):
|
||||
""" test the parse_redis_url method """
|
||||
# full regular
|
||||
conf = parse_redis_url("redis://user:password@localhost2:1234/2")
|
||||
conf = parse_redis_url("redis://user:password@localhost2:1234/2", False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 2)
|
||||
self.assertEqual(conf.get("PASSWORD"), "password")
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# full non local
|
||||
conf = parse_redis_url("redis://user:pass@www.localhost.com:1234/2")
|
||||
conf = parse_redis_url(
|
||||
"redis://user:pass@www.localhost.com:1234/2", False)
|
||||
self.assertEqual(conf.get("HOST"), "www.localhost.com")
|
||||
self.assertEqual(conf.get("DB"), 2)
|
||||
self.assertEqual(conf.get("PASSWORD"), "pass")
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# no user name
|
||||
conf = parse_redis_url("redis://password@localhost2:1234/2")
|
||||
conf = parse_redis_url("redis://password@localhost2:1234/2", False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 2)
|
||||
self.assertEqual(conf.get("PASSWORD"), None)
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# no user name 2 with colon
|
||||
conf = parse_redis_url("redis://:password@localhost2:1234/2")
|
||||
conf = parse_redis_url("redis://:password@localhost2:1234/2", False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 2)
|
||||
self.assertEqual(conf.get("PASSWORD"), "password")
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# Empty
|
||||
conf = parse_redis_url(None)
|
||||
conf = parse_redis_url(None, False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost")
|
||||
self.assertEqual(conf.get("DB"), 0)
|
||||
self.assertEqual(conf.get("PASSWORD"), None)
|
||||
self.assertEqual(conf.get("PORT"), 6379)
|
||||
|
||||
# no db
|
||||
conf = parse_redis_url("redis://:password@localhost2:1234")
|
||||
conf = parse_redis_url("redis://:password@localhost2:1234", False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 0)
|
||||
self.assertEqual(conf.get("PASSWORD"), "password")
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# no password
|
||||
conf = parse_redis_url("redis://localhost2:1234/0")
|
||||
conf = parse_redis_url("redis://localhost2:1234/0", False)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 0)
|
||||
self.assertEqual(conf.get("PASSWORD"), None)
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
# password with special character and set the password_quote = True
|
||||
conf = parse_redis_url("redis://:calmkart%23%40%21@localhost:6379/0", True)
|
||||
self.assertEqual(conf.get("HOST"), "localhost")
|
||||
self.assertEqual(conf.get("DB"), 0)
|
||||
self.assertEqual(conf.get("PASSWORD"), "calmkart#@!")
|
||||
self.assertEqual(conf.get("PORT"), 6379)
|
||||
|
||||
# password without special character and set the password_quote = True
|
||||
conf = parse_redis_url("redis://:password@localhost2:1234", True)
|
||||
self.assertEqual(conf.get("HOST"), "localhost2")
|
||||
self.assertEqual(conf.get("DB"), 0)
|
||||
self.assertEqual(conf.get("PASSWORD"), "password")
|
||||
self.assertEqual(conf.get("PORT"), 1234)
|
||||
|
||||
@patch("defender.config.DEFENDER_REDIS_NAME", "default")
|
||||
def test_get_redis_connection_django_conf(self):
|
||||
""" get the redis connection """
|
||||
|
|
|
|||
Loading…
Reference in a new issue