[IMP] auth_openid: forward port of patches made on 6.1 branch

revid:chs@openerp.com-20120802102525-2uyr5za46swxs0n7
        [FIX] auth_openid: Due to multiprocessus we must use a FileStore instead of a MemStore to store openid associations.
        [FIX] auth_openid: GoogleApps: avoid crash when handle not found in store.
        [IMP] auth_openid: flake8.

    revid:chs@openerp.com-20120403093926-4222u3cs3qc10xew
        [FIX] auth_openid: use correct api for login users

    revid:chs@openerp.com-20120403093627-easttnf2qoemeoli
        [FIX] auth_openid: allow login from direct http request

bzr revid: chs@openerp.com-20120810144333-o8zejl4pmdldab6j
This commit is contained in:
Christophe Simonis 2012-08-10 16:43:33 +02:00
parent a9c0de5325
commit c710e12517
1 changed files with 34 additions and 29 deletions

View File

@ -21,7 +21,7 @@
import logging
import os
import sys
import tempfile
import urllib
import werkzeug.urls
@ -31,53 +31,51 @@ from openerp.modules.registry import RegistryManager
try:
import openerp.addons.web.common.http as openerpweb
except ImportError:
import web.common.http as openerpweb
import web.common.http as openerpweb # noqa
from openid import oidutil
from openid.store import memstore
#from openid.store import filestore
from openid.store import filestore
from openid.consumer import consumer
from openid.cryptutil import randomString
from openid.extensions import ax, sreg
from .. import utils
_logger = logging.getLogger(__name__)
oidutil.log = _logger.debug
_storedir = os.path.join(tempfile.gettempdir(), 'openerp-auth_openid-store')
class GoogleAppsAwareConsumer(consumer.GenericConsumer):
def complete(self, message, endpoint, return_to):
if message.getOpenIDNamespace() == consumer.OPENID2_NS:
server_url = message.getArg(consumer.OPENID2_NS, 'op_endpoint', consumer.no_default)
server_url = message.getArg(consumer.OPENID2_NS, 'op_endpoint', '')
if server_url.startswith('https://www.google.com/a/'):
# update fields
for attr in ['claimed_id', 'identity']:
value = message.getArg(consumer.OPENID2_NS, attr)
value = 'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(value)
message.setArg(consumer.OPENID2_NS, attr, value)
# now, resign the message
assoc_handle = message.getArg(consumer.OPENID_NS, 'assoc_handle')
assoc = self.store.getAssociation(server_url, assoc_handle)
message.delArg(consumer.OPENID2_NS, 'sig')
message.delArg(consumer.OPENID2_NS, 'signed')
message = assoc.signMessage(message)
if assoc:
# update fields
for attr in ['claimed_id', 'identity']:
value = message.getArg(consumer.OPENID2_NS, attr, '')
value = 'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(value)
message.setArg(consumer.OPENID2_NS, attr, value)
return super(GoogleAppsAwareConsumer, self).complete(message, endpoint, return_to)
# now, resign the message
message.delArg(consumer.OPENID2_NS, 'sig')
message.delArg(consumer.OPENID2_NS, 'signed')
message = assoc.signMessage(message)
return super(GoogleAppsAwareConsumer, self).complete(message, endpoint, return_to)
class OpenIDController(openerpweb.Controller):
_cp_path = '/auth_openid/login'
_store = memstore.MemoryStore() # TODO use a filestore
_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"""
@ -118,8 +116,20 @@ class OpenIDController(openerpweb.Controller):
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)
@ -145,7 +155,6 @@ class OpenIDController(openerpweb.Controller):
form_html = request.htmlMarkup(realm, redirect_to)
return {'action': 'post', 'value': form_html, 'session_id': req.session_id}
@openerpweb.httprequest
def process(self, req, **kw):
session = getattr(req.session, 'openid_session', None)
@ -185,10 +194,8 @@ class OpenIDController(openerpweb.Controller):
domain += ['|', ('openid_email', '=', False)]
domain += [('openid_email', '=', openid_email)]
domain += [
('openid_url', '=', openid_url),
('active', '=', True),
]
domain += [('openid_url', '=', openid_url), ('active', '=', True)]
ids = Users.search(cr, 1, domain)
assert len(ids) < 2
if ids:
@ -199,12 +206,11 @@ class OpenIDController(openerpweb.Controller):
# TODO fill empty fields with the ones from sreg/ax
cr.commit()
u = req.session.login(dbname, login, key)
req.session.authenticate(dbname, login, key, {})
if not user_id:
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:
@ -217,9 +223,8 @@ class OpenIDController(openerpweb.Controller):
# information in a log.
session['message'] = 'Verification failed.'
fragment = '#loginerror' if not user_id else ''
return werkzeug.utils.redirect('/'+fragment)
return werkzeug.utils.redirect('/' + fragment)
@openerpweb.jsonrequest
def status(self, req):