django-configurations/configurations/example_generators.py
Finn-Thorben Sell 5cd3a86106
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
2022-03-24 14:25:41 +01:00

47 lines
1.8 KiB
Python

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