0.3.7: fix b64encode() incorrect padding

This commit is contained in:
Yusur 2025-07-19 14:16:57 +02:00
parent f5030ef25a
commit 98d0a9db14
6 changed files with 12 additions and 7 deletions

1
.gitignore vendored
View file

@ -24,3 +24,4 @@ dist/
.err .err
.vscode .vscode
/run.sh /run.sh
ROADMAP.md

View file

@ -4,6 +4,10 @@
👀 👀
## 0.3.7
- Fixed a bug in `b64decode()` padding handling which made the function inconsistent and non injective. Now, leading `'A'` is NEVER stripped.
## 0.3.6 ## 0.3.6
- Fixed `ConfigValue` behavior with multiple sources. It used to iterate through all the sources, possibly overwriting; now, iteration stops at first non-missing value. - Fixed `ConfigValue` behavior with multiple sources. It used to iterate through all the sources, possibly overwriting; now, iteration stops at first non-missing value.

View file

@ -27,7 +27,7 @@ from .itertools import makelist, kwargs_prefix, ltuple, rtuple, additem
from .i18n import I18n, JsonI18n, TomlI18n from .i18n import I18n, JsonI18n, TomlI18n
from .snowflake import Snowflake, SnowflakeGen from .snowflake import Snowflake, SnowflakeGen
__version__ = "0.3.6" __version__ = "0.3.7"
__all__ = ( __all__ = (
'Siq', 'SiqCache', 'SiqType', 'SiqGen', 'StringCase', 'Siq', 'SiqCache', 'SiqType', 'SiqGen', 'StringCase',

View file

@ -178,10 +178,10 @@ def b32ldecode(val: bytes | str) -> bytes:
def b64encode(val: bytes, *, strip: bool = True) -> str: def b64encode(val: bytes, *, strip: bool = True) -> str:
''' '''
Wrapper around base64.urlsafe_b64encode() which also strips trailing '=' and leading 'A'. Wrapper around base64.urlsafe_b64encode() which also strips trailing '='.
''' '''
b = want_str(base64.urlsafe_b64encode(val)) b = want_str(base64.urlsafe_b64encode(val))
return b.lstrip('A').rstrip('=') if strip else b return b.rstrip('=') if strip else b
def b64decode(val: bytes | str) -> bytes: def b64decode(val: bytes | str) -> bytes:
''' '''

View file

@ -23,7 +23,7 @@ import os
from typing import Any, Callable, Iterator from typing import Any, Callable, Iterator
from collections import OrderedDict from collections import OrderedDict
from .functools import deprecated_alias from .functools import deprecated
MISSING = object() MISSING = object()
@ -226,7 +226,7 @@ class ConfigOptions:
if first: if first:
self._srcs.move_to_end(key, False) self._srcs.move_to_end(key, False)
add_config_source = deprecated_alias(add_source) add_config_source = deprecated('use add_source() instead')(add_source)
def expose(self, public_name: str, attr_name: str | None = None) -> None: def expose(self, public_name: str, attr_name: str | None = None) -> None:
''' '''

View file

@ -40,12 +40,12 @@ class FlaskAuthSrc(AuthSrc):
def get_signature(self) -> bytes: def get_signature(self) -> bytes:
sig = request.headers.get('authorization-signature', None) sig = request.headers.get('authorization-signature', None)
return want_bytes(sig) if sig else None return want_bytes(sig) if sig else None
def invalid_exc(self, msg: str = 'Validation failed') -> Never: def invalid_exc(self, msg: str = 'validation failed') -> Never:
abort(400, msg) abort(400, msg)
def required_exc(self): def required_exc(self):
abort(401, 'Login required') abort(401, 'Login required')
def require_auth(cls: type[DeclarativeBase], db: SQLAlchemy) -> Callable: def require_auth(cls: type[DeclarativeBase], db: SQLAlchemy) -> Callable[Any, Callable]:
""" """
Make an auth_required() decorator for Flask views. Make an auth_required() decorator for Flask views.