Files
tryton/trytond/protocols/webdav.py
T

593 lines
21 KiB
Python
Raw Normal View History

#This file is part of Tryton. The COPYRIGHT file at the top level of
#this repository contains the full copyright notices and license terms.
2009-02-12 18:46:43 +01:00
import SocketServer
2008-02-14 01:43:39 +01:00
import socket
2009-02-12 18:46:43 +01:00
import BaseHTTPServer
import urlparse
import time
import urllib
import sys
2009-07-08 15:26:46 +02:00
import traceback
import logging
from threading import local
import xml.dom.minidom
2012-03-25 19:12:02 +02:00
import base64
from pywebdav.lib import WebDAVServer, iface
from pywebdav.lib.errors import DAV_Error, DAV_NotFound, DAV_Secret, \
DAV_Forbidden, DAV_Requested_Range_Not_Satisfiable
from pywebdav.lib.constants import COLLECTION, DAV_VERSION_1, DAV_VERSION_2
2012-04-01 23:08:15 +02:00
from pywebdav.lib.utils import get_urifilename, quote_uri
2012-03-25 19:12:02 +02:00
from pywebdav.lib.davcmd import copyone, copytree, moveone, movetree, \
delone, deltree
2010-08-19 22:01:12 +02:00
from trytond.protocols.sslsocket import SSLSocket
from trytond.protocols.common import daemon
2010-08-19 22:01:12 +02:00
from trytond.config import CONFIG
from trytond.security import login
from trytond.version import PACKAGE, VERSION, WEBSITE
from trytond.tools.misc import LocalDict
2013-09-06 22:32:37 +02:00
from trytond import backend
2010-08-19 22:01:12 +02:00
from trytond.pool import Pool
from trytond.transaction import Transaction
from trytond.cache import Cache
2011-09-05 20:30:26 +02:00
from trytond.exceptions import UserError, UserWarning, NotLogged, \
ConcurrencyException
domimpl = xml.dom.minidom.getDOMImplementation()
2009-11-10 14:14:30 +01:00
DAV_VERSION_1['version'] += ',access-control'
DAV_VERSION_2['version'] += ',access-control'
2012-04-01 23:08:15 +02:00
2009-07-08 15:26:46 +02:00
# Local int for multi-thread
class LocalInt(local):
def __init__(self, value=0):
2010-02-18 18:50:35 +01:00
super(LocalInt, self).__init__()
self.value = value
def __int__(self):
return int(self.value)
CACHE = LocalDict()
2008-02-14 01:43:39 +01:00
2012-03-25 19:12:02 +02:00
def setupConfig():
2008-07-18 20:02:30 +02:00
2012-03-25 19:12:02 +02:00
class ConfigDAV:
2008-07-18 20:02:30 +02:00
lockemulation = False
2008-07-23 23:14:37 +02:00
verbose = False
2012-03-25 19:12:02 +02:00
baseurl = ''
2008-07-18 20:02:30 +02:00
def getboolean(self, name):
return bool(self.get(name))
def get(self, name, default=None):
return getattr(self, name, default)
2012-03-25 19:12:02 +02:00
class Config:
DAV = ConfigDAV()
2008-07-18 20:02:30 +02:00
2012-03-25 19:12:02 +02:00
return Config()
2008-07-18 20:02:30 +02:00
2009-02-12 18:46:43 +01:00
class BaseThreadedHTTPServer(SocketServer.ThreadingMixIn,
BaseHTTPServer.HTTPServer):
timeout = 1
2009-02-12 18:46:43 +01:00
def server_bind(self):
self.socket.setsockopt(socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1)
2012-01-17 13:51:08 +01:00
self.socket.setsockopt(socket.SOL_SOCKET,
socket.SO_KEEPALIVE, 1)
2009-02-12 18:46:43 +01:00
BaseHTTPServer.HTTPServer.server_bind(self)
class SecureThreadedHTTPServer(BaseThreadedHTTPServer):
def __init__(self, server_address, HandlerClass):
BaseThreadedHTTPServer.__init__(self, server_address, HandlerClass)
2012-12-13 19:04:52 +01:00
self.socket = socket.socket(self.address_family, self.socket_type)
2009-02-12 18:46:43 +01:00
self.server_bind()
self.server_activate()
class WebDAVServerThread(daemon):
2009-02-12 18:46:43 +01:00
def __init__(self, interface, port, secure=False):
2011-10-28 10:20:23 +02:00
daemon.__init__(self, interface, port, secure,
name='WebDAVServerThread')
if self.secure:
2009-02-12 18:46:43 +01:00
handler_class = SecureWebDAVAuthRequestHandler
server_class = SecureThreadedHTTPServer
if self.ipv6:
2009-02-12 18:46:43 +01:00
server_class = SecureThreadedHTTPServer6
else:
handler_class = WebDAVAuthRequestHandler
server_class = BaseThreadedHTTPServer
if self.ipv6:
2009-02-12 18:46:43 +01:00
server_class = BaseThreadedHTTPServer6
2012-03-25 19:12:02 +02:00
handler_class._config = setupConfig()
2009-02-12 18:46:43 +01:00
handler_class.IFACE_CLASS = TrytonDAVInterface(interface, port, secure)
2012-03-25 19:12:02 +02:00
handler_class.IFACE_CLASS.baseurl = handler_class._config.DAV.baseurl
2009-02-12 18:46:43 +01:00
self.server = server_class((interface, port), handler_class)
2012-04-01 23:08:15 +02:00
2009-02-12 18:46:43 +01:00
class BaseThreadedHTTPServer6(BaseThreadedHTTPServer):
address_family = socket.AF_INET6
class SecureThreadedHTTPServer6(SecureThreadedHTTPServer):
address_family = socket.AF_INET6
2008-02-14 01:43:39 +01:00
class TrytonDAVInterface(iface.dav_interface):
2008-03-04 16:11:42 +01:00
def __init__(self, interface, port, secure=False):
if secure:
protocol = 'https'
else:
protocol = 'http'
2010-02-18 18:50:35 +01:00
self.baseuri = '%s://%s:%s/' % (protocol, interface or
socket.gethostname(), port)
2008-07-18 20:02:30 +02:00
self.verbose = False
2008-02-14 01:43:39 +01:00
2009-07-08 15:26:46 +02:00
def _log_exception(self, exception):
2011-09-05 20:30:26 +02:00
if CONFIG['verbose'] and not isinstance(exception, (
NotLogged, ConcurrencyException, UserError, UserWarning,
DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden)):
tb_s = ''.join(traceback.format_exception(*sys.exc_info()))
2009-07-08 15:26:46 +02:00
logger = logging.getLogger('webdav')
logger.error('Exception:\n' + tb_s)
2009-07-08 15:26:46 +02:00
@staticmethod
def get_dburi(uri):
uri = urlparse.urlsplit(uri)[2]
2009-08-28 16:31:44 +02:00
if uri and uri[0] == '/':
uri = uri[1:]
2008-02-14 01:43:39 +01:00
dbname, uri = (uri.split('/', 1) + [None])[0:2]
2009-05-12 13:56:51 +02:00
if dbname:
dbname = urllib.unquote_plus(dbname)
if uri:
uri = urllib.unquote_plus(uri)
2008-02-14 01:43:39 +01:00
return dbname, uri
def _get_dburi(self, uri):
return TrytonDAVInterface.get_dburi(uri)
2009-07-02 19:37:02 +02:00
def get_childs(self, uri, filter=None):
2008-02-14 01:43:39 +01:00
res = []
dbname, dburi = self._get_dburi(uri)
if not dbname:
2013-09-06 22:32:37 +02:00
database = backend.get('Database')().connect()
2011-05-16 12:22:43 +02:00
cursor = database.cursor()
2009-02-11 14:52:22 +01:00
try:
2011-05-16 12:22:43 +02:00
lists = database.list(cursor)
except Exception:
lists = []
2009-02-11 14:52:22 +01:00
finally:
cursor.close()
for dbname in lists:
2009-05-06 13:10:50 +02:00
res.append(urlparse.urljoin(uri, dbname))
2008-02-14 01:43:39 +01:00
return res
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2012-03-25 19:12:02 +02:00
scheme, netloc, path, params, query, fragment = \
urlparse.urlparse(uri)
if path[-1:] != '/':
path += '/'
2012-09-24 22:16:53 +02:00
for child in Collection.get_childs(dburi, filter=filter,
2010-08-19 22:01:12 +02:00
cache=CACHE):
2012-03-25 19:12:02 +02:00
res.append(urlparse.urlunparse((scheme, netloc,
path + child.encode('utf-8'), params, query,
fragment)))
2009-11-10 14:03:20 +01:00
except KeyError:
return res
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
2008-02-14 01:43:39 +01:00
return res
def get_data(self, uri, range=None):
2008-02-14 01:43:39 +01:00
dbname, dburi = self._get_dburi(uri)
if not dbname or (self.exists(uri) and self.is_collection(uri)):
2013-02-27 22:50:31 +01:00
res = ('<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 '
'Transitional//EN">')
2008-02-14 15:19:08 +01:00
res += '<html>'
res += '<head>'
2013-02-27 22:50:31 +01:00
res += ('<meta http-equiv="Content-Type" content="text/html; '
'charset=utf-8">')
res += ('<title>%s - WebDAV - %s</title>'
% (PACKAGE, dbname or 'root'))
2008-02-14 15:19:08 +01:00
res += '</head>'
res += '<body>'
2008-05-28 20:40:53 +02:00
res += '<h2>Collection: %s</h2>' % (get_urifilename(uri) or '/')
2008-02-14 15:19:08 +01:00
res += '<ul>'
if dbname:
2012-03-25 19:12:02 +02:00
scheme, netloc, path, params, query, fragment = \
urlparse.urlparse(uri)
if path[-1:] != '/':
path += '/'
2013-02-27 22:50:31 +01:00
res += ('<li><a href="%s">..</a></li>'
% urlparse.urlunparse((scheme, netloc, path + '..',
params, query, fragment)))
2008-02-16 15:54:18 +01:00
childs = self.get_childs(uri)
childs.sort()
for child in childs:
2013-02-27 22:50:31 +01:00
res += ('<li><a href="%s">%s</a></li>'
% (quote_uri(child), get_urifilename(child)))
2008-02-14 15:19:08 +01:00
res += '</ul>'
res += '<hr noshade>'
2013-02-27 22:50:31 +01:00
res += ('<em>Powered by <a href="%s">%s</a> version %s</em>'
% (quote_uri(WEBSITE), PACKAGE, VERSION))
2008-02-14 15:19:08 +01:00
res += '</body>'
res += '</html>'
return res
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_data(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
if range is None:
return res
size = len(res)
if range[1] == '':
range[1] = size
else:
range[1] = int(range[1])
if range[1] > size:
range[1] = size
if range[0] == '':
range[0] = size - range[1]
else:
range[0] = int(range[0])
if range[0] > size:
raise DAV_Requested_Range_Not_Satisfiable
return res[range[0]:range[1]]
def put(self, uri, data, content_type=''):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
raise DAV_Forbidden
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
try:
2012-09-24 22:16:53 +02:00
res = Collection.put(dburi, data, content_type, cache=CACHE)
2010-08-19 22:01:12 +02:00
Transaction().cursor.commit()
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
2009-05-12 15:39:54 +02:00
if res:
uparts = list(urlparse.urlsplit(uri))
uparts[2] = res
res = urlparse.urlunsplit(uparts)
return res
def mkcol(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
raise DAV_Forbidden
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
try:
2012-09-24 22:16:53 +02:00
res = Collection.mkcol(dburi, cache=CACHE)
2010-08-19 22:01:12 +02:00
Transaction().cursor.commit()
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
def _get_dav_resourcetype(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return COLLECTION
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_resourcetype(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
def _get_dav_displayname(self, uri):
2009-11-10 16:04:05 +01:00
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return uri.split('/')[-1]
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2009-11-10 16:04:05 +01:00
try:
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
res = Collection.get_displayname(dburi, cache=CACHE)
2009-11-10 16:04:05 +01:00
except KeyError:
raise DAV_NotFound
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
raise
except Exception, exception:
self._log_exception(exception)
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
def _get_dav_getcontentlength(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return '0'
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_contentlength(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
def _get_dav_getcontenttype(self, uri):
2008-02-14 15:19:08 +01:00
dbname, dburi = self._get_dburi(uri)
if not dbname or self.is_collection(uri):
return "text/html"
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_contenttype(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
2009-04-30 17:42:17 +02:00
def _get_dav_getetag(self, uri):
return '"' + str(self.get_lastmodified(uri)) + '"'
def get_creationdate(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return time.time()
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_creationdate(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
def get_lastmodified(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return time.time()
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.get_lastmodified(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
def rmcol(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
2009-11-10 14:03:20 +01:00
return 403
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
try:
2012-09-24 22:16:53 +02:00
res = Collection.rmcol(dburi, cache=CACHE)
2010-08-19 22:01:12 +02:00
Transaction().cursor.commit()
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-11-10 14:03:20 +01:00
return 500
return res
def rm(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
2009-11-10 14:03:20 +01:00
return 403
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
try:
2012-09-24 22:16:53 +02:00
res = Collection.rm(dburi, cache=CACHE)
2010-08-19 22:01:12 +02:00
Transaction().cursor.commit()
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2010-08-19 22:01:12 +02:00
Transaction().cursor.rollback()
2009-11-10 14:03:20 +01:00
return 500
return res
2008-02-14 01:43:39 +01:00
def exists(self, uri):
dbname, dburi = self._get_dburi(uri)
if not dbname or not dburi:
return 1
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
2009-02-11 14:52:22 +01:00
try:
2012-09-24 22:16:53 +02:00
res = Collection.exists(dburi, cache=CACHE)
2009-07-08 15:26:46 +02:00
except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise
2009-07-08 15:26:46 +02:00
except Exception, exception:
self._log_exception(exception)
2009-05-06 13:10:50 +02:00
raise DAV_Error(500)
return res
2008-02-14 01:43:39 +01:00
def is_collection(self, uri):
if self._get_dav_resourcetype(uri) == COLLECTION:
return 1
return 0
def copyone(self, src, dst, overwrite):
return copyone(self, src, dst, overwrite)
def copytree(self, src, dst, overwrite):
return copytree(self, src, dst, overwrite)
def moveone(self, src, dst, overwrite):
return moveone(self, src, dst, overwrite)
def movetree(self, src, dst, overwrite):
return movetree(self, src, dst, overwrite)
def delone(self, uri):
return delone(self, uri)
def deltree(self, uri):
return deltree(self, uri)
def copy(self, src, dst):
content = self._get_dav_getcontenttype(src)
data = self.get_data(src)
self.put(dst, data, content)
return 201
def copycol(self, src, dst):
return self.mkcol(dst)
def _get_dav_current_user_privilege_set(self, uri):
dbname, dburi = self._get_dburi(uri)
privileges = []
if not dbname or not dburi:
privileges = ['create', 'read', 'write', 'delete']
else:
2010-08-19 22:01:12 +02:00
pool = Pool(Transaction().cursor.database_name)
try:
2012-09-24 22:16:53 +02:00
Collection = pool.get('webdav.collection')
privileges = Collection.current_user_privilege_set(dburi,
2010-08-19 22:01:12 +02:00
cache=CACHE)
except KeyError:
pass
except Exception, exception:
self._log_exception(exception)
pass
doc = domimpl.createDocument(None, 'privilege', None)
privilege = doc.documentElement
privilege.tagName = 'D:privilege'
if 'create' in privileges:
bind = doc.createElement('D:bind')
privilege.appendChild(bind)
if 'read' in privileges:
read = doc.createElement('D:read')
privilege.appendChild(read)
read_acl = doc.createElement('D:read-acl')
privilege.appendChild(read_acl)
if 'write' in privileges:
write = doc.createElement('D:write')
privilege.appendChild(write)
write_content = doc.createElement('D:write-content')
privilege.appendChild(write_content)
write_properties = doc.createElement('D:write-properties')
privilege.appendChild(write_properties)
if 'delete' in privileges:
unbind = doc.createElement('D:unbind')
privilege.appendChild(unbind)
return privilege
2010-02-18 18:50:35 +01:00
TrytonDAVInterface.PROPS['DAV:'] = tuple(list(TrytonDAVInterface.PROPS['DAV:']
) + ['current-user-privilege-set'])
2008-02-14 01:43:39 +01:00
2012-03-25 19:12:02 +02:00
class WebDAVAuthRequestHandler(WebDAVServer.DAVRequestHandler):
2008-02-14 01:43:39 +01:00
2009-05-06 13:10:50 +02:00
def finish(self):
2012-03-25 19:12:02 +02:00
WebDAVServer.DAVRequestHandler.finish(self)
2011-12-28 11:33:04 +01:00
global CACHE
2010-08-19 22:01:12 +02:00
CACHE = LocalDict()
if not Transaction().cursor:
return
dbname = Transaction().cursor.database_name
Transaction().stop()
2009-05-06 13:10:50 +02:00
if dbname:
Cache.resets(dbname)
2012-03-25 19:12:02 +02:00
def parse_request(self):
if not BaseHTTPServer.BaseHTTPRequestHandler.parse_request(self):
return False
authorization = self.headers.get('Authorization', '')
if authorization:
scheme, credentials = authorization.split()
if scheme != 'Basic':
self.send_error(501)
return False
credentials = base64.decodestring(credentials)
user, password = credentials.split(':', 2)
if not self.get_userinfo(user, password, self.command):
self.send_autherror(401, "Authorization Required")
return False
else:
if not self.get_userinfo(None, None, self.command):
self.send_autherror(401, "Authorization Required")
return False
return True
2008-05-27 15:22:47 +02:00
def get_userinfo(self, user, password, command=''):
2012-03-25 19:12:02 +02:00
path = urlparse.urlparse(self.path).path
dbname = urllib.unquote_plus(path.split('/', 2)[1])
2013-09-06 22:32:37 +02:00
database = backend.get('Database')().connect()
2012-07-25 20:51:36 +02:00
cursor = database.cursor()
databases = database.list(cursor)
cursor.close()
if not dbname or dbname not in databases:
2012-03-25 19:12:02 +02:00
return True
if user:
user = int(login(dbname, user, password, cache=False))
if not user:
return None
else:
url = urlparse.urlparse(self.path)
query = urlparse.parse_qs(url.query)
path = url.path[len(dbname) + 2:]
if 'key' in query:
key, = query['key']
with Transaction().start(dbname, 0) as transaction:
database_list = Pool.database_list()
pool = Pool(dbname)
if not dbname in database_list:
pool.init()
2012-09-24 22:16:53 +02:00
Share = pool.get('webdav.share')
user = Share.get_login(key, command, path)
2012-03-25 19:12:02 +02:00
transaction.cursor.commit()
if not user:
return None
2009-05-06 13:10:50 +02:00
2010-08-19 22:01:12 +02:00
Transaction().start(dbname, user)
Cache.clean(dbname)
2012-03-25 19:12:02 +02:00
return user
2008-03-04 16:11:42 +01:00
2012-04-01 23:08:15 +02:00
2008-03-04 16:11:42 +01:00
class SecureWebDAVAuthRequestHandler(WebDAVAuthRequestHandler):
def setup(self):
2012-12-13 19:04:52 +01:00
self.request = SSLSocket(self.request)
WebDAVAuthRequestHandler.setup(self)