authentik.lib.utils.time

Time utilities

 1"""Time utilities"""
 2
 3import datetime
 4from hashlib import sha256
 5from random import randrange, seed
 6from socket import getfqdn
 7
 8from django.core.exceptions import ValidationError
 9from django.utils.translation import gettext_lazy as _
10
11ALLOWED_KEYS = (
12    "microseconds",
13    "milliseconds",
14    "seconds",
15    "minutes",
16    "hours",
17    "days",
18    "weeks",
19)
20
21
22def timedelta_string_validator(value: str):
23    """Validator for Django that checks if value can be parsed with `timedelta_from_string`"""
24    try:
25        timedelta_from_string(value)
26    except ValueError as exc:
27        raise ValidationError(
28            _("%(value)s is not in the correct format of 'hours=3;minutes=1'."),
29            params={"value": value},
30        ) from exc
31
32
33def timedelta_from_string(expr: str) -> datetime.timedelta:
34    """Convert a string with the format of 'hours=1;minute=3;seconds=5' to a
35    `datetime.timedelta` Object with hours = 1, minutes = 3, seconds = 5"""
36    kwargs = {}
37    for duration_pair in expr.split(";"):
38        key, value = duration_pair.split("=")
39        if key.lower() not in ALLOWED_KEYS:
40            continue
41        kwargs[key.lower()] = float(value.strip())
42    if len(kwargs) < 1:
43        raise ValueError("No valid keys to pass to timedelta")
44    return datetime.timedelta(**kwargs)
45
46
47def fqdn_rand(task: str, stop: int = 60) -> int:
48    """Get a random number within max based on the FQDN and task name"""
49    entropy = f"{getfqdn()}:{task}"
50    hasher = sha256()
51    hasher.update(entropy.encode("utf-8"))
52    seed(hasher.hexdigest())
53    return randrange(0, stop)  # nosec
ALLOWED_KEYS = ('microseconds', 'milliseconds', 'seconds', 'minutes', 'hours', 'days', 'weeks')
def timedelta_string_validator(value: str):
23def timedelta_string_validator(value: str):
24    """Validator for Django that checks if value can be parsed with `timedelta_from_string`"""
25    try:
26        timedelta_from_string(value)
27    except ValueError as exc:
28        raise ValidationError(
29            _("%(value)s is not in the correct format of 'hours=3;minutes=1'."),
30            params={"value": value},
31        ) from exc

Validator for Django that checks if value can be parsed with timedelta_from_string

def timedelta_from_string(expr: str) -> datetime.timedelta:
34def timedelta_from_string(expr: str) -> datetime.timedelta:
35    """Convert a string with the format of 'hours=1;minute=3;seconds=5' to a
36    `datetime.timedelta` Object with hours = 1, minutes = 3, seconds = 5"""
37    kwargs = {}
38    for duration_pair in expr.split(";"):
39        key, value = duration_pair.split("=")
40        if key.lower() not in ALLOWED_KEYS:
41            continue
42        kwargs[key.lower()] = float(value.strip())
43    if len(kwargs) < 1:
44        raise ValueError("No valid keys to pass to timedelta")
45    return datetime.timedelta(**kwargs)

Convert a string with the format of 'hours=1;minute=3;seconds=5' to a datetime.timedelta Object with hours = 1, minutes = 3, seconds = 5

def fqdn_rand(task: str, stop: int = 60) -> int:
48def fqdn_rand(task: str, stop: int = 60) -> int:
49    """Get a random number within max based on the FQDN and task name"""
50    entropy = f"{getfqdn()}:{task}"
51    hasher = sha256()
52    hasher.update(entropy.encode("utf-8"))
53    seed(hasher.hexdigest())
54    return randrange(0, stop)  # nosec

Get a random number within max based on the FQDN and task name