summaryrefslogtreecommitdiff
path: root/addons/document_webdav/nodes.py
diff options
context:
space:
mode:
Diffstat (limited to 'addons/document_webdav/nodes.py')
-rw-r--r--addons/document_webdav/nodes.py416
1 files changed, 0 insertions, 416 deletions
diff --git a/addons/document_webdav/nodes.py b/addons/document_webdav/nodes.py
deleted file mode 100644
index 9a35f3cfe1b..00000000000
--- a/addons/document_webdav/nodes.py
+++ /dev/null
@@ -1,416 +0,0 @@
-# -*- coding: utf-8 -*-
-##############################################################################
-#
-# OpenERP, Open Source Management Solution
-# Copyright (C) 2010 Tiny SPRL (<http://tiny.be>).
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-##############################################################################
-
-
-import time
-import urllib
-import uuid
-
-from openerp import SUPERUSER_ID
-from openerp.tools.safe_eval import safe_eval as eval
-
-from openerp.addons.document import document as nodes
-
-def dict_filter(srcdic, keys, res=None):
- ''' Return a copy of srcdic that has only keys set.
- If any of keys are missing from srcdic, the result won't have them,
- either.
- @param res If given, result will be updated there, instead of a new dict.
- '''
- if res is None:
- res = {}
- for k in keys:
- if k in srcdic:
- res[k] = srcdic[k]
- return res
-
-class node_acl_mixin(object):
- def _get_dav_owner(self, cr):
- return self.uuser
-
- def _get_dav_group(self, cr):
- return self.ugroup
-
- def _get_dav_supported_privilege_set(self, cr):
- return '' # TODO
-
- def _get_dav_current_user_privilege_set(self, cr):
- return '' # TODO
-
- def _get_dav_props_hlpr(self, cr, par_class, prop_model,
- prop_ref_field, res_id):
- """ Helper for dav properties, usable in subclasses
-
- @param par_class The parent class
- @param prop_model The name of the orm model holding the properties
- @param prop_ref_field The name of the field at prop_model pointing to us
- @param res_id the id of self in the corresponing orm table, that should
- match prop_model.prop_ref_field
- """
- ret = par_class.get_dav_props(self, cr)
- if prop_model:
- propobj = self.context._dirobj.pool[prop_model]
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- # Not really needed because we don't do eval here:
- # ctx.update({'uid': uid, 'dbname': self.context.dbname })
- # dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx)
- sdomain = [(prop_ref_field, '=', False),]
- if res_id:
- sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain
- prop_ids = propobj.search(cr, uid, sdomain, context=ctx)
- if prop_ids:
- ret = ret.copy()
- for pbro in propobj.browse(cr, uid, prop_ids, context=ctx):
- ret[pbro.namespace] = ret.get(pbro.namespace, ()) + \
- (pbro.name,)
- # Note that we cannot have properties to conditionally appear
- # on the context, yet.
-
- return ret
-
- def _get_dav_eprop_hlpr(self, cr, ns, prop,
- par_class, prop_model,
- prop_ref_field, res_id):
- """ Helper for get dav eprop, usable in subclasses
-
- @param namespace the one to search for
- @param name Name to search for
- @param par_class The parent class
- @param prop_model The name of the orm model holding the properties
- @param prop_ref_field The name of the field at prop_model pointing to us
- @param res_id the id of self in the corresponing orm table, that should
- match prop_model.prop_ref_field
- """
- ret = par_class.get_dav_eprop(self, cr, ns, prop)
- if ret is not None:
- return ret
- if prop_model:
- propobj = self.context._dirobj.pool[prop_model]
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- ctx.update({'uid': uid, 'dbname': self.context.dbname })
- ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
- dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx)
- sdomain = [(prop_ref_field, '=', False),('namespace', '=', ns), ('name','=', prop)]
- if res_id:
- sdomain = ['|', (prop_ref_field, '=', res_id)] + sdomain
- prop_ids = propobj.search(cr, uid, sdomain, context=ctx)
- if prop_ids:
- pbro = propobj.browse(cr, uid, prop_ids[0], context=ctx)
- val = pbro.value
- if pbro.do_subst:
- if val.startswith("('") and val.endswith(")"):
- glbls = { 'urlquote': urllib.quote, }
- val = eval(val, glbls, ctx)
- else:
- val = val % ctx
- return val
- return None
-
- def _dav_lock_hlpr(self, cr, lock_data, par_class, prop_model,
- prop_ref_field, res_id):
- """ Helper, which uses the dav properties table for placing locks
-
- @param lock_data a dictionary of input to this function.
- @return list of tuples, DAV:activelock _contents_ structure.
- See webdav.py:class Prop2Xml() for semantics
-
- Note: although the DAV response shall be an <activelock/>, this
- function will only return the elements inside the activelock,
- because the calling function needs to append the <lockroot/> in
- it. See webdav.py:mk_lock_response()
-
- In order to reuse code, this function can be called with
- lock_data['unlock_mode']=True, in order to unlock.
-
- @return bool in unlock mode, (davstruct, prop_id, token) in lock/refresh,
- or (False, prop_id, token) if already locked,
- or (False, False, False) if lock not found to refresh
- """
- assert prop_model
- assert res_id
- assert isinstance(lock_data, dict), '%r' % lock_data
- propobj = self.context._dirobj.pool[prop_model]
- uid = self.context.uid
- ctx = self.context.context.copy()
- ctx.update(self.dctx)
- ctx.update({'uid': uid, 'dbname': self.context.dbname })
- ctx['node_classname'] = "%s.%s" % (self.__class__.__module__, self.__class__.__name__)
- dict_filter(self.context.extra_ctx, ['username', 'groupname', 'webdav_path'], ctx)
- sdomain = [(prop_ref_field, '=', res_id), ('namespace', '=', 'DAV:'),
- ('name','=', 'lockdiscovery')]
- props_to_delete = []
- lock_found = False
- lock_val = None
- tmout2 = int(lock_data.get('timeout', 3*3600))
-
- prop_ids = propobj.search(cr, uid, sdomain, context=ctx)
- if prop_ids:
- for pbro in propobj.browse(cr, uid, prop_ids, context=ctx):
- val = pbro.value
- if pbro.do_subst:
- if val.startswith("('") and val.endswith(")"):
- glbls = { 'urlquote': urllib.quote, }
- val = eval(val, glbls, ctx)
- else:
- # all locks should be at "subst" format
- continue
- if not (val and isinstance(val, tuple)
- and val[0:2] == ( 'activelock','DAV:')):
- # print "Value is not activelock:", val
- continue
-
- old_token = False
- old_owner = False
- try:
- # discover the timeout. If anything goes wrong, delete
- # the lock (cleanup)
- tmout = False
- for parm in val[2]:
- if parm[1] != 'DAV:':
- continue
- if parm[0] == 'timeout':
- if isinstance(parm[2], basestring) \
- and parm[2].startswith('Second-'):
- tmout = int(parm[2][7:])
- elif parm[0] == 'locktoken':
- if isinstance(parm[2], basestring):
- old_token = parm[2]
- elif isinstance(parm[2], tuple) and \
- parm[2][0:2] == ('href','DAV:'):
- old_token = parm[2][2]
- else:
- # print "Mangled token in DAV property: %r" % parm[2]
- props_to_delete.append(pbro.id)
- continue
- elif parm[0] == 'owner':
- old_owner = parm[2] # not used yet
- if tmout:
- mdate = pbro.write_date or pbro.create_date
- mdate = time.mktime(time.strptime(mdate,'%Y-%m-%d %H:%M:%S'))
- if mdate + tmout < time.time():
- props_to_delete.append(pbro.id)
- continue
- else:
- props_to_delete.append(pbro.id)
- continue
- except ValueError:
- props_to_delete.append(pbro.id)
- continue
-
- # A valid lock is found here
- if lock_data.get('refresh', False):
- if old_token != lock_data.get('token'):
- continue
- # refresh mode. Just touch anything and the ORM will update
- # the write uid+date, won't it?
- # Note: we don't update the owner, because incoming refresh
- # wouldn't have a body, anyway.
- propobj.write(cr, uid, [pbro.id,], { 'name': 'lockdiscovery'})
- elif lock_data.get('unlock_mode', False):
- if old_token != lock_data.get('token'):
- continue
- props_to_delete.append(pbro.id)
-
- lock_found = pbro.id
- lock_val = val
-
- if tmout2 > 3*3600: # 3 hours maximum
- tmout2 = 3*3600
- elif tmout2 < 300:
- # 5 minutes minimum, but an unlock request can always
- # break it at any time. Ensures no negative values, either.
- tmout2 = 300
-
- if props_to_delete:
- # explicitly delete, as admin, any of the ids we have identified.
- propobj.unlink(cr, SUPERUSER_ID, props_to_delete)
-
- if lock_data.get('unlock_mode', False):
- return lock_found and True
- elif (not lock_found) and not (lock_data.get('refresh', False)):
- # Create a new lock, attach and return it.
- new_token = uuid.uuid4().urn
- lock_val = ('activelock', 'DAV:',
- [ ('locktype', 'DAV:', (lock_data.get('locktype',False) or 'write','DAV:')),
- ('lockscope', 'DAV:', (lock_data.get('lockscope',False) or 'exclusive','DAV:')),
- # ? ('depth', 'DAV:', lock_data.get('depth','0') ),
- ('timeout','DAV:', 'Second-%d' % tmout2),
- ('locktoken', 'DAV:', ('href', 'DAV:', new_token)),
- # ('lockroot', 'DAV: ..., we don't store that, appended by caller
- ])
- new_owner = lock_data.get('lockowner',False) or ctx.get('username', False)
- if new_owner:
- lock_val[2].append( ('owner', 'DAV:', new_owner) )
- prop_id = propobj.create(cr, uid, { prop_ref_field: res_id,
- 'namespace': 'DAV:', 'name': 'lockdiscovery',
- 'do_subst': True, 'value': repr(lock_val) })
- return (lock_val[2], prop_id, new_token )
- elif not lock_found: # and refresh
- return (False, False, False)
- elif lock_found and not lock_data.get('refresh', False):
- # already locked
- return (False, lock_found, old_token)
- else:
- return (lock_val[2], lock_found, old_token )
-
-class node_dir(node_acl_mixin, nodes.node_dir):
- """ override node_dir and add DAV functionality
- """
- DAV_PROPS = { "DAV:": ('owner', 'group',
- 'supported-privilege-set',
- 'current-user-privilege-set'),
- }
- DAV_M_NS = { "DAV:" : '_get_dav',}
- http_options = { 'DAV': ['access-control',] }
-
- def get_dav_resourcetype(self, cr):
- return ('collection', 'DAV:')
-
- def get_dav_props(self, cr):
- return self._get_dav_props_hlpr(cr, nodes.node_dir,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
- def get_dav_eprop(self, cr, ns, prop):
- return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_dir,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
-
-class node_file(node_acl_mixin, nodes.node_file):
- DAV_PROPS = { "DAV:": ('owner', 'group',
- 'supported-privilege-set',
- 'current-user-privilege-set',
- ),
- }
- DAV_M_NS = { "DAV:" : '_get_dav',}
- http_options = { 'DAV': ['access-control', ] }
- pass
-
- def get_dav_resourcetype(self, cr):
- return ''
-
- def get_dav_props(self, cr):
- return self._get_dav_props_hlpr(cr, nodes.node_file,
- 'document.webdav.file.property', 'file_id', self.file_id)
-
- def dav_lock(self, cr, lock_data):
- """ Locks or unlocks the node, using DAV semantics.
-
- Unlocking will be done when lock_data['unlock_mode'] == True
-
- See _dav_lock_hlpr() for calling details.
-
- It is fundamentally OK to use this function from non-DAV endpoints,
- but they will all have to emulate the tuple-in-list structure of
- the DAV lock data. RFC if this translation should be done inside
- the _dav_lock_hlpr (to ease other protocols).
- """
- return self._dav_lock_hlpr(cr, lock_data, nodes.node_file,
- 'document.webdav.file.property', 'file_id', self.file_id)
-
- def dav_unlock(self, cr, token):
- """Releases the token lock held for the node
-
- This is a utility complement of dav_lock()
- """
- lock_data = { 'token': token, 'unlock_mode': True }
- return self._dav_lock_hlpr(cr, lock_data, nodes.node_file,
- 'document.webdav.file.property', 'file_id', self.file_id)
-
- def get_dav_eprop(self, cr, ns, prop):
- if ns == 'DAV:' and prop == 'supportedlock':
- return [ ('lockentry', 'DAV:',
- [ ('lockscope','DAV:', ('shared', 'DAV:')),
- ('locktype','DAV:', ('write', 'DAV:')),
- ]),
- ('lockentry', 'DAV:',
- [ ('lockscope','DAV:', ('exclusive', 'DAV:')),
- ('locktype','DAV:', ('write', 'DAV:')),
- ] )
- ]
- return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_file,
- 'document.webdav.file.property', 'file_id', self.file_id)
-
-class node_database(nodes.node_database):
- def get_dav_resourcetype(self, cr):
- return ('collection', 'DAV:')
-
- def get_dav_props(self, cr):
- return self._get_dav_props_hlpr(cr, nodes.node_database,
- 'document.webdav.dir.property', 'dir_id', False)
-
- def get_dav_eprop(self, cr, ns, prop):
- return self._get_dav_eprop_hlpr(cr, nodes.node_database, ns, prop,
- 'document.webdav.dir.property', 'dir_id', False)
-
-class node_res_obj(node_acl_mixin, nodes.node_res_obj):
- DAV_PROPS = { "DAV:": ('owner', 'group',
- 'supported-privilege-set',
- 'current-user-privilege-set'),
- }
- DAV_M_NS = { "DAV:" : '_get_dav',}
- http_options = { 'DAV': ['access-control',] }
-
- def get_dav_resourcetype(self, cr):
- return ('collection', 'DAV:')
-
- def get_dav_props(self, cr):
- return self._get_dav_props_hlpr(cr, nodes.node_res_obj,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
- def get_dav_eprop(self, cr, ns, prop):
- return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_res_obj,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
-
-class node_res_dir(node_acl_mixin, nodes.node_res_dir):
- DAV_PROPS = { "DAV:": ('owner', 'group',
- 'supported-privilege-set',
- 'current-user-privilege-set'),
- }
- DAV_M_NS = { "DAV:" : '_get_dav',}
- http_options = { 'DAV': ['access-control',] }
- res_obj_class = node_res_obj
-
- def get_dav_resourcetype(self, cr):
- return ('collection', 'DAV:')
-
- def get_dav_props(self, cr):
- return self._get_dav_props_hlpr(cr, nodes.node_res_dir,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
- def get_dav_eprop(self, cr, ns, prop):
- return self._get_dav_eprop_hlpr(cr, ns, prop, nodes.node_res_dir,
- 'document.webdav.dir.property', 'dir_id', self.dir_id)
-
-# Some copies, so that this module can replace 'from document import nodes'
-get_node_context = nodes.get_node_context
-node_context = nodes.node_context
-node_class = nodes.node_class
-node_descriptor = nodes.node_descriptor
-
-
-#eof
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: