|
|
||||||||||||||||||
|
|
||||||||||||||||||
![]() |
![]() |
Issue 8 - Revision 8 / September 26, 2004
|
|||
|
Fine Grained Permissions - Step-by-Step - - - - - - - - - - - - By Chris Curvey | May 27, 2004 Introduction A fully configured Plone instance comes with a thoroughly functional and quite useful workflow. Content is always in one of four states: “private” (where only members of the site can see it), “visible” (where anyone who knows how to find it can see it), “pending” (which is just like “visible”, except the content shows up as awaiting approval), and “published” (where anonymous users, i.e. anyone, can see it). This is fine for many applications, yet many companies make their money by selling the information on their site (for example, ZopeMag). What you really want here is the ability to “publish to members of a group, and ONLY to those members.” Plone doesn't offer this out-of-the-box .This article will walk you through the steps needed to make it work. The ProblemThe customer is a small business association with very little technical experience. The owners make their living by providing information and services to the members of the association. Some of the information on their site is promotional in nature, and needs to be available to the general public. That's easy to handle with the standard Plone workflow. In order to entice people to become dues-paying members of the association, it publishes some “premium” content that is only available to dues-paying members. (Non-members can see the link, but are encouraged to become members when they click on the link.) Premium content can appear anywhere throughout the site. Note: In order to avoid confusion between the Plone concept of a “member” and the business concept of a member, we will refer to the dues-paying users as “subscribers.” In addition to having subscribers, the association has about 30 Special Interest Groups (SIGs). Each SIG has rules about who can join, and joining a SIG also requires an extra payment to the association. Each SIG has its own folder, which can contain either public content or SIG-only content, i.e. content available only to members of that SIG, but all SIG-only content is placed in that folder. The association also offers courses to the public. The instructors are usually not employees of the association, but are independent contractors. The association would like to set up a section of the site for each course where the instructor could post assignments and respond to student questions. Play Along at Home!This article is written as a tutorial, so you will want to have a Plonesite that you can play with while reading. I suggest that you set up a brand new Plonesite in order to minimize any complications that might arise from an existing site. DO NOT use a production site, since we will be modifying the default workflow. Handling Premium ContentThe first problem that we have is that the existing “states” within Plone don't offer us the ability to publish to a limited subset of users. If content is “private,” then it's only available to the author. If content is “visible”, then it's visible to anyone who knows the corresponding URL. It might be tempting to try to use this “security through obscurity” to protect your content, but this won't work for our small business association, since it may need to revoke permissions from a user for non-payment of dues. (If an ex-member of our association user-bookmarked an item, and it's still “visible”, the ex-member will still be able to see the content.) So the first thing to do is add a new “state” to our system. Using the ZMI:
Now try it out. In the root folder of your Plonesite, create a document called "ordinary" (using the Plone interface) and publish it. Create another document called "superduper" and make it a premium document. Using another browser (or after closing and reopening your browser): Using another browser (or after closing and reopening your browser):
This is the theory behind what we just did. If you're in a hurry, feel free to skip down to “Handling the SIGs” for another walkthrough. But here's a short version:
So at runtime, a user is in a group, which is associated with some roles, which are themselves collections of permissions. StatesThe key to all this is the Plone concept of a “state”. While states do many things:, the important thing for this example is that they contain a template for permissions. That's what we're changing when we go to the “permissions” tab for our “premium” state. So if you look at that permissions tab (remember, you see it through the ZMI by going to plone_workflow->states->premium->permissions), you realize that the nice folks at Plone have cut down the huge list of permissions available through the ZMI “security” tab to a manageable list. For non-folderish things (like documents), you only care about:
The workflow for folders is similar, and found in the folder_workflow. For folders, you care about the above three permissions, plus:
“Role” is a Zope concept: it is actually just a collection of permissions. If you look at the list of roles in Zope (across the top on any of the “security” pages), you will see:
Note that any user who has any role beyond “Anonymous” implicitly gets all the permissions granted to the “Authenticated” role by means of acquisition. (Because you have to be authenticated for the system to know that you have another role.) As a general rule, you should not grant “modify portal content” permissions to the “Authenticated” role, because that would allow any authenticated user (i.e., any logged-in user) to modify content, regardless of their other roles. The other dimension of acquisition comes from the "Acquire Permission Settings" checkbox. If this is checked, then any permissions from the folder that contains the object automatically apply to the object. Handling the SIGsIf you've gotten this far, you're probably asking yourself, “Why on earth do I have to go through 11 steps just to limit content to a subset of the public? That's crazy.” And the answer is: this is a complicated problem. Security in Zope (and therefore in Plone) is very fine-grained. It gives you a lot of control, but it can be a pain to set up. On the other hand, once it's done, it's done. Let us recall the issue with SIGs. A user can be a subscriber, and belong to zero, one, or more SIGs. That sounds like a permissions problem, doesn't it? Further, when you think “permissions,” you need to think “roles” and “states”. So now you need to go back and add a new state – which we will call “sig” - a corresponding transition called “makesig”, and a role called “sigMember”. (Think of this as an exercise.) add a group called “sigMembers” (via Plone) and then associate “sigMembers” with “sigMember” via the ZMI. Remember: when you are setting up the permissions template for the “sig” state, don't assign permissions to “subscriber,” assign them to “sigMember”. Now back to the Plone interface.
Now it's time to try this out. As “Manager”, go into the animal folder and create a document called “tiger”. Change its state to “sig”. Go into the vegetable folder and add a document called “carrot”. change its state to “sig” as well. Next, log out of the “manager” account and log in as “andy”. Go to the animal folder and click on “tiger”. You should be able to see the document. While still logged in as “andy”, go to the “vegetable” folder. You shouldn't be able to see anything, since “andy' doesn't have viewing rights in the vegetable folder. If you try to fake out the system by going directly to the “carrot” document (http://localhost:8080/myplonesite/vegetable/carrot), you should get an “insufficient privileges” report. Try the corresponding things now after logging in as “vera”. Did you get what you expected? What's Going on Here, II?The only new concept that we've used here is “local role.” A “local role” permits you to give all the permissions of a role to a user within a specified folder. Within our “animal” folder, any member of animalSig (such as Andy) is treated as having the SIG role, and is able to read the content. Anyone who is not a member of animalSig (such as Vera) is just an ordinary member, and isn't allowed to read the content. Because we have different folders, we can create different local roles inside each one, so we don't have to create a different role for each SIG. The added bonus is that non-technical folks can manage this through the Plone interface, which is a lot less daunting (and a lot safer) than giving them access to the ZMI. One question you might ask at this point is, “Instead of adding the 'sigMember' role, couldn't we have just created a local role for 'subscriber'?” The answer is, “not in this case.” Remember that we have two different levels of permissions – subscriber and SIG member. If we hadn't created the “sigMember” role, we couldn't prevent a subscriber from seeing all the information for all the SIGs. This we don't want to do, as the SIG members pay for the privilege of having access to a SIG. Adding a Collaborative “Coursework” AreaThe last problem we're going to try to solve is that of setting up special areas for courses. There are two things to remember. First, the course instructor needs to be able to create and manage documents (syllabus, assignments, course notes) within the folder for his course. Second, we want a way for students to be able to ask and answer questions. One note about this section: I've intentionally included some “false paths” in this section – not to confuse you, but to help you recognize common mistakes and how to correct them. Let's start by creating a new folder at the root level called “courses.” Inside the “courses” folder, add two more folders, “basketweaving” and “pottery”. Publish all three folders. We're going to add a new member, “Bob,” to the site. Bob is going to be our basket weaving instructor. Go to the “basket weaving” folder, and click on the “sharing” tab. Halfway down the page, you can search for an individual user: search for Bob. Now we have a choice of what role Bob should play within the basket weaving folder.
For the purposes of this tutorial, we're going to treat a group of students enrolled in a class as just another SIG. So we want Bob to be able to create content within the folder and publish it to users who have the SIG role within the folder. Assign Bob the “Reviewer” and “Owner” roles (you'll have to go through the process once for each role), and let's try it out. Log in to your Plonesite as Bob, and go to the Basket Weaving folder. Create a document. Publish it to the SIG. And watch the document disappear! What happened? Well, Bob has the right to publish to the SIG, but he is not a member of the SIG, which means he doesn't have the right (“permission”) to view content in the SIG. So the solution is to go back to the “sharing” tab, find Bob again, and add the “sigMember” role to Bob. Now it's time to create students in the class. We want students to have the “Member” role within the folder (so that they can create and submit content), and the “sigMember” role so that they can see content. But constantly having to go back and add both roles to each student is going to drive us crazy, especially if we have a lot of students. The solution is to create a new group. Using the Plone interface as “Manager”, go to the “plone setup” section, then to “user and group administration”. Create a new group called “students”, and give it “Member” and “sigMember” roles. Now add a user called “sam” and add him to the “students” group. Log in as Sam, and try to see what's in the “Basket Weaving” folder. You should be able to see it. Try to add a document. You should be able to add and submit it (but not to publish it). Log out as Sam and log in as Bob. The document that Sam created should be in your (Bob's) review list. This means that Bob can edit the document, adding his responses, and then publish the document to the SIG. (In reality, you would create a Discussion Board within your site and grant permissions to that, but product installation is beyond the scope of this article.) Two notes about this example. The first is that because we gave Bob the “Reviewer” role, Bob has the right to publish content to the public, or even publish “premium” content. In reality, you may not want to give Bob all these permissions (then again, you might). If you wanted to limit Bob so that he can only publish to the SIG, you can do it, but that's a more advanced topic, dealing with transitions and permissions. The second note is that if you have a lot of courses, you might want to create an “instructor” group and use that for assigning permissions to your instructors. TroubleshootingWhen you're working with states, you're eventually going to get things “not quite right”. Some permission will be set wrong, and you may end up going into the ZMI to manually change permissions until you figure out the right combination of permissions. When this happens, there's a useful little button that will clean up any changes you might have made during your experiments and put you back in a “known” state. If you go to the ZMI, then to portal_workflow for your Plonesite, and scroll down to the bottom of the page, there's a button marked “Update security settings.” What this will do is go through every workflow-aware object in your Plonesite and re-set the permissions as defined for each state. If you get confused about the roles within a site, go look at the states in the workflow.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| ZopeMag is committed to bringing you the best in Zope Documentation. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() |
Reproduction of material from any of ZopeMag's pages without prior written permission is strictly prohibited. Copyright 2003 - 2005 ZopeMag |
|