From 8c8ad9cf08f46798c2d61123a4af752dac4f7a10 Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Fri, 5 Aug 2022 13:05:55 +0200
Subject: [PATCH 1/2] management: add a LogToConsoleCommand base class (#62710)

---
 src/authentic2/base_commands.py               | 64 +++++++++++++++++++
 .../management/commands/sync-ldap-users.py    | 48 ++------------
 2 files changed, 70 insertions(+), 42 deletions(-)
 create mode 100644 src/authentic2/base_commands.py

diff --git a/src/authentic2/base_commands.py b/src/authentic2/base_commands.py
new file mode 100644
index 000000000..f2021f488
--- /dev/null
+++ b/src/authentic2/base_commands.py
@@ -0,0 +1,64 @@
+# authentic2 - versatile identity manager
+# Copyright (C) 2010-2022 Entr'ouvert
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU Affero General Public License as published
+# by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+import logging
+import os
+from contextlib import contextmanager
+
+from django.core.management.base import BaseCommand
+
+
+@contextmanager
+def log_to_console(loggername, verbosity):
+    if 'TERM' not in os.environ:
+        yield
+    else:
+        handler = logging.StreamHandler()
+        # add timestamp to messages
+        formatter = logging.Formatter(fmt='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
+        handler.setFormatter(formatter)
+
+        if verbosity == 1:
+            handler.setLevel(logging.ERROR)
+        elif verbosity == 2:
+            handler.setLevel(logging.INFO)
+        elif verbosity == 3:
+            handler.setLevel(logging.DEBUG)
+
+        logger = logging.getLogger(loggername)
+        initial_level = logger.level
+        try:
+            logger.propagate = False
+            logger.setLevel(logging.DEBUG)
+            logger.addHandler(handler)
+            yield
+        finally:
+            logger.propagate = True
+            logger.setLevel(initial_level)
+            logger.removeHandler(handler)
+
+
+class LogToConsoleCommand(BaseCommand):
+    loggername = None
+
+    def core_command(self, *args, **kwargs):
+        raise NotImplementedError
+
+    def handle(self, *args, **kwargs):
+        verbosity = int(kwargs['verbosity'])
+
+        with log_to_console(self.loggername, verbosity):
+            self.core_command(*args, **kwargs)
diff --git a/src/authentic2/management/commands/sync-ldap-users.py b/src/authentic2/management/commands/sync-ldap-users.py
index 50cc331bf..09d6b6d55 100644
--- a/src/authentic2/management/commands/sync-ldap-users.py
+++ b/src/authentic2/management/commands/sync-ldap-users.py
@@ -21,52 +21,16 @@ try:
 except ImportError:
     ldap = None
 
-import logging
-import os
-from contextlib import contextmanager
-
-from django.core.management.base import BaseCommand
-
 from authentic2.backends.ldap_backend import LDAPBackend
+from authentic2.base_commands import LogToConsoleCommand
 
 
-@contextmanager
-def log_ldap_to_console(verbosity):
-    if 'TERM' not in os.environ:
-        yield
-    else:
-        handler = logging.StreamHandler()
-        # add timestamp to messages
-        formatter = logging.Formatter(fmt='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
-        handler.setFormatter(formatter)
-
-        if verbosity == 1:
-            handler.setLevel(logging.ERROR)
-        elif verbosity == 2:
-            handler.setLevel(logging.INFO)
-        elif verbosity == 3:
-            handler.setLevel(logging.DEBUG)
+class Command(LogToConsoleCommand):
+    loggername = 'authentic2.backends.ldap_backend'
 
-        logger = logging.getLogger('authentic2.backends.ldap_backend')
-        initial_level = logger.level
-        try:
-            logger.propagate = False
-            logger.setLevel(logging.DEBUG)
-            logger.addHandler(handler)
-            yield
-        finally:
-            logger.propagate = True
-            logger.setLevel(initial_level)
-            logger.removeHandler(handler)
-
-
-class Command(BaseCommand):
     def add_arguments(self, parser):
         parser.add_argument('--realm', help='Limit sync to this realm')
 
-    def handle(self, *args, **kwargs):
-        verbosity = int(kwargs['verbosity'])
-
-        with log_ldap_to_console(verbosity):
-            for dummy in LDAPBackend.get_users(realm=kwargs['realm']):
-                continue
+    def core_command(self, *args, **kwargs):
+        for dummy in LDAPBackend.get_users(realm=kwargs['realm']):
+            continue
-- 
2.36.1

