You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by vt...@apache.org on 2004/02/16 02:52:42 UTC
svn commit: rev 6675 - in incubator/directory/janus/trunk/authentication/impl: . src src/java src/java/org src/java/org/apache src/java/org/apache/janus src/java/org/apache/janus/authentication src/java/org/apache/janus/authentication/realm src/test src/test/org src/test/org/apache src/test/org/apache/janus src/test/org/apache/janus/authentication src/test/org/apache/janus/authentication/realm
Author: vtence
Date: Sun Feb 15 17:52:41 2004
New Revision: 6675
Added:
incubator/directory/janus/trunk/authentication/impl/project.xml
- copied, changed from rev 6667, incubator/directory/janus/trunk/authentication/api/project.xml
incubator/directory/janus/trunk/authentication/impl/src/
incubator/directory/janus/trunk/authentication/impl/src/java/
incubator/directory/janus/trunk/authentication/impl/src/java/org/
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/DefaultSubject.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/AbstractCredentialCollection.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultAuthenticator.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultCredentialCollection.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/AbstractPrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/DefaultRealm.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/GroupPrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/UsernamePrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/test/
incubator/directory/janus/trunk/authentication/impl/src/test/org/
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/CatPrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DefaultSubjectTest.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DogPrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultAuthenticatorTest.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultCredentialCollectionTest.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/FruitPrincipal.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/GroupSupportRealm.java
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/realm/
incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/realm/DefaultRealmTest.java
Log:
o Added authentication impl
Copied: incubator/directory/janus/trunk/authentication/impl/project.xml (from rev 6667, incubator/directory/janus/trunk/authentication/api/project.xml)
==============================================================================
--- incubator/directory/janus/trunk/authentication/api/project.xml (original)
+++ incubator/directory/janus/trunk/authentication/impl/project.xml Sun Feb 15 17:52:41 2004
@@ -2,14 +2,21 @@
<project>
<extend>${basedir}/../../project.xml</extend>
- <name>Janus Authentication API</name>
- <id>janus-authentication-api</id>
+ <name>Janus Authentication API Implementation</name>
+ <id>janus-authentication-impl</id>
<package>org.apache.janus.authentication</package>
- <shortDescription>Janus Authentication API</shortDescription>
+ <shortDescription>Janus Authentication API Implementation</shortDescription>
<description>
- API for the Janus Security Framework
+ Implementation of the Janus Security Framework Authentication API
</description>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>janus-authentication-api</artifactId>
+ <version>${pom.currentVersion}</version>
+ </dependency>
+ </dependencies>
</project>
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/DefaultSubject.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/DefaultSubject.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultSubject implements Subject
+{
+ private final Set m_principals;
+ private boolean m_readOnly;
+
+ public DefaultSubject()
+ {
+ m_principals = new HashSet();
+ }
+
+ public boolean addPrincipal( Principal principal )
+ {
+ assertWritable();
+ return m_principals.add( principal );
+ }
+
+ public boolean addAllPrincipals( Collection principals )
+ {
+ boolean changed = false;
+ for ( Iterator it = principals.iterator(); it.hasNext(); )
+ {
+ final Principal p = (Principal) it.next();
+ changed |= addPrincipal( p );
+ }
+
+ return changed;
+ }
+
+ public boolean removePrincipal( Principal principal )
+ {
+ assertWritable();
+ return m_principals.remove( principal );
+ }
+
+ public boolean removeAllPrincipals( Collection principals )
+ {
+ boolean changed = false;
+ for ( Iterator it = principals.iterator(); it.hasNext(); )
+ {
+ final Principal p = (Principal) it.next();
+ changed |= removePrincipal( p );
+ }
+
+ return changed;
+ }
+
+ public Set getPrincipals()
+ {
+ return Collections.unmodifiableSet( m_principals );
+ }
+
+ public Set getPrincipals( Class c )
+ {
+ final Set subSet = new HashSet();
+
+ for ( Iterator it = m_principals.iterator(); it.hasNext(); )
+ {
+ final Principal principal = (Principal) it.next();
+ if ( c.isInstance( principal ) ) subSet.add( principal );
+ }
+
+ return subSet;
+ }
+
+ public void makeReadOnly()
+ {
+ m_readOnly = true;
+ }
+
+ private void assertWritable()
+ {
+ if ( m_readOnly )
+ {
+ throw new IllegalStateException( "In read-only state" );
+ }
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/AbstractCredentialCollection.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/AbstractCredentialCollection.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+/**
+ * Base class for <code>CredentialCollection</code>s implementations.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public abstract class AbstractCredentialCollection
+ implements CredentialCollection, Serializable
+{
+ /**
+ * The authentication method to use with this credential
+ * collection.
+ */
+ private String m_authMethod;
+
+ /**
+ * Sets the authentication method being used - or credential types.
+ */
+ protected void setAuthenticationMethod( String authMethod )
+ {
+ m_authMethod = authMethod;
+ }
+
+ public String getAuthenticationMethod()
+ {
+ return m_authMethod;
+ }
+
+ /**
+ * Returns a string describing this CredentialCollection object,
+ * providing information about all the credentials it contains.
+ */
+ public String toString()
+ {
+ final StringBuffer sb = new StringBuffer();
+ sb.append( "authentication-method=" ).append( m_authMethod );
+ sb.append( ", elements=" );
+
+ if ( elements().isEmpty() ) return sb.append( "{}" ).toString();
+
+ final Iterator i = elements().iterator();
+ sb.append( "{" );
+ while ( i.hasNext() )
+ {
+ sb.append( i.next().toString() );
+ sb.append( ", " );
+ }
+ // Remove trailing ", "
+ // This is safe since the elements collection is not empty
+ sb.setLength( sb.length() - 2 );
+ sb.append( "}" );
+
+ return sb.toString();
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( !(o instanceof CredentialCollection) ) return false;
+
+ final CredentialCollection credentialCollection = (CredentialCollection) o;
+
+ if ( !m_authMethod.equals(
+ credentialCollection.getAuthenticationMethod() ) )
+ {
+ return false;
+ }
+ if ( !elements().equals( credentialCollection.elements() ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int hashCode = m_authMethod.hashCode();
+ hashCode = hashCode * 29 + elements().hashCode();
+
+ return hashCode;
+ }
+}
\ No newline at end of file
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultAuthenticator.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultAuthenticator.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import org.apache.janus.DefaultSubject;
+import org.apache.janus.Subject;
+import org.apache.janus.authentication.realm.GroupSupport;
+import org.apache.janus.authentication.realm.Realm;
+
+import java.security.Principal;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultAuthenticator implements Authenticator
+{
+ private final Realm m_realm;
+
+ public DefaultAuthenticator( Realm realm )
+ {
+ m_realm = realm;
+ }
+
+ public Subject authenticate( CredentialCollection credentials )
+ throws AuthenticationException
+ {
+ Principal p = m_realm.validateCredentials( credentials );
+ if ( p == null )
+ {
+ throw new AuthenticationException( "Credentials rejected" );
+ }
+
+ DefaultSubject subject = new DefaultSubject();
+ subject.addPrincipal( p );
+
+ if ( m_realm instanceof GroupSupport )
+ {
+ Set groups = ((GroupSupport) m_realm).getGroupsForPrincipal( p );
+ subject.addAllPrincipals( groups );
+ }
+
+ return subject;
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultCredentialCollection.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/DefaultCredentialCollection.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultCredentialCollection extends AbstractCredentialCollection
+{
+ private final Set m_credentials;
+ private boolean m_readOnly;
+
+ public DefaultCredentialCollection( String authenticationMethod )
+ {
+ m_credentials = new HashSet();
+ setAuthenticationMethod( authenticationMethod );
+ }
+
+ public boolean add( Credential cred )
+ {
+ assertWritable();
+ return m_credentials.add( cred );
+ }
+
+ public boolean remove( Credential cred )
+ {
+ assertWritable();
+ return m_credentials.remove( cred );
+ }
+
+ public boolean isEmpty()
+ {
+ return m_credentials.isEmpty();
+ }
+
+ public CredentialCollection get( String type )
+ {
+ final DefaultCredentialCollection creds =
+ new DefaultCredentialCollection( getAuthenticationMethod() );
+
+ for ( Iterator it = m_credentials.iterator(); it.hasNext(); )
+ {
+ final Credential credential = (Credential) it.next();
+ if ( credential.getType().equals( type ) ) creds.add( credential );
+ }
+
+ return creds;
+ }
+
+ public Collection elements()
+ {
+ return Collections.unmodifiableCollection( m_credentials );
+ }
+
+ public void makeReadOnly()
+ {
+ m_readOnly = true;
+ }
+
+ private void assertWritable()
+ {
+ if ( m_readOnly )
+ {
+ throw new IllegalStateException( "In read-only state" );
+ }
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/AbstractPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/AbstractPrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication.realm;
+
+import java.security.Principal;
+
+/**
+ * A principal name is unique within the set
+ * of principals of the same type.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public abstract class AbstractPrincipal implements Principal
+{
+ private final String m_name;
+
+ public AbstractPrincipal( String name )
+ {
+ if ( name == null ) throw new NullPointerException( "name" );
+ if ( name.equals( "" ) )
+ {
+ throw new IllegalArgumentException( "Empty name" );
+ }
+ m_name = name;
+ }
+
+ public String getName()
+ {
+ return m_name;
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( !(o instanceof AbstractPrincipal) ) return false;
+
+ final AbstractPrincipal abstractPrincipal = (AbstractPrincipal) o;
+
+ if ( !m_name.equals( abstractPrincipal.m_name ) ) return false;
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return m_name.hashCode();
+ }
+
+ public String toString()
+ {
+ return "name=" + m_name;
+ }
+}
+
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/DefaultRealm.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/DefaultRealm.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication.realm;
+
+import org.apache.janus.authentication.Credential;
+import org.apache.janus.authentication.CredentialCollection;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Support username-authentication only and assumes a single password per username.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultRealm implements MutableRealm, GroupSupport
+{
+ private final Map m_credentials;
+ private final Map m_principals;
+
+ public DefaultRealm()
+ {
+ m_credentials = new HashMap();
+ m_principals = new HashMap();
+ }
+
+ public Set getPrincipals( Class c )
+ {
+ if ( c.equals( UsernamePrincipal.class ) )
+ {
+ return Collections.unmodifiableSet( m_credentials.keySet() );
+ }
+
+ if ( c.equals( GroupPrincipal.class ) )
+ {
+ return Collections.unmodifiableSet( m_principals.keySet() );
+ }
+
+ return null;
+ }
+
+ public Principal addPrincipal( String principalName )
+ throws PrincipalAlreadyExistsException
+ {
+ Principal user = new UsernamePrincipal( principalName );
+
+ if ( m_credentials.containsKey( user ) )
+ {
+ throw new PrincipalAlreadyExistsException(
+ "Principal already a member", user );
+ }
+
+ m_credentials.put( user, new HashSet() );
+ return user;
+ }
+
+ public Principal addGroup( String groupName )
+ throws GroupAlreadyExistsException
+ {
+ Principal group = new GroupPrincipal( groupName );
+
+ if ( m_principals.containsKey( group ) )
+ {
+ throw new GroupAlreadyExistsException( "Group already a member",
+ group );
+ }
+
+ m_principals.put( group, new HashSet() );
+ return group;
+ }
+
+ public boolean addCredentialToPrincipal( Principal p, Credential c )
+ {
+ Set creds = (Set) m_credentials.get( p );
+ if ( creds == null )
+ {
+ throw new IllegalArgumentException( "Imposter: " + p );
+ }
+ return creds.add( c );
+ }
+
+ public Principal validateCredentials( CredentialCollection credentials )
+ {
+ String authMethod = credentials.getAuthenticationMethod();
+ if ( !"username-password".equals( authMethod ) )
+ {
+ throw new UnsupportedOperationException(
+ "Authentication method: " + authMethod );
+ }
+ Credential username = getUsername( credentials );
+ if ( username == null ) return null;
+ Credential password = getPassword( credentials );
+ if ( password == null ) return null;
+
+ Principal identity = new UsernamePrincipal(
+ (String) username.getValue() );
+ Set creds = (Set) m_credentials.get( identity );
+ if ( creds == null || !creds.contains( password ) ) return null;
+
+ return identity;
+ }
+
+ public Set getGroupsForPrincipal( Principal principal )
+ {
+ Collection groups = m_principals.keySet();
+
+ Set memberOf = new HashSet();
+ for ( Iterator it = groups.iterator(); it.hasNext(); )
+ {
+ final Principal group = (Principal) it.next();
+ if ( isMember( group, principal ) ) memberOf.add( group );
+ }
+
+ return memberOf;
+ }
+
+ private Credential getPassword( CredentialCollection creds )
+ {
+ CredentialCollection passwords = creds.get( "password" );
+ if ( passwords.isEmpty() ) return null;
+ if ( passwords.elements().size() > 1 )
+ {
+ throw new IllegalArgumentException(
+ "Only one password is possible" );
+ }
+ return (Credential) passwords.elements().iterator().next();
+ }
+
+ private Credential getUsername( CredentialCollection creds )
+ {
+ CredentialCollection usernames = creds.get( "username" );
+ if ( usernames.isEmpty() ) return null;
+ if ( usernames.elements().size() > 1 )
+ {
+ throw new IllegalArgumentException(
+ "Only one username is possible" );
+ }
+ return (Credential) usernames.elements().iterator().next();
+ }
+
+ public Set getPrincipalsForGroup( Principal group )
+ {
+ Set principals = (Set) m_principals.get( group );
+ if ( principals == null ) principals = Collections.EMPTY_SET;
+
+ return principals;
+ }
+
+ public boolean addPrincipalToGroup( Principal group, Principal principal )
+ {
+ assertNotSame( group, principal );
+ assertIsGroup( group );
+ assertIsInRealm( principal );
+ assertNotAMember( principal, group );
+
+ Set principals = (Set) m_principals.get( group );
+ return principals.add( principal );
+ }
+
+ private void assertNotSame( Principal group, Principal principal )
+ {
+ if ( group.equals( principal ) )
+ {
+ throw new IllegalArgumentException(
+ "Can't add group to itself:" + group.getName() );
+ }
+ }
+
+ private void assertNotAMember( Principal principal, Principal group )
+ {
+ if ( isGroup( principal ) && isMember( principal, group ) )
+ {
+ throw new IllegalArgumentException( "Cyclic membership detected" );
+ }
+ }
+
+ private void assertIsInRealm( Principal principal )
+ {
+ if ( !isPrincipal( principal ) && !isGroup( principal ) )
+ {
+ throw new IllegalArgumentException(
+ "Not a valid principal or group: " + principal.getName() );
+ }
+ }
+
+ private void assertIsGroup( Principal group )
+ {
+ if ( !isGroup( group ) )
+ {
+ throw new IllegalArgumentException(
+ "Not a valid group: " + group.getName() );
+ }
+ }
+
+ private boolean isMember( Principal group, Principal principal )
+ {
+ Set members = (Set) m_principals.get( group );
+ if ( members.contains( principal ) ) return true;
+
+ for ( Iterator it = members.iterator(); it.hasNext(); )
+ {
+ final Principal member = (Principal) it.next();
+ if ( isGroup( member ) )
+ {
+ if ( isMember( member, principal ) ) return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean isGroup( Principal p )
+ {
+ return m_principals.keySet().contains( p );
+ }
+
+ private boolean isPrincipal( Principal p )
+ {
+ return m_credentials.keySet().contains( p );
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/GroupPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/GroupPrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication.realm;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class GroupPrincipal extends AbstractPrincipal
+{
+ public GroupPrincipal( String name )
+ {
+ super( name );
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( !(o instanceof GroupPrincipal) ) return false;
+
+ return super.equals( o );
+ }
+
+ public String toString()
+ {
+ return "[GroupPrincipal: " + super.toString() + "]";
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/UsernamePrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/java/org/apache/janus/authentication/realm/UsernamePrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication.realm;
+
+/**
+ * A principal representing a login username.
+ *
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class UsernamePrincipal extends AbstractPrincipal
+{
+ public UsernamePrincipal( String username )
+ {
+ super( username );
+ }
+
+ public boolean equals( Object o )
+ {
+ if ( this == o ) return true;
+ if ( !(o instanceof UsernamePrincipal) ) return false;
+
+ return super.equals( o );
+ }
+
+ public String toString()
+ {
+ return "[UsernamePrincipal: " + super.toString() + "]";
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/CatPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/CatPrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus;
+
+import org.apache.janus.authentication.realm.AbstractPrincipal;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class CatPrincipal extends AbstractPrincipal
+{
+ public CatPrincipal( String name )
+ {
+ super( name );
+ }
+}
\ No newline at end of file
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DefaultSubjectTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DefaultSubjectTest.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus;
+
+import junit.framework.TestCase;
+
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultSubjectTest extends TestCase
+{
+ public static void main( String[] args )
+ {
+ junit.textui.TestRunner.run( DefaultSubjectTest.class );
+ }
+
+ public void testContainsNoPrincipalByDefault()
+ {
+ DefaultSubject subject = new DefaultSubject();
+ assertTrue( "Subject should be constructed empty",
+ subject.getPrincipals().isEmpty() );
+ }
+
+ public void testMaintainsASetOfPrincipals()
+ {
+ Principal labrador = new DogPrincipal( "labrador" );
+ Principal rott = new DogPrincipal( "rott" );
+ Principal doberman = new DogPrincipal( "doberman" );
+ Principal dane = new DogPrincipal( "dane" );
+ DefaultSubject subject = new DefaultSubject();
+ subject.addPrincipal( labrador );
+ subject.addPrincipal( rott );
+ Collection remaining = new ArrayList();
+ remaining.add( doberman );
+ remaining.add( dane );
+ subject.addAllPrincipals( remaining );
+
+ Collection expected = new HashSet();
+ expected.add( labrador );
+ expected.add( rott );
+ expected.add( doberman );
+ expected.add( dane );
+ assertEquals( "Wrong principal set after addition", expected,
+ subject.getPrincipals() );
+
+ // Test removal as well
+ subject.removePrincipal( rott );
+ subject.removeAllPrincipals( remaining );
+
+ expected = new HashSet();
+ expected.add( labrador );
+ assertEquals( "Wrong principal set after removal", expected,
+ subject.getPrincipals() );
+ }
+
+ public void testPreventsModificationOfUnderlyingSet()
+ {
+ DefaultSubject subject = new DefaultSubject();
+ try
+ {
+ subject.getPrincipals().add( new Object() );
+ fail( "Underlying collection is modifiable" );
+ }
+ catch ( UnsupportedOperationException expected )
+ {
+ }
+ }
+
+ public void testIgnoresAdditionOfDuplicatePrincipals()
+ {
+ Principal alleyCat = new CatPrincipal( "alleyCat" );
+ DefaultSubject subject = new DefaultSubject();
+ assertTrue( "First time add failed", subject.addPrincipal( alleyCat ) );
+ assertFalse( "Add twice worked", subject.addPrincipal( alleyCat ) );
+ }
+
+ public void testIgnoresRemovalOfUnknownPrincipals()
+ {
+ Principal alleyCat = new CatPrincipal( "alleyCat" );
+ DefaultSubject subject = new DefaultSubject();
+ subject.addPrincipal( alleyCat );
+ assertTrue( "First time remove failed",
+ subject.removePrincipal( alleyCat ) );
+ assertFalse( "Remove twice worked",
+ subject.removePrincipal( alleyCat ) );
+ }
+
+ public void testReturnsPrincipalSubsetBasedOnClass()
+ {
+ Principal labrador = new DogPrincipal( "labrador" );
+ Principal alleyCat = new CatPrincipal( "alleyCat" );
+ DefaultSubject subject = new DefaultSubject();
+ subject.addPrincipal( labrador );
+ subject.addPrincipal( alleyCat );
+
+ Collection expected = new HashSet();
+ expected.add( labrador );
+ assertEquals( "Wrong principal subset", expected,
+ subject.getPrincipals( DogPrincipal.class ) );
+ }
+
+ public void testCanBeFrozen()
+ {
+ DefaultSubject subject = new DefaultSubject();
+ subject.makeReadOnly();
+ try
+ {
+ subject.addPrincipal( new CatPrincipal( "alleyCat" ) );
+ fail( "Subject still read-write" );
+ }
+ catch ( IllegalStateException expected )
+ {
+ }
+
+ try
+ {
+ subject.removePrincipal( new CatPrincipal( "alleyCat" ) );
+ fail( "Subject still read-write" );
+ }
+ catch ( IllegalStateException expected )
+ {
+ }
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DogPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/DogPrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus;
+
+import org.apache.janus.authentication.realm.AbstractPrincipal;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DogPrincipal extends AbstractPrincipal
+{
+ public DogPrincipal( String name )
+ {
+ super( name );
+ }
+}
\ No newline at end of file
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultAuthenticatorTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultAuthenticatorTest.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import com.mockobjects.dynamic.C;
+import com.mockobjects.dynamic.Mock;
+import junit.framework.TestCase;
+import org.apache.janus.Subject;
+import org.apache.janus.authentication.realm.GroupPrincipal;
+import org.apache.janus.authentication.realm.Realm;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultAuthenticatorTest extends TestCase
+{
+ private DefaultAuthenticator m_authenticator;
+ private Mock m_mockRealm;
+
+ public static void main( String[] args )
+ {
+ junit.textui.TestRunner.run( DefaultAuthenticatorTest.class );
+ }
+
+ protected void setUp() throws Exception
+ {
+ m_mockRealm
+ = new Mock( GroupSupportRealm.class );
+ m_authenticator
+ = new DefaultAuthenticator( (Realm) m_mockRealm.proxy() );
+ }
+
+ public void testAuthentication()
+ {
+ DefaultCredentialCollection credentials = new DefaultCredentialCollection(
+ "taste" );
+ m_mockRealm.matchAndReturn( "validateCredentials", C.same( credentials ),
+ new FruitPrincipal( "banana" ) );
+ Set groups = new HashSet();
+ groups.add( new GroupPrincipal( "fruit" ) );
+ groups.add( new GroupPrincipal( "yellow" ) );
+ m_mockRealm.matchAndReturn( "getGroupsForPrincipal",
+ new FruitPrincipal( "banana" ), groups );
+
+ Subject subject = null;
+ try
+ {
+ subject = m_authenticator.authenticate( credentials );
+ }
+ catch ( AuthenticationException e )
+ {
+ fail( "Login failed" );
+ }
+ assertTrue( "Principal was not added to subject",
+ subject.getPrincipals().contains(
+ new FruitPrincipal( "banana" ) ) );
+ assertTrue( "Groups were not added to subject",
+ subject.getPrincipals().containsAll( groups ) );
+ }
+
+ public void testAuthenticationFailure()
+ {
+ m_mockRealm.matchAndReturn( "validateCredentials", C.ANY_ARGS, null );
+
+ try
+ {
+ m_authenticator.authenticate(
+ new DefaultCredentialCollection( "dummy" ) );
+ fail( "Login has not failed" );
+ }
+ catch ( AuthenticationException expected )
+ {
+ assertTrue( true );
+ }
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultCredentialCollectionTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/DefaultCredentialCollectionTest.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultCredentialCollectionTest extends TestCase
+{
+ public static void main( String[] args )
+ {
+ junit.textui.TestRunner.run( DefaultCredentialCollectionTest.class );
+ }
+
+ public void testReturnsSubsetOfCredentialsBasedOnType()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ creds.add( new Credential( "username", "joe" ) );
+ creds.add( new Credential( "password", "turtle" ) );
+ creds.add( new Credential( "password", "sea" ) );
+
+ Collection expected = new ArrayList();
+ expected.add( new Credential( "password", "turtle" ) );
+ expected.add( new Credential( "password", "sea" ) );
+ CredentialCollection subCollection = creds.get( "password" );
+ Collection actual = new ArrayList( subCollection.elements() );
+ assertEquals( "Wrong number of credentials in subset", expected.size(),
+ actual.size() );
+
+ actual.removeAll( expected );
+ assertTrue( "Too many credentials in subset", actual.isEmpty() );
+
+ expected.removeAll( subCollection.elements() );
+ assertTrue( "Too few credentials in subset", expected.isEmpty() );
+ }
+
+ public void testSubCollectionKeepsSameAuthenticationMethod()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ Credential username = new Credential( "username", "joe" );
+ Credential password = new Credential( "password", "turtle" );
+ creds.add( username );
+ creds.add( password );
+
+ CredentialCollection subCollection = creds.get( "password" );
+ assertEquals( "Different authentication methods", creds.getAuthenticationMethod(),
+ subCollection.getAuthenticationMethod() );
+ }
+
+ public void testCanBeFrozen()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ creds.makeReadOnly();
+
+ Credential username = new Credential( "username", "joe" );
+ try
+ {
+ creds.add( username );
+ fail( "Credential collection still read-write" );
+ }
+ catch ( IllegalStateException expected )
+ {
+ }
+
+ try
+ {
+ creds.remove( username );
+ fail( "Credential collection still read-write" );
+ }
+ catch ( IllegalStateException expected )
+ {
+ }
+ }
+
+ public void testPreventsChangeOfUnderlyingCollection()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ try
+ {
+ creds.elements().add( new Credential( "username", "joe" ) );
+ fail( "Can change underlying collection" );
+ }
+ catch ( UnsupportedOperationException expected )
+ {
+ }
+ assertTrue( "Not longer empty", creds.isEmpty() );
+ }
+
+ public void testDuplicatesAreIgnoredOnAdd()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ Credential username = new Credential( "username", "joe" );
+ assertTrue( "First add failed", creds.add( username ) );
+ assertFalse( "Second add worked", creds.add( username ) );
+ }
+
+ public void testUnknownsAreIgnoredOnRemove()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "auth-method" );
+ Credential username = new Credential( "username", "joe" );
+ creds.add( username );
+ assertTrue( "First remove failed", creds.remove( username ) );
+ assertFalse( "Second remove worked", creds.remove( username ) );
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/FruitPrincipal.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/FruitPrincipal.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import org.apache.janus.authentication.realm.AbstractPrincipal;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class FruitPrincipal extends AbstractPrincipal
+{
+ public FruitPrincipal( String name )
+ {
+ super( name );
+ }
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/GroupSupportRealm.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/GroupSupportRealm.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication;
+
+import org.apache.janus.authentication.realm.Realm;
+import org.apache.janus.authentication.realm.GroupSupport;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+
+public interface GroupSupportRealm extends Realm, GroupSupport
+{
+}
Added: incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/realm/DefaultRealmTest.java
==============================================================================
--- (empty file)
+++ incubator/directory/janus/trunk/authentication/impl/src/test/org/apache/janus/authentication/realm/DefaultRealmTest.java Sun Feb 15 17:52:41 2004
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.apache.janus.authentication.realm;
+
+import junit.framework.TestCase;
+import org.apache.janus.authentication.Credential;
+import org.apache.janus.authentication.DefaultCredentialCollection;
+
+import java.security.Principal;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author <a href="mailto:directory-dev@incubator.apache.org">Apache Directory Project</a>
+ */
+public class DefaultRealmTest extends TestCase
+{
+ private DefaultRealm m_realm;
+
+ public static void main( String[] args )
+ {
+ junit.textui.TestRunner.run( DefaultRealmTest.class );
+ }
+
+ protected void setUp() throws Exception
+ {
+ m_realm = new DefaultRealm();
+ }
+
+ public void testAddsUsernamePrincipals() throws Exception
+ {
+ assertEquals( "Wrong principal was added to the realm",
+ new UsernamePrincipal( "joe" ), m_realm.addPrincipal( "joe" ) );
+ assertTrue( "Principal not found in realm",
+ m_realm.getPrincipals( UsernamePrincipal.class ).contains(
+ new UsernamePrincipal( "joe" ) ) );
+ }
+
+ public void testDuplicatePrincipalsAreNotAllowed() throws Exception
+ {
+ m_realm.addPrincipal( "joe" );
+ try
+ {
+ m_realm.addPrincipal( "joe" );
+ fail( "Duplicate principal added" );
+ }
+ catch ( PrincipalAlreadyExistsException expected )
+ {
+ }
+ }
+
+ public void testAdditionOfCredential() throws Exception
+ {
+ m_realm.addPrincipal( "john" );
+ m_realm.addCredentialToPrincipal( new UsernamePrincipal( "john" ),
+ new Credential( "password", "banana" ) );
+ assertFalse( "Credential was not added the first time",
+ m_realm.addCredentialToPrincipal(
+ new UsernamePrincipal( "john" ),
+ new Credential( "password", "banana" ) ) );
+ }
+
+ public void testAdditionOfCredentialsToImposterIsRefused()
+ {
+ try
+ {
+ m_realm.addCredentialToPrincipal(
+ new UsernamePrincipal( "freddy" ),
+ new Credential( "password", "banana" ) );
+ fail( "Addition of credential to imposter possible" );
+ }
+ catch ( IllegalArgumentException expected )
+ {
+ }
+ }
+
+ public void testAddsGroupPrincipals() throws GroupAlreadyExistsException
+ {
+ assertEquals( "Wrong group was added to the realm",
+ new GroupPrincipal( "The Does" ),
+ m_realm.addGroup( "The Does" ) );
+ assertTrue( "Group not found in realm",
+ m_realm.getPrincipals( GroupPrincipal.class ).contains(
+ new GroupPrincipal( "The Does" ) ) );
+ }
+
+ public void testDuplicateGroupsAreNotAllowed() throws Exception
+ {
+ m_realm.addGroup( "The Does" );
+ try
+ {
+ m_realm.addGroup( "The Does" );
+ fail( "Duplicate group added" );
+ }
+ catch ( GroupAlreadyExistsException expected )
+ {
+ }
+ }
+
+ public void testAdditionOfPrincipalToGroup() throws Exception
+ {
+ Principal group = m_realm.addGroup( "The Does" );
+ Principal principal = m_realm.addPrincipal( "John Doe" );
+ assertTrue( "Principal not added to group",
+ m_realm.addPrincipalToGroup( group, principal ) );
+ assertTrue( "Principal not a member of group",
+ m_realm.getPrincipalsForGroup( group ).contains( principal ) );
+ }
+
+ public void testAdditionOfSubGroupToGroup() throws Exception
+ {
+ Principal group = m_realm.addGroup( "The Does" );
+ Principal subGroup = m_realm.addGroup( "The Children" );
+ m_realm.addPrincipalToGroup( group, subGroup );
+ assertTrue( "Principal not a member of group",
+ m_realm.getPrincipalsForGroup( group ).contains( subGroup ) );
+ }
+
+ public void testCyclicMembershipIsProhibited() throws Exception
+ {
+ Principal group = m_realm.addGroup( "jazzmen" );
+ Principal subGroup = m_realm.addGroup( "saxophonists" );
+ m_realm.addPrincipalToGroup( group, subGroup );
+ try
+ {
+ m_realm.addPrincipalToGroup( subGroup, group );
+ fail( "Cyclic dependencies in group members" );
+ }
+ catch ( IllegalArgumentException expected )
+ {
+ }
+ }
+
+ public void testCredentialsValidation() throws Exception
+ {
+ Principal joe = m_realm.addPrincipal( "joe" );
+ m_realm.addCredentialToPrincipal( joe,
+ new Credential( "password", "supersize-me!" ) );
+
+ DefaultCredentialCollection valid = new DefaultCredentialCollection(
+ "username-password" );
+ valid.add( new Credential( "username", "joe" ) );
+ valid.add( new Credential( "password", "supersize-me!" ) );
+
+ assertEquals( "Authentication failed with correct password",
+ new UsernamePrincipal( "joe" ),
+ m_realm.validateCredentials( valid ) );
+
+ DefaultCredentialCollection invalid = new DefaultCredentialCollection(
+ "username-password" );
+ invalid.add( new Credential( "username", "joe" ) );
+ invalid.add( new Credential( "password", "noclue" ) );
+
+ assertEquals( "Authentication succeeded with invalid password", null,
+ m_realm.validateCredentials( invalid ) );
+
+ DefaultCredentialCollection unknown = new DefaultCredentialCollection(
+ "username-password" );
+ unknown.add( new Credential( "username", "garfield" ) );
+ unknown.add( new Credential( "password", "fish" ) );
+
+ assertEquals( "Authentication succeeded for unknown user", null,
+ m_realm.validateCredentials( unknown ) );
+ }
+
+ public void testCredentialCollectionShouldContainExactlyOneUsername()
+ {
+ DefaultCredentialCollection missingUsername = new DefaultCredentialCollection(
+ "username-password" );
+ missingUsername.add( new Credential( "password", "noclue" ) );
+ assertEquals( "Invalid principal returned", null,
+ m_realm.validateCredentials( missingUsername ) );
+
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "username-password" );
+ creds.add( new Credential( "username", "john" ) );
+ creds.add( new Credential( "username", "joe" ) );
+ creds.add( new Credential( "password", "pasta" ) );
+ try
+ {
+ m_realm.validateCredentials( creds );
+ fail( "More than one username was accepted" );
+ }
+ catch ( IllegalArgumentException expected )
+ {
+ }
+ }
+
+ public void testCredentialCollectionShouldContainExactlyOnePassword()
+ {
+ DefaultCredentialCollection missingPassword = new DefaultCredentialCollection(
+ "username-password" );
+ missingPassword.add( new Credential( "username", "joe" ) );
+ assertEquals( "Invalid principal returned", null,
+ m_realm.validateCredentials( missingPassword ) );
+
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "username-password" );
+ creds.add( new Credential( "username", "john" ) );
+ creds.add( new Credential( "password", "pasta" ) );
+ creds.add( new Credential( "password", "pizza" ) );
+ try
+ {
+ m_realm.validateCredentials( creds );
+ fail( "More than one password was accepted" );
+ }
+ catch ( IllegalArgumentException expected )
+ {
+ }
+ }
+
+ public void testUsernamePasswordIsTheSoleAuthenticationMethodSupported()
+ {
+ DefaultCredentialCollection creds = new DefaultCredentialCollection(
+ "X509Cert" );
+ try
+ {
+ m_realm.validateCredentials( creds );
+ fail( "Unsupported authentication method considered valid" );
+ }
+ catch ( UnsupportedOperationException expected )
+ {
+ }
+ }
+
+ public void testGroupMembershipIsRecursive() throws Exception
+ {
+ Principal theDoes = m_realm.addGroup( "The Does" );
+ Principal theJazzMen = m_realm.addGroup( "The JazzMen" );
+ Principal theSaxophonists = m_realm.addGroup( "The Saxophonists" );
+ m_realm.addPrincipalToGroup( theJazzMen, theSaxophonists );
+ m_realm.addGroup( "The Others" );
+
+ Principal johnDoe = m_realm.addPrincipal( "John Doe" );
+ m_realm.addPrincipalToGroup( theDoes, johnDoe );
+ m_realm.addPrincipalToGroup( theSaxophonists, johnDoe );
+
+ Collection actual = m_realm.getGroupsForPrincipal( johnDoe );
+ Set expected = new HashSet();
+ expected.add( theDoes );
+ expected.add( theJazzMen );
+ expected.add( theSaxophonists );
+ assertEquals( "Wrong membership", expected, actual );
+ }
+
+ public void testGroupIsNotSelfContained() throws Exception
+ {
+ Principal theDoes = m_realm.addGroup( "The Does" );
+ assertTrue( "Group self-contained",
+ m_realm.getGroupsForPrincipal( theDoes ).isEmpty() );
+ }
+}