OwlCyberSecurity - MANAGER
Edit File: serverinfo.py
## # Copyright (c) 2015-2017 Apple Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## from twisted.internet.defer import inlineCallbacks, succeed, returnValue from twistedcaldav import caldavxml, carddavxml, mkcolxml from twistedcaldav import customxml from twistedcaldav.caldavxml import caldav_namespace from twistedcaldav.carddavxml import carddav_namespace from twistedcaldav.customxml import calendarserver_namespace from txdav.xml import element as davxml from txdav.xml.element import dav_namespace, WebDAVUnknownElement from txweb2.dav.noneprops import NonePropertyStore from txweb2.http_headers import MimeType, ETag from twistedcaldav.resource import ReadOnlyNoCopyResourceMixIn from twistedcaldav.extensions import DAVResource, \ DAVResourceWithoutChildrenMixin from txweb2.http import XMLResponse from twistedcaldav.config import config from txweb2 import responsecode import hashlib from twistedcaldav.serverinfoxml import Class1_Feature, AccessControl_Feature, \ Quota_Feature, SyncCollection_Feature, AddMember_Feature, Name_Service, \ Features, ServerInfo, Token, Applications, Application """ draft-douglass-server-info: "DAV Server Information Object" """ def buildServerInfo(config): """ Build the DAV compliance header, server-info document, and server-info-token value based on the supplied L{config}. @param config: config to use @type config: L{twistedcaldav.config} @return: tuple of three items: compliance value, server-info XML document root element, server-info-token value @rtype: L{tuple} """ global_features = [ Class1_Feature(), AccessControl_Feature(), Quota_Feature(), SyncCollection_Feature(), AddMember_Feature(), ] compliance = () applications = [] if config.EnableCalDAV: if config.Scheduling.CalDAV.OldDraftCompatibility: compliance = caldavxml.caldav_full_compliance else: compliance = caldavxml.caldav_implicit_compliance features = [ WebDAVUnknownElement.withName(caldav_namespace, "calendar-access"), WebDAVUnknownElement.withName(caldav_namespace, "calendar-auto-schedule"), WebDAVUnknownElement.withName(calendarserver_namespace, "calendar-availability"), WebDAVUnknownElement.withName(calendarserver_namespace, "inbox-availability"), ] if config.EnableProxyPrincipals: compliance += customxml.calendarserver_proxy_compliance features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_proxy_compliance[0])) if config.EnablePrivateEvents: compliance += customxml.calendarserver_private_events_compliance features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_private_events_compliance[0])) if config.Scheduling.CalDAV.EnablePrivateComments: compliance += customxml.calendarserver_private_comments_compliance features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_private_comments_compliance[0])) if config.Sharing.Enabled: compliance += customxml.calendarserver_sharing_compliance # TODO: This is only needed whilst we do not support scheduling in shared calendars compliance += customxml.calendarserver_sharing_no_scheduling_compliance if config.Sharing.Calendars.Enabled and config.Sharing.Calendars.Groups.Enabled: compliance += customxml.calendarserver_group_sharee_compliance sharing = WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_sharing_compliance[0]) # TODO: This is only needed whilst we do not support scheduling in shared calendars sharing.children += (WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_sharing_no_scheduling_compliance[0]),) if config.Sharing.Calendars.Enabled and config.Sharing.Calendars.Groups.Enabled: sharing.children += (WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_group_sharee_compliance[0]),) features.append(sharing) if config.EnableCalendarQueryExtended: compliance += caldavxml.caldav_query_extended_compliance features.append(WebDAVUnknownElement.withName(caldav_namespace, caldavxml.caldav_query_extended_compliance[0])) if config.EnableDefaultAlarms: compliance += caldavxml.caldav_default_alarms_compliance features.append(WebDAVUnknownElement.withName(caldav_namespace, caldavxml.caldav_default_alarms_compliance[0])) if config.EnableManagedAttachments: compliance += caldavxml.caldav_managed_attachments_compliance features.append(WebDAVUnknownElement.withName(caldav_namespace, caldavxml.caldav_managed_attachments_compliance[0])) if config.Scheduling.Options.TimestampAttendeePartStatChanges: compliance += customxml.calendarserver_partstat_changes_compliance features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_partstat_changes_compliance[0])) if config.GroupAttendees.Enabled: compliance += customxml.calendarserver_group_attendee_compliance features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_group_attendee_compliance[0])) if config.EnableTimezonesByReference: compliance += caldavxml.caldav_timezones_by_reference_compliance features.append(WebDAVUnknownElement.withName(caldav_namespace, caldavxml.caldav_timezones_by_reference_compliance[0])) compliance += customxml.calendarserver_recurrence_split features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_recurrence_split[0])) applications.append( Application( Name_Service.fromString("caldav"), Features(*features), ) ) if config.EnableCardDAV: compliance += carddavxml.carddav_compliance features = [ WebDAVUnknownElement.withName(carddav_namespace, "addressbook"), ] applications.append( Application( Name_Service.fromString("carddav"), Features(*features), ) ) if config.EnableCardDAV: compliance += carddavxml.carddav_compliance if config.EnableCalDAV or config.EnableCardDAV: compliance += mkcolxml.mkcol_compliance global_features.append(WebDAVUnknownElement.withName(dav_namespace, mkcolxml.mkcol_compliance[0])) # Principal property search is always enabled compliance += customxml.calendarserver_principal_property_search_compliance global_features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_principal_property_search_compliance[0])) compliance += customxml.calendarserver_principal_search_compliance global_features.append(WebDAVUnknownElement.withName(calendarserver_namespace, customxml.calendarserver_principal_search_compliance[0])) # Home Depth:1 sync report will include WebDAV property changes on home child resources compliance += customxml.calendarserver_home_sync_compliance def _createServerInfo(token): return ServerInfo( Token.fromString(token), Features(*global_features), Applications(*applications) ) token = hashlib.md5(_createServerInfo("").toxml()).hexdigest() return compliance, _createServerInfo(token), token class ServerInfoResource (ReadOnlyNoCopyResourceMixIn, DAVResourceWithoutChildrenMixin, DAVResource): """ Server-info resource. Extends L{DAVResource} to allow server-info document retrieval. """ def __init__(self, parent): """ @param parent: the parent resource of this one. """ assert parent is not None DAVResource.__init__(self, principalCollections=parent.principalCollections()) self.parent = parent def deadProperties(self): if not hasattr(self, "_dead_properties"): self._dead_properties = NonePropertyStore(self) return self._dead_properties def etag(self): return succeed(ETag(config.ServerInfoToken)) def checkPreconditions(self, request): return None def checkPrivileges(self, request, privileges, recurse=False, principal=None, inherited_aces=None): return succeed(None) def defaultAccessControlList(self): return succeed( davxml.ACL( # DAV:Read for all principals (includes anonymous) davxml.ACE( davxml.Principal(davxml.All()), davxml.Grant( davxml.Privilege(davxml.Read()), ), davxml.Protected(), ), ) ) def contentType(self): return MimeType.fromString("text/xml; charset=utf-8") def resourceType(self): return None def isCollection(self): return False def isCalendarCollection(self): return False def isPseudoCalendarCollection(self): return False @inlineCallbacks def http_GET(self, request): """ The server-info GET method. """ yield self.authorize(request, (davxml.Read(),)) returnValue(XMLResponse(responsecode.OK, config.ServerInfo))