예제 #1
0
파일: openidrp.py 프로젝트: steel-ne/moin
    def login(self, userobj, **kw):
        """
        Handles an login request and continues to multistage continuation
        if necessary.
        """
        continuation = kw.get('multistage')
        # process another subsequent step
        if continuation:
            return self._handleContinuation()

        openid = kw.get('openid')
        # no openid entered
        if not openid:
            return ContinueLogin(userobj)

        # we make a consumer object with an in-memory storage
        oid_consumer = consumer.Consumer(session, self.store)

        # we catch any possible openid-related exceptions
        try:
            oid_response = oid_consumer.begin(openid)
        except HTTPFetchingError:
            return ContinueLogin(None, _('Failed to resolve OpenID.'))
        except DiscoveryFailure:
            return ContinueLogin(
                None, _('OpenID discovery failure, not a valid OpenID.'))
        else:
            # we got no response from the service
            if oid_response is None:
                return ContinueLogin(None, _('No OpenID service at this URL.'))

            # site root and where to return after the redirect
            site_root = url_for('frontend.show_root', _external=True)
            return_to = get_multistage_continuation_url(
                self.name, {'oidstage': '1'})

            # should we redirect the user?
            if oid_response.shouldSendRedirect():
                redirect_url = oid_response.redirectURL(site_root, return_to)
                return MultistageRedirectLogin(redirect_url)
            else:
                # send a form
                form_html = oid_response.htmlMarkup(
                    site_root,
                    return_to,
                    form_tag_attrs={'id': 'openid_message'})

                # returns a MultistageFormLogin
                return MultistageFormLogin(form_html)
예제 #2
0
    def login(self, user_obj, **kw):
        username = kw.get('username')
        password = kw.get('password')

        # we require non-empty password as ldap bind does a anon (not password
        # protected) bind if the password is empty and SUCCEEDS!
        if not password:
            return ContinueLogin(user_obj, _('Missing password. Please enter user name and password.'))

        try:
            try:
                u = None
                dn = None
                server = self.server_uri
                coding = self.coding
                logging.debug("Setting misc. ldap options...")
                ldap.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)  # ldap v2 is outdated
                ldap.set_option(ldap.OPT_REFERRALS, self.referrals)
                ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout)

                if hasattr(ldap, 'TLS_AVAIL') and ldap.TLS_AVAIL:
                    for option, value in (
                        (ldap.OPT_X_TLS_CACERTDIR, self.tls_cacertdir),
                        (ldap.OPT_X_TLS_CACERTFILE, self.tls_cacertfile),
                        (ldap.OPT_X_TLS_CERTFILE, self.tls_certfile),
                        (ldap.OPT_X_TLS_KEYFILE, self.tls_keyfile),
                        (ldap.OPT_X_TLS_REQUIRE_CERT, self.tls_require_cert),
                        (ldap.OPT_X_TLS, self.start_tls),
                        # (ldap.OPT_X_TLS_ALLOW, 1),
                    ):
                        if value is not None:
                            ldap.set_option(option, value)

                logging.debug("Trying to initialize {0!r}.".format(server))
                conn = ldap.initialize(server)
                logging.debug("Connected to LDAP server {0!r}.".format(server))

                if self.start_tls and server.startswith('ldap:'):
                    logging.debug("Trying to start TLS to {0!r}.".format(server))
                    try:
                        conn.start_tls_s()
                        logging.debug("Using TLS to {0!r}.".format(server))
                    except (ldap.SERVER_DOWN, ldap.CONNECT_ERROR) as err:
                        logging.warning("Couldn't establish TLS to {0!r} (err: {1!s}).".format(server, err))
                        raise

                # you can use %(username)s and %(password)s here to get the stuff entered in the form:
                binddn = self.bind_dn % locals()
                bindpw = self.bind_pw % locals()
                conn.simple_bind_s(binddn.encode(coding), bindpw.encode(coding))
                logging.debug("Bound with binddn {0!r}".format(binddn))

                # you can use %(username)s here to get the stuff entered in the form:
                filterstr = self.search_filter % locals()
                logging.debug("Searching {0!r}".format(filterstr))
                attrs = [getattr(self, attr) for attr in [
                    'email_attribute',
                    'displayname_attribute',
                    'surname_attribute',
                    'givenname_attribute',
                ] if getattr(self, attr) is not None]
                lusers = conn.search_st(self.base_dn, self.scope, filterstr.encode(coding),
                                     attrlist=attrs, timeout=self.timeout)
                # we remove entries with dn == None to get the real result list:
                lusers = [(_dn, _ldap_dict) for _dn, _ldap_dict in lusers if _dn is not None]
                for _dn, _ldap_dict in lusers:
                    logging.debug("dn:{0!r}".format(_dn))
                    for key, val in _ldap_dict.items():
                        logging.debug("    {0!r}: {1!r}".format(key, val))

                result_length = len(lusers)
                if result_length != 1:
                    if result_length > 1:
                        logging.warning("Search found more than one ({0}) matches for {1!r}.".format(
                            result_length, filterstr))
                    if result_length == 0:
                        logging.debug("Search found no matches for {0!r}.".format(filterstr, ))
                    if self.report_invalid_credentials:
                        return ContinueLogin(user_obj, _("Invalid username or password."))
                    else:
                        return ContinueLogin(user_obj)

                dn, ldap_dict = lusers[0]
                if not self.bind_once:
                    logging.debug("DN found is {0!r}, trying to bind with pw".format(dn))
                    conn.simple_bind_s(dn, password.encode(coding))
                    logging.debug("Bound with dn {0!r} (username: {1!r})".format(dn, username))

                if self.email_callback is None:
                    if self.email_attribute:
                        email = ldap_dict.get(self.email_attribute, [''])[0].decode(coding)
                    else:
                        email = None
                else:
                    email = self.email_callback(ldap_dict)

                display_name = ''
                try:
                    display_name = ldap_dict[self.displayname_attribute][0]
                except (KeyError, IndexError):
                    pass
                if not display_name:
                    sn = ldap_dict.get(self.surname_attribute, [''])[0]
                    gn = ldap_dict.get(self.givenname_attribute, [''])[0]
                    if sn and gn:
                        display_name = "{0}, {1}".format(sn, gn)
                    elif sn:
                        display_name = sn
                display_name = display_name.decode(coding)

                if self.name_callback:
                    username = self.name_callback(ldap_dict)

                if email:
                    u = user.User(auth_username=username, auth_method=self.name,
                                  auth_attribs=('name', 'password', 'email', 'mailto_author', ),
                                  trusted=self.trusted)
                    u.email = email
                else:
                    u = user.User(auth_username=username, auth_method=self.name,
                                  auth_attribs=('name', 'password', 'mailto_author', ),
                                  trusted=self.trusted)
                u.name = username
                u.display_name = display_name
                logging.debug("creating user object with name {0!r} email {1!r} display name {2!r}".format(
                    username, email, display_name))

            except ldap.INVALID_CREDENTIALS as err:
                logging.debug("invalid credentials (wrong password?) for dn {0!r} (username: {1!r})".format(
                    dn, username))
                return CancelLogin(_("Invalid username or password."))

            if u and self.autocreate:
                logging.debug("calling create_or_update to autocreate user {0!r}".format(u.name))
                u.create_or_update(True)
            return ContinueLogin(u)

        except ldap.SERVER_DOWN as err:
            # looks like this LDAP server isn't working, so we just try the next
            # authenticator object in cfg.auth list (there could be some second
            # ldap authenticator that queries a backup server or any other auth
            # method).
            logging.error("LDAP server {0} failed ({1!s}). "
                          "Trying to authenticate with next auth list entry.".format(server, err))
            return ContinueLogin(user_obj, _("LDAP server %(server)s failed.", server=server))

        except:  # noqa
            logging.exception("caught an exception, traceback follows...")
            return ContinueLogin(user_obj)
예제 #3
0
 def login(self, user_obj, **kw):
     username = kw.get('username')
     password = kw.get('password')
     if user_obj and user_obj.valid:
         self.do_smb(username, password, True)
     return ContinueLogin(user_obj)
예제 #4
0
파일: openidrp.py 프로젝트: steel-ne/moin
    def _handleContinuationVerify(self):
        """
        Handles the first stage continuation.
        """
        # the consumer object with an in-memory storage
        oid_consumer = consumer.Consumer(session, self.store)

        # a dict containing the parsed query string
        query = {}
        for key in request.values.keys():
            query[key] = request.values.get(key)
        # the current url (w/o query string)
        url = get_multistage_continuation_url(self.name, {'oidstage': '1'})

        # we get the info about the authentication
        oid_info = oid_consumer.complete(query, url)
        # the identity we've retrieved from the response
        if oid_info.status == consumer.FAILURE:
            # verification has failed
            # return an error message with description of error
            logging.debug("OpenIDError: {0}".format(oid_info.message))

            error_message = _('OpenID Error')
            return CancelLogin(error_message)
        elif oid_info.status == consumer.CANCEL:
            logging.debug("OpenID verification cancelled.")

            # verification was cancelled
            # return error
            return CancelLogin(_('OpenID verification cancelled.'))
        elif oid_info.status == consumer.SUCCESS:
            logging.debug('OpenID success. id: {0}'.format(
                oid_info.identity_url))

            # we get the provider's url
            # and the list of trusted providers
            trusted = self._trusted_providers
            server = oid_info.endpoint.server_url

            if server in trusted or not trusted:
                # the provider is trusted or all providers are trusted
                # we have successfully authenticated our openid
                # we get the user with this openid associated to him
                identity = oid_info.identity_url
                users = user.search_users(openid=identity)
                user_obj = users and user.User(uid=users[0].item.itemid,
                                               trusted=self.trusted,
                                               auth_method=self.name)

                # if the user actually exists
                if user_obj:
                    # we get the authenticated user object
                    # success!
                    user_obj.auth_method = self.name
                    flash(_('You have logged in with OpenID.'), "info")
                    return ContinueLogin(user_obj)

                # there is no user with this openid
                else:
                    # redirect the user to registration
                    return MultistageRedirectLogin(
                        url_for('frontend.register',
                                _external=True,
                                openid_openid=identity,
                                openid_submit='1'))

            # not trusted
            return ContinueLogin(None,
                                 _('This OpenID provider is not trusted.'))

        else:
            logging.debug("OpenID failure")
            # the auth failed miserably
            return CancelLogin(_('OpenID failure.'))
예제 #5
0
파일: log.py 프로젝트: wobsta/moin
 def login(self, user_obj, **kw):
     self.log('login', user_obj, kw)
     return ContinueLogin(user_obj)