def get_verified_credential(username, password, session=None): """Get a credential object The credential object for the given username... Otherwise, None is returned. """ # TODO: Add memcache layer, like in gaetk.handler.BasicHandler.login_required credential = Credential.get_by_key_name(username) if credential and credential.secret == password: if session: session['uid'] = credential.uid session['email'] = credential.email return credential
def get(self): """Handler for Federated login consumer (OpenID) AND HTTP-Basic-Auth. See http://code.google.com/appengine/articles/openid.html""" msg = '' continue_url = self.request.GET.get('continue', '/') openid_url = None session = get_current_session() # clean previous session if session.is_active(): session.terminate() # check if we are logged in via OpenID user = users.get_current_user() if user: logging.info('Google user = %s', user) # yes, active OpenID session # user.federated_provider() == 'https://www.google.com/a/hudora.de/o8/ud?be=o8' if not user.federated_provider(): # development server apps_domain = user.email().split('@')[-1].lower() else: apps_domain = user.federated_provider().split('/')[4].lower() username = user.email() credential = Credential.get_by_key_name(username) if not credential or not credential.uid == username: # So far we have no Credential entity for that user, create one if getattr(config, 'LOGIN_OPENID_CREDENTIAL_CREATOR', None): self.credential = config.LOGIN_OPENID_CREDENTIAL_CREATOR(user, apps_domain) if not self.credential: self.credential = create_credential_from_federated_login(user, apps_domain) session['uid'] = credential.uid # self.response.set_cookie('gaetk_opid', apps_domain, max_age=60*60*24*90) self.response.headers['Set-Cookie'] = 'gaetk_opid=%s; Max-Age=7776000' % apps_domain self.redirect(continue_url) return # we returned from the login form - did the user request OpenID login? for domain in ALLOWED_DOMAINS: if self.request.GET.get('%s.x' % domain): openid_url = 'https://www.google.com/accounts/o8/site-xrds?hd=%s' % domain if openid_url: logging.info("Openid login requested to %s", openid_url) if openid_url: # Hand over Authentication Processing to Google/OpenID self.redirect(users.create_login_url(continue_url, None, openid_url)) return else: # Try user:pass based Authentication username, password = None, None # see if we have HTTP-Basic Auth Data if self.request.headers.get('Authorization'): auth_type, encoded = self.request.headers.get('Authorization').split(None, 1) if auth_type.lower() == 'basic': username, password = encoded.decode('base64').split(':', 1) # see if we have gotten some Form Data instead if not (username and password): username = self.request.get('username').strip() password = self.request.get('password').strip() # verify user & password if username: logging.info("Login Attempt for %s", username) credential = Credential.get_by_key_name(username) if credential and credential.secret == password: # successfull login session['uid'] = credential.uid # redirect back where we came from logging.info("Login durch %s/%s, Umleitung zu %s", username, self.request.remote_addr, continue_url) self.redirect(continue_url) return else: logging.warning("Invalid Password for %s:%s", username, password) msg = 'Kann sie nicht anmelden' # Render Template with Login form self.render({'continue': continue_url, 'domains': ALLOWED_DOMAINS, 'msg': msg}, 'login.html')
def create_credential_from_federated_login(self, user, apps_domain): """Create a new credential object for a newly logged in OpenID user.""" credential = Credential.create(tenant=apps_domain, user=user, uid=user.email(), email=user.email(), text="Automatically created via OpenID Provider %s" % user.federated_provider()) return credential
def get(self): """Handler for Federated login consumer (OpenID) AND HTTP-Basic-Auth. For information on OpenID, see http://code.google.com/appengine/articles/openid.html""" continue_url = self.request.GET.get('continue', '/').encode('ascii', 'ignore') # check if we are logged in via OpenID user = users.get_current_user() if user: # yes, there is an active OpenID session # user.federated_provider() == 'https://www.google.com/a/hudora.de/o8/ud?be=o8' logging.info(u'login: User logged in via OpenID: %s', user) if not user.federated_provider(): # development server apps_domain = user.email().split('@')[-1].lower() else: apps_domain = user.federated_provider().split('/')[4].lower() username = user.email() credential = Credential.get_by_key_name(username) if not credential or not credential.uid == username: # So far we have no Credential entity for that user, create one by calling a factory function fnc = getattr(config, 'LOGIN_OPENID_CREDENTIAL_CREATOR', create_credential_from_federated_login) credential = fnc(user, apps_domain) self.session['uid'] = credential.uid self.session['email'] = username self.response.set_cookie('gaetkopid', apps_domain, max_age=7776000) self.redirect(continue_url) return # If the form data contains hints about an allowed (OpenID) domain, try to login the user via OpenID for domain in LOGIN_ALLOWED_DOMAINS: if self.request.GET.get('%s.x' % domain): openid_url = 'https://www.google.com/accounts/o8/site-xrds?hd=%s' % domain logging.info(u'login: OpenID login requested to %s', openid_url) # Hand over Authentication Processing to Google/OpenID self.redirect(users.create_login_url(continue_url, None, openid_url)) return # If it was impossible to authenticate via OpenID so far, # the user is tried to be authenticated via a username-password based approach. # The data is either taken from the HTTP header `Authorization` or the provided (form) data. msg = '' username, password = None, None # First, try HTTP basic auth (see RFC 2617) if self.request.headers.get('Authorization'): auth_type, encoded = self.request.headers.get('Authorization').split(None, 1) if auth_type.lower() == 'basic': username, password = encoded.decode('base64').split(':', 1) # Next, try to get data from the request parameters (form data) else: username = self.request.get('username', '').strip() password = self.request.get('password', '').strip() # Verify submitted username and password if username: credential = get_verified_credential(username, password, session=self.session) if credential: logging.info(u'login: Login by %s/%s, redirect to %s', username, self.request.remote_addr, continue_url) self.redirect(continue_url) return else: logging.warning(u'login: Invalid password for %s', username) msg = u'Anmeldung fehlgeschlagen' # Last attempt: If there's a cookie which contains the OpenID domain, try to login the user domain = self.request.cookies.get('gaetkopid', '') if domain in LOGIN_ALLOWED_DOMAINS: logging.info(u'login: automatically OpenID login to %s', domain) openid_url = 'https://www.google.com/accounts/o8/site-xrds?hd=%s' % domain # Hand over Authentication Processing to Google/OpenID self.redirect(users.create_login_url(continue_url, None, openid_url)) return # Render template with login form self.render({'continue': continue_url, 'domains': LOGIN_ALLOWED_DOMAINS, 'msg': msg}, 'login.html')