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)
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)
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)
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.'))
def login(self, user_obj, **kw): self.log('login', user_obj, kw) return ContinueLogin(user_obj)