Put session.py in http.py

bzr revid: nicolas.vanhoren@openerp.com-20130621114424-s0nd8orv5ej05pwv
This commit is contained in:
niv-openerp
2013-06-21 13:44:24 +02:00
parent 275b103855
commit c90e8119bb
2 changed files with 226 additions and 242 deletions
+226 -9
View File
@@ -34,8 +34,6 @@ import urllib2
import openerp
import session
import inspect
import functools
@@ -119,7 +117,7 @@ class WebRequest(object):
self.session_id = uuid.uuid4().hex
self.session = self.httpsession.get(self.session_id)
if not self.session:
self.session = session.OpenERPSession()
self.session = OpenERPSession()
self.httpsession[self.session_id] = self.session
with set_request(self):
@@ -157,13 +155,13 @@ class WebRequest(object):
elif self.auth_method == "noauth":
self.db = (self.session._db or openerp.addons.web.controllers.main.db_monodb()).lower()
if not self.db:
raise session.SessionExpiredException("No valid database for request %s" % self.httprequest)
raise SessionExpiredException("No valid database for request %s" % self.httprequest)
self.uid = None
else: # auth
try:
self.session.check_security()
except session.SessionExpiredException, e:
raise session.SessionExpiredException("Session expired for request %s" % self.httprequest)
except SessionExpiredException, e:
raise SessionExpiredException("Session expired for request %s" % self.httprequest)
self.db = self.session._db
self.uid = self.session._uid
@@ -337,7 +335,7 @@ class JsonRequest(WebRequest):
# _logger.debug("--> %s.%s\n%s", func.im_class.__name__, func.__name__, pprint.pformat(self.jsonrequest))
response['id'] = self.jsonrequest.get('id')
response["result"] = self._call_function(**self.params)
except session.AuthenticationError, e:
except AuthenticationError, e:
_logger.exception("Exception during JSON request handling.")
se = serialize_exception(e)
error = {
@@ -566,6 +564,225 @@ class Controller(object):
else:
return getattr(self, name)
#############################
# OpenERP Sessions #
#############################
class AuthenticationError(Exception):
pass
class SessionExpiredException(Exception):
pass
class Service(object):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
def __init__(self, session, service_name):
self.session = session
self.service_name = service_name
def __getattr__(self, method):
def proxy_method(*args):
result = openerp.netsvc.dispatch_rpc(self.service_name, method, args)
return result
return proxy_method
class Model(object):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
def __init__(self, session, model):
self.session = session
self.model = model
self.proxy = self.session.proxy('object')
def __getattr__(self, method):
self.session.assert_valid()
def proxy(*args, **kw):
# Can't provide any retro-compatibility for this case, so we check it and raise an Exception
# to tell the programmer to adapt his code
if not http.request.db or not http.request.uid or self.session._db != http.request.db \
or self.session._uid != http.request.uid:
raise Exception("Trying to use Model with badly configured database or user.")
mod = http.request.registry.get(self.model)
meth = getattr(mod, method)
cr = http.request.cr
result = meth(cr, http.request.uid, *args, **kw)
# reorder read
if method == "read":
if isinstance(result, list) and len(result) > 0 and "id" in result[0]:
index = {}
for r in result:
index[r['id']] = r
result = [index[x] for x in args[0] if x in index]
return result
return proxy
class OpenERPSession(object):
"""
An OpenERP RPC session, a given user can own multiple such sessions
in a web session.
.. attribute:: context
The session context, a ``dict``. Can be reloaded by calling
:meth:`openerpweb.openerpweb.OpenERPSession.get_context`
.. attribute:: domains_store
A ``dict`` matching domain keys to evaluable (but non-literal) domains.
Used to store references to non-literal domains which need to be
round-tripped to the client browser.
"""
def __init__(self):
self._creation_time = time.time()
self._db = False
self._uid = False
self._login = False
self._password = False
self._suicide = False
self.context = {}
self.jsonp_requests = {} # FIXME use a LRU
def authenticate(self, db, login, password, env=None):
"""
Authenticate the current user with the given db, login and password. If successful, store
the authentication parameters in the current session and request.
"""
uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, login, password, env])
self._db = db
self._uid = uid
self._login = login
self._password = password
http.request.db = db
http.request.uid = uid
if uid: self.get_context()
return uid
def check_security(self):
"""
Chech the current authentication parameters to know if those are still valid. This method
should be called at each request. If the authentication fails, a ``SessionExpiredException``
is raised.
"""
if not self._db or not self._uid:
raise SessionExpiredException("Session expired")
import openerp.service.security as security
security.check(self._db, self._uid, self._password)
def get_context(self):
"""
Re-initializes the current user's session context (based on
his preferences) by calling res.users.get_context() with the old
context.
:returns: the new context
"""
assert self._uid, "The user needs to be logged-in to initialize his context"
self.context = http.request.registry.get('res.users').context_get(http.request.cr, http.request.uid) or {}
self.context['uid'] = self._uid
self._fix_lang(self.context)
return self.context
def _fix_lang(self, context):
""" OpenERP provides languages which may not make sense and/or may not
be understood by the web client's libraries.
Fix those here.
:param dict context: context to fix
"""
lang = context['lang']
# inane OpenERP locale
if lang == 'ar_AR':
lang = 'ar'
# lang to lang_REGION (datejs only handles lang_REGION, no bare langs)
if lang in babel.core.LOCALE_ALIASES:
lang = babel.core.LOCALE_ALIASES[lang]
context['lang'] = lang or 'en_US'
def send(self, service_name, method, *args):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
return openerp.netsvc.dispatch_rpc(service_name, method, args)
def proxy(self, service):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
return Service(self, service)
def assert_valid(self, force=False):
"""
.. deprecated:: 8.0
Use ``check_security()`` instead.
Ensures this session is valid (logged into the openerp server)
"""
if self._uid and not force:
return
# TODO use authenticate instead of login
self._uid = self.proxy("common").login(self._db, self._login, self._password)
if not self._uid:
raise AuthenticationError("Authentication failure")
def ensure_valid(self):
"""
.. deprecated:: 8.0
Use ``check_security()`` instead.
"""
if self._uid:
try:
self.assert_valid(True)
except Exception:
self._uid = None
def execute(self, model, func, *l, **d):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
model = self.model(model)
r = getattr(model, func)(*l, **d)
return r
def exec_workflow(self, model, id, signal):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
self.assert_valid()
r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
return r
def model(self, model):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
Get an RPC proxy for the object ``model``, bound to this session.
:param model: an OpenERP model name
:type model: str
:rtype: a model object
"""
if self._db == False:
raise SessionExpiredException("Session expired")
return Model(self, model)
#----------------------------------------------------------
# Session context manager
#----------------------------------------------------------
@@ -584,7 +801,7 @@ def session_context(request, session_store, session_lock, sid):
# session id, and are generally noise
removed_sessions = set()
for key, value in request.session.items():
if not isinstance(value, session.OpenERPSession):
if not isinstance(value, OpenERPSession):
continue
if getattr(value, '_suicide', False) or (
not value._uid
@@ -612,7 +829,7 @@ def session_context(request, session_store, session_lock, sid):
in_store = session_store.get(sid)
for k, v in request.session.iteritems():
stored = in_store.get(k)
if stored and isinstance(v, session.OpenERPSession):
if stored and isinstance(v, OpenERPSession):
if hasattr(v, 'contexts_store'):
del v.contexts_store
if hasattr(v, 'domains_store'):
-233
View File
@@ -1,233 +0,0 @@
#!/usr/bin/python
import datetime
import babel
import dateutil.relativedelta
import logging
import time
import traceback
import sys
import openerp
import http
_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# OpenERPSession RPC openerp backend access
#----------------------------------------------------------
class AuthenticationError(Exception):
pass
class SessionExpiredException(Exception):
pass
class Service(object):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
def __init__(self, session, service_name):
self.session = session
self.service_name = service_name
def __getattr__(self, method):
def proxy_method(*args):
result = openerp.netsvc.dispatch_rpc(self.service_name, method, args)
return result
return proxy_method
class Model(object):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
def __init__(self, session, model):
self.session = session
self.model = model
self.proxy = self.session.proxy('object')
def __getattr__(self, method):
self.session.assert_valid()
def proxy(*args, **kw):
# Can't provide any retro-compatibility for this case, so we check it and raise an Exception
# to tell the programmer to adapt his code
if not http.request.db or not http.request.uid or self.session._db != http.request.db \
or self.session._uid != http.request.uid:
raise Exception("Trying to use Model with badly configured database or user.")
mod = http.request.registry.get(self.model)
meth = getattr(mod, method)
cr = http.request.cr
result = meth(cr, http.request.uid, *args, **kw)
# reorder read
if method == "read":
if isinstance(result, list) and len(result) > 0 and "id" in result[0]:
index = {}
for r in result:
index[r['id']] = r
result = [index[x] for x in args[0] if x in index]
return result
return proxy
class OpenERPSession(object):
"""
An OpenERP RPC session, a given user can own multiple such sessions
in a web session.
.. attribute:: context
The session context, a ``dict``. Can be reloaded by calling
:meth:`openerpweb.openerpweb.OpenERPSession.get_context`
.. attribute:: domains_store
A ``dict`` matching domain keys to evaluable (but non-literal) domains.
Used to store references to non-literal domains which need to be
round-tripped to the client browser.
"""
def __init__(self):
self._creation_time = time.time()
self._db = False
self._uid = False
self._login = False
self._password = False
self._suicide = False
self.context = {}
self.jsonp_requests = {} # FIXME use a LRU
def authenticate(self, db, login, password, env=None):
"""
Authenticate the current user with the given db, login and password. If successful, store
the authentication parameters in the current session and request.
"""
uid = openerp.netsvc.dispatch_rpc('common', 'authenticate', [db, login, password, env])
self._db = db
self._uid = uid
self._login = login
self._password = password
http.request.db = db
http.request.uid = uid
if uid: self.get_context()
return uid
def check_security(self):
"""
Chech the current authentication parameters to know if those are still valid. This method
should be called at each request. If the authentication fails, a ``SessionExpiredException``
is raised.
"""
if not self._db or not self._uid:
raise SessionExpiredException("Session expired")
import openerp.service.security as security
security.check(self._db, self._uid, self._password)
def get_context(self):
"""
Re-initializes the current user's session context (based on
his preferences) by calling res.users.get_context() with the old
context.
:returns: the new context
"""
assert self._uid, "The user needs to be logged-in to initialize his context"
self.context = http.request.registry.get('res.users').context_get(http.request.cr, http.request.uid) or {}
self.context['uid'] = self._uid
self._fix_lang(self.context)
return self.context
def _fix_lang(self, context):
""" OpenERP provides languages which may not make sense and/or may not
be understood by the web client's libraries.
Fix those here.
:param dict context: context to fix
"""
lang = context['lang']
# inane OpenERP locale
if lang == 'ar_AR':
lang = 'ar'
# lang to lang_REGION (datejs only handles lang_REGION, no bare langs)
if lang in babel.core.LOCALE_ALIASES:
lang = babel.core.LOCALE_ALIASES[lang]
context['lang'] = lang or 'en_US'
def send(self, service_name, method, *args):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
return openerp.netsvc.dispatch_rpc(service_name, method, args)
def proxy(self, service):
"""
.. deprecated:: 8.0
Use ``openerp.netsvc.dispatch_rpc()`` instead.
"""
return Service(self, service)
def assert_valid(self, force=False):
"""
.. deprecated:: 8.0
Use ``check_security()`` instead.
Ensures this session is valid (logged into the openerp server)
"""
if self._uid and not force:
return
# TODO use authenticate instead of login
self._uid = self.proxy("common").login(self._db, self._login, self._password)
if not self._uid:
raise AuthenticationError("Authentication failure")
def ensure_valid(self):
"""
.. deprecated:: 8.0
Use ``check_security()`` instead.
"""
if self._uid:
try:
self.assert_valid(True)
except Exception:
self._uid = None
def execute(self, model, func, *l, **d):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
model = self.model(model)
r = getattr(model, func)(*l, **d)
return r
def exec_workflow(self, model, id, signal):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
"""
self.assert_valid()
r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id)
return r
def model(self, model):
"""
.. deprecated:: 8.0
Use the resistry and cursor in ``openerp.addons.web.http.request`` instead.
Get an RPC proxy for the object ``model``, bound to this session.
:param model: an OpenERP model name
:type model: str
:rtype: a model object
"""
if self._db == False:
raise SessionExpiredException("Session expired")
return Model(self, model)
# vim:et:ts=4:sw=4: