def _authReadOnlyPrivileges(self, resource, url, records=None): items = [] if records is None: records = yield self._allRecords() for ( _ignore_provisioningResource, _ignore_recordType, recordResource, _ignore_record ) in records: items.append(( davxml.HRef().fromString(recordResource.principalURL()), davxml.Read(), True )) items.append(( davxml.HRef().fromString(recordResource.principalURL()), davxml.Write(), False )) items.append(( davxml.Unauthenticated(), davxml.Read(), False )) items.append(( davxml.Unauthenticated(), davxml.Write(), False )) results = [] for principal, privilege, allowed in items: results.append((resource, url, principal, privilege, allowed)) returnValue(results)
def defaultAccessControlList(self): privs = ( davxml.Privilege(davxml.Read()), davxml.Privilege(caldavxml.ScheduleDeliver()), ) if config.Scheduling.CalDAV.OldDraftCompatibility: privs += (davxml.Privilege(caldavxml.Schedule()),) aces = ( # DAV:Read, CalDAV:schedule-deliver for all principals (does not include anonymous) davxml.ACE( davxml.Principal(davxml.Authenticated()), davxml.Grant(*privs), davxml.Protected(), ), ) if config.FreeBusyURL.AnonymousAccess: aces += ( # DAV:Read, for unauthenticated principals davxml.ACE( davxml.Principal(davxml.Unauthenticated()), davxml.Grant( davxml.Privilege(davxml.Read()), ), davxml.Protected(), ), ) return succeed(davxml.ACL(*aces))
def getWikiACL(resource, request): """ Ask the wiki server we're paired with what level of access the authnUser has. Returns an ACL. Wiki authentication is a bit tricky because the end-user accessing a group calendar may not actually be enabled for calendaring. Therefore in that situation, the authzUser will have been replaced with the wiki principal in locateChild( ), so that any changes the user makes will have the wiki as the originator. The authnUser will always be the end-user. """ from twistedcaldav.directory.principal import DirectoryPrincipalResource if (not hasattr(resource, "record") or resource.record.recordType != RecordType.macOSXServerWiki): returnValue(None) if hasattr(request, 'wikiACL'): returnValue(request.wikiACL) wikiRecord = resource.record wikiID = wikiRecord.shortNames[0] userRecord = None try: url = request.authnUser.principalURL() principal = (yield request.locateResource(url)) if isinstance(principal, DirectoryPrincipalResource): userRecord = principal.record except: # TODO: better error handling pass try: access = yield wikiRecord.accessForRecord(userRecord) # The ACL we returns has ACEs for the end-user and the wiki principal # in case authzUser is the wiki principal. if access == WikiAccessLevel.read: request.wikiACL = davxml.ACL( davxml.ACE( (request.authnUser.principalElement() if request.authnUser is not None else davxml.Principal( davxml.Unauthenticated())), davxml.Grant( davxml.Privilege(davxml.Read()), davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()), # We allow write-properties so that direct sharees can # change e.g. calendar color properties davxml.Privilege(davxml.WriteProperties()), ), TwistedACLInheritable(), ), davxml.ACE( davxml.Principal( davxml.HRef.fromString( "/principals/wikis/{}/".format(wikiID))), davxml.Grant( davxml.Privilege(davxml.Read()), davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()), ), TwistedACLInheritable(), )) returnValue(request.wikiACL) elif access == WikiAccessLevel.write: request.wikiACL = davxml.ACL( davxml.ACE( (request.authnUser.principalElement() if request.authnUser is not None else davxml.Principal( davxml.Unauthenticated())), davxml.Grant( davxml.Privilege(davxml.Read()), davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()), davxml.Privilege(davxml.Write()), ), TwistedACLInheritable(), ), davxml.ACE( davxml.Principal( davxml.HRef.fromString( "/principals/wikis/{}/".format(wikiID))), davxml.Grant( davxml.Privilege(davxml.Read()), davxml.Privilege(davxml.ReadCurrentUserPrivilegeSet()), davxml.Privilege(davxml.Write()), ), TwistedACLInheritable(), )) returnValue(request.wikiACL) else: # "no-access": if userRecord is None: # Return a 401 so they have an opportunity to log in response = (yield UnauthorizedResponse.makeResponse( request.credentialFactories, request.remoteAddr, )) raise HTTPError(response) raise HTTPError( StatusResponse(responsecode.FORBIDDEN, "You are not allowed to access this wiki")) except HTTPError: # pass through the HTTPError we might have raised above raise except Exception as e: log.error("Wiki ACL lookup failed: {error}", error=e) raise HTTPError( StatusResponse(responsecode.SERVICE_UNAVAILABLE, "Wiki ACL lookup failed"))