mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
implement example generators
Example generators are an addition to the 'Value' classes that allow the error handler to display example values for the failed value. For example if no django secret key is found to be defined in the environment, an example (secure) value for such a secret key can now be generated on the fly and be suggested to the user
This commit is contained in:
parent
fd1b571594
commit
5cd3a86106
3 changed files with 53 additions and 2 deletions
|
|
@ -26,6 +26,9 @@ def extract_explanation_lines_from_value(value_instance: 'Value') -> List[str]:
|
|||
result.append(f"{value_instance.destination_name} is taken from the environment variable "
|
||||
f"{value_instance.full_environ_name} as a {type(value_instance).__name__}")
|
||||
|
||||
if value_instance.example_generator is not None:
|
||||
result.append(f"Example value: '{value_instance.example_generator()}'")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
|
|
|||
47
configurations/example_generators.py
Normal file
47
configurations/example_generators.py
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
from typing import Callable
|
||||
import secrets
|
||||
import base64
|
||||
from django.core.management.utils import get_random_secret_key
|
||||
from django.utils.crypto import get_random_string, RANDOM_STRING_CHARS
|
||||
|
||||
|
||||
def gen_django_secret_key() -> str:
|
||||
"""
|
||||
Generate a cryptographically secure random string that can safely be used as a SECRET_KEY in django
|
||||
"""
|
||||
return get_random_secret_key()
|
||||
|
||||
|
||||
def gen_random_string(length: int, allowed_chars: str = RANDOM_STRING_CHARS) -> Callable[[], str]:
|
||||
"""
|
||||
Create a parameterized generator which generates a cryptographically secure random string of the given length
|
||||
containing the given characters.
|
||||
"""
|
||||
def generate() -> str:
|
||||
return get_random_string(length, allowed_chars)
|
||||
return generate
|
||||
|
||||
|
||||
def gen_bytes(length: int, encoding: str) -> Callable[[], str]:
|
||||
"""
|
||||
Create a parameterized generator which generates a cryptographically secure random assortments of bytes of the given
|
||||
length and encoded in the given format
|
||||
|
||||
:param length: How many bytes should be generated. Not how long the encoded string will be.
|
||||
:param encoding: How the generated bytes should be encoded.
|
||||
Accepted values are "base64", "base64_urlsafe" and "hex" (case is ignored)
|
||||
"""
|
||||
encoding = encoding.lower()
|
||||
if encoding not in ("base64", "base64_urlsafe", "hex"):
|
||||
raise ValueError(f"Cannot gen_bytes with encoding '{encoding}'. Valid encodings are 'base64', 'base64_urlsafe'"
|
||||
f" and 'hex'")
|
||||
|
||||
def generate() -> str:
|
||||
b = secrets.token_bytes(length)
|
||||
if encoding == "base64":
|
||||
return base64.standard_b64encode(b).decode("ASCII")
|
||||
elif encoding == "base64_urlsafe":
|
||||
return base64.urlsafe_b64encode(b).decode("ASCII")
|
||||
elif encoding == "hex":
|
||||
return b.hex().upper()
|
||||
return generate
|
||||
|
|
@ -58,8 +58,8 @@ class Value:
|
|||
return instance
|
||||
|
||||
def __init__(self, default=None, environ=True, environ_name=None,
|
||||
environ_prefix='DJANGO', environ_required=False, help_text=None,
|
||||
help_reference=None, *args, **kwargs):
|
||||
environ_prefix='DJANGO', environ_required=False, example_generator=None,
|
||||
help_text=None, help_reference=None, *args, **kwargs):
|
||||
if isinstance(default, Value) and default.default is not None:
|
||||
self.default = copy.copy(default.default)
|
||||
else:
|
||||
|
|
@ -73,6 +73,7 @@ class Value:
|
|||
self.destination_name = None
|
||||
self.help_text = help_text
|
||||
self.help_reference = help_reference
|
||||
self.example_generator = example_generator
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
|
|
|||
Loading…
Reference in a new issue