Example #1
0
def main(global_config, **settings):
    """ This function returns a Pyramid WSGI application.
    """

    import logging
    logging.basicConfig(level=logging.DEBUG)

    config = Configurator(root_factory=get_root, settings=settings)
    config.begin()

    from pyramid_jinja2 import renderer_factory
    config.add_renderer('.jinja2', renderer_factory)

    # configure views, templates
    configure(config) 

    # configure session
    import pyramid_beaker
    session_factory = pyramid_beaker.session_factory_from_settings(settings)
    config.set_session_factory(session_factory)

    # configure OpenID-specific storage
    import stucco_openid.models
    from openid.store import filestore
    stucco_openid.models.root.store = \
        filestore.FileOpenIDStore(settings['openid.store_file_path'])

    config.end()
    return config.make_wsgi_app()
 def __init__(self, cache_path):
     self.session_path = os.path.join(cache_path, 'session')
     self.store_path = os.path.join(cache_path, 'store')
     for dir in self.session_path, self.store_path:
         if not os.path.exists(dir):
             os.makedirs(dir)
     self.store = filestore.FileOpenIDStore(self.store_path)
Example #3
0
def get_openid_consumer(request, session):
    """Initialize an OpenID store for authenticating comments.

    @param request: Pyblosxom request object

    @param session: session
    @type session: instance of C{Session}

    @return: An instance of OpenIDConsumer
    @rtype: OpenID consumer store or C{None}
    """
    config = request.getConfiguration()
    logger = tools.getLogger()

    store_dir = config.get('openid_store_dir')
    if store_dir is None:
        logger.error('You must define openid_store_dir in your '
                     'config to enable OpenID comments.')
        return None

    try:
        store = filestore.FileOpenIDStore(store_dir)
        return openid.Consumer(session, store)
    except Exception:
        trace = traceback.format_exception(*sys.exc_info())
        logger.error('Error initializing OpenID server:\n' + '\n'.join(trace))
        return None
Example #4
0
def make_store(store, config):
    conn = None
    if store == 'file':
        from openid.store import filestore
        cstore = filestore.FileOpenIDStore(config)
    elif store == 'mysql':
        import MySQLdb
        from DBUtils.PersistentDB import PersistentDB
        from openid.store.sqlstore import MySQLStore
        from sqlalchemy.engine.url import make_url

        def create_conn(dburi):
            url = make_url(dburi)
            p = {'db': url.database}
            if url.username:
                p['user'] = url.username
            if url.password:
                p['passwd'] = url.password
            if url.host:
                p['host'] = url.host
            if url.port:
                p['port'] = url.port
            return PersistentDB(MySQLdb, 1, **p).connection()

        conn = create_conn(config)
        cstore = MySQLStore(conn)
    else:
        raise Exception("Invalid store type %r" % store)
    return conn, cstore
Example #5
0
def verify_core(req):
    """This is the first phase of the OpenID login. We check the
	provided identifier, try to work out who we should ask about it,
	and redirect the user to the provider's site for their login
	process."""
    # Set up the OpenID library
    session = Session.Session(req, timeout=60)
    global store
    if store is None:
        Logger.log.debug("Creating new store")
        server_options = req.get_options()
        store_path = os.path.join(server_options['wor.root_path'], "oid_store")
        store = filestore.FileOpenIDStore(store_path)
    oid_consumer = consumer.Consumer(session, store)

    # Get the user's account details that they provided
    if getattr(req, "form", None) is None:
        req.form = util.FieldStorage(req, True)
    account = req.form.getfirst("openid_identifier")

    # Look up the OAuth provider for this account
    try:
        request = oid_consumer.begin(account)
    except consumer.DiscoveryFailure, ex:
        raise
Example #6
0
    def __init__(self, app, data_store_path, auth_prefix='/oid',
                 login_redirect=None, catch_401=False,
                 url_to_username=None):
        """
        Initialize the OpenID middleware

        ``app``
            Your WSGI app to call
            
        ``data_store_path``
            Directory to store crypto data in for use with OpenID servers.
            
        ``auth_prefix``
            Location for authentication process/verification
            
        ``login_redirect``
            Location to load after successful process of login
            
        ``catch_401``
            If true, then any 401 responses will turn into open ID login
            requirements.
            
        ``url_to_username``
            A function called like ``url_to_username(environ, url)``, which should
            return a string username.  If not given, the URL will be the username.
        """
        store = filestore.FileOpenIDStore(data_store_path)
        self.oidconsumer = consumer.OpenIDConsumer(store)

        self.app = app
        self.auth_prefix = auth_prefix
        self.data_store_path = data_store_path
        self.login_redirect = login_redirect
        self.catch_401 = catch_401
        self.url_to_username = url_to_username
    def __init__(self, provider):
        self.provider = provider
        self.consumer_class = None
        self.log_debug = logging.DEBUG >= log.getEffectiveLevel()

        self.config = get_oauth_config(provider)

        self.endpoint_regex = self.config.get('endpoint_regex')

        # application config items, dont use self.config
        store = config.get('openid_store', 'mem')
        if store == u"file":
            store_file_path = config.get('openid_store_path', None)
            self.openid_store = filestore.FileOpenIDStore(store_file_path)
        elif store == u"mem":
            self.openid_store = memstore.MemoryStore()
        elif store == u"sql":
            # TODO: This does not work as we need a connection, not a string
            # XXX
            #self.openid_store = sqlstore.SQLStore(sql_connstring,
            #        sql_associations_table, sql_connstring)
            raise NotImplementedError()

        self.scope = self.config.get('scope', None)
        self.return_to_query = {}
Example #8
0
    def __init__(self,
                 store,
                 openid_field,
                 error_field='',
                 store_file_path='',
                 session_name='',
                 login_handler_path='',
                 logout_handler_path='',
                 login_form_url='',
                 logged_in_url='',
                 logged_out_url='',
                 came_from_field='',
                 rememberer_name='',
                 sql_associations_table='',
                 sql_nonces_table='',
                 sql_connstring='',
                 ax_require='',
                 ax_optional='',
                 sreg_require='',
                 sreg_optional=''):

        self.rememberer_name = rememberer_name
        self.login_handler_path = login_handler_path
        self.logout_handler_path = logout_handler_path
        self.login_form_url = login_form_url
        self.session_name = session_name
        self.error_field = error_field
        self.came_from_field = came_from_field
        self.logged_out_url = logged_out_url
        self.logged_in_url = logged_in_url
        self.ax_require = {}

        for item in ax_require.split():
            key, value = item.split("=")
            self.ax_require[key] = value

        self.ax_optional = {}
        for item in ax_optional.split():
            key, value = item.split("=")
            self.ax_optional[key] = value

        self.sreg_require = [a.strip() for a in sreg_require.split()]
        self.sreg_optional = [a.strip() for a in sreg_optional.split()]

        # for the SQL store
        self.sql_associations_table = sql_associations_table
        self.sql_nonces_table = sql_nonces_table
        self.sql_connstring = sql_connstring

        # set up the store
        if store == u"file":
            self.store = filestore.FileOpenIDStore(store_file_path)
        elif store == u"mem":
            self.store = memstore.MemoryStore()
        elif store == u"sql":
            # TODO: This does not work as we need a connection, not a string
            self.store = sqlstore.SQLStore(sql_connstring,
                                           sql_associations_table,
                                           sql_connstring)
        self.openid_field = openid_field
 def __init__( self, cache_path ):
     assert oidutil is not None, OPENID_IMPORT_MESSAGE
     self.session_path = os.path.join( cache_path, 'session' )
     self.store_path = os.path.join( cache_path, 'store' )
     for dir in self.session_path, self.store_path:
         if not os.path.exists( dir ):
             os.makedirs( dir )
     self.store = filestore.FileOpenIDStore( self.store_path )
Example #10
0
def init_store(dir):
    """Init the OpenId store (file store).

    Arguments:
      - dir: where the store is located.
    """
    global OPENID_STORE
    OPENID_STORE = filestore.FileOpenIDStore(dir)
Example #11
0
def test_filestore():
    from openid.store import filestore
    import tempfile
    import shutil

    temp_dir = tempfile.mkdtemp()
    store = filestore.FileOpenIDStore(temp_dir)

    testStore(store)
    store.cleanup()
    shutil.rmtree(temp_dir)
Example #12
0
def main(host, port, data_path, weak_ssl=False):
    # Instantiate OpenID consumer store and OpenID consumer.  If you
    # were connecting to a database, you would create the database
    # connection and instantiate an appropriate store here.
    if data_path:
        store = filestore.FileOpenIDStore(data_path)
    else:
        store = memstore.MemoryStore()

    if weak_ssl:
        setDefaultFetcher(Urllib2Fetcher())

    addr = (host, port)
    server = OpenIDHTTPServer(store, addr, OpenIDRequestHandler)

    print 'Server running at:'
    print server.base_url
    server.serve_forever()
Example #13
0
def test_filestore():
    from openid.store import filestore
    import tempfile
    import shutil
    try:
        temp_dir = tempfile.mkdtemp()
    except AttributeError:
        import os
        temp_dir = os.tmpnam()
        os.mkdir(temp_dir)

    store = filestore.FileOpenIDStore(temp_dir)
    try:
        testStore(store)
        store.cleanup()
    except:
        raise
    else:
        shutil.rmtree(temp_dir)
    def __init__(self, provider='openid'):
        self.provider = provider
        self.consumer_class = None
        self.log_debug = logging.DEBUG >= log.getEffectiveLevel()

        self.endpoint_regex = None

        # application config items, dont use self.config
        #        store = config.get('openid_store', 'mem')
        store = "mem"
        if store == u"file":
            store_file_path = config.get('openid_store_path', None)
            self.openid_store = filestore.FileOpenIDStore(store_file_path)
        elif store == u"mem":
            self.openid_store = memstore.MemoryStore()
        elif store == u"sql":
            # TODO: This does not work as we need a connection, not a string
            self.openid_store = sqlstore.SQLStore(sql_connstring,
                                                  sql_associations_table,
                                                  sql_connstring)
        self.return_to_query = {}
Example #15
0
class OpenIDController(openerpweb.Controller):
    _cp_path = '/auth_openid/login'

    _store = filestore.FileOpenIDStore(_storedir)

    _REQUIRED_ATTRIBUTES = ['email']
    _OPTIONAL_ATTRIBUTES = 'nickname fullname postcode country language timezone'.split(
    )

    def _add_extensions(self, request):
        """Add extensions to the request"""

        sreg_request = sreg.SRegRequest(required=self._REQUIRED_ATTRIBUTES,
                                        optional=self._OPTIONAL_ATTRIBUTES)
        request.addExtension(sreg_request)

        ax_request = ax.FetchRequest()
        for alias in self._REQUIRED_ATTRIBUTES:
            uri = utils.SREG2AX[alias]
            ax_request.add(ax.AttrInfo(uri, required=True, alias=alias))
        for alias in self._OPTIONAL_ATTRIBUTES:
            uri = utils.SREG2AX[alias]
            ax_request.add(ax.AttrInfo(uri, required=False, alias=alias))

        request.addExtension(ax_request)

    def _get_attributes_from_success_response(self, success_response):
        attrs = {}

        all_attrs = self._REQUIRED_ATTRIBUTES + self._OPTIONAL_ATTRIBUTES

        sreg_resp = sreg.SRegResponse.fromSuccessResponse(success_response)
        if sreg_resp:
            for attr in all_attrs:
                value = sreg_resp.get(attr)
                if value is not None:
                    attrs[attr] = value

        ax_resp = ax.FetchResponse.fromSuccessResponse(success_response)
        if ax_resp:
            for attr in all_attrs:
                value = ax_resp.getSingle(utils.SREG2AX[attr])
                if value is not None:
                    attrs[attr] = value
        return attrs

    def _get_realm(self, req):
        return req.httprequest.host_url

    @openerpweb.httprequest
    def verify_direct(self, req, db, url):
        result = self._verify(req, db, url)
        if 'error' in result:
            return werkzeug.exceptions.BadRequest(result['error'])
        if result['action'] == 'redirect':
            return werkzeug.utils.redirect(result['value'])
        return result['value']

    @openerpweb.jsonrequest
    def verify(self, req, db, url):
        return self._verify(req, db, url)

    def _verify(self, req, db, url):
        redirect_to = werkzeug.urls.Href(req.httprequest.host_url +
                                         'auth_openid/login/process')(
                                             session_id=req.session_id)
        realm = self._get_realm(req)

        session = dict(dbname=db, openid_url=url)  # TODO add origin page ?
        oidconsumer = consumer.Consumer(session, self._store)

        try:
            request = oidconsumer.begin(url)
        except consumer.DiscoveryFailure, exc:
            fetch_error_string = 'Error in discovery: %s' % (str(exc[0]), )
            return {'error': fetch_error_string, 'title': 'OpenID Error'}

        if request is None:
            return {
                'error': 'No OpenID services found',
                'title': 'OpenID Error'
            }

        req.session.openid_session = session
        self._add_extensions(request)

        if request.shouldSendRedirect():
            redirect_url = request.redirectURL(realm, redirect_to)
            return {
                'action': 'redirect',
                'value': redirect_url,
                'session_id': req.session_id
            }
        else:
            form_html = request.htmlMarkup(realm, redirect_to)
            return {
                'action': 'post',
                'value': form_html,
                'session_id': req.session_id
            }
Example #16
0
class OpenIDController(http.Controller):

    _store = filestore.FileOpenIDStore(_storedir)

    _REQUIRED_ATTRIBUTES = ['email']
    _OPTIONAL_ATTRIBUTES = 'nickname fullname postcode country language timezone'.split(
    )

    def _add_extensions(self, oidrequest):
        """Add extensions to the oidrequest"""

        sreg_request = sreg.SRegRequest(required=self._REQUIRED_ATTRIBUTES,
                                        optional=self._OPTIONAL_ATTRIBUTES)
        oidrequest.addExtension(sreg_request)

        ax_request = ax.FetchRequest()
        for alias in self._REQUIRED_ATTRIBUTES:
            uri = utils.SREG2AX[alias]
            ax_request.add(ax.AttrInfo(uri, required=True, alias=alias))
        for alias in self._OPTIONAL_ATTRIBUTES:
            uri = utils.SREG2AX[alias]
            ax_request.add(ax.AttrInfo(uri, required=False, alias=alias))

        oidrequest.addExtension(ax_request)

    def _get_attributes_from_success_response(self, success_response):
        attrs = {}

        all_attrs = self._REQUIRED_ATTRIBUTES + self._OPTIONAL_ATTRIBUTES

        sreg_resp = sreg.SRegResponse.fromSuccessResponse(success_response)
        if sreg_resp:
            for attr in all_attrs:
                value = sreg_resp.get(attr)
                if value is not None:
                    attrs[attr] = value

        ax_resp = ax.FetchResponse.fromSuccessResponse(success_response)
        if ax_resp:
            for attr in all_attrs:
                value = ax_resp.getSingle(utils.SREG2AX[attr])
                if value is not None:
                    attrs[attr] = value
        return attrs

    def _get_realm(self):
        return request.httprequest.host_url

    @http.route('/auth_openid/login/verify_direct', type='http', auth='none')
    def verify_direct(self, db, url):
        result = self._verify(db, url)
        if 'error' in result:
            return werkzeug.exceptions.BadRequest(result['error'])
        if result['action'] == 'redirect':
            return werkzeug.utils.redirect(result['value'])
        return result['value']

    @http.route('/auth_openid/login/verify', type='json', auth='none')
    def verify(self, db, url):
        return self._verify(db, url)

    def _verify(self, db, url):
        redirect_to = werkzeug.urls.Href(request.httprequest.host_url +
                                         'auth_openid/login/process')(
                                             session_id=request.session_id)
        realm = self._get_realm()

        session = dict(dbname=db, openid_url=url)  # TODO add origin page ?
        oidconsumer = consumer.Consumer(session, self._store)

        try:
            oidrequest = oidconsumer.begin(url)
        except consumer.DiscoveryFailure as exc:
            fetch_error_string = 'Error in discovery: %s' % (str(exc[0]), )
            return {'error': fetch_error_string, 'title': 'OpenID Error'}

        if oidrequest is None:
            return {
                'error': 'No OpenID services found',
                'title': 'OpenID Error'
            }

        request.session.openid_session = session
        self._add_extensions(oidrequest)

        if oidrequest.shouldSendRedirect():
            redirect_url = oidrequest.redirectURL(realm, redirect_to)
            return {
                'action': 'redirect',
                'value': redirect_url,
                'session_id': request.session_id
            }
        else:
            form_html = oidrequest.htmlMarkup(realm, redirect_to)
            return {
                'action': 'post',
                'value': form_html,
                'session_id': request.session_id
            }

    @http.route('/auth_openid/login/process', type='http', auth='none')
    def process(self, **kw):
        session = getattr(request.session, 'openid_session', None)
        if not session:
            return set_cookie_and_redirect('/')

        oidconsumer = consumer.Consumer(session,
                                        self._store,
                                        consumer_class=GoogleAppsAwareConsumer)

        query = request.httprequest.args
        info = oidconsumer.complete(query, request.httprequest.base_url)
        display_identifier = info.getDisplayIdentifier()

        session['status'] = info.status

        if info.status == consumer.SUCCESS:
            dbname = session['dbname']
            registry = RegistryManager.get(dbname)
            with registry.cursor() as cr:
                Modules = registry.get('ir.module.module')

                installed = Modules.search_count(cr, SUPERUSER_ID, [
                    '&', ('name', '=', 'auth_openid'),
                    ('state', '=', 'installed')
                ]) == 1
                if installed:

                    Users = registry.get('res.users')

                    #openid_url = info.endpoint.canonicalID or display_identifier
                    openid_url = session['openid_url']

                    attrs = self._get_attributes_from_success_response(info)
                    attrs['openid_url'] = openid_url
                    session['attributes'] = attrs
                    openid_email = attrs.get('email', False)

                    domain = []
                    if openid_email:
                        domain += ['|', ('openid_email', '=', False)]
                    domain += [('openid_email', '=', openid_email)]

                    domain += [('openid_url', '=', openid_url),
                               ('active', '=', True)]

                    ids = Users.search(cr, SUPERUSER_ID, domain)
                    assert len(ids) < 2
                    if ids:
                        user_id = ids[0]
                        login = Users.browse(cr, SUPERUSER_ID, user_id).login
                        key = randomString(utils.KEY_LENGTH,
                                           '0123456789abcdef')
                        Users.write(cr, SUPERUSER_ID, [user_id],
                                    {'openid_key': key})
                        # TODO fill empty fields with the ones from sreg/ax
                        cr.commit()

                        return login_and_redirect(dbname, login, key)

            session[
                'message'] = 'This OpenID identifier is not associated to any active users'

        elif info.status == consumer.SETUP_NEEDED:
            session['message'] = info.setup_url
        elif info.status == consumer.FAILURE and display_identifier:
            fmt = "Verification of %s failed: %s"
            session['message'] = fmt % (display_identifier, info.message)
        else:  # FAILURE
            # Either we don't understand the code or there is no
            # openid_url included with the error. Give a generic
            # failure message. The library should supply debug
            # information in a log.
            session['message'] = 'Verification failed.'

        return set_cookie_and_redirect('/#action=login&loginerror=1')

    @http.route('/auth_openid/login/status', type='json', auth='none')
    def status(self):
        session = getattr(request.session, 'openid_session', {})
        return {
            'status': session.get('status'),
            'message': session.get('message')
        }
Example #17
0
def process_core(req):
    Logger.log.debug("Processing request: " + str(req))
    # Set up OpenID library
    session = Session.Session(req, timeout=60)
    global store
    if store is None:
        Logger.log.debug("Creating new store")
        server_options = req.get_options()
        store_path = os.path.join(server_options['wor.root_path'], "oid_store")
        store = filestore.FileOpenIDStore(store_path)
    oid_consumer = consumer.Consumer(session, store)

    # Get request parameters
    if getattr(req, "form", None) is None:
        req.form = util.FieldStorage(req, True)

    # Convert the request parameters into an ordinary decent
    # dictionary for the oid_consumer to use
    params = {}
    for k in req.form:
        params[k] = req.form.getfirst(k).value

    Logger.log.debug("Request was " + str(params))

    url = req.construct_url("/process")
    info = oid_consumer.complete(params, url)

    display_identifier = info.getDisplayIdentifier()

    if info.status == consumer.FAILURE and display_identifier:
        # In the case of failure, if info is non-None, it is the
        # URL that we were verifying. We include it in the error
        # message to help the user figure out what happened.
        fmt = "Verification of %s failed: %s"
        # FIXME: To avoid XSS issues, quote this identifier before
        # echoing it back (and below)
        message = fmt % (display_identifier, info.message)
    elif info.status == consumer.SUCCESS:
        # Success means that the transaction completed without
        # error. If info is None, it means that the user cancelled
        # the verification.
        css_class = 'alert'

        # This is a successful verification attempt. If this
        # was a real application, we would do our login,
        # comment posting, etc. here.
        fmt = "You have successfully verified %s as your identity."
        message = fmt % (display_identifier, )
        if info.endpoint.canonicalID:
            # You should authorize i-name users by their canonicalID,
            # rather than their more human-friendly identifiers.  That
            # way their account with you is not compromised if their
            # i-name registration expires and is bought by someone else.
            message += ("  This is an i-name, and its persistent ID is %s" %
                        (info.endpoint.canonicalID, ))

        # FIXME: We should check here whether the account exists. If
        # it doesn't, we need to create the account using SREG data,
        # and drop the user into a character-creation screen. If it
        # does exist, we should drop them into the game UI, in
        # "character-selection" mode.
        accid = Account.get_id_from_name(display_identifier)
        if accid is None:
            # Then there's no corresponding account: create one
            pass

        # We generate a random string to use as a session key, store
        # that locally for the account's session, and push it up to
        # the browser for temporary storage while it loads the game
        # interface.
        key = random_value(16)
        req.headers_out['X-WoR-Session-Key'] = key
        Account.set_session_key(accid, key)
        req.write(
            """<html><head><title>WoR</title><script src="/js/redirect.js" type="text/javascript"/></head><body onload="load_game(%{url}s);"></body></html>"""
            % ("http://game.worldofrodney.org/", ))

        return apache.OK

    elif info.status == consumer.CANCEL:
        # cancelled
        message = 'Verification cancelled'
    elif info.status == consumer.SETUP_NEEDED:
        if info.setup_url:
            message = '<a href=%s>Setup needed</a>' % (quoteattr(
                info.setup_url), )
        else:
            # This means auth didn't succeed, but you're welcome to try
            # non-immediate mode.
            message = 'Setup needed'
    else:
        # Either we don't understand the code or there is no
        # openid_url included with the error. Give a generic
        # failure message. The library should supply debug
        # information in a log.
        message = 'Verification failed.'

    req.write(message)

    return apache.OK