You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tb...@apache.org on 2006/12/12 16:24:14 UTC
svn commit: r486187 [13/49] - in /directory/trunks/triplesec: ./ admin-api/
admin-api/src/ admin-api/src/main/ admin-api/src/main/java/
admin-api/src/main/java/org/ admin-api/src/main/java/org/safehaus/
admin-api/src/main/java/org/safehaus/triplesec/ a...
Added: directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapApplicationPolicyIntegrationTest.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapApplicationPolicyIntegrationTest.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapApplicationPolicyIntegrationTest.java (added)
+++ directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapApplicationPolicyIntegrationTest.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,818 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.safehaus.triplesec.guardian.ldap;
+
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.safehaus.triplesec.guardian.ApplicationPolicy;
+import org.safehaus.triplesec.guardian.ApplicationPolicyFactory;
+import org.safehaus.triplesec.guardian.ChangeType;
+import org.safehaus.triplesec.guardian.Permission;
+import org.safehaus.triplesec.guardian.PolicyChangeListener;
+import org.safehaus.triplesec.guardian.Profile;
+import org.safehaus.triplesec.guardian.Role;
+import org.safehaus.triplesec.integration.TriplesecIntegration;
+
+
+/**
+ * TestCase to test the LDAP ApplicationPolicyStore implementation.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class LdapApplicationPolicyIntegrationTest extends TriplesecIntegration
+{
+ private Object lockObject = new Object();
+ private String originalName;
+ private ChangeType changeType;
+ private Profile profile;
+ private Role role;
+ private Permission permission;
+ private LdapApplicationPolicy store;
+
+
+ public LdapApplicationPolicyIntegrationTest( String string ) throws Exception
+ {
+ super( string );
+ }
+
+
+ public LdapApplicationPolicyIntegrationTest() throws Exception
+ {
+ super();
+ }
+
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ Properties props = new Properties();
+ props.setProperty( "applicationPrincipalDN", "appName=mockApplication,ou=applications,dc=example,dc=com" );
+ props.setProperty( "applicationCredentials", "testing" );
+
+ Class.forName( "org.safehaus.triplesec.guardian.ldap.LdapConnectionDriver" );
+ store = ( LdapApplicationPolicy ) ApplicationPolicyFactory.
+ newInstance( "ldap://localhost:"+super.getLdapPort()+"/dc=example,dc=com", props );
+ }
+
+
+ protected void tearDown() throws Exception
+ {
+ super.tearDown();
+ store.close();
+ store = null;
+ changeType = null;
+ profile = null;
+ role = null;
+ permission = null;
+ originalName = null;
+ }
+
+
+ public void testGetApplicationNameAndProfile()
+ {
+ String applicationName = LdapApplicationPolicy.getApplicationName(
+ "appName=testingApp,ou=applications,dc=example,dc=com" );
+ assertEquals( "testingApp", applicationName );
+
+ try
+ {
+ LdapApplicationPolicy.getApplicationName( "notanapp=blahblah" );
+ fail( "should never get here due to an exception" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+
+ }
+
+ Profile p = store.getProfile( "nonexistant" );
+ assertNull( p );
+
+ p = store.getProfile( "mockProfile0" );
+ assertTrue( p.getEffectivePermissions().isEmpty() );
+ assertEquals( 5, store.getRoles().size() );
+ assertEquals( p, store.getProfile( "mockProfile0" ) );
+
+ p = store.getProfile( "mockProfile1" );
+ assertEquals( 2, p.getEffectivePermissions().size() );
+ assertTrue( p.hasPermission( "mockPerm0" ) );
+ assertTrue( p.hasPermission( "mockPerm1" ) );
+ assertFalse( p.hasPermission( "mockPerm3") );
+ assertEquals( p, store.getProfile( "mockProfile1" ) );
+
+ p = store.getProfile( "mockProfile2" );
+ assertEquals( 2, p.getEffectivePermissions().size() );
+ assertTrue( p.hasPermission( "mockPerm0" ) );
+ assertTrue( p.hasPermission( "mockPerm1" ) );
+ assertFalse( p.hasPermission( "mockPerm3") );
+ assertEquals( p, store.getProfile( "mockProfile2" ) );
+
+ p = store.getProfile( "mockProfile3" );
+ assertEquals( 4, p.getEffectivePermissions().size() );
+ assertTrue( p.hasPermission( "mockPerm0" ) );
+ assertTrue( p.hasPermission( "mockPerm7" ) );
+ assertTrue( p.hasPermission( "mockPerm2" ) );
+ assertTrue( p.hasPermission( "mockPerm3" ) );
+ assertFalse( p.hasPermission( "mockPerm4" ) );
+ assertEquals( p, store.getProfile( "mockProfile3" ) );
+
+ p = store.getProfile( "mockProfile4" );
+ assertEquals( 7, p.getEffectivePermissions().size() );
+ assertTrue( p.hasPermission( "mockPerm0" ) );
+ assertFalse( p.hasPermission( "mockPerm1" ) );
+ assertTrue( p.hasPermission( "mockPerm2" ) );
+ assertTrue( p.hasPermission( "mockPerm3" ) );
+ assertTrue( p.hasPermission( "mockPerm4" ) );
+ assertTrue( p.hasPermission( "mockPerm5" ) );
+ assertTrue( p.hasPermission( "mockPerm6" ) );
+ assertFalse( p.hasPermission( "mockPerm7" ) );
+ assertFalse( p.hasPermission( "mockPerm8" ) );
+ assertTrue( p.hasPermission( "mockPerm9" ) );
+ assertFalse( p.hasPermission( "mockPerm14" ) );
+ assertEquals( p, store.getProfile( "mockProfile4" ) );
+
+ store.close();
+
+ try
+ {
+ store.getProfile( "asdf" );
+ fail( "should never get here due to an exception" );
+ }
+ catch ( IllegalStateException e )
+ {
+
+ }
+ }
+
+
+ public void testGetDependantProfilesRole() throws Exception
+ {
+ Role role0 = store.getRoles().get( "mockRole0" );
+ Set dependents = store.getDependentProfileNames( role0 );
+ assertEquals( 1, dependents.size() );
+
+ Role role1 = store.getRoles().get( "mockRole1" );
+ dependents = store.getDependentProfileNames( role1 );
+ assertEquals( 2, dependents.size() );
+ assertTrue( dependents.contains( "mockProfile1" ) );
+
+ Role role2 = store.getRoles().get( "mockRole2" );
+ dependents = store.getDependentProfileNames( role2 );
+ assertEquals( 3, dependents.size() );
+ assertTrue( dependents.contains( "mockProfile1" ) );
+ assertTrue( dependents.contains( "mockProfile2" ) );
+
+ Permission perm1 = store.getPermissions().get( "mockPerm1" );
+ dependents = store.getDependentProfileNames( perm1 );
+ assertEquals( 1, dependents.size() );
+
+ Permission perm7 = store.getPermissions().get( "mockPerm7" );
+ dependents = store.getDependentProfileNames( perm7 );
+ assertEquals( 3, dependents.size() );
+ assertTrue( dependents.contains( "mockProfile3" ) );
+ assertTrue( dependents.contains( "mockProfile4" ) );
+
+ Permission perm0 = store.getPermissions().get( "mockPerm0" );
+ dependents = store.getDependentProfileNames( perm0 );
+ assertEquals( 4, dependents.size() );
+ assertTrue( dependents.contains( "mockProfile2" ) );
+ assertTrue( dependents.contains( "mockProfile3" ) );
+ assertTrue( dependents.contains( "mockProfile4" ) );
+ }
+
+
+ public void testGetUserProfileIds() throws Exception
+ {
+ assertEquals( 5, this.store.getUserProfileIds( "akarasulu" ).size() );
+ assertEquals( 0, this.store.getUserProfileIds( "trustin" ).size() );
+ }
+
+
+ public void testGetProfileIds() throws Exception
+ {
+ Set ids = new HashSet();
+ for ( Iterator ii = this.store.getProfileIdIterator(); ii.hasNext(); /**/ )
+ {
+ ids.add( ii.next() );
+ }
+ assertEquals( 5, ids.size() );
+ assertTrue( ids.contains( "mockProfile0" ) );
+ assertTrue( ids.contains( "mockProfile1" ) );
+ assertTrue( ids.contains( "mockProfile2" ) );
+ assertTrue( ids.contains( "mockProfile3" ) );
+ assertTrue( ids.contains( "mockProfile4" ) );
+ assertFalse( ids.contains( "bogus" ) );
+ }
+
+
+ private InitialLdapContext getNewAppContext() throws NamingException
+ {
+ Hashtable env = new Hashtable();
+ env.put( "java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory" );
+ env.put( "java.naming.provider.url", "ldap://localhost:" + super.getLdapPort()
+ + "/appName=mockApplication,ou=applications,dc=example,dc=com" );
+ env.put( "java.naming.security.principal", "uid=admin,ou=system" );
+ env.put( "java.naming.security.credentials", "secret" );
+ env.put( "java.naming.security.authentication", "simple" );
+ return new InitialLdapContext( env, null );
+ }
+
+
+ public void testAddDelNotifications() throws Exception
+ {
+ // get a connection to the server to be used for alterations
+ InitialLdapContext ctx = getNewAppContext();
+
+ // prepare listener for notifications
+ store.addPolicyListener( new TestListener() );
+ Thread.sleep( 200 );
+
+ // -------------------------------------------------------------------
+ // Test Permission Addition and Notification
+ // -------------------------------------------------------------------
+
+ Attributes attrs = new BasicAttributes( "objectClass", "policyPermission", true );
+ attrs.put( "permName", "mockPerm10" );
+ attrs.put( "description", "testValue" );
+ ctx.createSubcontext( "permName=mockPerm10,ou=permissions", attrs );
+
+ // wait until the object is set or exit in 10 seconds
+ long startTime = System.currentTimeMillis();
+ long totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.permission != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.profile );
+ assertNull( this.role );
+ assertNotNull( this.permission );
+ assertEquals( "mockPerm10", this.permission.getName() );
+ assertEquals( ChangeType.ADD, this.changeType );
+ assertEquals( "testValue", this.permission.getDescription() );
+
+ // make sure that policy is updated with this new perm
+ assertEquals( this.permission, this.store.getPermissions().get( "mockPerm10" ) );
+ this.permission = null;
+ this.changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Permission Deletion and Notification
+ // -------------------------------------------------------------------
+
+ ctx.destroySubcontext( "permName=mockPerm10,ou=permissions" );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.permission != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.profile );
+ assertNull( this.role );
+ assertNotNull( this.permission );
+ assertEquals( "mockPerm10", this.permission.getName() );
+ assertEquals( ChangeType.DEL, this.changeType );
+ assertEquals( "testValue", this.permission.getDescription() );
+
+ // make sure that policy is updated with this new perm
+ assertNull( this.store.getPermissions().get( "mockPerm10" ) );
+ this.permission = null;
+ this.changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Role Addition and Notification
+ // -------------------------------------------------------------------
+
+ attrs = new BasicAttributes( "objectClass", "policyRole", true );
+ attrs.put( "roleName", "mockRole5" );
+ attrs.put( "description", "testValue" );
+ attrs.put( "grants", "mockPerm8" );
+ ctx.createSubcontext( "roleName=mockRole5,ou=roles", attrs );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.role != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.profile );
+ assertNull( this.permission );
+ assertNotNull( this.role );
+
+ assertEquals( "mockRole5", this.role.getName() );
+ assertEquals( ChangeType.ADD, this.changeType );
+ assertEquals( "testValue", this.role.getDescription() );
+ assertTrue( role.hasPermission( "mockPerm8" ) );
+ assertFalse( role.hasPermission( "mockPerm1" ) );
+
+ // make sure that policy is updated with this new role
+ assertEquals( this.role, this.store.getRoles().get( "mockRole5" ) );
+ this.role = null;
+ this.changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Role Deletions and Notification
+ // -------------------------------------------------------------------
+
+ ctx.destroySubcontext( "roleName=mockRole5,ou=roles" );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.role != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.profile );
+ assertNull( this.permission );
+ assertNotNull( this.role );
+
+ assertEquals( "mockRole5", this.role.getName() );
+ assertEquals( ChangeType.DEL, this.changeType );
+ assertEquals( "testValue", this.role.getDescription() );
+ assertTrue( role.hasPermission( "mockPerm8" ) );
+ assertFalse( role.hasPermission( "mockPerm1" ) );
+
+ // make sure that policy is updated with this new role
+ assertNull( this.store.getRoles().get( "mockRole5" ) );
+ this.role = null;
+ this.changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Profile Addition and Notification
+ // -------------------------------------------------------------------
+
+ attrs = new BasicAttributes( "objectClass", "policyProfile", true );
+ attrs.put( "profileId", "mockProfile5" );
+ attrs.put( "description", "testValue" );
+ attrs.put( "grants", "mockPerm8" );
+ attrs.put( "user", "akarasulu" );
+ ctx.createSubcontext( "profileId=mockProfile5,ou=profiles", attrs );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.profile != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.role );
+ assertNull( this.permission );
+ assertNotNull( this.profile );
+
+ assertEquals( "mockProfile5", this.profile.getProfileId() );
+ assertEquals( ChangeType.ADD, this.changeType );
+ assertEquals( "testValue", this.profile.getDescription() );
+ assertTrue( profile.hasPermission( "mockPerm8" ) );
+ assertFalse( profile.hasPermission( "mockPerm1" ) );
+
+ // -------------------------------------------------------------------
+ // Test Profile Deletion and Notification
+ // -------------------------------------------------------------------
+
+ ctx.destroySubcontext( "profileId=mockProfile5,ou=profiles" );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.profile != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.role );
+ assertNull( this.permission );
+ assertNotNull( this.profile );
+
+ assertEquals( "mockProfile5", this.profile.getProfileId() );
+ assertEquals( ChangeType.DEL, this.changeType );
+ assertEquals( "testValue", this.profile.getDescription() );
+ assertTrue( profile.hasPermission( "mockPerm8" ) );
+ assertFalse( profile.hasPermission( "mockPerm1" ) );
+ }
+
+
+ public void testModifyNotifications() throws Exception
+ {
+ // get a connection to the server to be used for alterations
+ InitialLdapContext ctx = getNewAppContext();
+
+ // prepare listener for notifications
+ store.addPolicyListener( new TestListener() );
+ Thread.sleep( 200 );
+
+ // -------------------------------------------------------------------
+ // Test Profile Alteration and Notification
+ // -------------------------------------------------------------------
+
+ ctx.modifyAttributes( "profileId=mockProfile3,ou=profiles", new ModificationItem[] {
+ new ModificationItem( DirContext.ADD_ATTRIBUTE,
+ new BasicAttribute( "description", "testValue" ) ),
+ new ModificationItem( DirContext.REPLACE_ATTRIBUTE,
+ new BasicAttribute( "grants", "mockPerm1" ) )
+ } );
+
+ // wait until the object is set or exit in 10 seconds
+ long startTime = System.currentTimeMillis();
+ long totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( profile != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNotNull( profile );
+ assertEquals( "mockProfile3", profile.getProfileId() );
+ assertEquals( ChangeType.MODIFY, changeType );
+ assertEquals( "testValue", profile.getDescription() );
+ assertTrue( profile.getGrants().contains( "mockPerm1" ));
+ assertFalse( profile.getGrants().contains( "mockPerm0" ));
+ assertFalse( profile.getGrants().contains( "mockPerm7" ));
+ profile = null;
+ changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Role Alteration and Notification
+ // -------------------------------------------------------------------
+
+ ctx.modifyAttributes( "roleName=mockRole1,ou=roles", new ModificationItem[] {
+ new ModificationItem( DirContext.ADD_ATTRIBUTE,
+ new BasicAttribute( "description", "testValue" ) ),
+ new ModificationItem( DirContext.REPLACE_ATTRIBUTE,
+ new BasicAttribute( "grants", "mockPerm1" ) )
+ } );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( role != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( profile );
+ assertNotNull( role );
+ assertEquals( "mockRole1", role.getName() );
+ assertEquals( ChangeType.MODIFY, changeType );
+ assertEquals( "testValue", role.getDescription() );
+ assertTrue( role.getGrants().contains( "mockPerm1" ));
+ assertFalse( role.getGrants().contains( "mockPerm0" ));
+
+ // make sure that policy is updated with this changed role
+ assertEquals( role, store.getRoles().get( "mockRole1" ) );
+ this.role = null;
+ this.changeType = null;
+
+ // -------------------------------------------------------------------
+ // Test Permission Alteration and Notification
+ // -------------------------------------------------------------------
+
+ ctx.modifyAttributes( "permName=mockPerm1,ou=permissions", new ModificationItem[] {
+ new ModificationItem( DirContext.ADD_ATTRIBUTE,
+ new BasicAttribute( "description", "testValue" ) )
+ } );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( this.permission != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( this.profile );
+ assertNull( this.role );
+ assertNotNull( this.permission );
+ assertEquals( "mockPerm1", this.permission.getName() );
+ assertEquals( ChangeType.MODIFY, this.changeType );
+ assertEquals( "testValue", this.permission.getDescription() );
+
+ // make sure that policy is updated with this changed perm
+ assertEquals( this.permission, this.store.getPermissions().get( "mockPerm1" ) );
+ assertEquals( this.permission, this.store.getRoles().get( "mockRole1" ).getGrants().get( "mockPerm1" ) );
+ assertEquals( this.permission, this.store.getRoles().get( "mockRole2" ).getGrants().get( "mockPerm1" ) );
+ assertNull( this.store.getRoles().get( "mockRole0" ).getGrants().get( "mockPerm1" ) );
+ assertNull( this.store.getRoles().get( "mockRole3" ).getGrants().get( "mockPerm1" ) );
+ assertNull( this.store.getRoles().get( "mockRole4" ).getGrants().get( "mockPerm1" ) );
+
+ ctx.close();
+ }
+
+
+ public void testRenameNotifications() throws Exception
+ {
+ // get a connection to the server to be used for alterations
+ InitialLdapContext ctx = getNewAppContext();
+
+ // prepare listener for notifications
+ store.addPolicyListener( new TestListener() );
+ Thread.sleep( 200 );
+
+ // -------------------------------------------------------------------
+ // Test Profile Rename and Notification
+ // -------------------------------------------------------------------
+
+ ctx.rename( "profileId=mockProfile3,ou=profiles", "profileId=renamed,ou=profiles" );
+
+ // wait until the object is set or exit in 10 seconds
+ long startTime = System.currentTimeMillis();
+ long totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( profile != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNotNull( profile );
+ assertEquals( "renamed", profile.getProfileId() );
+ assertNotNull( originalName );
+ assertEquals( "mockProfile3", originalName );
+ profile = null;
+ originalName = null;
+
+ // -------------------------------------------------------------------
+ // Test Role Rename and Notification
+ // -------------------------------------------------------------------
+
+ assertNotNull( store.getRoles().get( "mockRole0" ) );
+ assertNull( store.getRoles().get( "renamed" ) );
+ ctx.rename( "roleName=mockRole0,ou=roles", "roleName=renamed,ou=roles" );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 200 );
+ if ( role != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( profile );
+ assertNull( permission );
+ assertNull( store.getRoles().get( "mockRole0" ) );
+ assertNotNull( store.getRoles().get( "renamed" ) );
+ assertNotNull( role );
+ assertEquals( "renamed", role.getName() );
+ assertNotNull( originalName );
+ assertEquals( "mockRole0", originalName );
+ role = null;
+ originalName = null;
+
+ // -------------------------------------------------------------------
+ // Test Permission Rename and Notification
+ // -------------------------------------------------------------------
+
+ Attributes attrs = new BasicAttributes( "objectClass", "policyPermission", true );
+ attrs.put( "permName", "mockPerm10" );
+ attrs.put( "description", "testValue" );
+ ctx.createSubcontext( "permName=mockPerm10,ou=permissions", attrs );
+ ctx.rename( "permName=mockPerm10,ou=permissions", "permName=renamed,ou=permissions" );
+
+ // wait until the object is set or exit in 10 seconds
+ startTime = System.currentTimeMillis();
+ totalWaitTime = 0;
+ while ( totalWaitTime < 10000 )
+ {
+ synchronized( lockObject )
+ {
+ lockObject.wait( 250 );
+ if ( permission != null )
+ {
+ break;
+ }
+ else
+ {
+ totalWaitTime = System.currentTimeMillis() - startTime;
+ }
+ }
+ }
+
+ assertNull( profile );
+ assertNull( role );
+ assertNotNull( permission );
+ assertNotNull( store.getPermissions().get( "renamed" ) );
+ assertEquals( "renamed", permission.getName() );
+ assertNotNull( originalName );
+ assertEquals( "mockPerm10", originalName );
+ }
+
+
+ class TestListener implements PolicyChangeListener
+ {
+ public void roleChanged( ApplicationPolicy policy, Role role, ChangeType changeType )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.role = role;
+ LdapApplicationPolicyIntegrationTest.this.changeType = changeType;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+
+ public void roleRenamed( ApplicationPolicy policy, Role role, String oldName )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.originalName = oldName;
+ LdapApplicationPolicyIntegrationTest.this.role = role;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+
+ public void permissionChanged( ApplicationPolicy policy, Permission permission, ChangeType changeType )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.permission = permission;
+ LdapApplicationPolicyIntegrationTest.this.changeType = changeType;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+
+ public void permissionRenamed( ApplicationPolicy policy, Permission permission, String oldName )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.originalName = oldName;
+ LdapApplicationPolicyIntegrationTest.this.permission = permission;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+
+ public void profileChanged( ApplicationPolicy policy, Profile profile, ChangeType changeType )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.profile = profile;
+ LdapApplicationPolicyIntegrationTest.this.changeType = changeType;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+
+ public void profileRenamed( ApplicationPolicy policy, Profile profile, String oldName )
+ {
+ synchronized( lockObject )
+ {
+ LdapApplicationPolicyIntegrationTest.this.originalName = oldName;
+ LdapApplicationPolicyIntegrationTest.this.profile = profile;
+ LdapApplicationPolicyIntegrationTest.this.lockObject.notifyAll();
+ }
+ }
+ }
+}
+
\ No newline at end of file
Added: directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapConnectionDriverTest.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapConnectionDriverTest.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapConnectionDriverTest.java (added)
+++ directory/trunks/triplesec/guardian-ldap/src/test/java/org/safehaus/triplesec/guardian/ldap/LdapConnectionDriverTest.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.safehaus.triplesec.guardian.ldap;
+
+
+import junit.framework.TestCase;
+
+import java.util.Properties;
+
+
+/**
+ * Tests the LDAP ConnectionDriver.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+public class LdapConnectionDriverTest extends TestCase
+{
+ public void testNullProperties()
+ {
+ LdapConnectionDriver driver = new LdapConnectionDriver();
+
+ try
+ {
+ driver.newStore( "", null );
+ fail( "should not get here due to exception" );
+ }
+ catch( IllegalArgumentException e )
+ {
+ }
+ }
+
+
+ public void testNullUrl()
+ {
+ LdapConnectionDriver driver = new LdapConnectionDriver();
+ Properties props = new Properties();
+ props.setProperty( "applicationPrincipalDN", "appName=something" );
+ props.setProperty( "applicationCredentials", "secret" );
+ try
+ {
+ driver.newStore( null, props );
+ fail( "should never get here due to an exception" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+
+ }
+ }
+
+
+ public void testNoPrincipalName()
+ {
+ LdapConnectionDriver driver = new LdapConnectionDriver();
+
+ try
+ {
+ Properties props = new Properties();
+ props.setProperty( "applicationCredentials", "secret" );
+ driver.newStore( "", props );
+ fail( "should never get here due to an exception" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+
+ }
+ }
+
+
+ public void testNoCredentials()
+ {
+ LdapConnectionDriver driver = new LdapConnectionDriver();
+ Properties props = new Properties();
+ props.setProperty( "applicationPrincipalDN", "appName=something" );
+ try
+ {
+ driver.newStore( "", props );
+ fail( "should never get here due to an exception" );
+ }
+ catch ( IllegalArgumentException e )
+ {
+
+ }
+ }
+}
Added: directory/trunks/triplesec/guardian-ldap/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldap/src/test/resources/log4j.properties?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldap/src/test/resources/log4j.properties (added)
+++ directory/trunks/triplesec/guardian-ldap/src/test/resources/log4j.properties Tue Dec 12 07:23:31 2006
@@ -0,0 +1,11 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=ERROR, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+
Added: directory/trunks/triplesec/guardian-ldap/src/test/resources/server.ldif
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldap/src/test/resources/server.ldif?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldap/src/test/resources/server.ldif (added)
+++ directory/trunks/triplesec/guardian-ldap/src/test/resources/server.ldif Tue Dec 12 07:23:31 2006
@@ -0,0 +1,334 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+#
+# EXAMPLE.COM is freely and reserved for testing according to this RFC:
+#
+# http://www.rfc-editor.org/rfc/rfc2606.txt
+#
+#
+
+#
+# This ACI allows brouse access to the root suffix and one level below that to anyone.
+# At this level there is nothing critical exposed. Everything that matters is one or
+# more levels below this.
+#
+
+dn: cn=browseRootAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { maximum 1 }
+prescriptiveACI: { identificationTag "browseRoot", precedence 100, authenticationLevel none, itemOrUserFirst userFirst: { userClasses { allUsers }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse } } } } }
+
+dn: ou=Users, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Users
+
+#
+# This ACI allows users to modify a limited set of attributes in their own user
+# entry as well as read, compare those attributes. The user's entry must be
+# browseable and the DN must be returnable.
+#
+
+dn: cn=allowSelfModificationsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfModifications", precedence 14, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantModify, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {userPassword, krb5Key, givenName, cn, commonName, surName, sn, objectClass }}, grantsAndDenials { grantModify, grantAdd, grantRemove, grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+#
+# This ACI allows users to access a limited set of attributes in their own user
+# entry as well as compare those attributes. The user's entry must be browseable
+# and the DN must be returnable.
+#
+
+dn: cn=allowSelfAccessAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "allowSelfAccess", precedence 15, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { thisEntry }, userPermissions { { protectedItems {entry}, grantsAndDenials { grantReturnDN, grantBrowse, grantRead, grantDiscloseOnError } }, { protectedItems {allAttributeValues {uid, userPassword, givenName, cn, commonName, surName, sn, objectClass, creatorsName, modifiersName, createTimestamp, modifyTimestamp, krb5AccountDisabled, description, apacheSamType }}, grantsAndDenials { grantRead, grantDiscloseOnError, grantCompare } } } } }
+
+dn: ou=Groups, dc=example, dc=com
+objectclass: top
+objectclass: organizationalunit
+ou: Groups
+
+dn: cn=superUsers, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: superUsers
+uniqueMember: uid=admin, ou=system
+
+dn: cn=userAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: userAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=applicationAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: applicationAdmin
+uniqueMember: uid=admin, ou=system
+
+dn: cn=groupAdmins, ou=Groups, dc=example, dc=com
+objectClass: top
+objectClass: groupOfUniqueNames
+cn: groupAdmin
+uniqueMember: uid=admin, ou=system
+
+#
+# This ACI allows members of the superUsers group to have full modify and read access
+# to the entire realm as does the system administrator principal: uid=admin, ou=system.
+#
+# The only thing these users cannot do is modify the system partition. They are only
+# restricted to superUser rights within this realm partition
+#
+
+dn: cn=superUsersAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { }
+prescriptiveACI: { identificationTag "superUsersAci", precedence 20, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=superUsers,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+#
+# This ACI allows members of the userAdmin group to have full modify and read access
+# to user accounts besides their own. Hence they can administer users in the system.
+#
+
+dn: cn=userAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=users", maximum 1 }
+prescriptiveACI: { identificationTag "userAdminsAci", precedence 16, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=userAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the applicationAdmin group to have full modify and read access
+# to all applications in the realm. Adding users to this group is like a wild card for
+# application access.
+#
+
+dn: cn=applicationAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=applications" }
+prescriptiveACI: { identificationTag "applicationAdminsAci", precedence 17, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=applicationAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+
+#
+# This ACI allows members of the groupAdmins group to have full modify and read access
+# to all groups in the realm other than the superUsers, userAdmins, groupAdmins, and the
+# applicationAdmins groups.
+#
+# The rational behind this is to prevent these users from changing their or other
+# users' access rights for the entire system by modifying their membership in these
+# groups. Making someone a groupAdmin should not open the door to their ability to
+# grant themselves or others system wide administrative abilities.
+#
+# Really the groupAdmins group is intended for users that have the ability to manage
+# group membership in specific application administration groups and that's all.
+# These types of admins should not have the right to promote others to system level
+# administrators or complete super users.
+#
+
+dn: cn=groupAdminsAci,dc=example,dc=com
+objectClass: top
+objectClass: subentry
+objectClass: accessControlSubentry
+subtreeSpecification: { base "ou=groups", specificExclusions { chopBefore: "cn=userAdmins", chopBefore: "cn=groupAdmins", chopBefore: "cn=applicationAdmins", chopBefore: "cn=superUsers" } }
+prescriptiveACI: { identificationTag "groupAdminsAci", precedence 18, authenticationLevel simple, itemOrUserFirst userFirst: { userClasses { userGroup { "cn=groupAdmins,ou=groups,dc=example,dc=com" } }, userPermissions { { protectedItems {entry, allUserAttributeTypesAndValues}, grantsAndDenials { grantRead, grantReturnDN, grantBrowse, grantDiscloseOnError, grantCompare, grantAdd, grantRename, grantRemove, grantModify, grantImport, grantExport } } } } }
+
+dn: uid=krbtgt, ou=Users, dc=example,dc=com
+cn: Kerberos Server
+sn: Server
+givenname: Kerberos
+objectclass: top
+objectclass: uidObject
+objectclass: person
+objectclass: organizationalPerson
+objectclass: inetOrgPerson
+objectclass: krb5Principal
+objectclass: krb5KDCEntry
+ou: Users
+uid: krbtgt
+krb5PrincipalName: krbtgt/EXAMPLE.COM@EXAMPLE.COM
+krb5KeyVersionNumber: 0
+mail: admin@example.com
+roomnumber: 667
+userpassword: secret
+
+dn: ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalunit
+ou: applications
+
+dn: appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyApplication
+appName: mockApplication
+userPassword:: dGVzdGluZw==
+
+dn: ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: permissions
+
+dn: permName=mockPerm0,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm0
+
+dn: permName=mockPerm1,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm1
+
+dn: permName=mockPerm2,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm2
+
+dn: permName=mockPerm3,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm3
+
+dn: permName=mockPerm4,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm4
+
+dn: permName=mockPerm5,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm5
+
+dn: permName=mockPerm6,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm6
+
+dn: permName=mockPerm7,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm7
+
+dn: permName=mockPerm8,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm8
+
+dn: permName=mockPerm9,ou=permissions,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyPermission
+permName: mockPerm9
+
+dn: ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: roles
+
+dn: roleName=mockRole0,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: policyRole
+objectClass: top
+roleName: mockRole0
+
+dn: roleName=mockRole1,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm0
+roleName: mockRole1
+
+dn: roleName=mockRole2,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm1
+roleName: mockRole2
+
+dn: roleName=mockRole3,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm3
+grants: mockPerm2
+roleName: mockRole3
+
+dn: roleName=mockRole4,ou=roles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyRole
+grants: mockPerm9
+grants: mockPerm7
+grants: mockPerm6
+grants: mockPerm5
+grants: mockPerm4
+roleName: mockRole4
+
+dn: ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: organizationalUnit
+ou: profiles
+
+dn: profileId=mockProfile0,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+user: akarasulu
+profileId: mockProfile0
+
+dn: profileId=mockProfile1,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+roles: mockRole2
+roles: mockRole1
+user: akarasulu
+profileId: mockProfile1
+
+dn: profileId=mockProfile2,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+grants: mockPerm0
+roles: mockRole2
+user: akarasulu
+profileId: mockProfile2
+
+dn: profileId=mockProfile3,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+grants: mockPerm7
+grants: mockPerm0
+roles: mockRole3
+user: akarasulu
+profileId: mockProfile3
+
+dn: profileId=mockProfile4,ou=profiles,appName=mockApplication,ou=applications,dc=example,dc=com
+objectClass: top
+objectClass: policyProfile
+denials: mockPerm7
+grants: mockPerm0
+roles: mockRole4
+roles: mockRole3
+user: akarasulu
+profileId: mockProfile4
+
Added: directory/trunks/triplesec/guardian-ldap/src/test/resources/server.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldap/src/test/resources/server.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldap/src/test/resources/server.xml (added)
+++ directory/trunks/triplesec/guardian-ldap/src/test/resources/server.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+ "http://www.springframework.org/dtd/spring-beans.dtd">
+
+<beans>
+ <bean id="environment" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
+ <property name="properties">
+ <props>
+ <prop key="java.naming.security.authentication">simple</prop>
+ <prop key="java.naming.security.principal">uid=admin,ou=system</prop>
+ <prop key="java.naming.security.credentials">secret</prop>
+ <prop key="java.naming.provider.url">dc=example,dc=com</prop>
+ <prop key="java.naming.factory.state">org.safehaus.triplesec.store.ProfileStateFactory</prop>
+ <prop key="java.naming.factory.object">org.safehaus.triplesec.store.ProfileObjectFactory</prop>
+
+ <prop key="kdc.primary.realm">EXAMPLE.COM</prop>
+ <prop key="kdc.principal">krbtgt/EXAMPLE.COM@EXAMPLE.COM</prop>
+ <prop key="kdc.encryption.types">des-cbc-md5 des3-cbc-sha1 des3-cbc-md5 des-cbc-md4 des-cbc-crc</prop>
+ <prop key="kdc.entryBaseDn">ou=users,dc=example,dc=com</prop>
+ <prop key="kdc.java.naming.security.credentials">secret</prop>
+
+ <prop key="changepw.entryBaseDn">ou=users,dc=example,dc=com</prop>
+ <prop key="changepw.java.naming.security.credentials">secret</prop>
+ <prop key="changepw.principal">kadmin/changepw@EXAMPLE.COM</prop>
+
+ <!-- All times are in minutes -->
+ <prop key="kdc.allowable.clockskew">5</prop>
+ <prop key="kdc.tgs.maximum.ticket.lifetime">1440</prop>
+ <prop key="kdc.tgs.maximum.renewable.lifetime">10080</prop>
+ <prop key="kdc.pa.enc.timestamp.required">true</prop>
+ <prop key="kdc.tgs.empty.addresses.allowed">true</prop>
+ <prop key="kdc.tgs.forwardable.allowed">true</prop>
+ <prop key="kdc.tgs.proxiable.allowed">true</prop>
+ <prop key="kdc.tgs.postdate.allowed">true</prop>
+ <prop key="kdc.tgs.renewable.allowed">true</prop>
+
+ <prop key="safehaus.entry.basedn">ou=Users,dc=example,dc=com</prop>
+ <prop key="safehaus.load.testdata">true</prop>
+ <prop key="kerberos.sam.type.7">org.safehaus.triplesec.verifier.hotp.DefaultHotpSamVerifier</prop>
+ </props>
+ </property>
+ </bean>
+
+ <bean id="configuration" class="org.safehaus.triplesec.configuration.MutableTriplesecStartupConfiguration">
+ <property name="workingDirectory"><value>partitions</value></property>
+ <property name="allowAnonymousAccess"><value>false</value></property>
+ <property name="accessControlEnabled"><value>true</value></property>
+ <property name="ldapPort"><value>10389</value></property>
+ <property name="enableKerberos"><value>true</value></property>
+ <property name="enableNtp"><value>false</value></property>
+ <property name="enableChangePassword"><value>true</value></property>
+
+ <!-- Uncomment below to have the server load entries on startup! -->
+ <!-- ldifDirectory property can point to a relative file, directory or -->
+ <!-- can point to an absolute path to either using the URL path -->
+ <!-- notation: i.e. file:///Users/jack/apacheds/ldifs -->
+
+ <!-- Entries will optionally be filtered using LdifLoadFilters in the -->
+ <!-- order specified. The included Krb5KdcEntryFilter will filter -->
+ <!-- kerberos principals creating keys for them using their -->
+ <!-- userPassword attribute if present. -->
+
+ <!-- If missing the Triplesec server will use LDIF files under the conf -->
+ <!-- directory where it has been installed. -->
+
+ <!--
+ <property name="ldifDirectory">
+ <value>example.ldif</value>
+ </property>
+ -->
+ <property name="ldifFilters">
+ <list>
+ <bean class="org.apache.directory.server.protocol.shared.store.Krb5KdcEntryFilter"/>
+ </list>
+ </property>
+
+ <property name="activationConfiguration">
+ <bean class="org.safehaus.triplesec.configuration.ActivationConfiguration">
+ <property name="enableDecoyMidlet"><value>true</value></property>
+ <property name="otpLength"><value>6</value></property>
+ <property name="midletNameAttribute"><value>midletNameAttribute</value></property>
+ </bean>
+ </property>
+
+ <property name="smsConfiguration">
+ <bean class="org.safehaus.triplesec.configuration.SmsConfiguration">
+ <property name="smsUsername"><value>hauskeys</value></property>
+ <property name="smsPassword"><value>secret</value></property>
+ <property name="smsAccountName"><value>demo</value></property>
+ <property name="smsTransportUrl"><value>http://www.nbroadcasting.com/customers/messages/Sender.asp</value></property>
+ </bean>
+ </property>
+
+ <property name="smtpConfiguration">
+ <bean class="org.safehaus.triplesec.configuration.SmtpConfiguration">
+ <property name="smtpAuthenticate"><value>false</value></property>
+ <!-- uncomment and set above property if authentication is required by mail server
+ <property name="smtpUsername"><value>hauskeys</value></property>
+ <property name="smtpPassword"><value>secret</value></property>
+ -->
+ <property name="smtpHost"><value>localhost</value></property>
+ <property name="smtpSubject"><value>Triplesec Account Activated</value></property>
+ <property name="smtpFrom"><value>dev@safehaus.org</value></property>
+ </bean>
+ </property>
+
+ <property name="contextPartitionConfigurations">
+ <set>
+ <ref bean="examplePartitionConfiguration"/>
+ </set>
+ </property>
+ <property name="bootstrapSchemas">
+ <set>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.CorbaSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.CoreSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.CosineSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.ApacheSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.CollectiveSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.InetorgpersonSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.JavaSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.Krb5kdcSchema"/>
+ <bean class="org.apache.directory.server.core.schema.bootstrap.SystemSchema"/>
+ <bean class="org.safehaus.triplesec.store.schema.SafehausSchema"/>
+ </set>
+ </property>
+
+ <property name="extendedOperationHandlers">
+ <list>
+ <bean class="org.apache.directory.server.ldap.support.extended.GracefulShutdownHandler"/>
+ <bean class="org.apache.directory.server.ldap.support.extended.LaunchDiagnosticUiHandler"/>
+ </list>
+ </property>
+
+ <property name="interceptorConfigurations">
+ <list>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>normalizationService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.normalization.NormalizationService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>authenticationService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.authn.AuthenticationService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>referralService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.referral.ReferralService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>authorizationService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.authz.AuthorizationService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>defaultAuthorizationService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.authz.DefaultAuthorizationService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>exceptionService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.exception.ExceptionService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>schemaService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.schema.SchemaService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>subentryService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.subtree.SubentryService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>operationalAttributeService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.operational.OperationalAttributeService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>collectiveAttributeService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.collective.CollectiveAttributeService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>eventService</value></property>
+ <property name="interceptor">
+ <bean class="org.apache.directory.server.core.event.EventService" />
+ </property>
+ </bean>
+ <bean class="org.apache.directory.server.core.configuration.MutableInterceptorConfiguration">
+ <property name="name"><value>policyProtectionService</value></property>
+ <property name="interceptor">
+ <bean class="org.safehaus.triplesec.store.interceptor.PolicyProtectionInterceptor" />
+ </property>
+ </bean>
+ </list>
+ </property>
+ </bean>
+
+ <bean id="examplePartitionConfiguration" class="org.apache.directory.server.core.configuration.MutablePartitionConfiguration">
+ <property name="name"><value>example</value></property>
+ <property name="suffix"><value>dc=example,dc=com</value></property>
+ <property name="indexedAttributes">
+ <set>
+ <value>objectClass</value>
+ <value>ou</value>
+ <value>dc</value>
+ <value>uid</value>
+ <value>profileId</value>
+ <value>roles</value>
+ <value>grants</value>
+ <value>denials</value>
+ <value>krb5PrincipalName</value>
+ </set>
+ </property>
+ <property name="contextEntry">
+ <value>
+ objectClass: top
+ objectClass: domain
+ objectClass: extensibleObject
+ dc: example
+ administrativeRole: accessControlSpecificArea
+ administrativeRole: collectiveAttributeSpecificArea
+ </value>
+ </property>
+ </bean>
+
+ <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+ <property name="customEditors">
+ <map>
+ <entry key="javax.naming.directory.Attributes">
+ <bean class="org.apache.directory.server.core.configuration.AttributesPropertyEditor"/>
+ </entry>
+ </map>
+ </property>
+ </bean>
+</beans>
Added: directory/trunks/triplesec/guardian-ldif/pom.xml
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldif/pom.xml?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldif/pom.xml (added)
+++ directory/trunks/triplesec/guardian-ldif/pom.xml Tue Dec 12 07:23:31 2006
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.safehaus.triplesec</groupId>
+ <artifactId>build</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+ <artifactId>triplesec-guardian-ldif</artifactId>
+ <name>Triplesec Guardian LDIF Driver</name>
+ <description>
+ A driver which uses an LDAP LDIF as the policy store.
+ </description>
+ <packaging>jar</packaging>
+ <dependencies>
+ <dependency>
+ <artifactId>nlog4j</artifactId>
+ <groupId>org.slf4j</groupId>
+ <version>1.2.25</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <artifactId>shared-ldap</artifactId>
+ <groupId>org.apache.directory.shared</groupId>
+ <version>0.9.5.3-SNAPSHOT</version>
+ </dependency>
+ <dependency>
+ <artifactId>triplesec-guardian-api</artifactId>
+ <groupId>${pom.groupId}</groupId>
+ <version>${pom.version}</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <systemProperties>
+ <property>
+ <name>ldif.url</name>
+ <value>file://${basedir}/src/test/resources/server.ldif</value>
+ </property>
+ </systemProperties>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: directory/trunks/triplesec/guardian-ldif/src/main/java/org/safehaus/triplesec/guardian/ldif/LdifApplicationPolicy.java
URL: http://svn.apache.org/viewvc/directory/trunks/triplesec/guardian-ldif/src/main/java/org/safehaus/triplesec/guardian/ldif/LdifApplicationPolicy.java?view=auto&rev=486187
==============================================================================
--- directory/trunks/triplesec/guardian-ldif/src/main/java/org/safehaus/triplesec/guardian/ldif/LdifApplicationPolicy.java (added)
+++ directory/trunks/triplesec/guardian-ldif/src/main/java/org/safehaus/triplesec/guardian/ldif/LdifApplicationPolicy.java Tue Dec 12 07:23:31 2006
@@ -0,0 +1,557 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.safehaus.triplesec.guardian.ldif;
+
+
+import org.apache.directory.shared.ldap.ldif.Entry;
+import org.apache.directory.shared.ldap.ldif.LdifReader;
+import org.safehaus.triplesec.guardian.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.naming.directory.*;
+import javax.naming.NamingException;
+import javax.naming.NamingEnumeration;
+
+import java.io.File;
+import java.util.*;
+
+
+/**
+ * An LDIF file backed implementation of an application policy store.
+ *
+ * @author <a href="mailto:akarasulu@safehaus.org">Alex Karasulu</a>
+ * @version $Rev$
+ */
+class LdifApplicationPolicy implements ApplicationPolicy
+{
+ /** the logger interface for this class */
+ private static Logger log = LoggerFactory.getLogger( LdifApplicationPolicy.class );
+ /** the name of the application this store is associated with */
+ private final String applicationName;
+ /** the dn of the application */
+ private final String applicationDn;
+ /** a breif description of this application */
+ private String description;
+ /** the LDIF file that was loaded for this application */
+ private final File ldifFile;
+ /** the raw entries contained within the LDIF file */
+// private final Map entries;
+// private Attributes application = null;
+ /** the {@link Permissions} defined for this store's application */
+ private Permissions permissions;
+ /** the {@link Roles} defined for this store's application */
+ private Roles roles;
+ /** the {@link Profile}s loaded from LDIF */
+ private Map profileMap;
+ /** map of userNames to sets of profile ids */
+ private Map userProfilesMap;
+
+ boolean isClosed = false;
+ /** the administrators super profile */
+ private Profile adminProfile;
+
+
+ /**
+ * Creates an instance of the LDIF ApplicationPolicyStore. Two properties are
+ * expected in the info properties. One is the dn of the application principal.
+ * The other is the path to an ldif file.
+ * <table>
+ * <tr><th>property</th><th>description</th></tr>
+ * <tr><td>applicationPrincipalDN</td><td>the distinguished name of the application</td></tr>
+ * <tr><td>ldifFilePath</td><td>the path to the LDIF file containing the entries to load</td></tr>
+ * </table>
+ *
+ * @param ctx the base context under which ou=applications and ou=users can be found
+ * @param info additional information needed to load the LDIF file
+ * @throws GuardianException if failures are encountered while loading objects from the backing store
+ */
+ public LdifApplicationPolicy( File ldifFile, Properties info ) throws GuardianException
+ {
+ this.userProfilesMap = new HashMap();
+ this.profileMap = new HashMap();
+ this.applicationDn = info.getProperty( "applicationPrincipalDN" );
+ // extract the applicationName from the applicationPrincipalDN
+ this.applicationName = getApplicationName( applicationDn );
+ // extract the path to the LDIF file to load
+ this.ldifFile = ldifFile;
+ // loads the ldifs as a map of LdapNames to Attributes
+ load();
+ // create the admin profile with all permissions as grants and in all roles
+ this.adminProfile = new Profile( this, "admin", "admin", roles, permissions,
+ new Permissions( applicationName, new Permission[0] ), false );
+ }
+
+
+ private Map load() throws GuardianException
+ {
+ Map roleMap = new HashMap();
+ Map permissionMap = new HashMap();
+ Map profileMap = new HashMap();
+ Map entryMap = new HashMap();
+ try
+ {
+ LdifReader reader = new LdifReader();
+ List entries = reader.parseLdifFile( ldifFile.getAbsolutePath() );
+ for ( int ii = 0; ii < entries.size(); ii++ )
+ {
+ Entry entry = ( Entry ) entries.get( ii );
+ Attributes attributes = entry.getAttributes();
+ String dn = entry.getDn();
+ entryMap.put( dn, attributes );
+
+ if ( dn.equals( applicationDn ) )
+ {
+// application = attributes;
+ }
+ else if ( dn.endsWith( applicationDn ) )
+ {
+ Attribute oc = attributes.get( "objectClass" );
+ if ( oc.contains( "policyPermission" ) )
+ {
+ permissionMap.put( dn, attributes );
+ }
+ else if ( oc.contains( "policyRole" ) )
+ {
+ roleMap.put( dn, attributes );
+ }
+ else if ( oc.contains( "policyProfile" ) )
+ {
+ profileMap.put( dn, attributes );
+ }
+ }
+ }
+ }
+ catch ( Exception e )
+ {
+ String msg = "Failed to read from ldifFile '" + ldifFile + "'.";
+ log.error( msg, e );
+ throw new GuardianException( msg, e );
+ }
+
+ loadPermissions( permissionMap );
+ loadRoles( roleMap );
+ loadProfiles( profileMap );
+ return entryMap;
+ }
+
+
+ /**
+ * Loads the role entries extracted from the LDIF.
+ *
+ * @throws GuardianException if there is a problem with a role
+ */
+ private void loadRoles( Map roleMap ) throws GuardianException
+ {
+ Set roleSet = new HashSet();
+
+ try
+ {
+ Iterator keys = roleMap.keySet().iterator();
+ while ( keys.hasNext() )
+ {
+ String dn = ( String ) keys.next();
+ Attributes entry = ( Attributes ) roleMap.get( dn );
+ String roleName = ( String ) entry.get( "roleName" ).get();
+ Set permSet = new HashSet();
+ Attribute attributes = entry.get( "grants" );
+
+ if ( attributes != null )
+ {
+ NamingEnumeration grantsEnumeration = entry.get( "grants" ).getAll();
+ while ( grantsEnumeration.hasMore() )
+ {
+ String permName = ( String ) grantsEnumeration.next();
+ permSet.add( permissions.get( permName ) );
+ log.debug( "granting permission '" + permName + "' to role '" + roleName
+ + " in application '" + applicationName + "'" );
+ }
+ }
+ Permission[] permArray = new Permission[permSet.size()];
+ Permissions grants = new Permissions( applicationName, ( Permission[] ) permSet.toArray( permArray ) );
+
+ Attribute description = entry.get( "description" );
+ Role role;
+ if ( description == null || description.size() == 0 )
+ {
+ role = new Role( this, roleName, grants );
+ }
+ else
+ {
+ role = new Role( this, roleName, grants, ( String ) description.get() );
+ }
+
+ roleSet.add( role );
+ log.debug( "loading role '" + roleName + "' for application '" + applicationName + "'" );
+ }
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed on search to find roles for application " + applicationName;
+ log.error( msg, e );
+ throw new GuardianException( msg, e );
+ }
+
+ Role[] roleArray = new Role[roleSet.size()];
+ roleArray = ( Role[] ) roleSet.toArray( roleArray );
+ this.roles = new Roles( applicationName, roleArray );
+ }
+
+
+ /**
+ * Loads the permission entries extracted from the LDIF.
+ *
+ * @throws GuardianException if there is a problem with a permission
+ */
+ private void loadPermissions( Map permissionMap ) throws GuardianException
+ {
+ Set permSet = new HashSet();
+
+ try
+ {
+ Iterator keys = permissionMap.keySet().iterator();
+ while ( keys.hasNext() )
+ {
+ String dn = ( String ) keys.next();
+ Attributes entry = ( Attributes ) permissionMap.get( dn );
+ String permName = ( String ) entry.get( "permName" ).get();
+ Permission perm;
+ Attribute description = entry.get( "description" );
+ if ( description != null )
+ {
+ perm = new Permission( applicationName, permName, ( String ) description.get() );
+ }
+ else
+ {
+ perm = new Permission( applicationName, permName );
+ }
+ log.debug( "loading permission " + permName + " for application " + applicationName );
+ permSet.add( perm );
+ }
+ }
+ catch ( NamingException e )
+ {
+ String msg = "Failed on load of permissions for application " + applicationName;
+ log.error( msg, e );
+ throw new GuardianException( msg, e );
+ }
+
+ Permission[] permArray = new Permission[permSet.size()];
+ permArray = ( Permission[] ) permSet.toArray( permArray );
+ this.permissions = new Permissions( applicationName, permArray );
+ }
+
+
+ public String getApplicationName()
+ {
+ return this.applicationName;
+ }
+
+
+ public String getDescription()
+ {
+ return this.description;
+ }
+
+
+ public Roles getRoles()
+ {
+ return this.roles;
+ }
+
+
+ public Permissions getPermissions()
+ {
+ return permissions;
+ }
+
+
+ private static boolean parseBoolean( String bool )
+ {
+ if ( bool.equals( "true" ) )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Loads the profile entries extracted from the LDIF.
+ *
+ * @throws GuardianException if there is a problem with a profile
+ */
+ private void loadProfiles( Map profileEntryMap ) throws GuardianException
+ {
+ String[] profileDns = new String[profileEntryMap.size()];
+ profileEntryMap.keySet().toArray( profileDns );
+
+ for ( int ii = 0; ii < profileDns.length; ii++ )
+ {
+ Profile profile;
+ Permissions grants;
+ Permissions denials;
+ Roles roles;
+ String dn = profileDns[ii];
+ Attributes entry = ( Attributes ) profileEntryMap.get( dn );
+ String profileId;
+ String userName;
+ boolean disabled = false;
+
+ Attribute disabledAttr = entry.get( "safehausDisabled" );
+ try
+ {
+ if ( disabledAttr != null )
+ {
+ disabled = parseBoolean( ( ( String ) disabledAttr.get() ).toLowerCase() );
+ }
+ }
+ catch ( Exception e )
+ {
+ throw new GuardianException( "Failed trying to access safehausDiabled attribute: " + dn );
+ }
+
+ try
+ {
+ profileId = ( String ) entry.get( "profileId" ).get();
+ }
+ catch ( Exception e )
+ {
+ throw new GuardianException( "Could not find profileId attribute for profile: " + dn );
+ }
+
+ try
+ {
+ userName = ( String ) entry.get( "user" ).get();
+ }
+ catch ( Exception e )
+ {
+ throw new GuardianException( "Could not find user attribute for profile: " + dn );
+ }
+
+ // -------------------------------------------------------------------------------
+ // process and assemble the profile's granted permissions
+ // -------------------------------------------------------------------------------
+
+ Attribute grantsAttribute = entry.get( "grants" );
+ if ( grantsAttribute != null )
+ {
+ Set grantsSet = new HashSet();
+ try
+ {
+ NamingEnumeration grantsEnumeration = grantsAttribute.getAll();
+ while ( grantsEnumeration.hasMore() )
+ {
+ String grantedPermName = ( String ) grantsEnumeration.next();
+ grantsSet.add( this.permissions.get( grantedPermName ) );
+ }
+ }
+ catch ( NamingException e )
+ {
+ throw new GuardianException( "Failed to get grants for profile: " + dn );
+ }
+
+ Permission[] grantsArray = new Permission[grantsSet.size()];
+ grants = new Permissions( applicationName, ( Permission[] ) grantsSet.toArray( grantsArray ) );
+ }
+ else
+ {
+ grants = new Permissions( applicationName, new Permission[0] );
+ }
+
+ // -------------------------------------------------------------------------------
+ // process and assemble the profile's granted permissions
+ // -------------------------------------------------------------------------------
+
+ Attribute denialsAttribute = entry.get( "denials" );
+ if ( denialsAttribute != null )
+ {
+ Set denialsSet = new HashSet();
+ try
+ {
+ NamingEnumeration denialsEnumeration = denialsAttribute.getAll();
+ while ( denialsEnumeration.hasMore() )
+ {
+ String deniedPermName = ( String ) denialsEnumeration.next();
+ denialsSet.add( this.permissions.get( deniedPermName ) );
+ }
+ }
+ catch ( NamingException e )
+ {
+ throw new GuardianException( "Failed to get denials for profile: " + dn );
+ }
+ Permission[] denialsArray = new Permission[denialsSet.size()];
+ denials = new Permissions( applicationName, ( Permission[] ) denialsSet.toArray( denialsArray ) );
+ }
+ else
+ {
+ denials = new Permissions( applicationName, new Permission[0] );
+ }
+
+ // -------------------------------------------------------------------------------
+ // process and assemble the profile's assigned roles
+ // -------------------------------------------------------------------------------
+
+ Attribute rolesAttribute = entry.get( "roles" );
+ if ( rolesAttribute != null )
+ {
+ Set rolesSet = new HashSet();
+ try
+ {
+ NamingEnumeration rolesEnumeration = rolesAttribute.getAll();
+ while ( rolesEnumeration.hasMore() )
+ {
+ String assignedRoleName = ( String ) rolesEnumeration.next();
+ rolesSet.add( this.roles.get( assignedRoleName ) );
+ }
+ }
+ catch ( NamingException e )
+ {
+ throw new GuardianException( "Failed to get roles for profile: " + dn );
+ }
+ Role[] rolesArray = new Role[rolesSet.size()];
+ roles = new Roles( applicationName, ( Role[] ) rolesSet.toArray( rolesArray ) );
+ }
+ else
+ {
+ roles = new Roles( applicationName, new Role[0] );
+ }
+
+ Attribute description = entry.get( "description" );
+ if ( description == null || description.size() == 0 )
+ {
+ profile = new Profile( this, profileId, userName, roles, grants, denials, disabled );
+ }
+ else
+ {
+ String desc = "null";
+ try
+ {
+ desc = ( String ) description.get();
+ }
+ catch ( NamingException e )
+ {
+ throw new GuardianException( "Failed to get description for profile: " + dn );
+ }
+ profile = new Profile( this, profileId, userName, roles, grants, denials, desc, disabled );
+ }
+
+ profileMap.put( profileId, profile );
+
+ Set profileIdSet = ( Set ) userProfilesMap.get( userName );
+ if ( profileIdSet == null )
+ {
+ profileIdSet = new HashSet();
+ userProfilesMap.put( userName, profileIdSet );
+ }
+ profileIdSet.add( profileId );
+
+ if ( log.isDebugEnabled() )
+ {
+ log.debug( "loaded profile '" + profileId + "' in application '" + applicationName + "'" );
+ }
+ }
+ }
+
+
+ public Profile getProfile( String userName ) throws GuardianException
+ {
+ if ( isClosed )
+ {
+ throw new IllegalStateException( "This policy object has been closed." );
+ }
+
+ if ( profileMap.containsKey( userName ) )
+ {
+ return ( Profile ) profileMap.get( userName );
+ }
+
+ return null;
+ }
+
+
+ public void close() throws GuardianException
+ {
+ isClosed = true;
+ }
+
+
+ static String getApplicationName( String principalDN )
+ {
+ String rdn = principalDN.split( "," )[0].trim();
+ String[] rdnPair = rdn.split( "=" );
+
+ if ( ! rdnPair[0].trim().equalsIgnoreCase( "appName" ) )
+ {
+ throw new IllegalArgumentException( "Application principal name '" + principalDN
+ + "' is not an application DN" );
+ }
+
+ return rdnPair[1].trim();
+ }
+
+
+ public boolean removePolicyListener( PolicyChangeListener listener )
+ {
+ throw new RuntimeException( "Not implemented yet!" );
+ }
+
+
+ public boolean addPolicyListener( PolicyChangeListener listener )
+ {
+ throw new RuntimeException( "Not implemented yet!" );
+ }
+
+
+ public Set getDependentProfileNames( Role role ) throws GuardianException
+ {
+ throw new RuntimeException( "Not implemented yet!" );
+ }
+
+
+ public Set getDependentProfileNames( Permission permission ) throws GuardianException
+ {
+ throw new RuntimeException( "Not implemented yet!" );
+ }
+
+
+ public Set getUserProfileIds( String userName ) throws GuardianException
+ {
+ Set profileSet = ( Set ) userProfilesMap.get( userName );
+ if ( profileSet == null )
+ {
+ return Collections.EMPTY_SET;
+ }
+ return Collections.unmodifiableSet( profileSet );
+ }
+
+
+ public Iterator getProfileIdIterator()
+ {
+ return profileMap.keySet().iterator();
+ }
+
+
+ public Profile getAdminProfile()
+ {
+ return adminProfile;
+ }
+}