diff --git a/addons/web/http.py b/addons/web/http.py index 2dc41c8cad9..20431eb4233 100644 --- a/addons/web/http.py +++ b/addons/web/http.py @@ -83,10 +83,13 @@ class WebRequest(object): ``bool``, indicates whether the debug mode is active on the client """ - def __init__(self, request): - self.httprequest = request + def __init__(self, httprequest, method): + self.httprequest = httprequest self.httpresponse = None - self.httpsession = request.session + self.httpsession = httprequest.session + self.db = None + self.uid = None + self.method = method def init(self, params): self.params = dict(params) @@ -97,6 +100,9 @@ class WebRequest(object): self.session = session.OpenERPSession() self.httpsession[self.session_id] = self.session + self.authenticate() + + # TODO: remove this shit # set db/uid trackers - they're cleaned up at the WSGI # dispatching phase in openerp.service.wsgi_server.application if self.session._db: @@ -121,12 +127,38 @@ class WebRequest(object): # we use _ as seprator where RFC2616 uses '-' self.lang = lang.replace('-', '_') + def authenticate(self): + if self.method.auth == "nodb": + self.db = None + self.uid = None + elif self.method.auth == "noauth": + self.db = (self.session._db or openerp.addons.web.controllers.main.db_monodb(self)).lower() + self.uid = None + else: + self.session.check_security() + self.db = self.session._db + self.uid = self.session_uid + + def registry(self): + return openerp.modules.registry.RegistryManager.get(self.db) + + @contextlib.contextmanager + def cr(self): + with registry.cursor() as cr: + yield cr + @contextlib.contextmanager def registry_cr(self): - dbname = self.session._db or openerp.addons.web.controllers.main.db_monodb(self) - registry = openerp.modules.registry.RegistryManager.get(dbname.lower()) - with registry.cursor() as cr: - yield (registry, cr) + with self.cr() as cr: + yield (self.registry(), cr) + +def noauth(f): + f.auth = "noauth" + return f + +def nodb(f): + f.auth = "nodb" + return f def reject_nonliteral(dct): if '__ref' in dct: @@ -167,13 +199,14 @@ class JsonRequest(WebRequest): "id": null} """ - def dispatch(self, method): + def dispatch(self): """ Calls the method asked for by the JSON-RPC2 or JSONP request :param method: the method which received the request :returns: an utf8 encoded JSON-RPC2 or JSONP reply """ + method = self.method args = self.httprequest.args jsonp = args.get('jsonp') requestf = None @@ -291,7 +324,8 @@ def jsonrequest(f): class HttpRequest(WebRequest): """ Regular GET/POST request """ - def dispatch(self, method): + def dispatch(self): + method = self.method params = dict(self.httprequest.args) params.update(self.httprequest.form) params.update(self.httprequest.files) @@ -658,20 +692,22 @@ class Root(object): method = getattr(c, method_name, None) if method: exposed = getattr(method, 'exposed', False) + auth = getattr(method, 'auth', None) method = c.get_wrapped_method(method_name) + method.auth = auth if exposed == 'json': _logger.debug("Dispatch json to %s %s %s", ps, c, method_name) def fct(_request): - _req = JsonRequest(_request) + _req = JsonRequest(_request, method) with set_request(_req): - return request.dispatch(method) + return request.dispatch() return fct elif exposed == 'http': _logger.debug("Dispatch http to %s %s %s", ps, c, method_name) def fct(_request): - _req = HttpRequest(_request) + _req = HttpRequest(_request, method) with set_request(_req): - return request.dispatch(method) + return request.dispatch() return fct if method_name != "index": method_name = "index" diff --git a/addons/web/session.py b/addons/web/session.py index 13c3bc7cb94..9568da261f0 100644 --- a/addons/web/session.py +++ b/addons/web/session.py @@ -20,6 +20,7 @@ class AuthenticationError(Exception): class SessionExpiredException(Exception): pass +# deprecated class Service(object): def __init__(self, session, service_name): self.session = session @@ -31,6 +32,7 @@ class Service(object): return result return proxy_method +# deprecated class Model(object): def __init__(self, session, model): self.session = session @@ -84,12 +86,6 @@ class OpenERPSession(object): self.context = {} self.jsonp_requests = {} # FIXME use a LRU - def send(self, service_name, method, *args): - return openerp.netsvc.dispatch_rpc(service_name, method, args) - - def proxy(self, service): - return Service(self, service) - def bind(self, db, uid, login, password): self._db = db self._uid = uid @@ -103,6 +99,21 @@ class OpenERPSession(object): if uid: self.get_context() return uid + def check_security(self): + import openerp.service.security as security + if not self._db or not self._uid: + raise SessionExpiredException("Session expired") + security.check(self._db, self._uid, self._password) + + #deprecated + def send(self, service_name, method, *args): + return openerp.netsvc.dispatch_rpc(service_name, method, args) + + #deprecated + def proxy(self, service): + return Service(self, service) + + #deprecated def assert_valid(self, force=False): """ Ensures this session is valid (logged into the openerp server) @@ -114,6 +125,7 @@ class OpenERPSession(object): if not self._uid: raise AuthenticationError("Authentication failure") + #deprecated def ensure_valid(self): if self._uid: try: @@ -121,16 +133,19 @@ class OpenERPSession(object): except Exception: self._uid = None + #deprecated def execute(self, model, func, *l, **d): model = self.model(model) r = getattr(model, func)(*l, **d) return r + #deprecated def exec_workflow(self, model, id, signal): self.assert_valid() r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id) return r + #deprecated def model(self, model): """ Get an RPC proxy for the object ``model``, bound to this session.