JBoss Community Archive (Read Only)

PicketBox

EntitlementsManager

EntitlementsManager is a manager that can improve performance over the enforcement model.  Rather than make 100 authorization/enforcement calls, the EntitlementsManager helps to retrieve all the entitlements, a User (under a particular context) has, with one call. This is very useful for rich client applications that want to minimize network traffic. This is also very critical in a REST style architecture.

At PicketBox, we do not let the EntitlementsManager to do any access decision. All it does is saves entitlements in the way/form the user wants. It just gives back the entitlements a particular User has in a specific context.

Implementations

DefaultEntitlementsManager

This is the default implementation of the EntitlementsManager interface.  The fully qualified class name is org.picketbox.core.authorization.ent.impl.DefaultEntitlementsManager

Let us look at the interfaces and classes that comprise the entitlements.

The primary construct is the Entitlement.

package org.picketbox.core.authorization.ent;

/**
 * Interface to indicate an entitlement
*/
public interface Entitlement {
    String COLON = ":";
    String COMMA = ",";
    String OPEN_PAREN = "{";
    String CLOSE_PAREN = "}";

    /**
     * JSON Representation
     *
     * @return json representation
     */
    String json();
}

The Entitlement interface is an open interface that requires a representation in the JSON format.

Look at the examples section below to create specific instances of Entitlement.

There is an EntitlementCollection that is similar to Java Collections. This stores entitlements as an unit.

There is an EntitlementStore interface. This represents storage of entitlements at the User, Role and Group levels.

We provide one concrete implementation of the EntitlementStore namely InMemoryEntitlementStore. Look at examples below for usage.

We plan to provide a JPA based implementation soon.

Examples

The following test case highlights the usage.

/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2012, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.picketbox.test.authorization.ent;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.picketbox.core.UserContext;
import org.picketbox.core.authorization.Resource;
import org.picketbox.core.authorization.ent.Entitlement;
import org.picketbox.core.authorization.ent.EntitlementCollection;
import org.picketbox.core.authorization.ent.EntitlementStore;
import org.picketbox.core.authorization.ent.EntitlementsManager;
import org.picketbox.core.authorization.ent.impl.DefaultEntitlementsManager;
import org.picketbox.core.authorization.ent.impl.SimpleEntitlement;
import org.picketbox.core.authorization.impl.SimpleResource;
import org.picketlink.idm.model.Group;
import org.picketlink.idm.model.Role;
import org.picketlink.idm.model.SimpleGroup;
import org.picketlink.idm.model.SimpleRole;
import org.picketlink.idm.model.SimpleUser;
import org.picketlink.idm.model.User;

/**
 * Unit test the {@link EntitlementsManager} using the classic Unix File Permissions use case
 *
 * @author anil saldhana
 * @since Oct 25, 2012
 */
public class FileDirectoryEntitlementsUseCase {
    private EntitlementsManager mgr = null;

    private User useranil = new SimpleUser("anil");
    private Role employee = new SimpleRole("employee");
    private Group jboss = new SimpleGroup("1", "jboss", null);

    @Before
    public void setup() throws Exception {
        DefaultEntitlementsManager dm = new DefaultEntitlementsManager();

        // We have a directory called "home"
        DirResource home = new DirResource("home");
        DirResource anil = new DirResource("anil");
        home.add(anil); // /home/anil

        FileResource fileA = new FileResource("filea");
        FileResource fileB = new FileResource("fileb");
        FileResource fileC = new FileResource("filec");
        DirResource work = new DirResource("work");

        // anil directory has 3 files and 1 directory called work
        anil.add(fileA).add(fileB).add(fileC).add(work);

        Entitlement readEntitlement = new SimpleEntitlement("read");
        Entitlement writeEntitlement = new SimpleEntitlement("write");
        Entitlement executeEntitlement = new SimpleEntitlement("execute");

        EntitlementCollection rwx = EntitlementCollection.create("rwx", new Entitlement[] { readEntitlement, writeEntitlement,
                executeEntitlement });
        EntitlementCollection rw = EntitlementCollection.create("rwx", new Entitlement[] { readEntitlement, writeEntitlement });
        EntitlementCollection r = EntitlementCollection.create("rwx", new Entitlement[] { readEntitlement });

        EntitlementStore store = dm.store();
        store.addUserEntitlements(fileA, useranil, rwx);
        store.addUserEntitlements(fileB, useranil, rwx);
        store.addUserEntitlements(fileC, useranil, rwx);
        store.addUserEntitlements(work, useranil, rwx);

        store.addRoleEntitlements(fileA, employee, rw);
        store.addRoleEntitlements(fileA, employee, rw);
        store.addRoleEntitlements(fileA, employee, rw);
        store.addRoleEntitlements(fileA, employee, rw);

        store.addGroupEntitlements(fileA, jboss, r);
        store.addGroupEntitlements(fileA, jboss, r);
        store.addGroupEntitlements(fileA, jboss, r);
        store.addGroupEntitlements(fileA, jboss, r);

        mgr = dm;
    }

    @Test
    public void testFilePermissions() throws Exception {
        Resource fileA = new FileResource("filea");
        UserContext userContext = new UserContext();
        List<Role> roles = new ArrayList<Role>();
        roles.add(employee);

        List<Group> groups = new ArrayList<Group>();
        groups.add(jboss);

        userContext.setUser(useranil).setRoles(roles).setGroups(groups);

        EntitlementCollection enCollection = mgr.entitlements(fileA, userContext);
        assertTrue(enCollection.contains(new SimpleEntitlement("read")));
        assertTrue(enCollection.contains(new SimpleEntitlement("write")));
        assertTrue(enCollection.contains(new SimpleEntitlement("execute")));

        // Change the user context a bit to check roles have write permission
        userContext = new UserContext();
        userContext.setUser(new SimpleUser("Bond")).setRoles(roles).setGroups(groups);
        enCollection = mgr.entitlements(fileA, userContext);
        assertTrue(enCollection.contains(new SimpleEntitlement("read")));
        assertTrue(enCollection.contains(new SimpleEntitlement("write")));
        assertFalse(enCollection.contains(new SimpleEntitlement("execute")));

        // Change the user context a bit to check groups have read permission
        userContext = new UserContext();
        userContext.setUser(null).setRoles(null).setGroups(groups);
        enCollection = mgr.entitlements(fileA, userContext);
        assertTrue(enCollection.contains(new SimpleEntitlement("read")));
        assertFalse(enCollection.contains(new SimpleEntitlement("write")));
        assertFalse(enCollection.contains(new SimpleEntitlement("execute")));
    }

    @Test
    public void testBadUserFilePermissions() throws Exception {
        Resource fileA = new FileResource("filea");
        UserContext userContext = new UserContext();
        List<Role> roles = new ArrayList<Role>();
        roles.add(new SimpleRole("banned"));

        List<Group> groups = new ArrayList<Group>();
        groups.add(new SimpleGroup("2", "bannedgroup", null));

        userContext.setUser(new SimpleUser("baduser")).setRoles(roles).setGroups(groups);

        EntitlementCollection enCollection = mgr.entitlements(fileA, userContext);
        assertFalse(enCollection.contains(new SimpleEntitlement("read")));
    }

    public static class FileResource extends SimpleResource implements Resource {
        private static final long serialVersionUID = 1L;

        public FileResource(String name) {
            super(name);
        }
    }

    public static class DirResource extends FileResource implements Resource {
        private static final long serialVersionUID = 1L;
        private List<FileResource> files = new ArrayList<FileResource>();

        public DirResource(String name) {
            super(name);
        }

        public DirResource add(FileResource file) {
            this.files.add(file);
            return this;
        }

        public DirResource add(List<FileResource> files) {
            this.files.addAll(files);
            return this;
        }
    }
}

This test case tries to model the classic FileSystem permission model in the Unix world. There are permissions on Files and Directories at the User level, Role level and Group level.

Let us explain the test case further.

In this case, we have two Resources - a FileResource and a DirResource. A DirResource is just a collection of DirResource and/or FileResource.  This is from the UNIX file system world.

We use the DefaultEntitlementsManager and use its underlying default EntitlementStore via the .store() call and save our entitlements for the User, Role and Group.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 12:16:22 UTC, last content change 2012-11-05 18:04:11 UTC.