mirror of
https://github.com/Kozea/Radicale.git
synced 2025-08-28 19:40:54 +00:00
Resolved conflicts
This commit is contained in:
parent
cf81d1f9a7
commit
dd723dae5d
3 changed files with 99 additions and 100 deletions
|
@ -1,4 +1,4 @@
|
|||
# This file is part of Radicale Server - Calendar Server
|
||||
# This file is part of Radicale - CalDAV and CardDAV server
|
||||
# Copyright © 2008 Nicolas Kandel
|
||||
# Copyright © 2008 Pascal Halter
|
||||
# Copyright © 2008-2017 Guillaume Ayoub
|
||||
|
@ -18,92 +18,71 @@
|
|||
# along with Radicale. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import socket
|
||||
import xml.etree.ElementTree as ET
|
||||
from http import client
|
||||
from xml.etree import ElementTree as ET
|
||||
from typing import Dict, Optional, cast
|
||||
|
||||
import defusedxml.ElementTree as DefusedET
|
||||
|
||||
from radicale import app, httputils
|
||||
from radicale import item as radicale_item
|
||||
from radicale import storage, xmlutils
|
||||
import radicale.item as radicale_item
|
||||
from radicale import httputils, storage, types, xmlutils
|
||||
from radicale.app.base import Access, ApplicationBase
|
||||
from radicale.hook import HookNotificationItem, HookNotificationItemTypes
|
||||
from radicale.log import logger
|
||||
|
||||
|
||||
def xml_add_propstat_to(element, tag, status_number):
|
||||
"""Add a PROPSTAT response structure to an element.
|
||||
|
||||
The PROPSTAT answer structure is defined in rfc4918-9.1. It is added to the
|
||||
given ``element``, for the following ``tag`` with the given
|
||||
``status_number``.
|
||||
|
||||
"""
|
||||
propstat = ET.Element(xmlutils.make_clark("D:propstat"))
|
||||
element.append(propstat)
|
||||
|
||||
prop = ET.Element(xmlutils.make_clark("D:prop"))
|
||||
propstat.append(prop)
|
||||
|
||||
clark_tag = xmlutils.make_clark(tag)
|
||||
prop_tag = ET.Element(clark_tag)
|
||||
prop.append(prop_tag)
|
||||
|
||||
status = ET.Element(xmlutils.make_clark("D:status"))
|
||||
status.text = xmlutils.make_response(status_number)
|
||||
propstat.append(status)
|
||||
|
||||
|
||||
def xml_proppatch(base_prefix, path, xml_request, collection):
|
||||
def xml_proppatch(base_prefix: str, path: str,
|
||||
xml_request: Optional[ET.Element],
|
||||
collection: storage.BaseCollection) -> ET.Element:
|
||||
"""Read and answer PROPPATCH requests.
|
||||
|
||||
Read rfc4918-9.2 for info.
|
||||
|
||||
"""
|
||||
props_to_set = xmlutils.props_from_request(xml_request, actions=("set",))
|
||||
props_to_remove = xmlutils.props_from_request(xml_request,
|
||||
actions=("remove",))
|
||||
|
||||
multistatus = ET.Element(xmlutils.make_clark("D:multistatus"))
|
||||
response = ET.Element(xmlutils.make_clark("D:response"))
|
||||
multistatus.append(response)
|
||||
|
||||
href = ET.Element(xmlutils.make_clark("D:href"))
|
||||
href.text = xmlutils.make_href(base_prefix, path)
|
||||
response.append(href)
|
||||
# Create D:propstat element for props with status 200 OK
|
||||
propstat = ET.Element(xmlutils.make_clark("D:propstat"))
|
||||
status = ET.Element(xmlutils.make_clark("D:status"))
|
||||
status.text = xmlutils.make_response(200)
|
||||
props_ok = ET.Element(xmlutils.make_clark("D:prop"))
|
||||
propstat.append(props_ok)
|
||||
propstat.append(status)
|
||||
response.append(propstat)
|
||||
|
||||
new_props = collection.get_meta()
|
||||
for short_name, value in props_to_set.items():
|
||||
new_props[short_name] = value
|
||||
xml_add_propstat_to(response, short_name, 200)
|
||||
for short_name in props_to_remove:
|
||||
try:
|
||||
del new_props[short_name]
|
||||
except KeyError:
|
||||
pass
|
||||
xml_add_propstat_to(response, short_name, 200)
|
||||
radicale_item.check_and_sanitize_props(new_props)
|
||||
collection.set_meta(new_props)
|
||||
props_with_remove = xmlutils.props_from_request(xml_request)
|
||||
all_props_with_remove = cast(Dict[str, Optional[str]],
|
||||
dict(collection.get_meta()))
|
||||
all_props_with_remove.update(props_with_remove)
|
||||
all_props = radicale_item.check_and_sanitize_props(all_props_with_remove)
|
||||
collection.set_meta(all_props)
|
||||
for short_name in props_with_remove:
|
||||
props_ok.append(ET.Element(xmlutils.make_clark(short_name)))
|
||||
|
||||
return multistatus
|
||||
|
||||
|
||||
class ApplicationProppatchMixin:
|
||||
def do_PROPPATCH(self, environ, base_prefix, path, user):
|
||||
class ApplicationPartProppatch(ApplicationBase):
|
||||
|
||||
def do_PROPPATCH(self, environ: types.WSGIEnviron, base_prefix: str,
|
||||
path: str, user: str) -> types.WSGIResponse:
|
||||
"""Manage PROPPATCH request."""
|
||||
access = app.Access(self._rights, user, path)
|
||||
access = Access(self._rights, user, path)
|
||||
if not access.check("w"):
|
||||
return httputils.NOT_ALLOWED
|
||||
try:
|
||||
xml_content = self._read_xml_content(environ)
|
||||
xml_content = self._read_xml_request_body(environ)
|
||||
except RuntimeError as e:
|
||||
logger.warning(
|
||||
"Bad PROPPATCH request on %r: %s", path, e, exc_info=True)
|
||||
return httputils.BAD_REQUEST
|
||||
except socket.timeout:
|
||||
logger.debug("client timed out", exc_info=True)
|
||||
logger.debug("Client timed out", exc_info=True)
|
||||
return httputils.REQUEST_TIMEOUT
|
||||
with self._storage.acquire_lock("w", user):
|
||||
item = next(self._storage.discover(path), None)
|
||||
item = next(iter(self._storage.discover(path)), None)
|
||||
if not item:
|
||||
return httputils.NOT_FOUND
|
||||
if not access.check("w", item):
|
||||
|
@ -129,5 +108,4 @@ class ApplicationProppatchMixin:
|
|||
logger.warning(
|
||||
"Bad PROPPATCH request on %r: %s", path, e, exc_info=True)
|
||||
return httputils.BAD_REQUEST
|
||||
return (client.MULTI_STATUS, headers,
|
||||
self._write_xml_content(xml_answer))
|
||||
return client.MULTI_STATUS, headers, self._xml_response(xml_answer)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue