Talos Logo Full documentation

Talos release 0.5.2

These are the topics we deal with:

This section assumes you have read the overview, but not that you understood it completely.

1. Download and configuration

You can download Talos2 from sourceforge. If you indend to use Ivy, you can declare a dependency on Talos2 using the following line in your ivy.xml:

<dependency org="os-kit" name="talos2" rev="0.5" conf="build,default" />

Configuring your environment

You need to configure the Hibernate access, as per the Hibernate configuration documentation. The mappings are configured in the hibernate.cfg.xml file. This is how it looks like for Talos 0.5:

<!-- hibernate.cfg.xml -->

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Mappings -->
        <mapping class="org.talos.model.Capability"/>
        <mapping class="org.talos.model.Category"/>
        <mapping class="org.talos.model.GroupPermission"/>
        <mapping class="org.talos.model.Permission"/>
        <mapping class="org.talos.model.SecureObject"/>
        <mapping class="org.talos.model.SimplePermission"/>
        <mapping class="org.talos.model.Subject"/>
    </session-factory>
</hibernate-configuration>

2. General usage

Talos has a very small set of operations, all dealing with access rights. You can check access rights or permissions, in order to decide if some business logic can be executed by someone. And you can grant or revoke permissions to someone.

To make things easier to write and to explain, there are usually two steps you must perform:

  1. open a Talos instance
  2. select the elements you're manipulating. This means choose one or more subjects and one or more secure objects (or, alternatively, some subjects and some categories).
  3. grant, revoke or check permissions on them.

2.1. Accessing Talos

Talos uses Hibernate to access the database. You can instantiate a SessionFactory any way you wish and provide it to the TalosFactory's constructor. Or you can call TalosFactory.createDefault() to get a new instance. We recommend that you use an IoC container, but it isn't required in any way.

Each time you want to access the repository, you must open a new Talos instance from the factory, and close it at the end:

// open a new instance
Talos talos = factory.open();

// ... do something ...

// commit any changes you've done
talos.commit();

// close it when finished
talos.close();

Notice that you only need to call commit() if you're going to persist things. Otherwise, just call close() and Talos will take care of the cleanup.

What do you do with the Talos instance? Build containers, of course!

2.2. Containers

In order to grant, revoke or check permissions with Talos, you need to select a subset of the whole data to work with. Containers are objects that represent your selection. Some examples:

SubjectContainer sc = talos.withSubjects("mom", "dad", "Dave");
ObjectContainer oc = talos.allObjects();
CategoryContainer cc = talos.createCategory("music");
PermissionContainer pc = talos.createSimplePermissions("eat", "drink", "be merry");

2.2.1. Management operations

Containers usually perform management operations on the selected data. For example, after creating the category tools, you might want to add some data to it:

CategoryContainer cc = talos.createCategory("tools");
cc.addObjects("screw driver", "hammer", "plier");

Or let's say you want do delete some permissions:

pc.remove();

The containers also provide a few collection methods such as contains(String), list() and isEmpty(). Refer to the javadoc of the Container interface for more details.

2.2.2. Combining containers

Once you select some subjects and some secure objects, you can grant, revoke or check access rights on them. The following are equivalent ways to do the same:

// first way:
talos.withSubjects("Chuck Norris")
  .andCategories("people")
  .grant("round kick");

// second way:
talos.withCategories("people")
  .andSubjects("Chuck Norris")
  .grant("round kick");

// third way:
SubjectContainer sc = talos.withSubjects("Chuck Norris");
CategoryContainer cc = talos.withCategories("people");
PermissionContainer pc = talos.withPermissions("round kick");

sc.andCategories(cc.list()).grant(pc.list());

Chuck Norris round kicking isn't funny, but I think the message gets through.

2.3. The Bouncer

Talos allows you to grant, revoke and check access rights once you have a bouncer. to get your hands on one, you need to combine containers:

Bouncer bouncer = talos.withSubjects("admin")
  .andObjects("one", "two", "three");

This bouncer can then be used to change permissions for the subject "admin" on the three objects. The bouncer can:

bouncer.isAllowed("delete") is semantically equivalent to listExpanded().contains("delete").

2.3.1 Permission inheritance

Consider the table below. Each entry defines a subject, either an object or a category, and a list of permissions.

Subject Object Category Permissions
Andy Mingau - -
Andy Kitty - stroke
Andy - cat feed

Assuming that Kitty belongs to the category cat, the following sentence is true:

talos.withSubject("Andy")
  .andObject("Kitty")
  .isAllowed("feed", "stroke");

Andy is allowed to feed and stroke Kitty because each object inherits the permissions of the categories they belong to. The bouncer also knows if any additional permissions are implied by the group permissions in the permission set too, so you always get the full list.

Talos fetches the information it in the most efficient fashion, using a big (yet simple) Hibernate query. The results are cached, so if you need to know if Andy can feed or stroke a cat, you can use:

bouncer bouncer = talos.withSubject("Andy")
  .andObject("Kitty");

if (bouncer.isAllowed("feed") || bouncer.isAllowed("stroke")) {
  display("Kitty is happy!");
}

3. Data model

Talos handles with the following entities:

Secure Object
the target or instrument of an operation, usually data, a process or a service
Subject
The entity that executes operations
Permission
A token that allows an operation to be executed
Category
a collection of secure objects that share a common meaning.

We'll describe each one in the following sections.

3.1. Simple and Group permissions

Permissions are uniquely identified by their name, but exist as entities in the system. There are two kinds of permissions:

One use for group permissions is to allow several simple permissions to be granted at once. Let's say an application has the typical "read", "write", "delete" simple permissions. I can instruct Talos to consider all of them by the name of "manage":

talos = factory.open();
talos.createGroupPermissions("manage");
talos.createSimplePermissions("read", "write", "delete")
  .addToGroup("manage");
talos.commit();

Notice that if I grant "manage" to a subject, it will end up with four permissions, the group permission plus all its implied permissions. Group permissions might come in handy, but don't forget that they are regular permissions as well. As such, merely granting read, write and delete access will not automatically grant "manage".

3.1.1. Single-level nesting

Notice you can't add group permissions to group permissions, thus building a permission tree. Some engines provide that. We chose to only support one nesting level because that can be efficiently implemented over a relational database. Besides, we think this feature is rarely needed: if you just need to group permissions, store an array of names somewhere.

public static final String[] MANAGE = {"read", "write", "delete"};
// somewhere else:
talos.withSubject(aSubject)
  .andObject(anObject)
  .grant(MANAGE);

3.2. Subjects

Subjects, as other Talos entities, are identified by a name. This name must be unique in respect to other subjects. Apart from that, there isn't much to talk about them.

Talos can manipulate several subjects in one operation, and it assumes you are talking about all of them. The code below illustrates that:

boolean allowed = talos.withSubjects("Andy", "Lisa")
  .andObjects("Kitty")
  .isAllowed("feed");

Talos will check if both Andy and Lisa have the specified permissions on the target object. Similarly, grant() and revoke() also operate on all given subjects.

boolean allowed = talos.withSubjectsOr("Andy", "Lisa")
  .andObjects("Kitty")
  .isAllowed("feed");

Now, Talos will check if Andy or Lisa have the specified permissions on the target object.

3.3. Secure Objects

Talos identifies secure objects by their name, as you've probably noticed. The name must be unique in respect to other objects, and it has no meaning at all, or relation to other entities. Just because there's a subject called "frog", one cannot assume anything about an object with the same name. It might exist or not, and if it exists, it might have a completely different meaning. The application is responsible for giving meaning to these names. Talos has only one job: managing access rights.

As with subjects, several objects can be manipulated in the same operation. Again, Talos assumes you are talking about all of them. The code below illustrates that:

boolean allowed = talos.withSubjects("Mary")
  .andObjects("Mingau", "Kitty")
  .isAllowed("feed");

The variable will be true if Andy has permission to feed both cats. If several permissions are checked, he must have all of them for all of the objects.

3.4. Object Categories

Most applications don't grant access rights to each individual object. This operation would be costly and can be avoided by the usage of categories. Categories are conceptual groupings of objects. Each category's name must be unique in respect to other categories.

In the overview, we add all cats to a category "cats", and then can grant access rights to the categories and have them inherited by the objects belonging to them.

talos.createCategory("cats")
  .addObjects("Mingau", "Kitty", "Spotty");
talos.withCategory("cats")
  .andSubject("Andy")
  .grant("feed");

Now Andy can feed all cats. If later I add a new cat and add it to the category, Andy will be able to feed it too. Of course, categories can be used more creatively.

4. Getting creative

How would we implement a friends list like the one in Flickr? Suppose I post some photos and I want to mark some users as friends and some pictures as "friends-only".

Since this refers mostly to authorization, we would be better off storing all this information in Talos. We'll create two categories:

Each time I create a new user, we grant them rights to public photos. Each time a user marks (or unmarks) someone as a friend, we grant (or revoke) access rights on the category:

public void markAsFriend(String friendName, boolean marked) {
  String actor = authentication.getCurrentUser();
  Bouncer bouncer = talos.withSubject(friendName).andCategory("friends of " + actor);
  if (marked) {
    bouncer.grant("view", "comment");
  }
  else {
    bouncer.revokeAll();
  }
}

What happens when user "max2006" posts a new photograph?

  1. a secure object for the photo is created, let's say "pic1234";
  2. he is granted direct access to the picture;
  3. if the photo is public, it gets added to the category public photos;
  4. if it's not public but marked as friends-only, it gets added to his friends list

The logic looks like this:

public void grantRights(String userName, String photoName, boolean public, boolean friends) {
  Talos talos = talosFactory.open();
  // 1. create object
  ObjectContainer container = talos.createObject(photoName);

  // 2. grant direct access
  container.andSubject(userName).grant("view", "delete", "modify");

  // 3. add to category if public
  if (public) {
    container.addCategory("publich photos");
  }
  // 4. add to friends list if marked friends-only
  else if (friends) {
    container.addCategory("friends of " + userName);
  }

  talos.commit();
}

This is better than storing authorization attributes directly in the model because it simplifies authorization checks:

public void viewPhoto(String photoName) {
  String actor = authentication.getCurrentUser();

  if (talos.withSubject(actor).andObject("photoName").isAllowed("view")) {
    // show picture
  }
}

SourceForge.net Logo

Did you find a typo? Something wrong? Something missing? Please let us know.

Ξ This documentation is written and maintained using Xilize. We use dead-links.com to check for broken links on this website.

Non-commercial, non-derivative use of this documentation is permitted.