Java tutorial
/* * 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