|
| Subject | Action | Predicate |
| Admin | create, list, view, modify, delete | Zone |
| Admin | create, list, view, modify, delete, change_members, move | Group |
| Admin | create, list, view, modify, delete, change_password | User |
| Normal User | list, view | Zone |
| Normal User | list | Group |
| Normal User | list, view | User |
| Normal User | list, view, modify, delete, change_password | User (itself) |
We create a special permission called "add event" that we add to all subjects on their own user objects. For the other operations, we will use the permissions already existing in MUM.
ObjectsTalos calls the object of an action for which there is authorization a secure object.
MUM users, zones and groups are Marbles objects (as are Joey's Event objects). They are represented in Talos by secure objects with unique names using the convention Object:[persistent id], where persistent id is the object's unique identifier in the Marbles repository.
SubjectsThey are provided by the authorization interceptor based on the authenticated user. Currently, they are of the form User:[persistent id].
Teaching Talos to handle new objectsIn Joey's event tracking application, the subjects are everytime MUM users. The actions he added are the operations on event, and the objects are events themselves. Here are the authorization rules that Joey designed:
Something like this:
| Subject | Action | Predicate |
| Admin | add_event, list, view, modify, delete | Event (itself) |
| Admin | list, view | Event (if he can see the owner's profile) |
| Normal User | add_event, list, view, modify, delete | Event (itself) |
| Normal User | list, view | Event (if he can see the owner's profile) |
It's not deja-vu, the TalosCreator (org.mum.installation.TalosCreator) interface looks just like the Model Creator we've seen in chapter 2:
isUpdateNeeded(Talos talos):booleanupdate(Talos talos, Repository repo):voidWith Talos, we have made it. It is sooooo easy that Joey can do it while talking to Karen on the phone.
What you did in chapter 2 for the ModelCreator, is what you need to do for the TalosCreator as well:
(org.mum.installation.MumTalosCreator).ApplicationContext.xmlLetīs start with the first point. Create org.mumtutorial.installation.TutorialTalosCreator. This is how the code looks like:
public void update(Talos talos, Repository repo) {
if (super.isUpdateNeeded(talos)) {
super.update(talos, repo);
}
if (!talos.allPermissions().contains("add event")) {
talos.createSimplePermissions("add event");
}
}
public boolean isUpdateNeeded(Talos talos) {
return super.isUpdateNeeded(talos) ||
!talos.allPermissions().contains("add event");
}
Adding permissions to existing usersJoey, hang up! You forgot to add the permission for all users that might already be there. "Allright," he says, "how do I get the user keys?"
Now we use the repository to query some the user objects and get keys of the form Object:[id]. The method looks like this:
protected List<String> fetchUserKeys(Repository repo) {
List<String> names = new ArrayList<String>();
for (PObject obj : repo.createFilter("User").list()) {
names.add("Object:" + obj.getId());
}
return names;
}
With this piece of code, we can grant existing users the add event access right in org.mumtutorial.installation.TutorialTalosCreator.update():
if (!talos.allPermissions().contains("add event")) {
talos.createSimplePermissions("add event");
List<String> names = fetchUserKeys(repo);
if (!names.isEmpty()) {
talos.allSubjects()
.andObject(names.toArray(new String[names.size()]))
.grant("add event");
}
}
I should let Joey himself explain it to you, but since he doesn't exist, I'll tell you what he'd say:
— In my app, a subject is always a user. So all subjects means "all users". I'm giving permissions on users, so the objects I'm manipulating are also users. The Talos code says "grant add event and save event on the objects with the name in names to all subjects."
He's right. By the time the first grant is called, we're working on a set of pairs (subject, object) which represents all subjects matched to all objects. Further details on the Talos documentation
Adding permissions to new usersNow to the users that don't exist yet. Once again, we edit the SaveUser (org.mum.action.user.SaveUser) action. Currently, the user creation action creates a subject for the user, then a secure object (i.e. a Talos object) that belongs to the "users" category. Then it grants rights to change the password and modify himself, then list and view all zones, users and groups.
Here's what it will look like after we're done:
protected void setAccessRights() {
//create a subject for the user
SubjectContainer subject = getentenTalos().createSubject("User:" + user.getId());
//name of the user's secure object
String objectName = "Object:" + user.getId();
//create a secure object and add to the users category
getTalos().createObject(objectName)
.addCategories("users");
//grant some rights
subject.andObject(objectName)
.grant(AuthorizationConstants.ALL_PERMISSION)
.grant("add event");
subject.andCategory("zones", "users", "groups")
.grant("list", "view");
if(getCurrentUser() != null){
getTalos().withSubjects("User:" + getCurrentUser().getId())
.andObject("Object:"+ getUser().getId())
.grant("change password", "modify", "delete", "move");
}
}
We just added the add event permission to the grants for the user on itself.
Adding permissions to existing eventsThis section is a spoiler somehow, because we introduce the rights for events on the next page. But since this is TalosCreator related, it fits here better.
What we did for existing users previously is needed for existing events as well. We need to add rights to an event which permit the author to modify and delete the event.
To get all existing events add another method to org.mumtutorial.installation.TutorialTalosCreator:
protected List<Long> fetchEventIds(Repository repo) {
List<Long> ids = new ArrayList<Long>();
for (PObject obj : repo.createFilter("Event").list()) {
ids.add(obj.getId());
}
return ids;
}
Ok, let`s add the necessary rights for the old events then:
public void update(Talos talos, Repository repo) {
if (super.isUpdateNeeded(talos)) {
super.update(talos, repo);
}
if (!talos.allPermissions().contains("add event")) {
talos.createSimplePermissions("add event");
}
List<String> names = fetchUserKeys(repo);
if (!names.isEmpty()) {
talos.allSubjects().andObject(
names.toArray(new String[names.size()]))
.grant("add event");
}
List<Long> objectsIds = fetchEventIds(repo);
for (Long objectId : objectsIds) {
ObjectContainer oc = talos.createObject("Object:" + objectId);
PObject author = repo.load(objectId).get("author");
oc.andSubject("User:" + author.getId()).grant("modify", "delete");
}
}
Wiring the TalosCreatorWe'll have to add our creator to the ApplicationContext. Open the file /config/ApplicationContext.xml and change the class of the talos creator:
<bean
class="org.mum.installation.MumTalosCreator"
id="talosCreator"
name="TalosCreator"
singleton="true" />
to look like this:
<bean
class="org.mumtutorial.installation.TutorialTalosCreator"
id="talosCreator"
name="TalosCreator"
singleton="true" />
Now let's restart the application and secure our event management actions!
Please send us comments, questions, criticism!