Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ Unreleased

*

0.20.0 - 2025-11-27
********************

Added
=====

* Add configurable logging level for Casbin enforcer via ``CASBIN_LOG_LEVEL`` setting (defaults to WARNING).


0.19.2 - 2025-11-25
********************

Expand Down
2 changes: 1 addition & 1 deletion openedx_authz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

import os

__version__ = "0.19.2"
__version__ = "0.20.0"

ROOT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
19 changes: 19 additions & 0 deletions openedx_authz/engine/enforcer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
"""

import logging
from copy import deepcopy
from uuid import uuid4

from casbin import SyncedEnforcer
from casbin.util.log import DEFAULT_LOGGING, configure_logging
from casbin_adapter.enforcer import initialize_enforcer
from django.conf import settings

Expand Down Expand Up @@ -154,6 +156,19 @@ def configure_enforcer_auto_save_and_load(cls):

cls.configure_enforcer_auto_save(auto_save_policy)

@classmethod
def _configure_logging(cls) -> None:
"""Configure logging levels for Casbin's internal loggers.

This controls the verbosity of Casbin's policy evaluation and role management
logging. The log level defaults to WARNING if CASBIN_LOG_LEVEL is not set.
"""
log_level = getattr(settings, "CASBIN_LOG_LEVEL", "WARNING")
casbin_logging = deepcopy(DEFAULT_LOGGING)
for logger_name in casbin_logging["loggers"]:
casbin_logging["loggers"][logger_name]["level"] = log_level
configure_logging(casbin_logging)

@classmethod
def load_policy_if_needed(cls):
"""Load policy if the last load version indicates it's needed.
Expand Down Expand Up @@ -246,6 +261,10 @@ def _initialize_enforcer(cls) -> SyncedEnforcer:
# Avoid circular import
from openedx_authz.engine.matcher import is_admin_or_superuser_check # pylint: disable=import-outside-toplevel

# Configure logging BEFORE initialize_enforcer() because it creates a ProxyEnforcer
# that doesn't pass logging config and would use Casbin's defaults
cls._configure_logging()

db_alias = getattr(settings, "CASBIN_DB_ALIAS", "default")

try:
Expand Down
5 changes: 5 additions & 0 deletions openedx_authz/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ def plugin_settings(settings):
# Set default ContentLibrary model for swappable dependency
if not hasattr(settings, "OPENEDX_AUTHZ_CONTENT_LIBRARY_MODEL"):
settings.OPENEDX_AUTHZ_CONTENT_LIBRARY_MODEL = "content_libraries.ContentLibrary"

# Set default CASBIN_LOG_LEVEL if not already set.
# This setting defines the logging level for the Casbin enforcer.
if not hasattr(settings, "CASBIN_LOG_LEVEL"):
settings.CASBIN_LOG_LEVEL = "WARNING"