2010-03-04 09:03:42 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2009-08-29 15:23:46 +00:00
|
|
|
#
|
2010-07-26 09:33:36 +00:00
|
|
|
# Copyright P. Christeas <p_christ@hol.gr> 2008-2010
|
|
|
|
# Copyright 2010 OpenERP SA. (http://www.openerp.com)
|
2009-08-29 15:23:46 +00:00
|
|
|
#
|
|
|
|
#
|
|
|
|
# WARNING: This program as such is intended to be used by professional
|
|
|
|
# programmers who take the whole responsability of assessing all potential
|
|
|
|
# consequences resulting from its eventual inadequacies and bugs
|
|
|
|
# End users who are looking for a ready-to-use solution with commercial
|
|
|
|
# garantees and support are strongly adviced to contract a Free Software
|
|
|
|
# Service Company
|
|
|
|
#
|
|
|
|
# This program is Free Software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
###############################################################################
|
|
|
|
|
|
|
|
""" This file contains instance of the http server.
|
|
|
|
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
"""
|
|
|
|
from websrv_lib import *
|
|
|
|
import netsvc
|
2010-05-18 15:41:23 +00:00
|
|
|
import errno
|
2009-08-29 15:23:46 +00:00
|
|
|
import threading
|
|
|
|
import tools
|
2010-07-26 09:33:34 +00:00
|
|
|
import posixpath
|
|
|
|
import urllib
|
2009-08-29 15:23:46 +00:00
|
|
|
import os
|
2010-05-18 15:41:23 +00:00
|
|
|
import select
|
2009-08-29 15:23:46 +00:00
|
|
|
import socket
|
|
|
|
import xmlrpclib
|
2010-07-26 09:33:34 +00:00
|
|
|
import logging
|
2009-08-29 15:23:46 +00:00
|
|
|
|
|
|
|
from SimpleXMLRPCServer import SimpleXMLRPCDispatcher
|
|
|
|
|
|
|
|
try:
|
|
|
|
import fcntl
|
|
|
|
except ImportError:
|
|
|
|
fcntl = None
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-09-08 08:15:16 +00:00
|
|
|
try:
|
2009-11-24 14:44:05 +00:00
|
|
|
from ssl import SSLError
|
2009-09-08 08:15:16 +00:00
|
|
|
except ImportError:
|
2009-11-24 14:44:05 +00:00
|
|
|
class SSLError(Exception): pass
|
2009-08-29 15:23:46 +00:00
|
|
|
|
|
|
|
class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer):
|
|
|
|
""" A threaded httpd server, with all the necessary functionality for us.
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-11-24 14:44:05 +00:00
|
|
|
It also inherits the xml-rpc dispatcher, so that some xml-rpc functions
|
|
|
|
will be available to the request handler
|
2009-08-29 15:23:46 +00:00
|
|
|
"""
|
|
|
|
encoding = None
|
|
|
|
allow_none = False
|
|
|
|
allow_reuse_address = 1
|
|
|
|
_send_traceback_header = False
|
|
|
|
i = 0
|
|
|
|
|
|
|
|
def __init__(self, addr, requestHandler,
|
|
|
|
logRequests=True, allow_none=False, encoding=None, bind_and_activate=True):
|
|
|
|
self.logRequests = logRequests
|
|
|
|
|
|
|
|
SimpleXMLRPCDispatcher.__init__(self, allow_none, encoding)
|
2009-09-08 16:39:14 +00:00
|
|
|
HTTPServer.__init__(self, addr, requestHandler)
|
2010-07-26 09:33:35 +00:00
|
|
|
|
|
|
|
self.numThreads = 0
|
2010-07-26 09:33:35 +00:00
|
|
|
self.__threadno = 0
|
2009-08-29 15:23:46 +00:00
|
|
|
|
|
|
|
# [Bug #1222790] If possible, set close-on-exec flag; if a
|
|
|
|
# method spawns a subprocess, the subprocess shouldn't have
|
|
|
|
# the listening socket open.
|
|
|
|
if fcntl is not None and hasattr(fcntl, 'FD_CLOEXEC'):
|
|
|
|
flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFD)
|
|
|
|
flags |= fcntl.FD_CLOEXEC
|
|
|
|
fcntl.fcntl(self.fileno(), fcntl.F_SETFD, flags)
|
|
|
|
|
|
|
|
def handle_error(self, request, client_address):
|
|
|
|
""" Override the error handler
|
|
|
|
"""
|
2010-07-26 09:33:34 +00:00
|
|
|
|
|
|
|
logging.getLogger("init").exception("Server error in request from %s:" % (client_address,))
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2010-07-26 09:33:35 +00:00
|
|
|
def _mark_start(self, thread):
|
|
|
|
self.numThreads += 1
|
|
|
|
|
|
|
|
def _mark_end(self, thread):
|
|
|
|
self.numThreads -= 1
|
|
|
|
|
2010-07-26 09:33:35 +00:00
|
|
|
|
|
|
|
def _get_next_name(self):
|
|
|
|
self.__threadno += 1
|
|
|
|
return 'http-client-%d' % self.__threadno
|
2010-07-26 09:33:34 +00:00
|
|
|
class HttpLogHandler:
|
|
|
|
""" helper class for uniform log handling
|
|
|
|
Please define self._logger at each class that is derived from this
|
|
|
|
"""
|
|
|
|
_logger = None
|
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
def log_message(self, format, *args):
|
2010-07-26 09:33:34 +00:00
|
|
|
self._logger.debug(format % args) # todo: perhaps other level
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2009-09-03 21:08:02 +00:00
|
|
|
def log_error(self, format, *args):
|
2010-07-26 09:33:34 +00:00
|
|
|
self._logger.error(format % args)
|
2010-07-26 09:33:35 +00:00
|
|
|
|
|
|
|
def log_exception(self, format, *args):
|
|
|
|
self._logger.exception(format, *args)
|
2010-07-26 09:33:34 +00:00
|
|
|
|
|
|
|
def log_request(self, code='-', size='-'):
|
2010-07-26 09:33:35 +00:00
|
|
|
self._logger.log(netsvc.logging.DEBUG_RPC, '"%s" %s %s',
|
2010-07-26 09:33:34 +00:00
|
|
|
self.requestline, str(code), str(size))
|
|
|
|
|
|
|
|
class MultiHandler2(HttpLogHandler, MultiHTTPHandler):
|
|
|
|
_logger = logging.getLogger('http')
|
2009-09-03 21:08:02 +00:00
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
class SecureMultiHandler2(HttpLogHandler, SecureMultiHTTPHandler):
|
|
|
|
_logger = logging.getLogger('https')
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2009-08-31 13:29:56 +00:00
|
|
|
def getcert_fnames(self):
|
|
|
|
tc = tools.config
|
2010-08-10 13:12:00 +00:00
|
|
|
fcert = tc.get('secure_cert_file', 'server.cert')
|
|
|
|
fkey = tc.get('secure_pkey_file', 'server.key')
|
2009-11-24 14:44:05 +00:00
|
|
|
return (fcert,fkey)
|
2009-08-31 13:29:56 +00:00
|
|
|
|
2009-12-02 11:15:16 +00:00
|
|
|
class BaseHttpDaemon(threading.Thread, netsvc.Server):
|
2010-07-26 09:33:34 +00:00
|
|
|
_RealProto = '??'
|
|
|
|
|
2009-12-02 11:15:16 +00:00
|
|
|
def __init__(self, interface, port, handler):
|
2009-08-29 15:23:46 +00:00
|
|
|
threading.Thread.__init__(self)
|
2009-11-24 14:44:05 +00:00
|
|
|
netsvc.Server.__init__(self)
|
2009-08-29 15:23:46 +00:00
|
|
|
self.__port = port
|
|
|
|
self.__interface = interface
|
|
|
|
|
|
|
|
try:
|
2009-12-02 11:15:16 +00:00
|
|
|
self.server = ThreadedHTTPServer((interface, port), handler)
|
2009-11-24 14:44:05 +00:00
|
|
|
self.server.vdirs = []
|
|
|
|
self.server.logRequests = True
|
2010-07-13 15:22:44 +00:00
|
|
|
self.server.timeout = self._busywait_timeout
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger("web-services").info(
|
|
|
|
"starting %s service at %s port %d" %
|
|
|
|
(self._RealProto, interface or '0.0.0.0', port,))
|
2009-08-29 15:23:46 +00:00
|
|
|
except Exception, e:
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger("httpd").exception("Error occured when starting the server daemon.")
|
2009-08-29 15:23:46 +00:00
|
|
|
raise
|
|
|
|
|
2010-05-18 15:41:23 +00:00
|
|
|
@property
|
|
|
|
def socket(self):
|
|
|
|
return self.server.socket
|
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
def attach(self, path, gw):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
self.running = False
|
2010-05-18 15:41:23 +00:00
|
|
|
self._close_socket()
|
2009-08-29 15:23:46 +00:00
|
|
|
|
|
|
|
def run(self):
|
|
|
|
self.running = True
|
|
|
|
while self.running:
|
2010-05-18 15:41:23 +00:00
|
|
|
try:
|
|
|
|
self.server.handle_request()
|
|
|
|
except (socket.error, select.error), e:
|
|
|
|
if self.running or e.args[0] != errno.EBADF:
|
|
|
|
raise
|
2009-08-29 15:23:46 +00:00
|
|
|
return True
|
|
|
|
|
2010-07-26 09:33:35 +00:00
|
|
|
def stats(self):
|
|
|
|
res = "%sd: " % self._RealProto + ((self.running and "running") or "stopped")
|
|
|
|
if self.server:
|
|
|
|
res += ", %d threads" % (self.server.numThreads,)
|
|
|
|
return res
|
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
def append_svc(self, service):
|
|
|
|
if not isinstance(service, HTTPDir):
|
|
|
|
raise Exception("Wrong class for http service")
|
|
|
|
|
|
|
|
pos = len(self.server.vdirs)
|
|
|
|
lastpos = pos
|
|
|
|
while pos > 0:
|
|
|
|
pos -= 1
|
|
|
|
if self.server.vdirs[pos].matches(service.path):
|
|
|
|
lastpos = pos
|
|
|
|
# we won't break here, but search all way to the top, to
|
|
|
|
# ensure there is no lesser entry that will shadow the one
|
|
|
|
# we are inserting.
|
|
|
|
self.server.vdirs.insert(lastpos, service)
|
|
|
|
|
|
|
|
def list_services(self):
|
|
|
|
ret = []
|
|
|
|
for svc in self.server.vdirs:
|
|
|
|
ret.append( ( svc.path, str(svc.handler)) )
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
2009-12-02 11:15:16 +00:00
|
|
|
class HttpDaemon(BaseHttpDaemon):
|
2010-07-26 09:33:34 +00:00
|
|
|
_RealProto = 'HTTP'
|
2009-08-29 15:23:46 +00:00
|
|
|
def __init__(self, interface, port):
|
2009-12-02 11:15:16 +00:00
|
|
|
super(HttpDaemon, self).__init__(interface, port,
|
|
|
|
handler=MultiHandler2)
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2010-01-31 15:55:08 +00:00
|
|
|
class HttpSDaemon(BaseHttpDaemon):
|
2010-07-26 09:33:34 +00:00
|
|
|
_RealProto = 'HTTPS'
|
2009-12-02 11:15:16 +00:00
|
|
|
def __init__(self, interface, port):
|
2009-08-29 15:23:46 +00:00
|
|
|
try:
|
2010-01-31 15:55:08 +00:00
|
|
|
super(HttpSDaemon, self).__init__(interface, port,
|
|
|
|
handler=SecureMultiHandler2)
|
2009-08-29 15:23:46 +00:00
|
|
|
except SSLError, e:
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger('httpsd').exception( \
|
|
|
|
"Can not load the certificate and/or the private key files")
|
2009-08-29 15:23:46 +00:00
|
|
|
raise
|
2009-08-31 13:29:56 +00:00
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
httpd = None
|
|
|
|
httpsd = None
|
|
|
|
|
|
|
|
def init_servers():
|
2009-11-24 14:44:05 +00:00
|
|
|
global httpd, httpsd
|
2010-05-31 14:17:39 +00:00
|
|
|
if tools.config.get('xmlrpc'):
|
|
|
|
httpd = HttpDaemon(tools.config.get('xmlrpc_interface', ''),
|
|
|
|
int(tools.config.get('xmlrpc_port', 8069)))
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2010-05-31 14:17:39 +00:00
|
|
|
if tools.config.get('xmlrpcs'):
|
|
|
|
httpsd = HttpSDaemon(tools.config.get('xmlrpcs_interface', ''),
|
|
|
|
int(tools.config.get('xmlrpcs_port', 8071)))
|
2009-08-29 15:23:46 +00:00
|
|
|
|
|
|
|
def reg_http_service(hts, secure_only = False):
|
2009-11-24 14:44:05 +00:00
|
|
|
""" Register some handler to httpd.
|
|
|
|
hts must be an HTTPDir
|
|
|
|
"""
|
|
|
|
global httpd, httpsd
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-11-24 14:44:05 +00:00
|
|
|
if httpd and not secure_only:
|
2010-07-26 09:33:34 +00:00
|
|
|
httpd.append_svc(hts)
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-11-24 14:44:05 +00:00
|
|
|
if httpsd:
|
2010-07-26 09:33:34 +00:00
|
|
|
httpsd.append_svc(hts)
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-11-24 14:44:05 +00:00
|
|
|
if (not httpd) and (not httpsd):
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger('httpd').warning("No httpd available to register service %s" % hts.path)
|
2009-11-24 14:44:05 +00:00
|
|
|
return
|
2009-08-29 15:23:46 +00:00
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
def list_http_services(protocol=None):
|
|
|
|
global httpd, httpsd
|
|
|
|
if httpd and (protocol == 'http' or protocol == None):
|
|
|
|
return httpd.list_services()
|
|
|
|
elif httpsd and (protocol == 'https' or protocol == None):
|
|
|
|
return httpsd.list_services()
|
|
|
|
else:
|
|
|
|
raise Exception("Incorrect protocol or no http services")
|
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
import SimpleXMLRPCServer
|
2010-07-26 09:33:34 +00:00
|
|
|
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,HttpLogHandler,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
|
2010-03-04 09:05:56 +00:00
|
|
|
rpc_paths = []
|
2009-08-29 15:23:46 +00:00
|
|
|
protocol_version = 'HTTP/1.1'
|
2010-07-26 09:33:34 +00:00
|
|
|
_logger = logging.getLogger('xmlrpc')
|
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
def _dispatch(self, method, params):
|
|
|
|
try:
|
|
|
|
service_name = self.path.split("/")[-1]
|
|
|
|
return self.dispatch(service_name, method, params)
|
|
|
|
except netsvc.OpenERPDispatcherException, e:
|
|
|
|
raise xmlrpclib.Fault(tools.exception_to_unicode(e.exception), e.traceback)
|
|
|
|
|
|
|
|
def handle(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def finish(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setup(self):
|
|
|
|
self.connection = dummyconn()
|
2009-11-24 14:44:05 +00:00
|
|
|
if not len(XMLRPCRequestHandler.rpc_paths):
|
|
|
|
XMLRPCRequestHandler.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys())
|
2009-08-29 15:23:46 +00:00
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
def init_xmlrpc():
|
2010-05-31 14:17:39 +00:00
|
|
|
if tools.config.get('xmlrpc', False):
|
|
|
|
# Example of http file serving:
|
|
|
|
# reg_http_service(HTTPDir('/test/',HTTPHandler))
|
|
|
|
reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler))
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger("web-services").info("Registered XML-RPC over HTTP")
|
2010-05-31 14:17:39 +00:00
|
|
|
|
2010-07-28 12:29:09 +00:00
|
|
|
if tools.config.get('xmlrpcs', False) \
|
|
|
|
and not tools.config.get('xmlrpc', False):
|
|
|
|
# only register at the secure server
|
|
|
|
reg_http_service(HTTPDir('/xmlrpc/', XMLRPCRequestHandler), True)
|
|
|
|
logging.getLogger("web-services").info("Registered XML-RPC over HTTPS only")
|
2010-07-26 09:33:34 +00:00
|
|
|
|
2010-07-26 09:33:35 +00:00
|
|
|
class StaticHTTPHandler(HttpLogHandler, FixSendError, HttpOptions, HTTPHandler):
|
2010-07-26 09:33:34 +00:00
|
|
|
_logger = logging.getLogger('httpd')
|
2010-07-26 09:33:36 +00:00
|
|
|
_HTTP_OPTIONS = { 'Allow': ['OPTIONS', 'GET', 'HEAD'] }
|
2009-09-03 21:08:02 +00:00
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
def __init__(self,request, client_address, server):
|
|
|
|
HTTPHandler.__init__(self,request,client_address,server)
|
2010-08-10 13:12:00 +00:00
|
|
|
document_root = tools.config.get('static_http_document_root', False)
|
|
|
|
assert document_root, "Please specify static_http_document_root in configuration, or disable static-httpd!"
|
|
|
|
self.__basepath = document_root
|
2010-07-26 09:33:34 +00:00
|
|
|
|
|
|
|
def translate_path(self, path):
|
|
|
|
"""Translate a /-separated PATH to the local filename syntax.
|
|
|
|
|
|
|
|
Components that mean special things to the local file system
|
|
|
|
(e.g. drive or directory names) are ignored. (XXX They should
|
|
|
|
probably be diagnosed.)
|
|
|
|
|
|
|
|
"""
|
|
|
|
# abandon query parameters
|
|
|
|
path = path.split('?',1)[0]
|
|
|
|
path = path.split('#',1)[0]
|
|
|
|
path = posixpath.normpath(urllib.unquote(path))
|
|
|
|
words = path.split('/')
|
|
|
|
words = filter(None, words)
|
|
|
|
path = self.__basepath
|
|
|
|
for word in words:
|
|
|
|
if word in (os.curdir, os.pardir): continue
|
|
|
|
path = os.path.join(path, word)
|
|
|
|
return path
|
|
|
|
|
|
|
|
def init_static_http():
|
2010-08-10 13:12:00 +00:00
|
|
|
if not tools.config.get('static_http_enable', False):
|
2010-07-26 09:33:34 +00:00
|
|
|
return
|
|
|
|
|
2010-08-10 13:12:00 +00:00
|
|
|
document_root = tools.config.get('static_http_document_root', False)
|
|
|
|
assert document_root, "Document root must be specified explicitly to enable static HTTP service (option --static-http-document-root)"
|
2010-07-26 09:33:34 +00:00
|
|
|
|
2010-08-10 13:12:00 +00:00
|
|
|
base_path = tools.config.get('static_http_url_prefix', '/')
|
2010-07-26 09:33:34 +00:00
|
|
|
|
|
|
|
reg_http_service(HTTPDir(base_path,StaticHTTPHandler))
|
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger("web-services").info("Registered HTTP dir %s for %s" % \
|
2010-08-10 13:12:00 +00:00
|
|
|
(document_root, base_path))
|
2010-07-26 09:33:34 +00:00
|
|
|
|
2009-09-03 21:08:02 +00:00
|
|
|
class OerpAuthProxy(AuthProxy):
|
2009-11-24 14:44:05 +00:00
|
|
|
""" Require basic authentication..
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2009-11-24 14:44:05 +00:00
|
|
|
This is a copy of the BasicAuthProxy, which however checks/caches the db
|
|
|
|
as well.
|
|
|
|
"""
|
|
|
|
def __init__(self,provider):
|
|
|
|
AuthProxy.__init__(self,provider)
|
|
|
|
self.auth_creds = {}
|
|
|
|
self.auth_tries = 0
|
|
|
|
self.last_auth = None
|
|
|
|
|
2010-04-06 11:09:53 +00:00
|
|
|
def checkRequest(self,handler,path, db=False):
|
2009-11-24 14:44:05 +00:00
|
|
|
auth_str = handler.headers.get('Authorization',False)
|
|
|
|
try:
|
2010-04-06 11:09:53 +00:00
|
|
|
if not db:
|
|
|
|
db = handler.get_db_from_path(path)
|
2010-06-24 13:43:32 +00:00
|
|
|
except Exception:
|
2009-11-24 14:44:05 +00:00
|
|
|
if path.startswith('/'):
|
|
|
|
path = path[1:]
|
|
|
|
psp= path.split('/')
|
|
|
|
if len(psp)>1:
|
|
|
|
db = psp[0]
|
|
|
|
else:
|
|
|
|
#FIXME!
|
|
|
|
self.provider.log("Wrong path: %s, failing auth" %path)
|
2010-04-06 11:09:53 +00:00
|
|
|
raise AuthRejectedExc("Authorization failed. Wrong sub-path.")
|
|
|
|
if self.auth_creds.get(db):
|
|
|
|
return True
|
2009-11-24 14:44:05 +00:00
|
|
|
if auth_str and auth_str.startswith('Basic '):
|
|
|
|
auth_str=auth_str[len('Basic '):]
|
|
|
|
(user,passwd) = base64.decodestring(auth_str).split(':')
|
|
|
|
self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db))
|
|
|
|
acd = self.provider.authenticate(db,user,passwd,handler.client_address)
|
|
|
|
if acd != False:
|
|
|
|
self.auth_creds[db] = acd
|
2010-04-06 11:09:53 +00:00
|
|
|
self.last_auth = db
|
2009-11-24 14:44:05 +00:00
|
|
|
return True
|
|
|
|
if self.auth_tries > 5:
|
|
|
|
self.provider.log("Failing authorization after 5 requests w/o password")
|
|
|
|
raise AuthRejectedExc("Authorization failed.")
|
|
|
|
self.auth_tries += 1
|
2010-06-27 19:54:25 +00:00
|
|
|
raise AuthRequiredExc(atype='Basic', realm=self.provider.realm)
|
2009-09-03 21:08:02 +00:00
|
|
|
|
|
|
|
import security
|
|
|
|
class OpenERPAuthProvider(AuthProvider):
|
2010-06-27 19:54:25 +00:00
|
|
|
def __init__(self,realm='OpenERP User'):
|
2009-11-24 14:44:05 +00:00
|
|
|
self.realm = realm
|
|
|
|
|
|
|
|
def setupAuth(self, multi, handler):
|
|
|
|
if not multi.sec_realms.has_key(self.realm):
|
|
|
|
multi.sec_realms[self.realm] = OerpAuthProxy(self)
|
|
|
|
handler.auth_proxy = multi.sec_realms[self.realm]
|
|
|
|
|
|
|
|
def authenticate(self, db, user, passwd, client_address):
|
|
|
|
try:
|
|
|
|
uid = security.login(db,user,passwd)
|
|
|
|
if uid is False:
|
|
|
|
return False
|
|
|
|
return (user, passwd, db, uid)
|
|
|
|
except Exception,e:
|
2010-07-26 09:33:34 +00:00
|
|
|
logging.getLogger("auth").debug("Fail auth: %s" % e )
|
2009-11-24 14:44:05 +00:00
|
|
|
return False
|
2010-03-04 09:05:56 +00:00
|
|
|
|
2010-07-26 09:33:34 +00:00
|
|
|
def log(self, msg, lvl=logging.INFO):
|
|
|
|
logging.getLogger("auth").log(lvl,msg)
|
2009-09-03 21:08:02 +00:00
|
|
|
|
2009-08-29 15:23:46 +00:00
|
|
|
#eof
|