def login(self, request, user_obj, **kw): _ = request.getText logging.debug("got: user_obj=%r" % user_obj) if not (user_obj and user_obj.valid): # No other method succeeded, so we cannot authorize # but maybe some following auth methods can still "fix" that. logging.debug("did not get valid user from previous auth method") return ContinueLogin(user_obj) # Got a valid user object - we can do stuff! logging.debug("got valid user (name=%r) from previous auth method" % user_obj.auth_username) # XXX Check auth_username for dodgy chars (should be none as it is authenticated, but...) # shouldn't really be necessary since execute() quotes them all... # OK, now check mysql! try: m = MySQLdb.connect(host=self.host, user=self.user, passwd=self.passwd, db=self.dbname) except: logging.exception("authorization failed due to exception when connecting to DB, traceback follows...") return CancelLogin(_('Failed to connect to database.')) c = m.cursor() c.execute(self.mysql_group_query, user_obj.auth_username) results = c.fetchall() if results: # Checked out OK logging.debug("got %d results -- authorized!" % len(results)) return ContinueLogin(user_obj) else: logging.debug("did not get match from DB -- not authorized") return CancelLogin(_("Invalid username or password."))
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 _handle_name_continuation(self, request): _ = request.getText logging.debug('openid %s' % request.session) logging.debug('openid %s' % request.form.get('openid_identifier')) if not 'openid.id' in request.session: return CancelLogin(_('No OpenID found in session.')) newname = request.form.get('username', '') if not newname: return MultistageFormLogin(self._get_account_name) if not user.isValidName(request, newname): return MultistageFormLogin(self._get_account_name_inval_user) uid = None if newname: uid = user.getUserId(request, newname) if not uid: # we can create a new user with this name :) u = user.User(request, auth_method=self.name, auth_username=request.session['openid.id'], auth_attribs=self.auth_attribs) u.name = newname u = self._handle_user_data(request, u) return ContinueLogin(u) # requested username already exists. if they know the password, # they can associate that account with the openid. assoc = lambda req, form: self._associate_account(req, form, newname) return MultistageFormLogin(assoc)
def login(self, request, user_obj, **kw): if kw.get('multistage'): uid = request.session.get('botbouncer.uid', None) if not uid: return CancelLogin(None) openid = request.session['botbouncer.id'] del request.session['botbouncer.id'] del request.session['botbouncer.uid'] user_obj = user.User(request, uid, auth_method='openid', auth_username=openid) if not user_obj or not user_obj.valid: return ContinueLogin(user_obj) if user_obj.auth_method != 'openid': return ContinueLogin(user_obj) openid_id = user_obj.auth_username _ = request.getText try: url = "http://botbouncer.com/api/info?openid=%s&api_key=%s" % ( quote_plus(openid_id), self.apikey) data = urlopen(url).read().strip() except IOError: return CancelLogin(_('Could not contact botbouncer.com.')) data = data.split(':') if len(data) != 2 or data[0] != 'verified': return CancelLogin( 'botbouncer.com verification failed, probably invalid API key.' ) if data[1].lower() == 'true': # they proved they are human already return ContinueLogin(user_obj) # tell them to verify at bot bouncer first request.session['botbouncer.id'] = openid_id request.session['botbouncer.uid'] = user_obj.id goto = "http://botbouncer.com/captcha/queryuser?return_to=%%return_form&openid=%s" % ( quote_plus(request.session['botbouncer.id'])) return MultistageRedirectLogin(goto)
def login(self, request, user_obj, **kw): open_id = kw.get('openid_identifier') oidstage = request.form.get('oidstage') logging.info('stage %s' % oidstage) logging.info('params: %s' % kw) if open_id or oidstage: return self._handle_continuation(request) else: return ContinueLogin(user_obj)
def _handle_verify_continuation(self, request): _ = request.getText oidconsumer = consumer.Consumer(request.session, MoinOpenIDStore(request)) query = {} for key in request.values.keys(): query[key] = request.values.get(key) current_url = get_multistage_continuation_url(request, self.name, {'oidstage': '1'}) info = oidconsumer.complete(query, current_url) if info.status == consumer.FAILURE: logging.debug(_("OpenID error: %s.") % info.message) return CancelLogin(_('OpenID error: %s.') % info.message) elif info.status == consumer.CANCEL: logging.debug(_("OpenID verification canceled.")) return CancelLogin(_('Verification canceled.')) elif info.status == consumer.SUCCESS: logging.debug(_("OpenID success. id: %s") % info.identity_url) request.session['openid.id'] = info.identity_url request.session['openid.info'] = info # try to find user object uid = user.getUserIdByOpenId(request, info.identity_url) if uid: u = user.User(request, id=uid, auth_method=self.name, auth_username=info.identity_url, auth_attribs=self.auth_attribs) else: u = None # create or update the user according to the registration data u = self._handle_user_data(request, u) if u: return ContinueLogin(u) # if no user found, then we need to ask for a username, # possibly associating an existing account. logging.debug("OpenID: No user found, prompting for username") #request.session['openid.id'] = info.identity_url return MultistageFormLogin(self._get_account_name) else: logging.debug(_("OpenID failure")) return CancelLogin(_('OpenID failure.'))
def login(self, request, user_obj, **kw): username = kw.get('username') password = kw.get('password') if not username or not password: return ContinueLogin(user_obj) logging.debug("trying to authenticate %r" % username) wikiname, username = username.split(' ', 1) # XXX Hack because ':' is not allowed in name field wikitag, wikiurl, name, err = wikiutil.resolve_interwiki(request, wikiname, username) logging.debug("resolve wiki returned: %r %r %r %r" % (wikitag, wikiurl, name, err)) if err or wikitag not in self.trusted_wikis: return ContinueLogin(user_obj) homewiki = xmlrpclib.ServerProxy(wikiurl + "?action=xmlrpc2") auth_token = homewiki.getAuthToken(name, password) if not auth_token: logging.debug("%r wiki did not return an auth token." % wikitag) return ContinueLogin(user_obj) logging.debug("successfully got an auth token for %r. trying to get user profile data..." % name) mc = xmlrpclib.MultiCall(homewiki) mc.applyAuthToken(auth_token) mc.getUserProfile() result, account_data = mc() if result != "SUCCESS": logging.debug("%r wiki did not accept auth token." % wikitag) return ContinueLogin(None) if not account_data: logging.debug("%r wiki did not return a user profile." % wikitag) return ContinueLogin(None) logging.debug("%r wiki returned a user profile." % wikitag) # TODO: check remote auth_attribs u = user.User(request, name=name, auth_method=self.name, auth_attribs=('name', 'aliasname', 'password', 'email', )) for key, value in account_data.iteritems(): if key not in request.cfg.user_transient_fields: setattr(u, key, value) u.valid = True if self.autocreate: u.create_or_update(True) logging.debug("successful interwiki auth for %r" % name) return ContinueLogin(u)
def _handle_verify_continuation(self, request): _ = request.getText info = {} #Response() #info.status = 'success' openid = request.form.get('openid_identifier') if openid: logging.debug(_("OpenID success. id: %s") % openid) request.session['openid.id'] = openid request.session['openid.info'] = info # try to find user object uid = user.getUserIdByOpenId(request, openid) logging.debug('openid %s' % request.session['openid.id']) logging.debug('uid %s' % uid) if uid: u = user.User(request, id=uid, auth_method=self.name, auth_username=openid, auth_attribs=self.auth_attribs) else: u = None # create or update the user according to the registration data u = self._handle_user_data(request, u) if u: return ContinueLogin(u) # if no user found, then we need to ask for a username, # possibly associating an existing account. logging.debug("OpenID: No user found, prompting for username") #request.session['openid.id'] = info.identity_url return MultistageFormLogin(self._get_account_name) else: logging.debug(_("OpenID failure")) return CancelLogin(_('Unable to get OpenID.'))
def _handle_associate_continuation(self, request): if not 'openid.id' in request.session: return CancelLogin(_('No OpenID found in session.')) _ = request.getText username = request.form.get('username', '') password = request.form.get('password', '') if not password: return self._handle_name_continuation(request) u = user.User(request, name=username, password=password, auth_method=self.name, auth_username=request.session['openid.id'], auth_attribs=self.auth_attribs) if u.valid: self._handle_user_data(request, u) return ContinueLogin( u, _('Your account is now associated to your OpenID.')) else: msg = _('The password you entered is not valid.') assoc = lambda req, form: self._associate_account( req, form, username, msg=msg) return MultistageFormLogin(assoc)
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)) l = 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: l.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() l.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 = l.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)) l.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: logging.exception("caught an exception, traceback follows...") return ContinueLogin(user_obj)
def login(self, request, user_obj, **kw): username = kw.get('username') password = kw.get('password') if user_obj and user_obj.valid: self.do_smb(request, username, password, True) return ContinueLogin(user_obj)
class LDAPAuth(BaseAuth): """ get authentication data from form, authenticate against LDAP (or Active Directory), fetch some user infos from LDAP and create a user object for that user. The session is kept by moin automatically. """ login_inputs = ['username', 'password'] logout_possible = True name = 'ldap' def __init__( self, server_uri='ldap://localhost', # ldap / active directory server URI # use ldaps://server:636 url for ldaps, # use ldap://server for ldap without tls (and set start_tls to 0), # use ldap://server for ldap with tls (and set start_tls to 1 or 2). bind_dn='', # We can either use some fixed user and password for binding to LDAP. # Be careful if you need a % char in those strings - as they are used as # a format string, you have to write %% to get a single % in the end. #bind_dn = '*****@*****.**' # (AD) #bind_dn = 'cn=admin,dc=example,dc=org' # (OpenLDAP) #bind_pw = 'secret' # or we can use the username and password we got from the user: #bind_dn = '%(username)[email protected]' # DN we use for first bind (AD) #bind_pw = '%(password)s' # password we use for first bind # or we can bind anonymously (if that is supported by your directory). # In any case, bind_dn and bind_pw must be defined. bind_pw='', base_dn='', # base DN we use for searching #base_dn = 'ou=SOMEUNIT,dc=example,dc=org' scope=ldap. SCOPE_SUBTREE, # scope of the search we do (2 == ldap.SCOPE_SUBTREE) referrals=0, # LDAP REFERRALS (0 needed for AD) search_filter='(uid=%(username)s)', # ldap filter used for searching: #search_filter = '(sAMAccountName=%(username)s)' # (AD) #search_filter = '(uid=%(username)s)' # (OpenLDAP) # you can also do more complex filtering like: # "(&(cn=%(username)s)(memberOf=CN=WikiUsers,OU=Groups,DC=example,DC=org))" # some attribute names we use to extract information from LDAP: givenname_attribute=None, # ('givenName') ldap attribute we get the first name from surname_attribute=None, # ('sn') ldap attribute we get the family name from aliasname_attribute=None, # ('displayName') ldap attribute we get the aliasname from email_attribute=None, # ('mail') ldap attribute we get the email address from email_callback=None, # called to make up email address name_callback=None, # called to use a Wiki name different from the login name coding='utf-8', # coding used for ldap queries and result values timeout=10, # how long we wait for the ldap server [s] start_tls=0, # 0 = No, 1 = Try, 2 = Required tls_cacertdir=None, tls_cacertfile=None, tls_certfile=None, tls_keyfile=None, tls_require_cert=0, # 0 == ldap.OPT_X_TLS_NEVER (needed for self-signed certs) bind_once=False, # set to True to only do one bind - useful if configured to bind as the user on the first attempt autocreate=False, # set to True if you want to autocreate user profiles name='ldap', # use e.g. 'ldap_pdc' and 'ldap_bdc' (or 'ldap1' and 'ldap2') if you auth against 2 ldap servers report_invalid_credentials=True, # whether to emit "invalid username or password" msg at login time or not ): self.server_uri = server_uri self.bind_dn = bind_dn self.bind_pw = bind_pw self.base_dn = base_dn self.scope = scope self.referrals = referrals self.search_filter = search_filter self.givenname_attribute = givenname_attribute self.surname_attribute = surname_attribute self.aliasname_attribute = aliasname_attribute self.email_attribute = email_attribute self.email_callback = email_callback self.name_callback = name_callback self.coding = coding self.timeout = timeout self.start_tls = start_tls self.tls_cacertdir = tls_cacertdir self.tls_cacertfile = tls_cacertfile self.tls_certfile = tls_certfile self.tls_keyfile = tls_keyfile self.tls_require_cert = tls_require_cert self.bind_once = bind_once self.autocreate = autocreate self.name = name self.report_invalid_credentials = report_invalid_credentials def login(self, request, user_obj, **kw): username = kw.get('username') password = kw.get('password') _ = request.getText # 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 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) server = self.server_uri logging.debug("Trying to initialize %r." % server) l = ldap.initialize(server) logging.debug("Connected to LDAP server %r." % server) if self.start_tls and server.startswith('ldap:'): logging.debug("Trying to start TLS to %r." % server) try: l.start_tls_s() logging.debug("Using TLS to %r." % server) except (ldap.SERVER_DOWN, ldap.CONNECT_ERROR), err: logging.warning( "Couldn't establish TLS to %r (err: %s)." % (server, str(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() l.simple_bind_s(binddn.encode(coding), bindpw.encode(coding)) logging.debug("Bound with binddn %r" % binddn) # you can use %(username)s here to get the stuff entered in the form: filterstr = self.search_filter % locals() logging.debug("Searching %r" % filterstr) attrs = [ getattr(self, attr) for attr in [ 'email_attribute', 'aliasname_attribute', 'surname_attribute', 'givenname_attribute', ] if getattr(self, attr) is not None ] lusers = l.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:%r" % dn) for key, val in ldap_dict.items(): logging.debug(" %r: %r" % (key, val)) result_length = len(lusers) if result_length != 1: if result_length > 1: logging.warning( "Search found more than one (%d) matches for %r." % (result_length, filterstr)) if result_length == 0: logging.debug("Search found no matches for %r." % (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 %r, trying to bind with pw" % dn) l.simple_bind_s(dn, password.encode(coding)) logging.debug("Bound with dn %r (username: %r)" % (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) aliasname = '' try: aliasname = ldap_dict[self.aliasname_attribute][0] except (KeyError, IndexError): pass if not aliasname: sn = ldap_dict.get(self.surname_attribute, [''])[0] gn = ldap_dict.get(self.givenname_attribute, [''])[0] if sn and gn: aliasname = "%s, %s" % (sn, gn) elif sn: aliasname = sn aliasname = aliasname.decode(coding) if self.name_callback: username = self.name_callback(ldap_dict) if email: u = user.User(request, auth_username=username, auth_method=self.name, auth_attribs=( 'name', 'password', 'email', 'mailto_author', )) u.email = email else: u = user.User(request, auth_username=username, auth_method=self.name, auth_attribs=( 'name', 'password', 'mailto_author', )) u.name = username u.aliasname = aliasname u.remember_me = 0 # 0 enforces cookie_lifetime config param logging.debug( "creating user object with name %r email %r alias %r" % (username, email, aliasname)) except ldap.INVALID_CREDENTIALS, err: logging.debug( "invalid credentials (wrong password?) for dn %r (username: %r)" % (dn, username)) return CancelLogin(_("Invalid username or password.")) if u and self.autocreate: logging.debug( "calling create_or_update to autocreate user %r" % u.name) u.create_or_update(True) return ContinueLogin(u)
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(users[0][ITEMID], trusted=self.trusted) # if the user actually exists if user_obj: # we get the authenticated user object # success! user_obj.auth_method = self.name 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.'))
u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'email', 'mailto_author', )) u.email = email else: u = user.User(auth_username=username, auth_method=self.name, auth_attribs=('name', 'password', 'mailto_author', )) u.name = username u.aliasname = aliasname logging.debug("creating user object with name %r email %r alias %r" % (username, email, aliasname)) except ldap.INVALID_CREDENTIALS, err: logging.debug("invalid credentials (wrong password?) for dn %r (username: %r)" % (dn, username)) return CancelLogin(_("Invalid username or password.")) if u and self.autocreate: logging.debug("calling create_or_update to autocreate user %r" % u.name) u.create_or_update(True) return ContinueLogin(u) except ldap.SERVER_DOWN, 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 %s failed (%s). " "Trying to authenticate with next auth list entry." % (server, str(err))) return ContinueLogin(user_obj, _("LDAP server %(server)s failed.", server=server)) except: logging.exception("caught an exception, traceback follows...") return ContinueLogin(user_obj)
def login(self, request, user_obj, **kw): self.log(request, 'login', user_obj, kw) return ContinueLogin(user_obj)
"creating user object with name %r email %r alias %r" % (username, email, aliasname)) except ldap.INVALID_CREDENTIALS, err: logging.debug( "invalid credentials (wrong password?) for dn %r (username: %r)" % (dn, username)) return CancelLogin(_("Invalid username or password.")) if u and self.autocreate: logging.debug( "calling create_or_update to autocreate user %r" % u.name) u.create_or_update(True) return ContinueLogin(u) except ldap.SERVER_DOWN, 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 %s failed (%s). " "Trying to authenticate with next auth list entry." % (server, str(err))) return ContinueLogin( user_obj, _("LDAP server %(server)s failed.") % {'server': server}) except: logging.exception("caught an exception, traceback follows...") return ContinueLogin(user_obj)
def login(self, request, user_obj, **kw): username = kw.get('username') password = kw.get('password') _ = request.getText # 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 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) server = self.server_uri logging.debug("Trying to initialize %r." % server) l = ldap.initialize(server) logging.debug("Connected to LDAP server %r." % server) if self.start_tls and server.startswith('ldap:'): logging.debug("Trying to start TLS to %r." % server) try: l.start_tls_s() logging.debug("Using TLS to %r." % server) except (ldap.SERVER_DOWN, ldap.CONNECT_ERROR), err: logging.warning( "Couldn't establish TLS to %r (err: %s)." % (server, str(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() l.simple_bind_s(binddn.encode(coding), bindpw.encode(coding)) logging.debug("Bound with binddn %r" % binddn) # you can use %(username)s here to get the stuff entered in the form: filterstr = self.search_filter % locals() logging.debug("Searching %r" % filterstr) attrs = [ getattr(self, attr) for attr in [ 'email_attribute', 'aliasname_attribute', 'surname_attribute', 'givenname_attribute', ] if getattr(self, attr) is not None ] lusers = l.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:%r" % dn) for key, val in ldap_dict.items(): logging.debug(" %r: %r" % (key, val)) result_length = len(lusers) if result_length != 1: if result_length > 1: logging.warning( "Search found more than one (%d) matches for %r." % (result_length, filterstr)) if result_length == 0: logging.debug("Search found no matches for %r." % (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 %r, trying to bind with pw" % dn) l.simple_bind_s(dn, password.encode(coding)) logging.debug("Bound with dn %r (username: %r)" % (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) aliasname = '' try: aliasname = ldap_dict[self.aliasname_attribute][0] except (KeyError, IndexError): pass if not aliasname: sn = ldap_dict.get(self.surname_attribute, [''])[0] gn = ldap_dict.get(self.givenname_attribute, [''])[0] if sn and gn: aliasname = "%s, %s" % (sn, gn) elif sn: aliasname = sn aliasname = aliasname.decode(coding) if self.name_callback: username = self.name_callback(ldap_dict) if email: u = user.User(request, auth_username=username, auth_method=self.name, auth_attribs=( 'name', 'password', 'email', 'mailto_author', )) u.email = email else: u = user.User(request, auth_username=username, auth_method=self.name, auth_attribs=( 'name', 'password', 'mailto_author', )) u.name = username u.aliasname = aliasname u.remember_me = 0 # 0 enforces cookie_lifetime config param logging.debug( "creating user object with name %r email %r alias %r" % (username, email, aliasname)) except ldap.INVALID_CREDENTIALS, err: logging.debug( "invalid credentials (wrong password?) for dn %r (username: %r)" % (dn, username)) return CancelLogin(_("Invalid username or password."))
def login(self, request, user_obj, **kw): continuation = kw.get('multistage') if continuation: return self._handle_continuation(request) # openid is designed to work together with other auths if user_obj and user_obj.valid: return ContinueLogin(user_obj) openid_id = kw.get('openid_identifier') # nothing entered? continue... if not self._forced_service and not openid_id: return ContinueLogin(user_obj) _ = request.getText # user entered something but the session can't be stored if not request.cfg.cookie_lifetime[0]: return ContinueLogin( user_obj, _('Anonymous sessions need to be enabled for OpenID login.')) oidconsumer = consumer.Consumer(request.session, MoinOpenIDStore(request)) try: fserv = self._forced_service if fserv: if isinstance(fserv, str) or isinstance(fserv, unicode): oidreq = oidconsumer.begin(fserv) else: oidreq = oidconsumer.beginWithoutDiscovery(fserv) else: oidreq = oidconsumer.begin(openid_id) except HTTPFetchingError: return ContinueLogin(None, _('Failed to resolve OpenID.')) except DiscoveryFailure: return ContinueLogin( None, _('OpenID discovery failure, not a valid OpenID.')) else: if oidreq is None: return ContinueLogin(None, _('No OpenID.')) self._modify_request(oidreq, request.cfg) return_to = get_multistage_continuation_url( request, self.name, {'oidstage': '1'}) trust_root = request.url_root if oidreq.shouldSendRedirect(): redirect_url = oidreq.redirectURL(trust_root, return_to) return MultistageRedirectLogin(redirect_url) else: form_html = oidreq.formMarkup( trust_root, return_to, form_tag_attrs={'id': 'openid_message'}) mcall = lambda request, form:\ self._openid_form(request, form, form_html) ret = MultistageFormLogin(mcall) return ret
def login(self, user_obj, **kw): self.log('login', user_obj, kw) return ContinueLogin(user_obj)
def login(self, request, user_obj, **kw): username = kw.get('username') password = kw.get('password') if self.dbconfig is None: logging.exception( "Please configure this authentication agent (mysql config missing)" ) return None, None, None try: import MySQLdb except: logging.exception("Failed to import MySQL connector!") return None, None, None try: db = MySQLdb.connect(host=self.dbconfig['host'], user=self.dbconfig['user'], passwd=self.dbconfig['passwd'], db=self.dbconfig['dbname']) except: logging.exception( "authorization failed due to exception when connecting to DB, traceback follows..." ) return None, None, None # Okay, let's start! query = """SELECT Password, Name, Email FROM GDN_User WHERE GDN_User.Name = '%s'; """ % username logging.debug("Executing query: " + query) c = db.cursor(MySQLdb.cursors.DictCursor) c.execute(query) vanilla_data = c.fetchone() # Hashed password is here. Compare it. valid = self.phpass.check_password(password, vanilla_data["Password"]) logging.debug("Valid state: " + str(valid)) if valid: u = user.User(request, name=vanilla_data["Name"], auth_username=vanilla_data["Name"], auth_method=self.name) changed = False if u.aliasname != vanilla_data["Name"]: u.aliasname = vanilla_data["Name"] changed = True if u.email != vanilla_data["Email"]: u.email = vanilla_data["Email"] changed = True if u and self.autocreate: u.create_or_update(changed) if u and u.valid: return ContinueLogin( u) # True to get other methods called, too else: logging.debug( "%s: could not authenticate user %r (not valid)" % (self.name, username)) return ContinueLogin(user_obj, _("Invalid username or password.")) return user_obj, True # continue with next method in auth list