# HG changeset patch # User Mads Kiilerich # Date 2018-12-26 01:54:23 # Node ID c9d859a89a88a81c98e1235784c99349d819cedc # Parent cb472dfe807d82f151a8dac4f8c67da64aa5ff94 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. diff --git a/kallithea/lib/auth_modules/__init__.py b/kallithea/lib/auth_modules/__init__.py --- a/kallithea/lib/auth_modules/__init__.py +++ b/kallithea/lib/auth_modules/__init__.py @@ -54,7 +54,6 @@ class KallitheaAuthPluginBase(object): "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 @@ class KallitheaAuthPluginBase(object): ) 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 @@ class KallitheaAuthPluginBase(object): 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 @@ class KallitheaExternalAuthPlugin(Kallit 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 @@ class KallitheaExternalAuthPlugin(Kallit 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 @@ def authenticate(username, password, env 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 authenticate(username, password, env 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: diff --git a/kallithea/lib/auth_modules/auth_container.py b/kallithea/lib/auth_modules/auth_container.py --- a/kallithea/lib/auth_modules/auth_container.py +++ b/kallithea/lib/auth_modules/auth_container.py @@ -105,10 +105,6 @@ class KallitheaAuthPlugin(auth_modules.K 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 @@ class KallitheaAuthPlugin(auth_modules.K # 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 @@ class KallitheaAuthPlugin(auth_modules.K 'groups': [], 'email': email or '', 'admin': admin or False, - 'active': active, 'extern_name': username, } diff --git a/kallithea/lib/auth_modules/auth_crowd.py b/kallithea/lib/auth_modules/auth_crowd.py --- a/kallithea/lib/auth_modules/auth_crowd.py +++ b/kallithea/lib/auth_modules/auth_crowd.py @@ -193,10 +193,6 @@ class KallitheaAuthPlugin(auth_modules.K 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 @@ class KallitheaAuthPlugin(auth_modules.K # 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 @@ class KallitheaAuthPlugin(auth_modules.K 'groups': crowd_user["groups"], 'email': crowd_user["email"] or email, 'admin': admin, - 'active': active, 'extern_name': crowd_user["name"], } diff --git a/kallithea/lib/auth_modules/auth_internal.py b/kallithea/lib/auth_modules/auth_internal.py --- a/kallithea/lib/auth_modules/auth_internal.py +++ b/kallithea/lib/auth_modules/auth_internal.py @@ -47,10 +47,6 @@ class KallitheaAuthPlugin(auth_modules.K 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 @@ class KallitheaAuthPlugin(auth_modules.K "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 diff --git a/kallithea/lib/auth_modules/auth_ldap.py b/kallithea/lib/auth_modules/auth_ldap.py --- a/kallithea/lib/auth_modules/auth_ldap.py +++ b/kallithea/lib/auth_modules/auth_ldap.py @@ -289,10 +289,6 @@ class KallitheaAuthPlugin(auth_modules.K 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 @@ class KallitheaAuthPlugin(auth_modules.K # 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 @@ class KallitheaAuthPlugin(auth_modules.K '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']) diff --git a/kallithea/lib/auth_modules/auth_pam.py b/kallithea/lib/auth_modules/auth_pam.py --- a/kallithea/lib/auth_modules/auth_pam.py +++ b/kallithea/lib/auth_modules/auth_pam.py @@ -115,7 +115,6 @@ class KallitheaAuthPlugin(auth_modules.K # 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 @@ class KallitheaAuthPlugin(auth_modules.K 'groups': [g.gr_name for g in grp.getgrall() if username in g.gr_mem], 'email': email, 'admin': admin, - 'active': active, 'extern_name': username, }