Exemple #1
0
    def auth(self, userobj, username, password, settings, **kwargs):
        """
        Given a user object (which may be null), username, a plaintext password,
        and a settings object (containing all the keys needed as listed in settings()),
        authenticate this user's login attempt.

        Return None on failure. On success, return a dictionary of the form:

            see: KallitheaAuthPluginBase.auth_func_attrs
        This is later validated for correctness
        """
        if not username or not password:
            log.debug('Empty username or password skipping...')
            return None

        log.debug("Crowd settings: \n%s" % (formatted_json(settings)))
        server = CrowdServer(**settings)
        server.set_credentials(settings["app_name"], settings["app_password"])
        crowd_user = server.user_auth(username, password)
        log.debug("Crowd returned: \n%s" % (formatted_json(crowd_user)))
        if not crowd_user["status"]:
            return None

        res = server.user_groups(crowd_user["name"])
        log.debug("Crowd groups: \n%s" % (formatted_json(res)))
        crowd_user["groups"] = [x["name"] for x in res["groups"]]

        # 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', '')
        extern_type = getattr(userobj, 'extern_type', '')

        user_attrs = {
            'username': username,
            'firstname': crowd_user["first-name"] or firstname,
            'lastname': crowd_user["last-name"] or lastname,
            'groups': crowd_user["groups"],
            'email': crowd_user["email"] or email,
            'admin': admin,
            'active': active,
            'active_from_extern': crowd_user.get('active'),
            'extern_name': crowd_user["name"],
            'extern_type': extern_type,
        }

        # set an admin if we're in admin_groups of crowd
        for group in settings["admin_groups"].split(","):
            if group in user_attrs["groups"]:
                user_attrs["admin"] = True
        log.debug("Final crowd user object: \n%s" %
                  (formatted_json(user_attrs)))
        log.info('user %s authenticated correctly' % user_attrs['username'])
        return user_attrs
Exemple #2
0
    def auth(self, userobj, username, password, settings, **kwargs):
        """
        Given a user object (which may be null), username, a plaintext password,
        and a settings object (containing all the keys needed as listed in settings()),
        authenticate this user's login attempt.

        Return None on failure. On success, return a dictionary of the form:

            see: KallitheaAuthPluginBase.auth_func_attrs
        This is later validated for correctness
        """
        if not username or not password:
            log.debug('Empty username or password skipping...')
            return None

        log.debug("Crowd settings: \n%s", formatted_json(settings))
        server = CrowdServer(**settings)
        server.set_credentials(settings["app_name"], settings["app_password"])
        crowd_user = server.user_auth(username, password)
        log.debug("Crowd returned: \n%s", formatted_json(crowd_user))
        if not crowd_user["status"]:
            return None

        res = server.user_groups(crowd_user["name"])
        log.debug("Crowd groups: \n%s", formatted_json(res))
        crowd_user["groups"] = [x["name"] for x in res["groups"]]

        # 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', '')

        user_data = {
            'username': crowd_user["name"] or username,
            'firstname': crowd_user["first-name"] or firstname,
            'lastname': crowd_user["last-name"] or lastname,
            'groups': crowd_user["groups"],
            'email': crowd_user["email"] or email,
            'admin': admin,
            'active': active,
            'active_from_extern': crowd_user.get('active'), # ???
            'extern_name': crowd_user["name"],
        }

        # set an admin if we're in admin_groups of crowd
        for group in settings["admin_groups"].split(","):
            if group in user_data["groups"]:
                user_data["admin"] = True
        log.debug("Final crowd user object: \n%s", formatted_json(user_data))
        log.info('user %s authenticated correctly', user_data['username'])
        return user_data
Exemple #3
0
    def auth_settings(self):
        """POST create and store auth settings"""
        self.__load_defaults()
        _form = AuthSettingsForm(c.enabled_plugins)()
        log.debug("POST Result: %s" % formatted_json(dict(request.POST)))

        try:
            form_result = _form.to_python(dict(request.POST))
            for k, v in form_result.items():
                if k == 'auth_plugins':
                    # we want to store it comma separated inside our settings
                    v = ','.join(v)
                log.debug("%s = %s" % (k, str(v)))
                setting = Setting.create_or_update(k, v)
                Session().add(setting)
            Session().commit()
            h.flash(_('Auth settings updated successfully'),
                       category='success')
        except formencode.Invalid, errors:
            log.error(traceback.format_exc())
            e = errors.error_dict or {}
            return self.index(
                defaults=errors.value,
                errors=e,
                prefix_error=False)
    def __render(self, defaults, errors):
        c.defaults = {}
        c.plugin_settings = {}
        c.plugin_shortnames = {}

        for plugin in self.enabled_plugins:
            module = plugin.__class__.__module__
            c.plugin_shortnames[module] = plugin.name
            c.plugin_settings[module] = plugin.plugin_settings()
            for v in c.plugin_settings[module]:
                fullname = "auth_%s_%s" % (plugin.name, v["name"])
                if "default" in v:
                    c.defaults[fullname] = v["default"]
                # Current values will be the default on the form, if there are any
                setting = Setting.get_by_name(fullname)
                if setting is not None:
                    c.defaults[fullname] = setting.app_settings_value
        # we want to show , separated list of enabled plugins
        c.defaults['auth_plugins'] = ','.join(c.enabled_plugin_names)

        if defaults:
            c.defaults.update(defaults)

        log.debug(formatted_json(defaults))
        return formencode.htmlfill.render(
            render('admin/auth/auth_settings.html'),
            defaults=c.defaults,
            errors=errors,
            prefix_error=False,
            encoding="UTF-8",
            force_defaults=False)
Exemple #5
0
    def __render(self, defaults, errors):
        c.defaults = {}
        c.plugin_settings = {}
        c.plugin_shortnames = {}

        for plugin in self.enabled_plugins:
            module = plugin.__class__.__module__
            c.plugin_shortnames[module] = plugin.name
            c.plugin_settings[module] = plugin.plugin_settings()
            for v in c.plugin_settings[module]:
                fullname = "auth_%s_%s" % (plugin.name, v["name"])
                if "default" in v:
                    c.defaults[fullname] = v["default"]
                # Current values will be the default on the form, if there are any
                setting = Setting.get_by_name(fullname)
                if setting is not None:
                    c.defaults[fullname] = setting.app_settings_value
        # we want to show , separated list of enabled plugins
        c.defaults['auth_plugins'] = ','.join(c.enabled_plugin_names)

        if defaults:
            c.defaults.update(defaults)

        log.debug(formatted_json(defaults))
        return formencode.htmlfill.render(
            render('admin/auth/auth_settings.html'),
            defaults=c.defaults,
            errors=errors,
            prefix_error=False,
            encoding="UTF-8",
            force_defaults=False)
Exemple #6
0
    def auth(self, userobj, username, password, settings, **kwargs):
        if username not in _auth_cache:
            # Need lock here, as PAM authentication is not thread safe
            _pam_lock.acquire()
            try:
                auth_result = pam.authenticate(username, password,
                                               settings["service"])
                # cache result only if we properly authenticated
                if auth_result:
                    _auth_cache[username] = time.time()
            finally:
                _pam_lock.release()

            if not auth_result:
                log.error("PAM was unable to authenticate user: %s" %
                          (username, ))
                return None
        else:
            log.debug("Using cached auth for user: %s" % (username, ))

        # 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', '')
        extern_type = getattr(userobj, 'extern_type', '')

        user_attrs = {
            'username': username,
            'firstname': firstname,
            'lastname': lastname,
            'groups':
            [g.gr_name for g in grp.getgrall() if username in g.gr_mem],
            'email': email,
            'admin': admin,
            'active': active,
            "active_from_extern": None,
            'extern_name': username,
            'extern_type': extern_type,
        }

        try:
            user_data = pwd.getpwnam(username)
            regex = settings["gecos"]
            match = re.search(regex, user_data.pw_gecos)
            if match:
                user_attrs["firstname"] = match.group('first_name')
                user_attrs["lastname"] = match.group('last_name')
        except Exception:
            log.warning("Cannot extract additional info for PAM user %s",
                        username)
            pass

        log.debug("pamuser: \n%s" % formatted_json(user_attrs))
        log.info('user %s authenticated correctly' % user_attrs['username'])
        return user_attrs
Exemple #7
0
    def auth(self, userobj, username, password, settings, **kwargs):
        if not username:
            log.debug('Empty username - skipping...')
            return None
        if username not in _auth_cache:
            # Need lock here, as PAM authentication is not thread safe
            _pam_lock.acquire()
            try:
                auth_result = pam_authenticate(username, password,
                                               settings["service"])
                # cache result only if we properly authenticated
                if auth_result:
                    _auth_cache[username] = time.time()
            finally:
                _pam_lock.release()

            if not auth_result:
                log.error("PAM was unable to authenticate user: %s", username)
                return None
        else:
            log.debug("Using cached auth for user: %s", username)

        # 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', '')

        user_data = {
            'username': username,
            'firstname': firstname,
            'lastname': lastname,
            'groups': [g.gr_name for g in grp.getgrall() if username in g.gr_mem],
            'email': email,
            'admin': admin,
            'active': active,
            "active_from_extern": None,
            'extern_name': username,
        }

        try:
            user_pw_data = pwd.getpwnam(username)
            regex = settings["gecos"]
            match = re.search(regex, user_pw_data.pw_gecos)
            if match:
                user_data["firstname"] = match.group('first_name')
                user_data["lastname"] = match.group('last_name')
        except Exception:
            log.warning("Cannot extract additional info for PAM user %s", username)
            pass

        log.debug("pamuser: \n%s", formatted_json(user_data))
        log.info('user %s authenticated correctly', user_data['username'])
        return user_data
Exemple #8
0
    def auth_settings(self):
        """POST create and store auth settings"""
        self.__load_defaults()
        log.debug("POST Result: %s", formatted_json(dict(request.POST)))

        # First, parse only the plugin list (not the plugin settings).
        _auth_plugins_validator = AuthSettingsForm([]).fields['auth_plugins']
        try:
            new_enabled_plugins = _auth_plugins_validator.to_python(
                request.POST.get('auth_plugins'))
        except formencode.Invalid:
            # User provided an invalid plugin list. Just fall back to
            # the list of currently enabled plugins. (We'll re-validate
            # and show an error message to the user, below.)
            pass
        else:
            # Hide plugins that the user has asked to be disabled, but
            # do not show plugins that the user has asked to be enabled
            # (yet), since that'll cause validation errors and/or wrong
            # settings being applied (e.g. checkboxes being cleared),
            # since the plugin settings will not be in the POST data.
            c.enabled_plugin_names = [
                p for p in c.enabled_plugin_names if p in new_enabled_plugins
            ]

        # Next, parse everything including plugin settings.
        _form = AuthSettingsForm(c.enabled_plugin_names)()

        try:
            form_result = _form.to_python(dict(request.POST))
            for k, v in form_result.items():
                if k == 'auth_plugins':
                    # we want to store it comma separated inside our settings
                    v = ','.join(v)
                log.debug("%s = %s", k, str(v))
                setting = Setting.create_or_update(k, v)
            Session().commit()
            h.flash(_('Auth settings updated successfully'),
                    category='success')
        except formencode.Invalid as errors:
            log.error(traceback.format_exc())
            e = errors.error_dict or {}
            return self.__render(
                defaults=errors.value,
                errors=e,
            )
        except Exception:
            log.error(traceback.format_exc())
            h.flash(_('error occurred during update of auth settings'),
                    category='error')

        raise HTTPFound(location=url('auth_home'))
Exemple #9
0
    def auth_settings(self):
        """POST create and store auth settings"""
        self.__load_defaults()
        log.debug("POST Result: %s", formatted_json(dict(request.POST)))

        # First, parse only the plugin list (not the plugin settings).
        _auth_plugins_validator = AuthSettingsForm([]).fields['auth_plugins']
        try:
            new_enabled_plugins = _auth_plugins_validator.to_python(request.POST.get('auth_plugins'))
        except formencode.Invalid:
            # User provided an invalid plugin list. Just fall back to
            # the list of currently enabled plugins. (We'll re-validate
            # and show an error message to the user, below.)
            pass
        else:
            # Hide plugins that the user has asked to be disabled, but
            # do not show plugins that the user has asked to be enabled
            # (yet), since that'll cause validation errors and/or wrong
            # settings being applied (e.g. checkboxes being cleared),
            # since the plugin settings will not be in the POST data.
            c.enabled_plugins = [ p for p in c.enabled_plugins if p in new_enabled_plugins ]

        # Next, parse everything including plugin settings.
        _form = AuthSettingsForm(c.enabled_plugins)()

        try:
            form_result = _form.to_python(dict(request.POST))
            for k, v in form_result.items():
                if k == 'auth_plugins':
                    # we want to store it comma separated inside our settings
                    v = ','.join(v)
                log.debug("%s = %s", k, str(v))
                setting = Setting.create_or_update(k, v)
                Session().add(setting)
            Session().commit()
            h.flash(_('Auth settings updated successfully'),
                       category='success')
        except formencode.Invalid as errors:
            log.error(traceback.format_exc())
            e = errors.error_dict or {}
            return self.__render(
                defaults=errors.value,
                errors=e,
            )
        except Exception:
            log.error(traceback.format_exc())
            h.flash(_('error occurred during update of auth settings'),
                    category='error')

        raise HTTPFound(location=url('auth_home'))
Exemple #10
0
    def _request(self,
                 url,
                 body=None,
                 headers=None,
                 method=None,
                 noformat=False,
                 empty_response_ok=False):
        _headers = {
            "Content-type": "application/json",
            "Accept": "application/json"
        }
        if self.user and self.passwd:
            authstring = base64.b64encode("%s:%s" % (self.user, self.passwd))
            _headers["Authorization"] = "Basic %s" % authstring
        if headers:
            _headers.update(headers)
        log.debug("Sent crowd: \n%s" % (formatted_json({
            "url": url,
            "body": body,
            "headers": _headers
        })))
        request = urllib2.Request(url, body, _headers)
        if method:
            request.get_method = lambda: method

        global msg
        msg = ""
        try:
            rdoc = self.opener.open(request)
            msg = "".join(rdoc.readlines())
            if not msg and empty_response_ok:
                rval = {}
                rval["status"] = True
                rval["error"] = "Response body was empty"
            elif not noformat:
                rval = json.loads(msg)
                rval["status"] = True
            else:
                rval = "".join(rdoc.readlines())
        except Exception, e:
            if not noformat:
                rval = {
                    "status": False,
                    "body": body,
                    "error": str(e) + "\n" + msg
                }
            else:
                rval = None
Exemple #11
0
    def index(self, defaults=None, errors=None, prefix_error=False):
        self.__load_defaults()
        _defaults = {}
        # default plugins loaded
        formglobals = {
            "auth_plugins": ["kallithea.lib.auth_modules.auth_internal"]
        }
        formglobals.update(Setting.get_auth_settings())
        formglobals["plugin_settings"] = {}
        formglobals["auth_plugins_shortnames"] = {}
        _defaults["auth_plugins"] = formglobals["auth_plugins"]

        for module in formglobals["auth_plugins"]:
            plugin = auth_modules.loadplugin(module)
            plugin_name = plugin.name
            formglobals["auth_plugins_shortnames"][module] = plugin_name
            formglobals["plugin_settings"][module] = plugin.plugin_settings()
            for v in formglobals["plugin_settings"][module]:
                fullname = ("auth_" + plugin_name + "_" + v["name"])
                if "default" in v:
                    _defaults[fullname] = v["default"]
                # Current values will be the default on the form, if there are any
                setting = Setting.get_by_name(fullname)
                if setting:
                    _defaults[fullname] = setting.app_settings_value
        # we want to show , separated list of enabled plugins
        _defaults['auth_plugins'] = ','.join(_defaults['auth_plugins'])
        if defaults:
            _defaults.update(defaults)

        formglobals["defaults"] = _defaults
        # set template context variables
        for k, v in formglobals.iteritems():
            setattr(c, k, v)

        log.debug(pprint.pformat(formglobals, indent=4))
        log.debug(formatted_json(defaults))
        return formencode.htmlfill.render(
            render('admin/auth/auth_settings.html'),
            defaults=_defaults,
            errors=errors,
            prefix_error=prefix_error,
            encoding="UTF-8",
            force_defaults=False)
Exemple #12
0
    def index(self, defaults=None, errors=None, prefix_error=False):
        self.__load_defaults()
        _defaults = {}
        # default plugins loaded
        formglobals = {
            "auth_plugins": ["kallithea.lib.auth_modules.auth_internal"]
        }
        formglobals.update(Setting.get_auth_settings())
        formglobals["plugin_settings"] = {}
        formglobals["auth_plugins_shortnames"] = {}
        _defaults["auth_plugins"] = formglobals["auth_plugins"]

        for module in formglobals["auth_plugins"]:
            plugin = auth_modules.loadplugin(module)
            plugin_name = plugin.name
            formglobals["auth_plugins_shortnames"][module] = plugin_name
            formglobals["plugin_settings"][module] = plugin.plugin_settings()
            for v in formglobals["plugin_settings"][module]:
                fullname = ("auth_" + plugin_name + "_" + v["name"])
                if "default" in v:
                    _defaults[fullname] = v["default"]
                # Current values will be the default on the form, if there are any
                setting = Setting.get_by_name(fullname)
                if setting:
                    _defaults[fullname] = setting.app_settings_value
        # we want to show , separated list of enabled plugins
        _defaults['auth_plugins'] = ','.join(_defaults['auth_plugins'])
        if defaults:
            _defaults.update(defaults)

        formglobals["defaults"] = _defaults
        # set template context variables
        for k, v in formglobals.iteritems():
            setattr(c, k, v)

        log.debug(pprint.pformat(formglobals, indent=4))
        log.debug(formatted_json(defaults))
        return formencode.htmlfill.render(
            render('admin/auth/auth_settings.html'),
            defaults=_defaults,
            errors=errors,
            prefix_error=prefix_error,
            encoding="UTF-8",
            force_defaults=False)
    def auth(self, userobj, username, password, settings, **kwargs):
        if not userobj:
            log.debug('userobj was:%s skipping', userobj)
            return None
        if userobj.extern_type != self.name:
            log.warning(
                "userobj:%s extern_type mismatch got:`%s` expected:`%s`",
                userobj, userobj.extern_type, self.name)
            return None
        if not username:
            log.debug('Empty username - skipping...')
            return None

        user_data = {
            "username": userobj.username,
            "firstname": userobj.firstname,
            "lastname": userobj.lastname,
            "groups": [],
            "email": userobj.email,
            "admin": userobj.admin,
            "active": userobj.active,
            "active_from_extern": userobj.active,
            "extern_name": userobj.user_id,
        }

        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

            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
Exemple #14
0
    def auth(self, userobj, username, password, settings, **kwargs):
        if not userobj:
            log.debug('userobj was:%s skipping', userobj)
            return None
        if userobj.extern_type != self.name:
            log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`",
                     userobj, userobj.extern_type, self.name)
            return None
        if not username:
            log.debug('Empty username - skipping...')
            return None

        user_data = {
            "username": userobj.username,
            "firstname": userobj.firstname,
            "lastname": userobj.lastname,
            "groups": [],
            "email": userobj.email,
            "admin": userobj.admin,
            "active": userobj.active,
            "active_from_extern": userobj.active,
            "extern_name": userobj.user_id,
        }

        log.debug(formatted_json(user_data))
        if userobj.active:
            from kallithea.lib import auth
            password_match = auth.KallitheaCrypto.hash_check(password, userobj.password)
            if userobj.username == User.DEFAULT_USER and userobj.active:
                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
Exemple #15
0
    def auth(self, userobj, username, password, settings, **kwargs):
        if not userobj:
            log.debug('userobj was:%s skipping' % (userobj, ))
            return None
        if userobj.extern_type != self.name:
            log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`"
                     % (userobj, userobj.extern_type, self.name))
            return None

        user_attrs = {
            "username": userobj.username,
            "firstname": userobj.firstname,
            "lastname": userobj.lastname,
            "groups": [],
            "email": userobj.email,
            "admin": userobj.admin,
            "active": userobj.active,
            "active_from_extern": userobj.active,
            "extern_name": userobj.user_id,
            'extern_type': userobj.extern_type,
        }

        log.debug(formatted_json(user_attrs))
        if userobj.active:
            from kallithea.lib import auth
            password_match = auth.KallitheaCrypto.hash_check(password, userobj.password)
            if userobj.username == User.DEFAULT_USER and userobj.active:
                log.info('user %s authenticated correctly as anonymous user' %
                         username)
                return user_attrs

            elif userobj.username == username and password_match:
                log.info('user %s authenticated correctly' % user_attrs['username'])
                return user_attrs
            log.error("user %s had a bad password" % username)
            return None
        else:
            log.warning('user %s tried auth but is disabled' % username)
            return None
Exemple #16
0
    def _request(self, url, body=None, headers=None,
                 method=None, noformat=False,
                 empty_response_ok=False):
        _headers = {"Content-type": "application/json",
                    "Accept": "application/json"}
        if self.user and self.passwd:
            authstring = base64.b64encode("%s:%s" % (self.user, self.passwd))
            _headers["Authorization"] = "Basic %s" % authstring
        if headers:
            _headers.update(headers)
        log.debug("Sent crowd: \n%s",
                  formatted_json({"url": url, "body": body,
                                           "headers": _headers}))
        request = urllib2.Request(url, body, _headers)
        if method:
            request.get_method = lambda: method

        global msg
        msg = ""
        try:
            rdoc = self.opener.open(request)
            msg = "".join(rdoc.readlines())
            if not msg and empty_response_ok:
                rval = {}
                rval["status"] = True
                rval["error"] = "Response body was empty"
            elif not noformat:
                rval = json.loads(msg)
                rval["status"] = True
            else:
                rval = "".join(rdoc.readlines())
        except Exception as e:
            if not noformat:
                rval = {"status": False,
                        "body": body,
                        "error": str(e) + "\n" + msg}
            else:
                rval = None
        return rval
Exemple #17
0
    def auth_settings(self):
        """POST create and store auth settings"""
        self.__load_defaults()
        _form = AuthSettingsForm(c.enabled_plugins)()
        log.debug("POST Result: %s" % formatted_json(dict(request.POST)))

        try:
            form_result = _form.to_python(dict(request.POST))
            for k, v in form_result.items():
                if k == 'auth_plugins':
                    # we want to store it comma separated inside our settings
                    v = ','.join(v)
                log.debug("%s = %s" % (k, str(v)))
                setting = Setting.create_or_update(k, v)
                Session().add(setting)
            Session().commit()
            h.flash(_('Auth settings updated successfully'),
                    category='success')
        except formencode.Invalid, errors:
            log.error(traceback.format_exc())
            e = errors.error_dict or {}
            return self.index(defaults=errors.value,
                              errors=e,
                              prefix_error=False)
Exemple #18
0
def authenticate(username, password, environ=None):
    """
    Authentication function used for access control,
    It tries to authenticate based on enabled authentication modules.

    :param username: username can be empty for container auth
    :param password: password can be empty for container auth
    :param environ: environ headers passed for container auth
    :returns: None if auth failed, user_data dict if auth is correct
    """

    auth_plugins = Setting.get_auth_plugins()
    log.debug('Authentication against %s plugins', auth_plugins)
    for module in auth_plugins:
        try:
            plugin = loadplugin(module)
        except (ImportError, AttributeError, TypeError) as e:
            raise ImportError('Failed to load authentication module %s : %s'
                              % (module, str(e)))
        log.debug('Trying authentication using ** %s **', module)
        # load plugin settings from Kallithea database
        plugin_name = plugin.name
        plugin_settings = {}
        for v in plugin.plugin_settings():
            conf_key = "auth_%s_%s" % (plugin_name, v["name"])
            setting = Setting.get_by_name(conf_key)
            plugin_settings[v["name"]] = setting.app_settings_value if setting else None
        log.debug('Plugin settings \n%s', formatted_json(plugin_settings))

        if not str2bool(plugin_settings["enabled"]):
            log.info("Authentication plugin %s is disabled, skipping for %s",
                     module, username)
            continue

        # use plugin's method of user extraction.
        user = plugin.get_user(username, environ=environ,
                               settings=plugin_settings)
        log.debug('Plugin %s extracted user is `%s`', module, user)
        if not plugin.accepts(user):
            log.debug('Plugin %s does not accept user `%s` for authentication',
                      module, user)
            continue
        else:
            log.debug('Plugin %s accepted user `%s` for authentication',
                      module, user)
            # The user might have tried to authenticate using their email address,
            # then the username variable wouldn't contain a valid username.
            # But as the plugin has accepted the user, .username field should
            # have a valid username, so use it for authentication purposes.
            if user is not None:
                username = user.username

        log.info('Authenticating user using %s plugin', plugin.__module__)

        # _authenticate is a wrapper for .auth() method of plugin.
        # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin
        # it also maps users to Database and maps the attributes returned
        # from .auth() to Kallithea database. If this function returns data
        # then auth is correct.
        user_data = plugin._authenticate(user, username, password,
                                           plugin_settings,
                                           environ=environ or {})
        log.debug('PLUGIN USER DATA: %s', user_data)

        if user_data is not None:
            log.debug('Plugin returned proper authentication data')
            return user_data

        # we failed to Auth because .auth() method didn't return the user
        if username:
            log.warning("User `%s` failed to authenticate against %s",
                        username, plugin.__module__)
    return None
Exemple #19
0
def authenticate(username, password, environ=None):
    """
    Authentication function used for access control,
    It tries to authenticate based on enabled authentication modules.

    :param username: username can be empty for container auth
    :param password: password can be empty for container auth
    :param environ: environ headers passed for container auth
    :returns: None if auth failed, plugin_user dict if auth is correct
    """

    auth_plugins = Setting.get_auth_plugins()
    log.debug('Authentication against %s plugins' % (auth_plugins, ))
    for module in auth_plugins:
        try:
            plugin = loadplugin(module)
        except (ImportError, AttributeError, TypeError), e:
            raise ImportError('Failed to load authentication module %s : %s' %
                              (module, str(e)))
        log.debug('Trying authentication using ** %s **' % (module, ))
        # load plugin settings from Kallithea database
        plugin_name = plugin.name
        plugin_settings = {}
        for v in plugin.plugin_settings():
            conf_key = "auth_%s_%s" % (plugin_name, v["name"])
            setting = Setting.get_by_name(conf_key)
            plugin_settings[
                v["name"]] = setting.app_settings_value if setting else None
        log.debug('Plugin settings \n%s' % formatted_json(plugin_settings))

        if not str2bool(plugin_settings["enabled"]):
            log.info("Authentication plugin %s is disabled, skipping for %s" %
                     (module, username))
            continue

        # use plugin's method of user extraction.
        user = plugin.get_user(username,
                               environ=environ,
                               settings=plugin_settings)
        log.debug('Plugin %s extracted user is `%s`' % (module, user))
        if not plugin.accepts(user):
            log.debug(
                'Plugin %s does not accept user `%s` for authentication' %
                (module, user))
            continue
        else:
            log.debug('Plugin %s accepted user `%s` for authentication' %
                      (module, user))

        log.info('Authenticating user using %s plugin' % plugin.__module__)
        # _authenticate is a wrapper for .auth() method of plugin.
        # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin
        # it also maps users to Database and maps the attributes returned
        # from .auth() to Kallithea database. If this function returns data
        # then auth is correct.
        plugin_user = plugin._authenticate(user,
                                           username,
                                           password,
                                           plugin_settings,
                                           environ=environ or {})
        log.debug('PLUGIN USER DATA: %s' % plugin_user)

        if plugin_user:
            log.debug('Plugin returned proper authentication data')
            return plugin_user

        # we failed to Auth because .auth() method didn't return proper the user
        if username:
            log.warning("User `%s` failed to authenticate against %s" %
                        (username, plugin.__module__))
Exemple #20
0
def authenticate(username, password, environ=None):
    """
    Authentication function used for access control,
    It tries to authenticate based on enabled authentication modules.

    :param username: username can be empty for container auth
    :param password: password can be empty for container auth
    :param environ: environ headers passed for container auth
    :returns: None if auth failed, user_data dict if auth is correct
    """

    auth_plugins = get_auth_plugins()
    for plugin in auth_plugins:
        module = plugin.__class__.__module__
        log.debug('Trying authentication using %s', module)
        # load plugin settings from Kallithea database
        plugin_name = plugin.name
        plugin_settings = {}
        for v in plugin.plugin_settings():
            conf_key = "auth_%s_%s" % (plugin_name, v["name"])
            setting = Setting.get_by_name(conf_key)
            plugin_settings[
                v["name"]] = setting.app_settings_value if setting else None
        log.debug('Settings for auth plugin %s:\n%s', plugin_name,
                  formatted_json(plugin_settings))

        if not str2bool(plugin_settings["enabled"]):
            log.info("Authentication plugin %s is disabled, skipping for %s",
                     module, username)
            continue

        # use plugin's method of user extraction.
        user = plugin.get_user(username,
                               environ=environ,
                               settings=plugin_settings)
        log.debug('Plugin %s extracted user `%s`', module, user)
        if not plugin.accepts(user):
            log.debug('Plugin %s does not accept user `%s` for authentication',
                      module, user)
            continue
        else:
            log.debug('Plugin %s accepted user `%s` for authentication',
                      module, user)
            # The user might have tried to authenticate using their email address,
            # then the username variable wouldn't contain a valid username.
            # But as the plugin has accepted the user, .username field should
            # have a valid username, so use it for authentication purposes.
            if user is not None:
                username = user.username

        log.info('Authenticating user using %s plugin', module)

        # _authenticate is a wrapper for .auth() method of plugin.
        # it checks if .auth() sends proper data. For KallitheaExternalAuthPlugin
        # it also maps users to Database and maps the attributes returned
        # from .auth() to Kallithea database. If this function returns data
        # then auth is correct.
        user_data = plugin._authenticate(user,
                                         username,
                                         password,
                                         plugin_settings,
                                         environ=environ or {})
        log.debug('Plugin user data: %s', user_data)

        if user_data is not None:
            log.debug('Plugin returned proper authentication data')
            return user_data

        # we failed to Auth because .auth() method didn't return the user
        if username:
            log.warning("User `%s` failed to authenticate against %s",
                        username, module)
    return None