[CalendarServer-changes] [5136] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Feb 16 14:30:15 PST 2010


Revision: 5136
          http://trac.macosforge.org/projects/calendarserver/changeset/5136
Author:   sagen at apple.com
Date:     2010-02-16 14:30:15 -0800 (Tue, 16 Feb 2010)
Log Message:
-----------
Centralized setup of directory and resource hierarchy for server processes.

Modified Paths:
--------------
    CalendarServer/trunk/calendarserver/sidecar/task.py
    CalendarServer/trunk/calendarserver/tap/caldav.py
    CalendarServer/trunk/twistedcaldav/mail.py

Added Paths:
-----------
    CalendarServer/trunk/calendarserver/util.py

Modified: CalendarServer/trunk/calendarserver/sidecar/task.py
===================================================================
--- CalendarServer/trunk/calendarserver/sidecar/task.py	2010-02-16 22:29:19 UTC (rev 5135)
+++ CalendarServer/trunk/calendarserver/sidecar/task.py	2010-02-16 22:30:15 UTC (rev 5136)
@@ -22,7 +22,6 @@
     "Task",
 ]
 
-from time import sleep
 import os
 
 from zope.interface import implements
@@ -31,24 +30,19 @@
 from twisted.internet.defer import DeferredList, inlineCallbacks, returnValue
 from twisted.internet.reactor import callLater
 from twisted.plugin import IPlugin
-from twisted.python.reflect import namedClass
 from twisted.python.usage import Options, UsageError
 from twisted.web2.http_headers import Headers
 
 from twext.log import Logger, LoggingMixIn
 from twext.log import logLevelForNamespace, setLogLevelForNamespace
 
-from twistedcaldav import memcachepool
 from twistedcaldav.config import config
 from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
-from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.ical import Component
-from twistedcaldav.notify import installNotificationClient
 from twistedcaldav.scheduling.cuaddress import LocalCalendarUser
 from twistedcaldav.scheduling.scheduler import DirectScheduler
-from twistedcaldav.static import CalendarHomeProvisioningFile
 
-from calendarserver.provision.root import RootResource
+from calendarserver.util import getRootResource
 
 log = Logger()
 
@@ -201,9 +195,9 @@
 
 class CalDAVTaskService(Service):
 
-    def __init__(self, root, directory):
+    def __init__(self, root):
         self.root = root
-        self.directory = directory
+        self.directory = root.directory
         self.seconds = 30 # How often to check for new tasks in incomingDir
         self.taskDir = os.path.join(config.DataRoot, "tasks")
         # New task files are placed into "incoming"
@@ -345,13 +339,6 @@
     description = "Calendar Server Task Process"
     options = CalDAVTaskOptions
 
-    #
-    # Default resource classes
-    #
-    rootResourceClass            = RootResource
-    principalResourceClass       = DirectoryPrincipalProvisioningResource
-    calendarResourceClass        = CalendarHomeProvisioningFile
-
     def makeService(self, options):
 
         #
@@ -366,71 +353,10 @@
         oldLogLevel = logLevelForNamespace(None)
         setLogLevelForNamespace(None, "info")
 
-        #
-        # Setup the Directory
-        #
-        directoryClass = namedClass(config.DirectoryService.type)
+        rootResource = getRootResource(config)
 
-        self.log_info("Configuring directory service of type: %s"
-                      % (config.DirectoryService.type,))
+        service = CalDAVTaskService(rootResource)
 
-        directory = directoryClass(config.DirectoryService.params)
-
-        # Wait for the directory to become available
-        while not directory.isAvailable():
-            sleep(5)
-
-        #
-        # Configure Memcached Client Pool
-        #
-        memcachepool.installPools(
-            config.Memcached.Pools,
-            config.Memcached.MaxClients,
-        )
-
-        #
-        # Configure NotificationClient
-        #
-        if config.Notifications.Enabled:
-            installNotificationClient(
-                config.Notifications.InternalNotificationHost,
-                config.Notifications.InternalNotificationPort,
-            )
-
-        #
-        # Setup Resource hierarchy
-        #
-        self.log_info("Setting up document root at: %s"
-                      % (config.DocumentRoot,))
-        self.log_info("Setting up principal collection: %r"
-                      % (self.principalResourceClass,))
-
-        principalCollection = self.principalResourceClass(
-            "/principals/",
-            directory,
-        )
-
-        self.log_info("Setting up calendar collection: %r"
-                      % (self.calendarResourceClass,))
-
-        calendarCollection = self.calendarResourceClass(
-            os.path.join(config.DocumentRoot, "calendars"),
-            directory, "/calendars/",
-        )
-
-        self.log_info("Setting up root resource: %r"
-                      % (self.rootResourceClass,))
-
-        root = self.rootResourceClass(
-            config.DocumentRoot,
-            principalCollections=(principalCollection,),
-        )
-
-        root.putChild("principals", principalCollection)
-        root.putChild("calendars", calendarCollection)
-
-        service = CalDAVTaskService(root, directory)
-
         # Change log level back to what it was before
         setLogLevelForNamespace(None, oldLogLevel)
 

Modified: CalendarServer/trunk/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/trunk/calendarserver/tap/caldav.py	2010-02-16 22:29:19 UTC (rev 5135)
+++ CalendarServer/trunk/calendarserver/tap/caldav.py	2010-02-16 22:30:15 UTC (rev 5136)
@@ -25,7 +25,7 @@
 import socket
 import stat
 import sys
-from time import sleep, time
+from time import time
 
 from subprocess import Popen, PIPE
 from pwd import getpwnam, getpwuid
@@ -37,9 +37,7 @@
 
 from twisted.python.log import FileLogObserver
 from twisted.python.usage import Options, UsageError
-from twisted.python.reflect import namedClass
 from twisted.plugin import IPlugin
-from twisted.internet import reactor
 from twisted.internet.reactor import callLater, spawnProcess
 from twisted.internet.process import ProcessExitedAlready
 from twisted.internet.protocol import Protocol, Factory
@@ -47,11 +45,7 @@
 from twisted.application.service import Service, MultiService, IServiceMaker
 from twisted.scripts.mktap import getid
 from twisted.runner import procmon
-from twisted.cred.portal import Portal
-from twisted.web2.dav import auth
-from twisted.web2.auth.basic import BasicCredentialFactory
 from twisted.web2.server import Site
-from twisted.web2.static import File as FileResource
 
 from twext.log import Logger, LoggingMixIn
 from twext.log import logLevelForNamespace, setLogLevelForNamespace
@@ -66,30 +60,18 @@
     from version import version as getVersion
     version = "%s (%s)" % getVersion()
 
-from twistedcaldav import memcachepool
 from twistedcaldav.accesslog import AMPCommonAccessLoggingObserver
 from twistedcaldav.accesslog import AMPLoggingFactory
-from twistedcaldav.accesslog import DirectoryLogWrapperResource
 from twistedcaldav.accesslog import RotatingFileAccessLoggingObserver
 from twistedcaldav.config import ConfigurationError
 from twistedcaldav.config import config
-from twistedcaldav.directory import augment, calendaruserproxy
-from twistedcaldav.directory.aggregate import AggregateDirectoryService
-from twistedcaldav.directory.calendaruserproxyloader import XMLCalendarUserProxyLoader
-from twistedcaldav.directory.digest import QopDigestCredentialFactory
 from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
-from twistedcaldav.directory.sudo import SudoDirectoryService
-from twistedcaldav.directory.util import NotFilePath
-from twistedcaldav.directory.wiki import WikiDirectoryService
 from twistedcaldav.localization import processLocalizationFiles
 from twistedcaldav.mail import IMIPReplyInboxResource
-from twistedcaldav.notify import installNotificationClient
-from twistedcaldav.resource import CalDAVResource, AuthenticationWrapper
 from twistedcaldav.static import CalendarHomeProvisioningFile
 from twistedcaldav.static import IScheduleInboxFile
 from twistedcaldav.static import TimezoneServiceFile
 from twistedcaldav.stdconfig import DEFAULT_CONFIG, DEFAULT_CONFIG_FILE
-from twistedcaldav.timezones import TimezoneCache
 from twistedcaldav.upgrade import upgradeData
 from twistedcaldav.util import getNCPU
 
@@ -102,6 +84,7 @@
 from calendarserver.provision.root import RootResource
 from calendarserver.webadmin.resource import WebAdminResource
 from calendarserver.webcal.resource import WebCalendarResource
+from calendarserver.util import getRootResource
 
 log = Logger()
 
@@ -507,321 +490,17 @@
         oldLogLevel = logLevelForNamespace(None)
         setLogLevelForNamespace(None, "info")
 
-        #
-        # Setup the Directory
-        #
-        directories = []
-
-        directoryClass = namedClass(config.DirectoryService.type)
-
-        self.log_info("Configuring directory service of type: %s"
-                      % (config.DirectoryService.type,))
-
-        baseDirectory = directoryClass(config.DirectoryService.params)
-
-        # Wait for the directory to become available
-        while not baseDirectory.isAvailable():
-            sleep(5)
-
-        directories.append(baseDirectory)
-
-        #
-        # Setup the Locations and Resources Service
-        #
-        if config.ResourceService.Enabled:
-            resourceClass = namedClass(config.ResourceService.type)
-
-            self.log_info("Configuring resource service of type: %s" % (resourceClass,))
-
-            resourceDirectory = resourceClass(config.ResourceService.params)
-            directories.append(resourceDirectory)
-
-        #
-        # Add sudoers directory
-        #
-        sudoDirectory = None
-
-        if config.SudoersFile and os.path.exists(config.SudoersFile):
-            self.log_info("Configuring SudoDirectoryService with file: %s"
-                          % (config.SudoersFile,))
-
-            sudoDirectory = SudoDirectoryService(config.SudoersFile)
-            sudoDirectory.realmName = baseDirectory.realmName
-
-            CalDAVResource.sudoDirectory = sudoDirectory
-            directories.insert(0, sudoDirectory)
-        else:
-            self.log_info(
-                "Not using SudoDirectoryService; file doesn't exist: %s"
-                % (config.SudoersFile,)
-            )
-
-        #
-        # Add wiki directory service
-        #
-        if config.Authentication.Wiki.Enabled:
-            wikiDirectory = WikiDirectoryService()
-            wikiDirectory.realmName = baseDirectory.realmName
-            directories.append(wikiDirectory)
-
-        directory = AggregateDirectoryService(directories)
-        self.directory = directory
-
-        if sudoDirectory:
-            directory.userRecordTypes.insert(0,
-                SudoDirectoryService.recordType_sudoers)
-
-        #
-        # Setup the Augment Service
-        #
-        augmentClass = namedClass(config.AugmentService.type)
-
-        self.log_info("Configuring augment service of type: %s" % (augmentClass,))
-
-        try:
-            augment.AugmentService = augmentClass(**config.AugmentService.params)
-        except IOError, e:
-            self.log_error("Could not start augment service")
-            raise
-
-        #
-        # Setup the PoxyDB Service
-        #
-        proxydbClass = namedClass(config.ProxyDBService.type)
-
-        self.log_info("Configuring proxydb service of type: %s" % (proxydbClass,))
-
-        try:
-            calendaruserproxy.ProxyDBService = proxydbClass(**config.ProxyDBService.params)
-        except IOError, e:
-            self.log_error("Could not start proxydb service")
-            raise
-
-        #
-        # Make sure proxies get initialized
-        #
-        if config.ProxyLoadFromFile:
-            def _doProxyUpdate():
-                loader = XMLCalendarUserProxyLoader(config.ProxyLoadFromFile)
-                return loader.updateProxyDB()
-            
-            reactor.addSystemEventTrigger("after", "startup", _doProxyUpdate)
-
-        #
-        # Configure Memcached Client Pool
-        #
-        memcachepool.installPools(
-            config.Memcached.Pools,
-            config.Memcached.MaxClients,
-        )
-
-        #
-        # Configure NotificationClient
-        #
-        if config.Notifications.Enabled:
-            installNotificationClient(
-                config.Notifications.InternalNotificationHost,
-                config.Notifications.InternalNotificationPort,
-            )
-
-        #
-        # Configure the Site and Wrappers
-        #
-        credentialFactories = []
-
-        portal = Portal(auth.DavRealm())
-
-        portal.registerChecker(directory)
-
-        realm = directory.realmName or ""
-
-        self.log_info("Configuring authentication for realm: %s" % (realm,))
-
-        for scheme, schemeConfig in config.Authentication.iteritems():
-            scheme = scheme.lower()
-
-            credFactory = None
-
-            if schemeConfig["Enabled"]:
-                self.log_info("Setting up scheme: %s" % (scheme,))
-
-                if scheme == "kerberos":
-                    if not NegotiateCredentialFactory:
-                        self.log_info("Kerberos support not available")
-                        continue
-
-                    try:
-                        principal = schemeConfig["ServicePrincipal"]
-                        if not principal:
-                            credFactory = NegotiateCredentialFactory(
-                                type="HTTP",
-                                hostname=config.ServerHostName,
-                            )
-                        else:
-                            credFactory = NegotiateCredentialFactory(
-                                principal=principal,
-                            )
-                    except ValueError:
-                        self.log_info("Could not start Kerberos")
-                        continue
-
-                elif scheme == "digest":
-                    credFactory = QopDigestCredentialFactory(
-                        schemeConfig["Algorithm"],
-                        schemeConfig["Qop"],
-                        realm,
-                    )
-
-                elif scheme == "basic":
-                    credFactory = BasicCredentialFactory(realm)
-
-                elif scheme == "wiki":
-                    pass
-
-                else:
-                    self.log_error("Unknown scheme: %s" % (scheme,))
-
-            if credFactory:
-                credentialFactories.append(credFactory)
-
-
-        # Set up a basic credential factory for use on the /inbox iMIP
-        # injection resource
-        inboxCredentialFactory = BasicCredentialFactory(realm)
-
-        #
-        # Setup Resource hierarchy
-        #
-        self.log_info("Setting up document root at: %s"
-                      % (config.DocumentRoot,))
-        self.log_info("Setting up principal collection: %r"
-                      % (self.principalResourceClass,))
-
-        principalCollection = self.principalResourceClass(
-            "/principals/",
-            directory,
-        )
-        self.principalCollection = principalCollection
-
-        self.log_info("Setting up calendar collection: %r"
-                      % (self.calendarResourceClass,))
-
-        calendarCollection = self.calendarResourceClass(
-            os.path.join(config.DocumentRoot, "calendars"),
-            directory, "/calendars/",
-        )
-
-        self.log_info("Setting up root resource: %r"
-                      % (self.rootResourceClass,))
-
-        root = self.rootResourceClass(
-            config.DocumentRoot,
-            principalCollections=(principalCollection,),
-        )
-        self.root = root
-
-        root.putChild("principals", principalCollection)
-        root.putChild("calendars", calendarCollection)
-
-        for name, info in config.Aliases.iteritems():
-            if os.path.sep in name or not info.get("path", None):
-                self.log_error("Invalid alias: %s" % (name,))
-                continue
-            self.log_info("Adding alias %s -> %s" % (name, info["path"]))
-            resource = FileResource(info["path"])
-            root.putChild(name, resource)
-
-        # Timezone service is optional
-        if config.EnableTimezoneService:
-            self.log_info("Setting up time zone service resource: %r"
-                          % (self.timezoneServiceResourceClass,))
-
-            timezoneService = self.timezoneServiceResourceClass(
-                NotFilePath(isfile=True),
-                root,
-            )
-            root.putChild("timezones", timezoneService)
-
-        # iSchedule service is optional
-        if config.Scheduling.iSchedule.Enabled:
-            self.log_info("Setting up iSchedule inbox resource: %r"
-                          % (self.iScheduleResourceClass,))
-
-            ischedule = self.iScheduleResourceClass(
-                NotFilePath(isfile=True),
-                root,
-            )
-            root.putChild("ischedule", ischedule)
-
-        #
-        # IMIP delivery resource
-        #
+        additional = []
         if config.Scheduling.iMIP.Enabled:
-            self.log_info("Setting up iMIP inbox resource: %r"
-                          % (self.imipResourceClass,))
+            additional.append(("inbox", IMIPReplyInboxResource, [], "basic"))
+        rootResource = getRootResource(config, additional)
 
-            # The authenticationWrapper below will be configured to always
-            # allow basic auth on /inbox
-            root.putChild("inbox", self.imipResourceClass(root))
-
         #
-        # WebCal
-        #
-        if config.WebCalendarRoot:
-            self.log_info("Setting up WebCalendar resource: %s"
-                          % (config.WebCalendarRoot,))
-            webCalendar = self.webCalendarResourceClass(
-                config.WebCalendarRoot,
-                principalCollections=(principalCollection,),
-            )
-            root.putChild("webcal", webCalendar)
-
-        #
-        # WebAdmin
-        #
-        if config.EnableWebAdmin:
-            self.log_info("Setting up WebAdmin resource")
-            webAdmin = self.webAdminResourceClass(
-                config.WebCalendarRoot,
-                root,
-                directory,
-                principalCollections=(principalCollection,),
-            )
-            root.putChild("admin", webAdmin)
-
-        #
-        # Configure ancillary data
-        #
-        self.log_info("Setting up Timezone Cache")
-        TimezoneCache.create()
-
-
-
-        self.log_info("Configuring authentication wrapper")
-
-        authWrapper = AuthenticationWrapper(
-            root,
-            portal,
-            credentialFactories,
-            (auth.IPrincipal,),
-            overrides = {
-                "/inbox" : (inboxCredentialFactory,),
-            }
-        )
-
-        logWrapper = DirectoryLogWrapperResource(
-            authWrapper,
-            directory,
-        )
-
-        #
         # Configure the service
         #
         self.log_info("Setting up service")
 
         if config.ProcessType == "Slave":
-            realRoot = logWrapper
-
             if config.ControlSocket:
                 mode = "AF_UNIX"
                 id = config.ControlSocket
@@ -837,8 +516,6 @@
             # Make sure no old socket files are lying around.
             self.deleteStaleSocketFiles()
 
-            realRoot = logWrapper
-
             logObserver = RotatingFileAccessLoggingObserver(
                 config.AccessLogFile,
             )
@@ -847,7 +524,7 @@
 
         service = CalDAVService(logObserver)
 
-        site = Site(realRoot)
+        site = Site(rootResource)
 
         httpFactory = LimitingHTTPFactory(
             site,

Added: CalendarServer/trunk/calendarserver/util.py
===================================================================
--- CalendarServer/trunk/calendarserver/util.py	                        (rev 0)
+++ CalendarServer/trunk/calendarserver/util.py	2010-02-16 22:30:15 UTC (rev 5136)
@@ -0,0 +1,384 @@
+# -*- test-case-name: calendarserver.tap.test.test_caldav -*-
+##
+# Copyright (c) 2005-2010 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.
+##
+
+__all__ = [
+    "getRootResource",
+]
+
+import os
+from time import sleep
+
+from twisted.python.reflect import namedClass
+from twisted.internet import reactor
+from twisted.cred.portal import Portal
+from twisted.web2.dav import auth
+from twisted.web2.auth.basic import BasicCredentialFactory
+from twisted.web2.static import File as FileResource
+
+from twext.log import Logger
+
+from twistedcaldav import memcachepool
+from twistedcaldav.accesslog import DirectoryLogWrapperResource
+from twistedcaldav.directory import augment, calendaruserproxy
+from twistedcaldav.directory.aggregate import AggregateDirectoryService
+from twistedcaldav.directory.calendaruserproxyloader import XMLCalendarUserProxyLoader
+from twistedcaldav.directory.digest import QopDigestCredentialFactory
+from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
+from twistedcaldav.directory.sudo import SudoDirectoryService
+from twistedcaldav.directory.util import NotFilePath
+from twistedcaldav.directory.wiki import WikiDirectoryService
+from twistedcaldav.notify import installNotificationClient
+from twistedcaldav.resource import CalDAVResource, AuthenticationWrapper
+from twistedcaldav.static import CalendarHomeProvisioningFile
+from twistedcaldav.static import IScheduleInboxFile
+from twistedcaldav.static import TimezoneServiceFile
+from twistedcaldav.timezones import TimezoneCache
+
+try:
+    from twistedcaldav.authkerb import NegotiateCredentialFactory
+    NegotiateCredentialFactory  # pacify pyflakes
+except ImportError:
+    NegotiateCredentialFactory = None
+
+from calendarserver.provision.root import RootResource
+from calendarserver.webadmin.resource import WebAdminResource
+from calendarserver.webcal.resource import WebCalendarResource
+
+log = Logger()
+
+
+
+def getRootResource(config, resources=None):
+    """
+    Set up directory service and resource hierarchy based on config.
+    Return root resource.
+
+    Additional resources can be added to the hierarchy by passing a list of
+    tuples containing: path, resource class, __init__ args list, and optional
+    authentication scheme ("basic" or "digest").
+    """
+
+    #
+    # Default resource classes
+    #
+    rootResourceClass            = RootResource
+    principalResourceClass       = DirectoryPrincipalProvisioningResource
+    calendarResourceClass        = CalendarHomeProvisioningFile
+    iScheduleResourceClass       = IScheduleInboxFile
+    timezoneServiceResourceClass = TimezoneServiceFile
+    webCalendarResourceClass     = WebCalendarResource
+    webAdminResourceClass        = WebAdminResource
+
+    #
+    # Setup the Directory
+    #
+    directories = []
+
+    directoryClass = namedClass(config.DirectoryService.type)
+
+    log.info("Configuring directory service of type: %s"
+        % (config.DirectoryService.type,))
+
+    baseDirectory = directoryClass(config.DirectoryService.params)
+
+    # Wait for the directory to become available
+    while not baseDirectory.isAvailable():
+        sleep(5)
+
+    directories.append(baseDirectory)
+
+    #
+    # Setup the Locations and Resources Service
+    #
+    if config.ResourceService.Enabled:
+        resourceClass = namedClass(config.ResourceService.type)
+
+        log.info("Configuring resource service of type: %s" % (resourceClass,))
+
+        resourceDirectory = resourceClass(config.ResourceService.params)
+        directories.append(resourceDirectory)
+
+    #
+    # Add sudoers directory
+    #
+    sudoDirectory = None
+
+    if config.SudoersFile and os.path.exists(config.SudoersFile):
+        log.info("Configuring SudoDirectoryService with file: %s"
+                      % (config.SudoersFile,))
+
+        sudoDirectory = SudoDirectoryService(config.SudoersFile)
+        sudoDirectory.realmName = baseDirectory.realmName
+
+        CalDAVResource.sudoDirectory = sudoDirectory
+        directories.insert(0, sudoDirectory)
+    else:
+        log.info( "Not using SudoDirectoryService; file doesn't exist: %s"
+            % (config.SudoersFile,)
+        )
+
+    #
+    # Add wiki directory service
+    #
+    if config.Authentication.Wiki.Enabled:
+        wikiDirectory = WikiDirectoryService()
+        wikiDirectory.realmName = baseDirectory.realmName
+        directories.append(wikiDirectory)
+
+    directory = AggregateDirectoryService(directories)
+
+    if sudoDirectory:
+        directory.userRecordTypes.insert(0,
+            SudoDirectoryService.recordType_sudoers)
+
+    #
+    # Setup the Augment Service
+    #
+    augmentClass = namedClass(config.AugmentService.type)
+
+    log.info("Configuring augment service of type: %s" % (augmentClass,))
+
+    try:
+        augment.AugmentService = augmentClass(**config.AugmentService.params)
+    except IOError:
+        log.error("Could not start augment service")
+        raise
+
+    #
+    # Setup the PoxyDB Service
+    #
+    proxydbClass = namedClass(config.ProxyDBService.type)
+
+    log.info("Configuring proxydb service of type: %s" % (proxydbClass,))
+
+    try:
+        calendaruserproxy.ProxyDBService = proxydbClass(**config.ProxyDBService.params)
+    except IOError:
+        log.error("Could not start proxydb service")
+        raise
+
+    #
+    # Make sure proxies get initialized
+    #
+    if config.ProxyLoadFromFile:
+        def _doProxyUpdate():
+            loader = XMLCalendarUserProxyLoader(config.ProxyLoadFromFile)
+            return loader.updateProxyDB()
+
+        reactor.addSystemEventTrigger("after", "startup", _doProxyUpdate)
+
+    #
+    # Configure Memcached Client Pool
+    #
+    memcachepool.installPools(
+        config.Memcached.Pools,
+        config.Memcached.MaxClients,
+    )
+
+    #
+    # Configure NotificationClient
+    #
+    if config.Notifications.Enabled:
+        installNotificationClient(
+            config.Notifications.InternalNotificationHost,
+            config.Notifications.InternalNotificationPort,
+        )
+
+    #
+    # Configure the Site and Wrappers
+    #
+    credentialFactories = []
+
+    portal = Portal(auth.DavRealm())
+
+    portal.registerChecker(directory)
+
+    realm = directory.realmName or ""
+
+    log.info("Configuring authentication for realm: %s" % (realm,))
+
+    for scheme, schemeConfig in config.Authentication.iteritems():
+        scheme = scheme.lower()
+
+        credFactory = None
+
+        if schemeConfig["Enabled"]:
+            log.info("Setting up scheme: %s" % (scheme,))
+
+            if scheme == "kerberos":
+                if not NegotiateCredentialFactory:
+                    log.info("Kerberos support not available")
+                    continue
+
+                try:
+                    principal = schemeConfig["ServicePrincipal"]
+                    if not principal:
+                        credFactory = NegotiateCredentialFactory(
+                            type="HTTP",
+                            hostname=config.ServerHostName,
+                        )
+                    else:
+                        credFactory = NegotiateCredentialFactory(
+                            principal=principal,
+                        )
+                except ValueError:
+                    log.info("Could not start Kerberos")
+                    continue
+
+            elif scheme == "digest":
+                credFactory = QopDigestCredentialFactory(
+                    schemeConfig["Algorithm"],
+                    schemeConfig["Qop"],
+                    realm,
+                )
+
+            elif scheme == "basic":
+                credFactory = BasicCredentialFactory(realm)
+
+            elif scheme == "wiki":
+                pass
+
+            else:
+                log.error("Unknown scheme: %s" % (scheme,))
+
+        if credFactory:
+            credentialFactories.append(credFactory)
+
+
+    #
+    # Setup Resource hierarchy
+    #
+    log.info("Setting up document root at: %s"
+                  % (config.DocumentRoot,))
+    log.info("Setting up principal collection: %r"
+                  % (principalResourceClass,))
+
+    principalCollection = principalResourceClass("/principals/", directory)
+
+    log.info("Setting up calendar collection: %r" % (calendarResourceClass,))
+
+    calendarCollection = calendarResourceClass(
+        os.path.join(config.DocumentRoot, "calendars"),
+        directory, "/calendars/",
+    )
+
+    log.info("Setting up root resource: %r" % (rootResourceClass,))
+
+    root = rootResourceClass(
+        config.DocumentRoot,
+        principalCollections=(principalCollection,),
+    )
+
+    root.putChild("principals", principalCollection)
+    root.putChild("calendars", calendarCollection)
+
+    for name, info in config.Aliases.iteritems():
+        if os.path.sep in name or not info.get("path", None):
+            log.error("Invalid alias: %s" % (name,))
+            continue
+        log.info("Adding alias %s -> %s" % (name, info["path"]))
+        resource = FileResource(info["path"])
+        root.putChild(name, resource)
+
+    # Timezone service is optional
+    if config.EnableTimezoneService:
+        log.info("Setting up time zone service resource: %r"
+                      % (timezoneServiceResourceClass,))
+
+        timezoneService = timezoneServiceResourceClass(
+            NotFilePath(isfile=True),
+            root,
+        )
+        root.putChild("timezones", timezoneService)
+
+    # iSchedule service is optional
+    if config.Scheduling.iSchedule.Enabled:
+        log.info("Setting up iSchedule inbox resource: %r"
+                      % (iScheduleResourceClass,))
+
+        ischedule = iScheduleResourceClass(
+            NotFilePath(isfile=True),
+            root,
+        )
+        root.putChild("ischedule", ischedule)
+
+    #
+    # WebCal
+    #
+    if config.WebCalendarRoot:
+        log.info("Setting up WebCalendar resource: %s"
+                      % (config.WebCalendarRoot,))
+        webCalendar = webCalendarResourceClass(
+            config.WebCalendarRoot,
+            principalCollections=(principalCollection,),
+        )
+        root.putChild("webcal", webCalendar)
+
+    #
+    # WebAdmin
+    #
+    if config.EnableWebAdmin:
+        log.info("Setting up WebAdmin resource")
+        webAdmin = webAdminResourceClass(
+            config.WebCalendarRoot,
+            root,
+            directory,
+            principalCollections=(principalCollection,),
+        )
+        root.putChild("admin", webAdmin)
+
+    #
+    # Configure ancillary data
+    #
+    log.info("Setting up Timezone Cache")
+    TimezoneCache.create()
+
+
+    log.info("Configuring authentication wrapper")
+
+    overrides = { }
+    if resources:
+        for path, cls, args, scheme in resources:
+            root.putChild(path, cls(root, *args))
+
+            if scheme == "basic":
+                overrides[path] = (BasicCredentialFactory(realm),)
+
+            elif scheme == "digest":
+                schemeConfig = config.Authentication.Digest
+                overrides[path] = (QopDigestCredentialFactory(
+                    schemeConfig["Algorithm"],
+                    schemeConfig["Qop"],
+                    realm,
+                ),)
+            log.info("Overriding %s with %s (%s)" % (path, cls, scheme))
+
+    authWrapper = AuthenticationWrapper(
+        root,
+        portal,
+        credentialFactories,
+        (auth.IPrincipal,),
+        overrides=overrides,
+    )
+
+    logWrapper = DirectoryLogWrapperResource(
+        authWrapper,
+        directory,
+    )
+
+    return logWrapper
+

Modified: CalendarServer/trunk/twistedcaldav/mail.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/mail.py	2010-02-16 22:29:19 UTC (rev 5135)
+++ CalendarServer/trunk/twistedcaldav/mail.py	2010-02-16 22:30:15 UTC (rev 5136)
@@ -37,19 +37,15 @@
 from zope.interface import implements
 
 from twisted.application import internet, service
-from twisted.cred.portal import Portal
 from twisted.internet import protocol, defer, ssl, reactor
 from twisted.internet.defer import inlineCallbacks, returnValue, succeed
 from twisted.mail import pop3client, imap4
 from twisted.mail.smtp import messageid, rfc822date, ESMTPSenderFactory
 from twisted.plugin import IPlugin
-from twisted.python.reflect import namedClass
 from twisted.python.usage import Options, UsageError
 from twisted.web import client
 from twisted.web2 import server, responsecode
-from twisted.web2.auth.basic import BasicCredentialFactory
 from twisted.web2.channel.http import HTTPFactory
-from twisted.web2.dav import auth
 from twisted.web2.dav import davxml
 from twisted.web2.dav.noneprops import NonePropertyStore
 from twisted.web2.http import Response, HTTPError
@@ -60,7 +56,6 @@
 from twistedcaldav import ical, caldavxml
 from twistedcaldav import memcachepool
 from twistedcaldav.config import config
-from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource
 from twistedcaldav.directory.util import NotFilePath
 from twistedcaldav.ical import Property
 from twistedcaldav.localization import translationTo
@@ -73,7 +68,7 @@
 from twistedcaldav.sql import AbstractSQLDatabase
 from twistedcaldav.localization import translationTo
 
-from calendarserver.provision.root import RootResource
+from calendarserver.util import getRootResource
 
 
 __all__ = [
@@ -588,32 +583,13 @@
         self.settings = settings
         self.mailer = mailer
 
-        directoryClass = namedClass(config.DirectoryService.type)
-        directory = directoryClass(config.DirectoryService.params)
-
-        principalCollection = DirectoryPrincipalProvisioningResource(
-            "/principals/",
-            directory,
-        )
-
-        root = RootResource(
-            config.DocumentRoot,
-            principalCollections=(principalCollection,),
-        )
-
-        # Authenticated /inbox
-        portal = Portal(auth.DavRealm())
-        portal.registerChecker(directory)
-        realm = directory.realmName or ""
-        root.putChild('inbox',
-            auth.AuthenticationWrapper(
-                IMIPInvitationInboxResource(root, mailer),
-                portal,
-                (BasicCredentialFactory(realm),),
-                (auth.IPrincipal,),
+        rootResource = getRootResource(config,
+            (
+                ("inbox", IMIPInvitationInboxResource, (mailer,), "basic"),
             )
         )
-        self.factory = HTTPFactory(server.Site(root))
+
+        self.factory = HTTPFactory(server.Site(rootResource))
         self.server = internet.TCPServer(settings['MailGatewayPort'],
             self.factory)
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100216/3294fff4/attachment-0001.html>


More information about the calendarserver-changes mailing list