changeset 7482:c9d859a89a88

auth: move 'active' handling out of the individual auth modules The 'active' flag in the Kallithea user database is very fundamental and should not be specific to auth modules. Modules should only care about whether the user is active in the external authentication system. user_activation_state is thus removed, and 'hg.extern_activate.auto' is now consistently checked for all kinds of external authentication.
author Mads Kiilerich <mads@kiilerich.com>
date Wed, 26 Dec 2018 01:54:23 +0100
parents cb472dfe807d
children 2e3e1dacdbb7
files kallithea/lib/auth_modules/__init__.py kallithea/lib/auth_modules/auth_container.py kallithea/lib/auth_modules/auth_crowd.py kallithea/lib/auth_modules/auth_internal.py kallithea/lib/auth_modules/auth_ldap.py kallithea/lib/auth_modules/auth_pam.py
diffstat 6 files changed, 27 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/kallithea/lib/auth_modules/__init__.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/__init__.py	Wed Dec 26 01:54:23 2018 +0100
@@ -54,7 +54,6 @@
         "groups": '["list", "of", "groups"]',
         "extern_name": "name in external source of record",
         "admin": 'True|False defines if user should be Kallithea admin',
-        "active": 'True|False defines active state of user in Kallithea',
     }
 
     @property
@@ -196,14 +195,6 @@
         )
         return rcsettings
 
-    def user_activation_state(self):
-        """
-        Defines user activation state when creating new users
-
-        :returns: boolean
-        """
-        raise NotImplementedError("Not implemented in base class")
-
     def auth(self, userobj, username, passwd, settings, **kwargs):
         """
         Given a user object (which may be None), username, a plaintext password,
@@ -220,11 +211,6 @@
     def _authenticate(self, userobj, username, passwd, settings, **kwargs):
         """
         Wrapper to call self.auth() that validates call on it
-
-        :param userobj: userobj
-        :param username: username
-        :param passwd: plaintext password
-        :param settings: plugin settings
         """
         user_data = self.auth(userobj, username, passwd, settings, **kwargs)
         if user_data is not None:
@@ -255,6 +241,12 @@
         user_data = super(KallitheaExternalAuthPlugin, self)._authenticate(
             userobj, username, passwd, settings, **kwargs)
         if user_data is not None:
+            if userobj is None: # external authentication of unknown user that will be created soon
+                def_user_perms = User.get_default_user().AuthUser.permissions['global']
+                active = 'hg.extern_activate.auto' in def_user_perms
+            else:
+                active = userobj.active
+
             if self.use_fake_password():
                 # Randomize the PW because we don't need it, but don't want
                 # them blank either
@@ -268,10 +260,10 @@
                 email=user_data["email"],
                 firstname=user_data["firstname"],
                 lastname=user_data["lastname"],
-                active=user_data["active"],
+                active=active,
                 admin=user_data["admin"],
                 extern_name=user_data["extern_name"],
-                extern_type=self.name
+                extern_type=self.name,
             )
             # enforce user is just in given groups, all of them has to be ones
             # created from plugins. We store this info in _group_data JSON field
@@ -369,6 +361,11 @@
         user = plugin.get_user(username, environ=environ,
                                settings=plugin_settings)
         log.debug('Plugin %s extracted user `%s`', module, user)
+
+        if user is not None and not user.active:
+            log.error("Rejecting authentication of in-active user %s", user)
+            continue
+
         if not plugin.accepts(user):
             log.debug('Plugin %s does not accept user `%s` for authentication',
                       module, user)
@@ -408,7 +405,7 @@
 
 def get_managed_fields(user):
     """return list of fields that are managed by the user's auth source, usually some of
-    'username', 'firstname', 'lastname', 'email', 'active', 'password'
+    'username', 'firstname', 'lastname', 'email', 'password'
     """
     auth_plugins = get_auth_plugins()
     for plugin in auth_plugins:
--- a/kallithea/lib/auth_modules/auth_container.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/auth_container.py	Wed Dec 26 01:54:23 2018 +0100
@@ -105,10 +105,6 @@
     def use_fake_password(self):
         return True
 
-    def user_activation_state(self):
-        def_user_perms = User.get_default_user().AuthUser.permissions['global']
-        return 'hg.extern_activate.auto' in def_user_perms
-
     def _clean_username(self, username):
         # Removing realm and domain from username
         username = username.partition('@')[0]
@@ -195,7 +191,6 @@
 
         # old attrs fetched from Kallithea database
         admin = getattr(userobj, 'admin', False)
-        active = getattr(userobj, 'active', True)
         email = environ.get(settings.get('email_header'), getattr(userobj, 'email', ''))
         firstname = environ.get(settings.get('firstname_header'), getattr(userobj, 'firstname', ''))
         lastname = environ.get(settings.get('lastname_header'), getattr(userobj, 'lastname', ''))
@@ -207,7 +202,6 @@
             'groups': [],
             'email': email or '',
             'admin': admin or False,
-            'active': active,
             'extern_name': username,
         }
 
--- a/kallithea/lib/auth_modules/auth_crowd.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/auth_crowd.py	Wed Dec 26 01:54:23 2018 +0100
@@ -193,10 +193,6 @@
     def use_fake_password(self):
         return True
 
-    def user_activation_state(self):
-        def_user_perms = User.get_default_user().AuthUser.permissions['global']
-        return 'hg.extern_activate.auto' in def_user_perms
-
     def auth(self, userobj, username, password, settings, **kwargs):
         """
         Given a user object (which may be null), username, a plaintext password,
@@ -231,7 +227,6 @@
 
         # old attrs fetched from Kallithea database
         admin = getattr(userobj, 'admin', False)
-        active = getattr(userobj, 'active', True)
         email = getattr(userobj, 'email', '')
         firstname = getattr(userobj, 'firstname', '')
         lastname = getattr(userobj, 'lastname', '')
@@ -243,7 +238,6 @@
             'groups': crowd_user["groups"],
             'email': crowd_user["email"] or email,
             'admin': admin,
-            'active': active,
             'extern_name': crowd_user["name"],
         }
 
--- a/kallithea/lib/auth_modules/auth_internal.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/auth_internal.py	Wed Dec 26 01:54:23 2018 +0100
@@ -47,10 +47,6 @@
     def settings(self):
         return []
 
-    def user_activation_state(self):
-        def_user_perms = User.get_default_user().AuthUser.permissions['global']
-        return 'hg.register.auto_activate' in def_user_perms
-
     def accepts(self, user, accepts_empty=True):
         """
         Custom accepts for this auth that doesn't accept empty users. We
@@ -78,27 +74,23 @@
             "groups": [],
             "email": userobj.email,
             "admin": userobj.admin,
-            "active": userobj.active,
             "extern_name": userobj.user_id,
         }
+        log.debug(formatted_json(user_data))
 
-        log.debug(formatted_json(user_data))
-        if userobj.active:
-            from kallithea.lib import auth
-            password_match = auth.check_password(password, userobj.password)
-            if userobj.is_default_user and userobj.active:
-                log.info('user %s authenticated correctly as anonymous user',
-                         username)
-                return user_data
+        from kallithea.lib import auth
+        password_match = auth.check_password(password, userobj.password)
+        if userobj.is_default_user:
+            log.info('user %s authenticated correctly as anonymous user',
+                     username)
+            return user_data
 
-            elif userobj.username == username and password_match:
-                log.info('user %s authenticated correctly', user_data['username'])
-                return user_data
-            log.error("user %s had a bad password", username)
-            return None
-        else:
-            log.warning('user %s tried auth but is disabled', username)
-            return None
+        elif userobj.username == username and password_match:
+            log.info('user %s authenticated correctly', user_data['username'])
+            return user_data
+
+        log.error("user %s had a bad password", username)
+        return None
 
     def get_managed_fields(self):
         # Note: 'username' should only be editable (at least for user) if self registration is enabled
--- a/kallithea/lib/auth_modules/auth_ldap.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/auth_ldap.py	Wed Dec 26 01:54:23 2018 +0100
@@ -289,10 +289,6 @@
     def use_fake_password(self):
         return True
 
-    def user_activation_state(self):
-        def_user_perms = User.get_default_user().AuthUser.permissions['global']
-        return 'hg.extern_activate.auto' in def_user_perms
-
     def auth(self, userobj, username, password, settings, **kwargs):
         """
         Given a user object (which may be null), username, a plaintext password,
@@ -339,7 +335,6 @@
 
             # old attrs fetched from Kallithea database
             admin = getattr(userobj, 'admin', False)
-            active = getattr(userobj, 'active', self.user_activation_state())
             email = getattr(userobj, 'email', '')
             firstname = getattr(userobj, 'firstname', '')
             lastname = getattr(userobj, 'lastname', '')
@@ -351,7 +346,6 @@
                 'groups': [],
                 'email': get_ldap_attr('attr_email') or email,
                 'admin': admin,
-                'active': active,
                 'extern_name': user_dn,
             }
             log.info('user %s authenticated correctly', user_data['username'])
--- a/kallithea/lib/auth_modules/auth_pam.py	Wed Dec 26 01:53:28 2018 +0100
+++ b/kallithea/lib/auth_modules/auth_pam.py	Wed Dec 26 01:54:23 2018 +0100
@@ -115,7 +115,6 @@
 
         # old attrs fetched from Kallithea database
         admin = getattr(userobj, 'admin', False)
-        active = getattr(userobj, 'active', True)
         email = getattr(userobj, 'email', '') or "%s@%s" % (username, socket.gethostname())
         firstname = getattr(userobj, 'firstname', '')
         lastname = getattr(userobj, 'lastname', '')
@@ -127,7 +126,6 @@
             'groups': [g.gr_name for g in grp.getgrall() if username in g.gr_mem],
             'email': email,
             'admin': admin,
-            'active': active,
             'extern_name': username,
         }