1
#This file is part of Tryton. The COPYRIGHT file at the top level of
2
#this repository contains the full copyright notices and license terms.
7
from DAV import AuthServer, WebDAVServer, iface
8
from DAV.errors import *
9
from DAV.constants import COLLECTION, OBJECT
10
from DAV.utils import get_uriparentpath, get_urifilename, quote_uri
11
from DAV.davcmd import copyone, copytree, moveone, movetree, delone, deltree
12
from netsvc import LocalService, SSLSocket
15
from version import PACKAGE, VERSION, WEBSITE
16
from tools.misc import Cache
18
# Local int for multi-thread
20
if sys.version_info[:2] < (2, 4):
21
from threadinglocal import local
23
from threading import local
26
class LocalInt(local):
28
def __init__(self, value=0):
32
return int(self.value)
36
# Fix for bad use of Document in DAV.utils make_xmlresponse
37
from DAV.utils import VERSION as DAV_VERSION
38
if DAV_VERSION == '0.6':
39
from xml.dom.Document import Document
40
Document.Document = Document
42
# Fix for unset _config in DAVRequestHandler
43
if DAV_VERSION == '0.8':
54
WebDAVServer.DAVRequestHandler._config = _Config()
57
class TrytonDAVInterface(iface.dav_interface):
59
def __init__(self, interface, port, secure=False):
64
self.baseuri = '%s://%s:%s/' % (protocol, interface or socket.gethostname(), port)
67
def _get_dburi(self, uri):
68
uri = urlparse.urlsplit(uri)[2]
71
dbname, uri = (uri.split('/', 1) + [None])[0:2]
74
def get_childs(self, uri):
76
dbname, dburi = self._get_dburi(uri)
78
db = LocalService('db')
79
for dbname in db.list():
80
res.append(urlparse.urljoin(self.baseuri, dbname))
82
pool = pooler.get_pool(dbname)
83
cursor = pooler.get_db(dbname).cursor()
84
collection_obj = pool.get('webdav.collection')
87
for child in collection_obj.get_childs(cursor, int(USER_ID), dburi):
88
res.append(urlparse.urljoin(self.baseuri, uri + child))
92
def get_data(self, uri):
93
dbname, dburi = self._get_dburi(uri)
94
if not dbname or (self.exists(uri) and self.is_collection(uri)):
95
res = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">'
98
res += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'
99
res += '<title>%s - WebDAV - %s</title>' \
100
% (PACKAGE, dbname or 'root')
103
res += '<h2>Collection: %s</h2>' % (get_urifilename(uri) or '/')
106
res += '<li><a href="%s">..</a></li>' \
107
% (quote_uri(get_uriparentpath(uri) or '/'))
108
childs = self.get_childs(uri)
111
res += '<li><a href="%s">%s</a></li>' \
112
% (quote_uri(child), get_urifilename(child))
114
res += '<hr noshade>'
115
res += '<em>Powered by <a href="%s">%s</a> version %s</em>' \
116
% (quote_uri(WEBSITE), PACKAGE, VERSION)
120
pool = pooler.get_pool(dbname)
121
cursor = pooler.get_db(dbname).cursor()
122
collection_obj = pool.get('webdav.collection')
124
res = collection_obj.get_data(cursor, int(USER_ID), dburi)
129
def put(self, uri, data, content_type=''):
130
dbname, dburi = self._get_dburi(uri)
131
if not dbname or not dburi:
133
pool = pooler.get_pool(dbname)
134
cursor = pooler.get_db(dbname).cursor()
135
collection_obj = pool.get('webdav.collection')
138
res = collection_obj.put(cursor, int(USER_ID), dburi, data,
148
def mkcol(self, uri):
149
dbname, dburi = self._get_dburi(uri)
150
if not dbname or not dburi:
152
pool = pooler.get_pool(dbname)
153
cursor = pooler.get_db(dbname).cursor()
154
collection_obj = pool.get('webdav.collection')
157
res = collection_obj.mkcol(cursor, int(USER_ID), dburi)
166
def _get_dav_resourcetype(self, uri):
167
dbname, dburi = self._get_dburi(uri)
168
if not dbname or not dburi:
170
pool = pooler.get_pool(dbname)
171
cursor = pooler.get_db(dbname).cursor()
172
collection_obj = pool.get('webdav.collection')
173
res = collection_obj.get_resourcetype(cursor, int(USER_ID), dburi)
177
def _get_dav_displayname(self, uri):
180
def _get_dav_getcontentlength(self, uri):
181
dbname, dburi = self._get_dburi(uri)
182
if not dbname or not dburi:
184
pool = pooler.get_pool(dbname)
185
cursor = pooler.get_db(dbname).cursor()
186
collection_obj = pool.get('webdav.collection')
187
res = collection_obj.get_contentlength(cursor, int(USER_ID), dburi)
191
def _get_dav_getcontenttype(self, uri):
192
dbname, dburi = self._get_dburi(uri)
193
if not dbname or self.is_collection(uri):
195
pool = pooler.get_pool(dbname)
196
cursor = pooler.get_db(dbname).cursor()
197
collection_obj = pool.get('webdav.collection')
198
res = collection_obj.get_contenttype(cursor, int(USER_ID), dburi)
202
def get_creationdate(self, uri):
203
dbname, dburi = self._get_dburi(uri)
204
if not dbname or not dburi:
206
pool = pooler.get_pool(dbname)
207
cursor = pooler.get_db(dbname).cursor()
208
collection_obj = pool.get('webdav.collection')
209
res = collection_obj.get_creationdate(cursor, int(USER_ID), dburi)
213
def get_lastmodified(self, uri):
214
dbname, dburi = self._get_dburi(uri)
215
if not dbname or not dburi:
217
pool = pooler.get_pool(dbname)
218
cursor = pooler.get_db(dbname).cursor()
219
collection_obj = pool.get('webdav.collection')
220
res = collection_obj.get_lastmodified(cursor, int(USER_ID), dburi)
224
def rmcol(self, uri):
225
dbname, dburi = self._get_dburi(uri)
226
if not dbname or not dburi:
228
pool = pooler.get_pool(dbname)
229
cursor = pooler.get_db(dbname).cursor()
230
collection_obj = pool.get('webdav.collection')
233
res = collection_obj.rmcol(cursor, int(USER_ID), dburi)
243
dbname, dburi = self._get_dburi(uri)
244
if not dbname or not dburi:
246
pool = pooler.get_pool(dbname)
247
cursor = pooler.get_db(dbname).cursor()
248
collection_obj = pool.get('webdav.collection')
251
res = collection_obj.rm(cursor, int(USER_ID), dburi)
260
def exists(self, uri):
261
dbname, dburi = self._get_dburi(uri)
262
if not dbname or not dburi:
264
pool = pooler.get_pool(dbname)
265
cursor = pooler.get_db(dbname).cursor()
266
collection_obj = pool.get('webdav.collection')
267
res = collection_obj.exists(cursor, int(USER_ID), dburi)
271
def is_collection(self, uri):
272
if self._get_dav_resourcetype(uri) == COLLECTION:
276
def copyone(self, src, dst, overwrite):
277
return copyone(self, src, dst, overwrite)
279
def copytree(self, src, dst, overwrite):
280
return copytree(self, src, dst, overwrite)
282
def moveone(self, src, dst, overwrite):
283
return moveone(self, src, dst, overwrite)
285
def movetree(self, src, dst, overwrite):
286
return movetree(self, src, dst, overwrite)
288
def delone(self, uri):
289
return delone(self, uri)
291
def deltree(self, uri):
292
return deltree(self, uri)
294
def copy(self, src, dst):
295
content = self._get_dav_getcontenttype(src)
296
data = self.get_data(src)
297
self.put(dst, data, content)
300
def copycol(self, src, dst):
301
return self.mkcol(dst)
304
class WebDAVAuthRequestHandler(AuthServer.BufferedAuthRequestHandler,
305
WebDAVServer.DAVRequestHandler):
307
def get_userinfo(self, user, password, command=''):
309
dbname = self.path.split('/', 2)[1]
312
USER_ID = security.login(dbname, user, password, cache=False)
319
class SecureWebDAVAuthRequestHandler(WebDAVAuthRequestHandler):
322
self.connection = SSLSocket(self.request)
323
self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
324
self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)