[checkmk-commits] Check_MK Git: check_mk: userdb: moved htpasswd saving to htpasswd userdb module; Modularized user saving

git version control git at mathias-kettner.de
Wed Nov 21 14:35:05 CET 2012


Module: check_mk
Branch: master
Commit: 1ae0f6b3a5c7d03915fe15e42f1079bc19841949
URL:    http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=1ae0f6b3a5c7d03915fe15e42f1079bc19841949

Author: Lars Michelsen <lm at mathias-kettner.de>
Date:   Wed Nov 14 12:07:09 2012 +0100

userdb: moved htpasswd saving to htpasswd userdb module; Modularized user saving

---

 web/htdocs/userdb.py           |   44 ++++++++++++++++++++++++++++++---------
 web/htdocs/wato.py             |   39 +++++++++--------------------------
 web/plugins/userdb/htpasswd.py |   23 ++++++++++++++++++++-
 web/plugins/userdb/ldap.py     |   15 -------------
 4 files changed, 66 insertions(+), 55 deletions(-)

diff --git a/web/htdocs/userdb.py b/web/htdocs/userdb.py
index 960bfe7..643c048 100644
--- a/web/htdocs/userdb.py
+++ b/web/htdocs/userdb.py
@@ -54,21 +54,25 @@ def list_user_connectors():
 def connector_enabled(connector_id):
     return connector_id in config.user_connectors
 
+def enabled_connectors():
+    connectors = []
+    for connector in multisite_user_connectors:
+        if connector['id'] in config.user_connectors:
+            connectors.append(connector)
+    return connectors
+
 # Returns the connector dictionary of the given id
 def get_connector(connector_id):
     if connector_id is None:
         connector_id = 'htpasswd'
-    for connector in multisite_user_connectors:
+    for connector in enabled_connectors():
         if connector['id'] == connector_id:
             return connector
 
-# Returns a list of locked attributes. If connector is None the htpasswd
-# connector is assumed.
+# Returns a list of locked attributes
 def locked_attributes(connector_id):
-    for connector in multisite_user_connectors:
-        if connector['id'] == connector_id:
-            return connector.get('locked_attributes', lambda: [])()
-    return []
+    connector = get_connector(connector_id)
+    return connector.get('locked_attributes', lambda: [])()
 
 # This is a function needed in WATO and the htpasswd module. This should
 # really be modularized one day. Till this day this is a good place ...
@@ -116,7 +120,7 @@ def user_locked(username):
 
 # This hook is called to validate the login credentials provided by a user
 def hook_login(username, password):
-    for connector in multisite_user_connectors:
+    for connector in enabled_connectors():
         handler = connector.get('login', None)
         if not handler:
             continue
@@ -147,11 +151,12 @@ def hook_login(username, password):
 # Hook function can be registered here to be executed to synchronize all users.
 # Is called on:
 #   a) before rendering the user management page in WATO
+#   b) a user is created during login (only for this user)
 def hook_sync(connector_id = None, add_to_changelog = False, only_username = None):
     if connector_id:
         connectors = [ get_connector(connector_id) ]
     else:
-        connectors = multisite_user_connectors
+        connectors = enabled_connectors()
 
     for connector in connectors:
         handler = connector.get('sync', None)
@@ -168,10 +173,29 @@ def hook_sync(connector_id = None, add_to_changelog = False, only_username = Non
                 else:
                     raise
 
+# Hook function can be registered here to be executed during saving of the
+# new user construct
+def hook_save(users):
+    for connector in enabled_connectors():
+        handler = connector.get('save', None)
+        if not handler:
+            continue
+        try:
+            handler(users)
+        except:
+            if config.debug:
+                import traceback
+                html.show_error(
+                    "<h3>" + _("Error executing sync hook") + "</h3>"
+                    "<pre>%s</pre>" % (traceback.format_exc())
+                )
+            else:
+                raise
+
 # Hook function can be registered here to execute actions on a "regular" base without
 # user triggered action. This hook is called on each page load.
 def hook_page():
-    for connector in multisite_user_connectors:
+    for connector in enabled_connectors():
         handler = connector.get('page', None)
         if handler:
             handler()
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 83f443c..5b5ecf4 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -7895,15 +7895,14 @@ def mode_edit_user(phase):
 
     if new:
         if cloneid:
-            user = users.get(cloneid, {})
+            user = users.get(cloneid, userdb.new_user_template('htpasswd'))
         else:
-            user = {}
+            user = userdb.new_user_template('htpasswd')
     else:
-        user = users.get(userid, {})
+        user = users.get(userid, userdb.new_user_template('htpasswd'))
 
     # Returns true if an attribute is locked and should be read only. Is only
     # checked when modifying an existing user
-    # FIXME: Also lock those attributes on form processing
     locked_attributes = userdb.locked_attributes(user.get('connector'))
     def is_locked(attr):
         return not new and attr in locked_attributes
@@ -7975,11 +7974,9 @@ def mode_edit_user(phase):
                 new_user["password"] = userdb.encrypt_password(password)
                 increase_serial = True # password changed, reflect in auth serial
 
-        # Set initial password serial or increase existing
-        if new:
-            new_user["serial"] = 0
-        elif increase_serial:
-            new_user["serial"] += 1
+        # Increase serial (if needed)
+        if increase_serial:
+            new_user['serial'] = new_user.get('serial', 0) + 1
 
         # Email address
         email = html.var("email").strip()
@@ -8444,27 +8441,11 @@ def save_users(profiles):
     out.write("# Written by WATO\n# encoding: utf-8\n\n")
     out.write("multisite_users = \\\n%s\n" % pprint.pformat(users))
 
-    # Apache htpasswd. We only store passwords here. During
-    # loading we created entries for all admin users we know. Other
-    # users from htpasswd are lost. If you start managing users with
-    # WATO, you should continue to do so or stop doing to for ever...
-    # Locked accounts get a '!' before their password. This disable it.
-    # FIXME: implement as 'save'-hook in htpasswd connector
-    filename = defaults.htpasswd_file
-    out = create_user_file(filename, "w")
-    for id, user in profiles.items():
-        # only process users which are handled by htpasswd connector
-        if user.get('connector', 'htpasswd') != 'htpasswd':
-            continue
-
-        if user.get("password"):
-            if user.get("locked", False):
-                locksym = '!'
-            else:
-                locksym = ""
-            out.write("%s:%s%s\n" % (id, locksym, user["password"]))
+    # Execute user connector save hooks
+    userdb.hook_save(profiles)
 
-        # Authentication secret for local processes
+    # Write authentication secret for local processes
+    for id, user in profiles.items():
         auth_dir = defaults.var_dir + "/web/" + id
         auth_file = auth_dir + "/automation.secret"
         make_nagios_directory(auth_dir)
diff --git a/web/plugins/userdb/htpasswd.py b/web/plugins/userdb/htpasswd.py
index bdcb089..5fc9f56 100644
--- a/web/plugins/userdb/htpasswd.py
+++ b/web/plugins/userdb/htpasswd.py
@@ -90,11 +90,32 @@ def htpasswd_login(username, password):
         return None # not existing user, skip over
     return password_valid(users[username], password)
 
+# Saves htpasswd connector managed users
+def htpasswd_save(users):
+    # Apache htpasswd. We only store passwords here. During
+    # loading we created entries for all admin users we know. Other
+    # users from htpasswd are lost. If you start managing users with
+    # WATO, you should continue to do so or stop doing to for ever...
+    # Locked accounts get a '!' before their password. This disable it.
+    out = create_user_file(defaults.htpasswd_file, "w")
+    for id, user in users.items():
+        # only process users which are handled by htpasswd connector
+        if user.get('connector', 'htpasswd') != 'htpasswd':
+            continue
+
+        if user.get("password"):
+            if user.get("locked", False):
+                locksym = '!'
+            else:
+                locksym = ""
+            out.write("%s:%s%s\n" % (id, locksym, user["password"]))
+
 multisite_user_connectors.append({
     'id':    'htpasswd',
     'title': _('htpasswd file'),
 
     # Register hook functions
     'login': htpasswd_login,
-    # Not registering: sync, save, locked_attributes, page
+    'save':  htpasswd_save,
+    # Not registering: sync, locked_attributes, page
 })
diff --git a/web/plugins/userdb/ldap.py b/web/plugins/userdb/ldap.py
index 7efb909..fec04e0 100644
--- a/web/plugins/userdb/ldap.py
+++ b/web/plugins/userdb/ldap.py
@@ -59,21 +59,6 @@ user_filter = {
     'openldap': '(objectcategory=user)',
 }
 
-def ldap_ad_auth_expired():
-    # FIXME
-    pass
-
-def ldap_openldap_auth_expired():
-    # FIXME
-    pass
-
-# Directory type specific function to check wether or not a user
-# session is expired (e.g. because the password has been)
-ldap_pw_expire_check = {
-    'ad':       ldap_ad_auth_expired,
-    'openldap': ldap_openldap_auth_expired,
-}
-
 #   .----------------------------------------------------------------------.
 #   |                      _     ____    _    ____                         |
 #   |                     | |   |  _ \  / \  |  _ \                        |



More information about the checkmk-commits mailing list