[Zope3-checkins] SVN: Zope3/trunk/ First checkin of the home folder
code. Using the Home Folder Manager you
Stephan Richter
srichter at cosmos.phy.tufts.edu
Sat Dec 4 10:11:35 EST 2004
Log message for revision 28558:
First checkin of the home folder code. Using the Home Folder Manager you
can assign home folders to principals.
Changed:
U Zope3/trunk/doc/CHANGES.txt
A Zope3/trunk/package-includes/homefolder-configure.zcml
A Zope3/trunk/src/zope/app/homefolder/
A Zope3/trunk/src/zope/app/homefolder/README.txt
A Zope3/trunk/src/zope/app/homefolder/__init__.py
A Zope3/trunk/src/zope/app/homefolder/browser.py
A Zope3/trunk/src/zope/app/homefolder/browser.zcml
A Zope3/trunk/src/zope/app/homefolder/configure.zcml
A Zope3/trunk/src/zope/app/homefolder/homefolder.pt
A Zope3/trunk/src/zope/app/homefolder/homefolder.py
A Zope3/trunk/src/zope/app/homefolder/interfaces.py
A Zope3/trunk/src/zope/app/homefolder/tests.py
-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/doc/CHANGES.txt 2004-12-04 15:11:34 UTC (rev 28558)
@@ -52,17 +52,35 @@
- Implemented the `zope:localUtility` directive, so that you can use it
instead of the `zope:content` directive, which we had to use
before. The new directive automatically makes the utility implement
- `ILocalUtility`. I also changed all the local utility declarations to
- use this new directive.
+ `ILocalUtility` and `IAttributeAnnotatable`. I also changed all the
+ local utility declarations to use this new directive.
- The `Attribute` and `Method` class of the `zope.interface` have now a
new public `interface` attribute that stores the interface they are
defined in.
- - New Pluggable Authentication Service, which is similar in
- philosophy to the Zope 2 PAS. One of the main reasons for
- this is to support principal groups.
+ - New Pluggable Authentication Service, which is similar in philosophy to
+ the Zope 2 PAS. One of the main reasons for this is to support
+ principal groups. The following features are available in the core:
+ o Extraction Plugins: Basic HTTP Auth, Session
+
+ o Challenger Plugins: Basic HTTP Auth, No Challenge if Authenticated,
+ Form Challenger
+
+ o Authentication Plugins: Persistent (ZODB), SQL-based (LDAP is also
+ available, but needs to be separately be downloaded)
+
+ o Principal Factory Plugins: Default factory
+
+ o Principal Search Plugins: Persistent (ZODB), SQL-based
+
+ o Group Folder: The group folder allows the developer to assign groups
+ to principals.
+
+ o Home Folder: This utility allows you assign a home folder to a
+ principal.
+
- Added "sources", which are like vocabularies except that they
support very large collections of values that must be
searched, rather than browsed.
Added: Zope3/trunk/package-includes/homefolder-configure.zcml
===================================================================
--- Zope3/trunk/package-includes/homefolder-configure.zcml 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/package-includes/homefolder-configure.zcml 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1 @@
+<include package="zope.app.homefolder" />
Added: Zope3/trunk/src/zope/app/homefolder/README.txt
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/README.txt 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/README.txt 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,198 @@
+=====================
+Principal Home Folder
+=====================
+
+The principal home folder subscriber let's you assign home folders to
+principals as you would do in any OS. This particular implementation of such a
+feature is intended as a demo of the power of the way to handle principals
+and not as the holy grail. If you have concerns about the assumptions made in
+this implementation (which are probably legitamite), just ignore this package
+altogether.
+
+Managing the Home Folders
+-------------------------
+
+Let's say we have a principal and we want to have a home folder for it. The
+first task is to create the home folder manager, which keeps track of the
+principal's home folders:
+
+ >>> from zope.app.homefolder.homefolder import HomeFolderManager
+ >>> manager = HomeFolderManager()
+
+Now the manager will not be able to do much, because it does not know where to
+look for the principal home folders. Therefore we have to specify a folder
+container:
+
+ >>> from zope.app.container.btree import BTreeContainer
+ >>> baseFolder = BTreeContainer()
+ >>> manager.homeFolderBase = baseFolder
+
+Now we can assign a home folder to a principal:
+
+ >>> manager.assignHomeFolder('stephan')
+
+Since we did not specify the name of the home folder, it is just the same
+as the principal id:
+
+ >>> manager.assignments['stephan']
+ 'stephan'
+
+Since the home folder did not exist and the `createHomeFolder` option was
+turned on, the directory was created for you:
+
+ >>> 'stephan' in baseFolder
+ True
+
+When creating the home folder, the principal also automatically receives the
+`zope.Manager` role:
+
+ >>> from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+ >>> roles = IPrincipalRoleManager(baseFolder['stephan'])
+ >>> [(role, str(setting))
+ ... for role, setting in roles.getRolesForPrincipal('stephan')]
+ [(u'zope.Manager', 'PermissionSetting: Allow')]
+
+If a folder already exists for the provided name, then the creation is simply
+skipped silently:
+
+ >>> from zope.app.folder import Folder
+ >>> baseFolder['sc3'] = Folder()
+ >>> manager.assignHomeFolder('sc3')
+ >>> manager.assignments['sc3']
+ 'sc3'
+
+This has the advantage that you can choose your own `IContainer`
+implementation instead of relying on the vanilla folder.
+
+Now let's look at some derivations of the same task.
+
+ 1. Sometimes you want to specify an alternative folder name:
+
+ >>> manager.assignHomeFolder('jim', folderName='J1m')
+ >>> manager.assignments['jim']
+ 'J1m'
+ >>> 'J1m' in baseFolder
+ True
+
+ 2. Even though folders are created by default, you can specifically turn
+ that behavior off for a particular assignment:
+
+ >>> manager.assignHomeFolder('dreamcatcher', create=False)
+ >>> manager.assignments['dreamcatcher']
+ 'dreamcatcher'
+ >>> 'dreamcatcher' in baseFolder
+ False
+
+ 3. You wish not to create a folder by default:
+
+ >>> manager.createHomeFolder = False
+ >>> manager.assignHomeFolder('philiKON')
+ >>> manager.assignments['philiKON']
+ 'philiKON'
+ >>> 'philiKON' in baseFolder
+ False
+
+ 4. You do not want to create a folder by default, you want to create the
+ folder for a specific user:
+
+ >>> manager.assignHomeFolder('stevea', create=True)
+ >>> manager.assignments['stevea']
+ 'stevea'
+ >>> 'stevea' in baseFolder
+ True
+
+Let's now look at removing home folder assignments. By default, removing an
+assignment will *not* delete the actual folder:
+
+ >>> manager.unassignHomeFolder('stevea')
+ >>> 'stevea' not in manager.assignments
+ True
+ >>> 'stevea' in baseFolder
+ True
+
+But if you specify the `delete` argument, then the folder will be deleted:
+
+ >>> 'J1m' in baseFolder
+ True
+ >>> manager.unassignHomeFolder('jim', delete=True)
+ >>> 'jim' not in manager.assignments
+ True
+ >>> 'J1m' in baseFolder
+ False
+
+Next, let's have a look at retrieving the home folder for a principal. This
+can be done as follows:
+
+ >>> homeFolder = manager.getHomeFolder('stephan')
+ >>> homeFolder is baseFolder['stephan']
+ True
+
+
+If you try to get a folder and it does not yet exist, `None` will be
+returned. Remember 'dreamcatcher', which has an assignment, but not a folder?
+
+ >>> 'dreamcatcher' in baseFolder
+ False
+ >>> homeFolder = manager.getHomeFolder('dreamcatcher')
+ >>> homeFolder is None
+ True
+
+
+Accessing the Home Folder
+-------------------------
+
+But how does the home folder gets assigned to a principal? There are two ways
+of accessing the homefolder. The first is via a simple adapter that provides a
+`homeFolder` attribute. The second method provides the folder via a path
+adapter called `homefolder`.
+
+Let's start by creatig a principal:
+
+ >>> from zope.security.interfaces import IPrincipal
+ >>> from zope.interface import implements
+ >>> class Principal:
+ ... implements(IPrincipal)
+ ... def __init__(self, id):
+ ... self.id = id
+ >>> principal = Principal('stephan')
+
+We also need to register our manager as a utility:
+
+ >>> from zope.app.tests import ztapi
+ >>> from zope.app.homefolder.interfaces import IHomeFolderManager
+ >>> ztapi.provideUtility(IHomeFolderManager, manager, 'manager')
+
+
+(1) Now we can access the home folder via the adapter:
+
+ >>> from zope.app.homefolder.interfaces import IHomeFolder
+ >>> adapter = IHomeFolder(principal)
+ >>> adapter.homeFolder is baseFolder['stephan']
+ True
+
+(2) Or alternatively via the path adapter:
+
+ >>> from zope.app.traversing.interfaces import IPathAdapter
+ >>> from zope.app import zapi
+ >>> zapi.getAdapter(principal, IPathAdapter,
+ ... "homefolder") is baseFolder['stephan']
+ True
+
+As you can see the path adapter just returns the homefolder. This way we can
+guarantee that always the folder's full API is available. Of course the real
+way it will be used is via a TALES expression:
+
+ Setup of the Engine
+
+ >>> from zope.app.pagetemplate.engine import Engine
+ >>> from zope.tales.tales import Context
+ >>> context = Context(Engine, {'principal': principal})
+
+ Executing the TALES expression
+
+ >>> bytecode = Engine.compile('principal/homefolder:keys')
+ >>> list(bytecode(context))
+ []
+ >>> baseFolder['stephan'][u'documents'] = Folder()
+ >>> list(bytecode(context))
+ [u'documents']
Added: Zope3/trunk/src/zope/app/homefolder/__init__.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/__init__.py 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/__init__.py 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1 @@
+# Make directory a Python package.
Added: Zope3/trunk/src/zope/app/homefolder/browser.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/browser.py 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/browser.py 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,98 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Home Folder related views.
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+import zope.schema
+from zope.schema.vocabulary import SimpleVocabulary
+from zope.security.proxy import removeSecurityProxy
+
+from zope.app import zapi
+from zope.app.form.browser import TextWidget, MultiSelectWidget
+from zope.app.form.utility import setUpWidget
+from zope.app.form.interfaces import IInputWidget
+from zope.app.security.vocabulary import PrincipalSource
+
+class PathWidget(TextWidget):
+
+ def _toFieldValue(self, input):
+ path = super(PathWidget, self)._toFieldValue(input)
+ root = zapi.getRoot(self.context.context)
+ return removeSecurityProxy(zapi.traverse(root, path))
+
+ def _toFormValue(self, value):
+ if value is None:
+ return ''
+ return zapi.getPath(value)
+
+
+class AssignHomeFolder(object):
+
+ def setupWidgets(self):
+ self.principal_field = zope.schema.Choice(
+ __name__ = 'principal',
+ title=u'Principal Id',
+ source=PrincipalSource(),
+ required=False)
+
+ self.folderName_field = zope.schema.TextLine(
+ __name__ = 'folderName',
+ title=u'Folder Name',
+ required=False)
+
+ self.selectedPrincipals_field = zope.schema.List(
+ __name__ = 'selectedPrincipals',
+ title=u'Existing Assignments',
+ value_type=zope.schema.Choice(
+ vocabulary=SimpleVocabulary.fromItems(
+ [('%s (%s)' %(key, value), key)
+ for key, value in self.context.assignments.items()]
+ )),
+ required=False)
+
+ setUpWidget(self, 'principal', self.principal_field, IInputWidget)
+ setUpWidget(self, 'folderName', self.folderName_field, IInputWidget)
+ self.selectedPrincipals_widget = MultiSelectWidget(
+ self.selectedPrincipals_field.bind(self),
+ self.selectedPrincipals_field.value_type.vocabulary,
+ self.request)
+ self.selectedPrincipals_widget.setRenderedValue([])
+
+ def update(self):
+ self.setupWidgets()
+
+ if 'SUBMIT_ASSIGN' in self.request:
+ if not self.principal_widget.hasInput():
+ return u''
+
+ principal = self.principal_widget.getInputValue()
+ name = self.folderName_widget.getInputValue()
+
+ self.context.assignHomeFolder(principal, name)
+ self.setupWidgets()
+ return u'Home Folder assignment was successful.'
+
+ if 'SUBMIT_UNASSIGN' in self.request:
+ if not self.selectedPrincipals_widget.hasInput():
+ return u''
+
+ for id in self.selectedPrincipals_widget.getInputValue():
+ self.context.unassignHomeFolder(id)
+
+ self.setupWidgets()
+ return u'Principals were successfully unassigned.'
+
+ return u''
Added: Zope3/trunk/src/zope/app/homefolder/browser.zcml
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/browser.zcml 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/browser.zcml 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,53 @@
+<zope:configure
+ xmlns:zope="http://namespaces.zope.org/zope"
+ xmlns="http://namespaces.zope.org/browser">
+
+ <addform
+ schema="..homefolder.IHomeFolderManager"
+ label="Add Home Folder Manager"
+ content_factory="..homefolder.HomeFolderManager"
+ name="AddHomeFolderManagerForm.html"
+ permission="zope.ManageServices">
+
+ <widget
+ field="homeFolderBase"
+ class=".homefolder.PathWidget" />
+
+ </addform>
+
+ <addMenuItem
+ title="Home Folder Manager"
+ class="..homefolder.HomeFolderManager"
+ permission="zope.ManageServices"
+ view="AddHomeFolderManagerForm.html"
+ />
+
+ <editform
+ schema="..homefolder.IHomeFolderManager"
+ label="Edit Home Folder Manager"
+ name="edit.html"
+ permission="zope.ManageServices"
+ menu="zmi_views" title="Edit">
+
+ <widget
+ field="homeFolderBase"
+ class=".homefolder.PathWidget" />
+
+ </editform>
+
+ <page
+ name="assignments.html"
+ for="..homefolder.IHomeFolderManager"
+ template="homefolder.pt"
+ class=".homefolder.AssignHomeFolder"
+ permission="zope.ManageServices"
+ menu="zmi_views" title="Assignments"
+ />
+
+ <tool
+ interface="..homefolder.IHomeFolderManager"
+ title="Home Folder Manager"
+ description="A Principal Home Folder Manager"
+ />
+
+</zope:configure>
Added: Zope3/trunk/src/zope/app/homefolder/configure.zcml
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/configure.zcml 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/configure.zcml 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,81 @@
+<configure
+ xmlns="http://namespaces.zope.org/zope"
+ xmlns:browser="http://namespaces.zope.org/browser"
+ i18n_domain="zope"
+ >
+
+ <adapter
+ for="zope.security.interfaces.IPrincipal"
+ provides=".interfaces.IHomeFolder"
+ factory=".homefolder.HomeFolder"
+ />
+
+ <adapter
+ for="zope.security.interfaces.IPrincipal"
+ provides="zope.app.traversing.interfaces.IPathAdapter"
+ factory=".homefolder.getHomeFolder"
+ name="homefolder" />
+
+ <localUtility class=".homefolder.HomeFolderManager">
+
+ <require
+ permission="zope.ManageServices"
+ interface=".homefolder.IHomeFolderManager"
+ set_schema=".homefolder.IHomeFolderManager" />
+
+ <require
+ permission="zope.ManageServices"
+ attributes="assignments" />
+
+ </localUtility>
+
+ <browser:addform
+ schema=".interfaces.IHomeFolderManager"
+ label="Add Home Folder Manager"
+ content_factory=".homefolder.HomeFolderManager"
+ name="AddHomeFolderManagerForm.html"
+ permission="zope.ManageServices">
+
+ <browser:widget
+ field="homeFolderBase"
+ class=".browser.PathWidget" />
+
+ </browser:addform>
+
+ <browser:addMenuItem
+ title="Home Folder Manager"
+ class=".homefolder.HomeFolderManager"
+ permission="zope.ManageServices"
+ view="AddHomeFolderManagerForm.html"
+ />
+
+ <browser:editform
+ schema=".interfaces.IHomeFolderManager"
+ label="Edit Home Folder Manager"
+ name="edit.html"
+ permission="zope.ManageServices"
+ menu="zmi_views" title="Edit">
+
+ <browser:widget
+ field="homeFolderBase"
+ class=".browser.PathWidget" />
+
+ </browser:editform>
+
+ <browser:page
+ name="assignments.html"
+ for=".interfaces.IHomeFolderManager"
+ template="homefolder.pt"
+ class=".browser.AssignHomeFolder"
+ permission="zope.ManageServices"
+ menu="zmi_views" title="Assignments"
+ />
+
+ <browser:tool
+ interface=".interfaces.IHomeFolderManager"
+ title="Home Folder Manager"
+ description="A Principal Home Folder Manager"
+ />
+
+
+</configure>
Added: Zope3/trunk/src/zope/app/homefolder/homefolder.pt
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/homefolder.pt 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/homefolder.pt 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,44 @@
+<html metal:use-macro="context/@@standard_macros/view">
+<body>
+<div metal:fill-slot="body">
+
+ <div class="message"
+ tal:define="status view/update"
+ tal:condition="status"
+ tal:content="status" />
+
+ <form action="" method="POST">
+ <h3 i18n:translate="">Assign a Principal</h3>
+
+ <div class="row" tal:define="widget nocall:view/principal_widget">
+ <metal:block use-macro="context/@@form_macros/widget_row" />
+ </div>
+
+ <div class="row" tal:define="widget nocall:view/folderName_widget">
+ <metal:block use-macro="context/@@form_macros/widget_row" />
+ </div>
+
+ <div class="row">
+ <div class="controls">
+ <input type="submit" value="Assign" name="SUBMIT_ASSIGN"
+ i18n:attributes="value assign-button" />
+ </div>
+ </div>
+
+ <h3 i18n:translate="">Unassign Principals</h3>
+
+ <div class="row" tal:define="widget nocall:view/selectedPrincipals_widget">
+ <metal:block use-macro="context/@@form_macros/widget_row" />
+ </div>
+
+ <div class="row">
+ <div class="controls">
+ <input type="submit" value="Unassign" name="SUBMIT_UNASSIGN"
+ i18n:attributes="value unassign-button" />
+ </div>
+ </div>
+ </form>
+
+</div>
+</body>
+</html>
\ No newline at end of file
Added: Zope3/trunk/src/zope/app/homefolder/homefolder.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/homefolder.py 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/homefolder.py 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,95 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Home Directory of a User
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+from persistent import Persistent
+from BTrees.OOBTree import OOBTree
+
+from zope.interface import implements
+
+from zope.app import zapi
+from zope.app.container.contained import Contained
+from zope.app.folder import Folder
+from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+
+from zope.app.homefolder.interfaces import IHomeFolder, IHomeFolderManager
+
+class HomeFolderManager(Persistent, Contained):
+ """ """
+ implements(IHomeFolderManager)
+
+ # See IHomeFolderManager
+ homeFolderBase = None
+ createHomeFolder = True
+ homeFolderRole = u'zope.Manager'
+
+ def __init__(self):
+ self.assignments = OOBTree()
+
+ def assignHomeFolder(self, principalId, folderName=None, create=None):
+ """See IHomeFolderManager"""
+ # The name of the home folder is folderName, if specified, otherwise
+ # it is the principal id
+ name = folderName or principalId
+ # Make the assignment.
+ self.assignments[principalId] = name
+
+ # Create a home folder instance, if the correct flags are set.
+ if (create is True) or (create is None and self.createHomeFolder):
+ if name not in self.homeFolderBase:
+ self.homeFolderBase[name] = Folder()
+ principal_roles = IPrincipalRoleManager(self.homeFolderBase[name])
+ principal_roles.assignRoleToPrincipal(
+ self.homeFolderRole, principalId)
+
+
+ def unassignHomeFolder(self, principalId, delete=False):
+ """See IHomeFolderManager"""
+ folderName = self.assignments[principalId]
+ if delete is True:
+ del self.homeFolderBase[folderName]
+ del self.assignments[principalId]
+
+
+ def getHomeFolder(self, principalId):
+ """See IHomeFolderManager"""
+ if principalId not in self.assignments:
+ return None
+
+ return self.homeFolderBase.get(self.assignments[principalId], None)
+
+
+class HomeFolder(object):
+ """Home folder adapter for a principal."""
+ implements(IHomeFolder)
+
+ def __init__(self, principal):
+ self.principal = principal
+
+ homeFolder = property(lambda self: getHomeFolder(self.principal))
+
+
+def getHomeFolder(principal):
+ """Get the home folder instance of the principal."""
+ principalId = principal.id
+ for name, manager in zapi.getUtilitiesFor(IHomeFolderManager):
+ folder = manager.getHomeFolder(principalId)
+ if folder is not None:
+ return folder
+
+ return None
+
Added: Zope3/trunk/src/zope/app/homefolder/interfaces.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/interfaces.py 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/interfaces.py 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,89 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Home Folder Interfaces
+
+$Id$
+"""
+__docformat__ = "reStructuredText"
+
+from zope.interface import Interface
+from zope.schema import Field, Bool, Choice
+from zope.app.i18n import ZopeMessageIDFactory as _
+
+class IHomeFolder(Interface):
+ """Describes the home directory of a principal."""
+
+ homeFolder = Field(
+ title=_("Home Folder"),
+ description=_("The principal's home folder; if none has been "
+ "defined, this attribute will be `None`."))
+
+
+class IHomeFolderManager(Interface):
+ """Home Folder Manager
+
+ This utility manages the assignments of home folders to principals. It
+ will create and expect all
+ """
+
+ homeFolderBase = Field(
+ title=_("Base Folder"),
+ description=_("The Base Folder for the Principal Home Folder."),
+ required=True)
+
+ createHomeFolder = Bool(
+ title=_("Create Home Folder"),
+ description=_("Whether home folders should be created, if missing."),
+ required=True,
+ default=True)
+
+ homeFolderRole = Choice(
+ title=_("Local Home Folder Role"),
+ description=_("The local role that the user will have in "
+ "its home folder. This role is only set on folders "
+ "that are created by the manager."),
+ vocabulary="Role Ids",
+ default=u'zope.Manager'
+ )
+
+ def assignHomeFolder(principalId, folderName=None, create=None):
+ """Assigns a particular folder as the home folder of a principal.
+
+ If the `folderName` is `None`, then the principal id will be used as
+ the folder name.
+
+ If `createHomeFolder` or `create` is set to `True`, the method is also
+ responsible for creating the folder. During creation, the principal
+ should get manager rights inside the folder. If `create` is
+ specifically set to `False`, then the folder is never created even if
+ `createHomeFolder` is `True`.
+ """
+
+ def unassignHomeFolder(principalId, delete=False):
+ """Remove a home folder assignment.
+
+ If `delete` is `True`, then delete the home folder including all of
+ its content.
+ """
+
+ def getHomeFolder(principalId):
+ """Get the home folder instance of the specified principal.
+
+ If the home folder does not exist and `autoCreateFolder` is set to
+ `True`, then create the home folder. During creation, the principal
+ should get manager rights inside the folder.
+
+ If the home folder does not exist and `autoCreateFolder` is set to
+ `False`, then return `None`.
+ """
Added: Zope3/trunk/src/zope/app/homefolder/tests.py
===================================================================
--- Zope3/trunk/src/zope/app/homefolder/tests.py 2004-12-03 20:53:33 UTC (rev 28557)
+++ Zope3/trunk/src/zope/app/homefolder/tests.py 2004-12-04 15:11:34 UTC (rev 28558)
@@ -0,0 +1,57 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Pluggable Authentication Service Tests
+
+$Id: tests.py 28311 2004-11-01 19:03:56Z jim $
+"""
+__docformat__ = "reStructuredText"
+
+import unittest
+from zope.security.interfaces import IPrincipal
+from zope.testing import doctest
+from zope.app.tests import placelesssetup, setup, ztapi
+
+from zope.app.annotation.interfaces import IAnnotatable
+from zope.app.securitypolicy.interfaces import IPrincipalRoleManager
+from zope.app.securitypolicy.principalrole import AnnotationPrincipalRoleManager
+from zope.app.traversing.interfaces import IPathAdapter
+
+from zope.app.homefolder.homefolder import HomeFolder, getHomeFolder
+from zope.app.homefolder.interfaces import IHomeFolder
+
+
+def homeFolderSetUp(test):
+ placelesssetup.setUp()
+ setup.setUpAnnotations()
+ setup.setUpTraversal()
+
+ ztapi.provideAdapter(IAnnotatable, IPrincipalRoleManager,
+ AnnotationPrincipalRoleManager)
+ ztapi.provideAdapter(IPrincipal, IHomeFolder,
+ HomeFolder)
+ ztapi.provideAdapter(IPrincipal, IPathAdapter,
+ getHomeFolder,
+ name="homefolder")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ doctest.DocFileSuite('README.txt',
+ setUp=homeFolderSetUp,
+ tearDown=placelesssetup.tearDown),
+ ))
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='test_suite')
+
More information about the Zope3-Checkins
mailing list