Exemple #1
0
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
Exemple #2
0
    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')
Exemple #3
0
 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
Exemple #4
0
    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')