Revision: 899 http://trac.macosforge.org/projects/calendarserver/changeset/899 Author: dreid@apple.com Date: 2006-12-22 15:02:29 -0800 (Fri, 22 Dec 2006) Log Message: ----------- HOORAY SUDO SUPPORT Modified Paths: -------------- CalendarServer/branches/users/dreid/sudoers/conf/accounts.xml CalendarServer/branches/users/dreid/sudoers/conf/sudoers.plist CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/directory.py CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/sudo.py CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/xmlaccountsparser.py CalendarServer/branches/users/dreid/sudoers/twistedcaldav/extensions.py CalendarServer/branches/users/dreid/sudoers/twistedcaldav/resource.py CalendarServer/branches/users/dreid/sudoers/twistedcaldav/tap.py Modified: CalendarServer/branches/users/dreid/sudoers/conf/accounts.xml =================================================================== --- CalendarServer/branches/users/dreid/sudoers/conf/accounts.xml 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/conf/accounts.xml 2006-12-22 23:02:29 UTC (rev 899) @@ -25,12 +25,6 @@ <name>Super User</name> </user> <user> - <uid>proxy</uid> - <password>proxy</password> - <name>User who can authorize as someone else</name> - <canproxy/> <!-- FIXME: Is the directory the right place to configure this bit? --> - </user> - <user> <uid>test</uid> <password>test</password> <name>Test User</name> Modified: CalendarServer/branches/users/dreid/sudoers/conf/sudoers.plist =================================================================== --- CalendarServer/branches/users/dreid/sudoers/conf/sudoers.plist 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/conf/sudoers.plist 2006-12-22 23:02:29 UTC (rev 899) @@ -29,6 +29,12 @@ <string></string> </dict> --> + <dict> + <key>username</key> + <string>bob</string> + <key>password</key> + <string>bob</string> + </dict> </array> </dict> </plist> Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/directory.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/directory.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/directory.py 2006-12-22 23:02:29 UTC (rev 899) @@ -76,6 +76,8 @@ credentialInterfaces = (IPrincipalCredentials,) def requestAvatarId(self, credentials): + import pdb + pdb.set_trace() credentials = IPrincipalCredentials(credentials) # FIXME: ? Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/sudo.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/sudo.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/sudo.py 2006-12-22 23:02:29 UTC (rev 899) @@ -94,7 +94,25 @@ if entry['username'] == shortName: return self._recordForEntry(entry) + def requestAvatarId(self, credentials): + # FIXME: ? + # We were checking if principal is enabled; seems unnecessary in current + # implementation because you shouldn't have a principal object for a + # disabled directory principal. + user = self.recordWithShortName("sudoer", + credentials.credentials.username) + if user is None: + raise UnauthorizedLogin("No such user: %s" % (user,)) + + if user.verifyCredentials(credentials.credentials): + return ( + credentials.authnPrincipal.principalURL(), + credentials.authzPrincipal.principalURL(), + ) + else: + raise UnauthorizedLogin("Incorrect credentials for %s" % (user,)) + class SudoDirectoryRecord(DirectoryRecord): """ L{DirectoryRecord} implementation for Sudo users. Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/xmlaccountsparser.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/xmlaccountsparser.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/directory/xmlaccountsparser.py 2006-12-22 23:02:29 UTC (rev 899) @@ -42,7 +42,7 @@ ELEMENT_MEMBERS = "members" ELEMENT_MEMBER = "member" ELEMENT_CUADDR = "cuaddr" -ELEMENT_CANPROXY = "canproxy" +# ELEMENT_CANPROXY = "canproxy" ATTRIBUTE_REALM = "realm" ATTRIBUTE_REPEAT = "repeat" @@ -129,7 +129,7 @@ self.members = set() self.groups = set() self.calendarUserAddresses = set() - self.canproxy = False +# self.canproxy = False def repeat(self, ctr): """ @@ -162,7 +162,7 @@ result.name = name result.members = self.members result.calendarUserAddresses = calendarUserAddresses - result.canproxy = self.canproxy +# result.canproxy = self.canproxy return result def parseXML(self, node): @@ -181,9 +181,9 @@ elif child._get_localName() == ELEMENT_CUADDR: if child.firstChild is not None: self.calendarUserAddresses.add(child.firstChild.data.encode("utf-8")) - elif child._get_localName() == ELEMENT_CANPROXY: - CalDAVResource.proxyUsers.add(self.shortName) - self.canproxy = True +# elif child._get_localName() == ELEMENT_CANPROXY: +# CalDAVResource.proxyUsers.add(self.shortName) +# self.canproxy = True def _parseMembers(self, node): for child in node._get_childNodes(): Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/extensions.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/extensions.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/extensions.py 2006-12-22 23:02:29 UTC (rev 899) @@ -46,6 +46,24 @@ Extended L{twisted.web2.dav.resource.DAVResource} implementation. """ + def findPrincipalForAuthID(self, authid): + """ + Return an authentication and authorization principal identifiers for + the authentication identifier passed in. Check for sudo users before + regular users. + """ + + record = self.directory.recordWithShortName('sudoer', authid) + + if record: + for collection in self.principalCollections(): + principal = collection.principalForRecord(record) + if principal is not None: + return principal + + return super(DAVResource, self).findPrincipalForAuthID(authid) + + class DAVFile (SuperDAVFile): """ Extended L{twisted.web2.dav.static.DAVFile} implementation. @@ -213,6 +231,14 @@ response.headers.setHeader("content-type", MimeType("text", "html")) return response + def findPrincipalForAuthID(self, authid): + """ + returns the principals by asking it's parent, because it doesn't have + a reference to the directory + """ + return self.parent.findPrincipalForAuthID(authid) + + class ReadOnlyResourceMixIn (object): """ Read only resource. Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/resource.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/resource.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/resource.py 2006-12-22 23:02:29 UTC (rev 899) @@ -74,10 +74,6 @@ # resources to that size, or C{None} for no limit. sizeLimit = None - # Set containing user ids of all the users who have been given - # the right to authorize as someone else. - proxyUsers = set() - ## # HTTP ## @@ -259,9 +255,14 @@ authz = authz[0] # See if authenticated uid is a proxy user - if authid in CalDAVResource.proxyUsers: + sudoRecord = self.directory.recordWithShortName( + 'sudoer', + authid) + + if sudoRecord: if authz: - if authz in CalDAVResource.proxyUsers: + record = self.directory.recordWithShortName('sudoer', authz) + if record: log.msg("Cannot proxy as another proxy: user '%s' as user '%s'" % (authid, authz)) raise HTTPError(responsecode.UNAUTHORIZED) else: Modified: CalendarServer/branches/users/dreid/sudoers/twistedcaldav/tap.py =================================================================== --- CalendarServer/branches/users/dreid/sudoers/twistedcaldav/tap.py 2006-12-22 19:26:19 UTC (rev 898) +++ CalendarServer/branches/users/dreid/sudoers/twistedcaldav/tap.py 2006-12-22 23:02:29 UTC (rev 899) @@ -45,6 +45,7 @@ from twistedcaldav.config import config, parseConfig, defaultConfig from twistedcaldav.logging import RotatingFileAccessLoggingObserver from twistedcaldav.root import RootResource +from twistedcaldav.resource import CalDAVResource from twistedcaldav.directory.principal import DirectoryPrincipalProvisioningResource from twistedcaldav.directory.aggregate import AggregateDirectoryService from twistedcaldav.directory.sudo import SudoDirectoryService @@ -132,9 +133,13 @@ directoryClass = namedClass(config.DirectoryService['type']) baseDirectory = directoryClass(**config.DirectoryService['params']) + sudoDirectory = None + if config.SudoersFile: sudoDirectory = SudoDirectoryService(config.SudoersFile) sudoDirectory.realmName = baseDirectory.realmName + + CalDAVResource.sudoDirectory = sudoDirectory directory = AggregateDirectoryService((baseDirectory, sudoDirectory)) @@ -196,6 +201,12 @@ portal.registerChecker(directory) + # FIXME: This is a hack, why doesn't aggregate directory service + # do the right thing. + + if sudoDirectory: + portal.registerChecker(sudoDirectory) + realm = directory.realmName or "" for scheme, schemeConfig in config.Authentication.iteritems():