Authorization checks

We have three authorization rules to implement, so let's go one by one.

Authorizing event creation

User A can create an event for himself.

Let's do what Joey says. "Himself" in the sentence means, to Talos, the object called "Object:[id]" with the id of the user, received by the action as its authorId, so the code looks like:

public boolean authorize(String subject) {
  return getTalos().withSubjects(subject)
    .andObject("Object:" + author.getId())
    .isAllowed("add event");
}

Neat, isn't it? Use this code to show the form (in CreateEvent). To save the data (in SaveEvent), just create first the PObject author:

public boolean authorize(String subject) {
    PObject author = event.get("author");
    return getTalos().withSubjects(subject)
        .andObject("Object:" + author.getId())
        .isAllowed("add event");
}

Granting rights to new events

There's something else to implement here:

User A can modify and/or delete events created by A.

Everytime I create an event, I need to create a secure object for it in Talos. This is part of the action's execution step (SaveEvent), so we add some code to id:

 public String execute() throws Exception {
  //... omitted code
  getRepository().commit();
  setAccessRights();
  getTalos().commit();
  return SUCCESS;
}

We will also create a protected method, so that other people can evolve the access rights management like we did in SaveUser before:

protected void setAccessRights() {
  ObjectContainer oc = this.getTalos()
    .createObject("Object:" + event.getId());
  oc.andSubject("User:" + getAuthor().getId())
    .grant("modify", "delete");
}

Authorizing modification

After we granted rights on the event to the user, you can guess what the authorization for EditEvent and UpdateEvent looks like:

public boolean authorize(String subject) {
  return getTalos().withSubjects(subject)
    .andObject("Object:" + event.getId())
    .isAllowed("modify");
}

Event deletion

The authorization in DeleteEvent is also obvious:

public boolean authorize(String subject) {
  return getTalos().withSubjects(subject)
    .andObject("Object:" + event.getId())
    .isAllowed("delete");
}

But there's something to do after the event is deleted, right? Let's do it right inside the execute method:

public String execute() throws Exception {
  //... omitted code
  event.delete();
  getRepository().commit();
  getTalos().withObjects("Object:" + event.getId())
    .remove();
    getTalos().commit();
  //... omitted code
  return SUCCESS;
}

Event visualization

The final rule reads:

User A can see an event created by user B if it can see B's profile.

Seeing B's profile means having "view" permission on B, so the check in ViewEvent is this:

public boolean authorize(String subject) {
  PObject author = this.getEvent().get("author");
  return getTalos().withSubjects(subject)
    .andObject("Object:" + author.getId())
    .isAllowed("view");
}

The case of ListEvents is even simpler:

public boolean authorize(String subject) {
  return getTalos().withSubjects(subject)
    .andObject("Object:" + author.getId())
    .isAllowed("view");
}

Conclusion

Authorization is really simple: it uses Talos and relies on the authorization interceptor, which calls the authorize() method for each action.

We recommend you think about authorization as early as possible in your design.

Please send us comments, questions, criticism:

Please send us comments, questions, criticism!