Fixed an issue that prevented the password reset tokens from working. Added email templates for password reset success and new account creation. Added more dynamic email template support.
76 lines
2.3 KiB
Python
76 lines
2.3 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
import sys
|
|
import typing as t
|
|
|
|
from werkzeug.local import LocalProxy
|
|
|
|
from .globals import request
|
|
|
|
if t.TYPE_CHECKING: # pragma: no cover
|
|
from .app import Flask
|
|
|
|
|
|
@LocalProxy
|
|
def wsgi_errors_stream() -> t.TextIO:
|
|
"""Find the most appropriate error stream for the application. If a request
|
|
is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``.
|
|
|
|
If you configure your own :class:`logging.StreamHandler`, you may want to
|
|
use this for the stream. If you are using file or dict configuration and
|
|
can't import this directly, you can refer to it as
|
|
``ext://flask.logging.wsgi_errors_stream``.
|
|
"""
|
|
return request.environ["wsgi.errors"] if request else sys.stderr
|
|
|
|
|
|
def has_level_handler(logger: logging.Logger) -> bool:
|
|
"""Check if there is a handler in the logging chain that will handle the
|
|
given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`.
|
|
"""
|
|
level = logger.getEffectiveLevel()
|
|
current = logger
|
|
|
|
while current:
|
|
if any(handler.level <= level for handler in current.handlers):
|
|
return True
|
|
|
|
if not current.propagate:
|
|
break
|
|
|
|
current = current.parent # type: ignore
|
|
|
|
return False
|
|
|
|
|
|
#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format
|
|
#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``.
|
|
default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore
|
|
default_handler.setFormatter(
|
|
logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")
|
|
)
|
|
|
|
|
|
def create_logger(app: Flask) -> logging.Logger:
|
|
"""Get the Flask app's logger and configure it if needed.
|
|
|
|
The logger name will be the same as
|
|
:attr:`app.import_name <flask.Flask.name>`.
|
|
|
|
When :attr:`~flask.Flask.debug` is enabled, set the logger level to
|
|
:data:`logging.DEBUG` if it is not set.
|
|
|
|
If there is no handler for the logger's effective level, add a
|
|
:class:`~logging.StreamHandler` for
|
|
:func:`~flask.logging.wsgi_errors_stream` with a basic format.
|
|
"""
|
|
logger = logging.getLogger(app.name)
|
|
|
|
if app.debug and not logger.level:
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
if not has_level_handler(logger):
|
|
logger.addHandler(default_handler)
|
|
|
|
return logger
|