com.silverwrist.dynamo.security.AclObject.java Source code

Java tutorial

Introduction

Here is the source code for com.silverwrist.dynamo.security.AclObject.java

Source

/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002-03 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.dynamo.security;

import java.security.Principal;
import java.security.acl.*;
import java.util.*;
import org.apache.commons.collections.*;
import com.silverwrist.dynamo.db.NamespaceCache;
import com.silverwrist.dynamo.db.UserProxyManagement;
import com.silverwrist.dynamo.except.*;
import com.silverwrist.dynamo.iface.*;
import com.silverwrist.dynamo.util.*;

class AclObject implements DynamoAcl {
    /*--------------------------------------------------------------------------------
     * Attributes
     *--------------------------------------------------------------------------------
     */

    private AclOperations m_ops; // ACL operations object
    private NamespaceCache m_ns_cache; // namespace cache object
    private UserProxyManagement m_proxy; // for generating user and group proxies
    private AceCache m_ace_cache; // cache for ACEs
    private int m_aclid; // ID of this ACL
    private String m_aclname; // name of this ACL

    /*--------------------------------------------------------------------------------
     * Constructor
     *--------------------------------------------------------------------------------
     */

    AclObject(AclOperations ops, NamespaceCache ns_cache, UserProxyManagement proxy, AceCache ace_cache, Map data) {
        m_ops = ops;
        m_ns_cache = ns_cache;
        m_proxy = proxy;
        m_ace_cache = ace_cache;
        m_aclid = ((Integer) (data.get(SRMOperations.HMKEY_ACLID))).intValue();
        m_aclname = ((String) (data.get(SRMOperations.HMKEY_ACLNAME)));

    } // end constructor

    /*--------------------------------------------------------------------------------
     * Internal operations
     *--------------------------------------------------------------------------------
     */

    private static final int getAceID(AclEntry entry) {
        if (entry instanceof DynamoAce)
            return ((DynamoAce) entry).getAceID();
        throw new IllegalArgumentException("expected a DynamoAce as argument");

    } // end getAceID

    private final PropertyKey getPKey(Permission perm) throws DatabaseException {
        if (perm instanceof PermObject)
            return ((PermObject) perm).getPKey();
        if (perm instanceof DynamoPermission) { // convert to a PropertyKey
            DynamoPermission dp = (DynamoPermission) perm;
            return new PropertyKey(m_ns_cache.namespaceNameToId(dp.getNamespace()), dp.getName());

        } // end if

        throw new IllegalArgumentException("expected DynamoPermission as argument");

    } // end getPKey

    /*--------------------------------------------------------------------------------
     * Implementations from interface Owner
     *--------------------------------------------------------------------------------
     */

    public boolean addOwner(Principal caller, Principal owner) throws NotOwnerException {
        try { // call down to the database
            return m_ops.addOwner(m_aclid, new PrincipalID(caller), new PrincipalID(owner));

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end addOwner

    public boolean deleteOwner(Principal caller, Principal owner) throws NotOwnerException, LastOwnerException {
        try { // call down to the database
            return m_ops.deleteOwner(m_aclid, new PrincipalID(caller), new PrincipalID(owner));

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end deleteOwner

    public boolean isOwner(Principal owner) {
        try { // call down to the database
            return m_ops.testOwner(m_aclid, new PrincipalID(owner));

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end isOwner

    /*--------------------------------------------------------------------------------
     * Implementations from interface Acl
     *--------------------------------------------------------------------------------
     */

    public void setName(Principal caller, String name) throws NotOwnerException {
        try { // call down to the database
            m_ops.setAclName(m_aclid, new PrincipalID(caller), name);
            m_aclname = name;

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end setName

    public String getName() {
        return m_aclname;

    } // end getName

    public boolean addEntry(Principal caller, AclEntry entry) throws NotOwnerException {
        try { // call down to the database
            return m_ops.insertAce(m_aclid, new PrincipalID(caller), getAceID(entry), -1);

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end addEntry

    public boolean removeEntry(Principal caller, AclEntry entry) throws NotOwnerException {
        try { // call down to the database
            return m_ops.removeAce(m_aclid, new PrincipalID(caller), getAceID(entry));

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end removeEntry

    public Enumeration getPermissions(Principal user) {
        PrincipalID prid = new PrincipalID(user);
        Collection rc = null;
        try { // is this for a user or a group?
            if (prid.isGroup()) { // compute permissions only for the group itself
                // (everything that appears in positive set but not in negative set)
                Set positive = m_ops.getGroupPermissionSetForGroup(m_aclid, prid.getID(), false);
                Set negative = m_ops.getGroupPermissionSetForGroup(m_aclid, prid.getID(), true);
                rc = CollectionUtils.subtract(positive, negative);

            } // end if
            else { // compute permissions for the user and for all groups of which the user is a member
                Set pos_group = m_ops.getGroupPermissionSetForUser(m_aclid, prid.getID(), false);
                Set neg_group = m_ops.getGroupPermissionSetForUser(m_aclid, prid.getID(), true);
                Set pos_user = m_ops.getUserPermissionSet(m_aclid, prid.getID(), false);
                Set neg_user = m_ops.getUserPermissionSet(m_aclid, prid.getID(), true);
                // "Real" groups have been normalized by removing all elements present in the corresponding
                // "other" group as well
                Collection real_pos_group = CollectionUtils.subtract(pos_group, neg_group);
                Collection real_neg_group = CollectionUtils.subtract(neg_group, pos_group);
                Collection real_pos_user = CollectionUtils.subtract(pos_user, neg_user);
                Collection real_neg_user = CollectionUtils.subtract(neg_user, pos_user);
                // "grant_group" = all permissions granted by the groups and not explicitly denied by user
                Collection grant_group = CollectionUtils.subtract(real_pos_group, real_neg_user);
                // "deny_group" = all permissions denied by the groups and not explicitly granted by user
                Collection deny_group = CollectionUtils.subtract(real_neg_group, real_pos_user);
                // "grant" - all grants from user plus all surviving grants from groups
                Collection grant = CollectionUtils.union(real_pos_user, grant_group);
                // "deny" - all denies from user plus all surviving denies from groups
                Collection deny = CollectionUtils.union(real_neg_user, deny_group);
                rc = CollectionUtils.subtract(grant, deny);

            } // end else

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

        // Compute the proper return value.
        if (rc.isEmpty())
            return Collections.enumeration(Collections.EMPTY_LIST);
        ArrayList real_rc = new ArrayList(rc.size());
        Iterator it = rc.iterator();
        while (it.hasNext()) { // transform PropertyKey values into PermObjects
            PropertyKey pk = (PropertyKey) (it.next());
            real_rc.add(new PermObject(pk, m_ns_cache));

        } // end while

        return Collections.enumeration(real_rc);

    } // end getPermissions

    public Enumeration entries() {
        try { // get the IDs of all the ACEs
            int[] ids = m_ops.getAceIDs(m_aclid);

            // now get the ACEs themselves
            ArrayList rc = new ArrayList(ids.length);
            for (int i = 0; i < ids.length; i++)
                rc.add(m_ace_cache.getAce(ids[i]));
            return Collections.enumeration(rc);

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end entries

    public boolean checkPermission(Principal principal, Permission permission) {
        PrincipalID prid = new PrincipalID(principal);
        try { // test user or group permissions, depending
            if (prid.isGroup())
                return m_ops.testGroupPermission(m_aclid, prid.getID(), getPKey(permission));
            else
                return m_ops.testUserPermission(m_aclid, prid.getID(), getPKey(permission));

        } // end try
        catch (DatabaseException e) { // translate this into a SecurityRuntimeException
            throw new SecurityRuntimeException(e);

        } // end catch

    } // end checkPermission

    public String toString() {
        return "DynamoAcl[" + m_aclid + "]: " + m_aclname;

    } // end toString

    /*--------------------------------------------------------------------------------
     * Implementations from interface DynamoAcl
     *--------------------------------------------------------------------------------
     */

    public int getAclID() {
        return m_aclid;

    } // end getAclID

    public int getAceCount() throws DatabaseException {
        return m_ops.getAceCount(m_aclid);

    } // end getAceCount

    public DynamoAce getAce(Principal caller, int index) throws DatabaseException, NotOwnerException {
        if (index < 0)
            throw new IndexOutOfBoundsException("ACE index less than 0");

        // get the ACE ID from the database and then get it from the ACE cache
        return m_ace_cache.getAce(m_ops.getAceID(m_aclid, new PrincipalID(caller), index));

    } // end getAce

    public DynamoAce getMatchingAce(Principal caller, Principal target, boolean negative)
            throws DatabaseException, NotOwnerException {
        int aid = m_ops.getMatchingAceID(m_aclid, new PrincipalID(caller), new PrincipalID(target), negative);
        if (aid < 0)
            return null;
        return m_ace_cache.getAce(aid);

    } // end getMatchingAce

    public int getIndexOfAce(Principal caller, DynamoAce ace) throws DatabaseException, NotOwnerException {
        return m_ops.getIndexOfAceIDInAcl(m_aclid, new PrincipalID(caller), ace.getAceID());

    } // end getIndexOfAce

    public boolean insertEntry(Principal caller, AclEntry entry, int at_index)
            throws DatabaseException, NotOwnerException {
        // call down to the database
        return m_ops.insertAce(m_aclid, new PrincipalID(caller), getAceID(entry), at_index);

    } // end insertEntry

    public boolean testPermission(DynamoUser user, String perm_namespace, String perm_name)
            throws DatabaseException {
        // call down to the database
        return m_ops.testUserPermission(m_aclid, user.getUID(),
                new PropertyKey(m_ns_cache.namespaceNameToId(perm_namespace), perm_name));

    } // end testPermission

} // end class AclObject