JBoss Identity SVN: r169 - in trunk: identity-impl/src/main/java/org/jboss/identity/impl/api and 5 other directories.
by jboss-identity-commits@lists.jboss.org
Author: bdaw
Date: 2008-12-17 12:15:21 -0500 (Wed, 17 Dec 2008)
New Revision: 169
Modified:
trunk/identity-api/src/main/java/org/jboss/identity/api/AttributesManager.java
trunk/identity-api/src/main/java/org/jboss/identity/api/Role.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/AttributesManagerImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/BinaryCredential.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/PasswordCredential.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RelationshipManagerImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/SimpleRoleImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java
trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/IdentityStore.java
Log:
++
Modified: trunk/identity-api/src/main/java/org/jboss/identity/api/AttributesManager.java
===================================================================
--- trunk/identity-api/src/main/java/org/jboss/identity/api/AttributesManager.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-api/src/main/java/org/jboss/identity/api/AttributesManager.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -168,7 +168,7 @@
* @param identity
* @param credentialType
*/
- void hasCredential(Identity identity, CredentialType credentialType);
+ boolean hasCredential(Identity identity, CredentialType credentialType) throws IdentityException;
/**
*
@@ -176,13 +176,13 @@
* @param credentials
* @return
*/
- boolean validateCredentials(Identity identity, Credential[] credentials);
+ boolean validateCredentials(Identity identity, Credential[] credentials) throws IdentityException;
/**
*
* @param identity
* @param credential
*/
- void updateCredential(Identity identity, Credential credential);
+ void updateCredential(Identity identity, Credential credential) throws IdentityException;
}
Modified: trunk/identity-api/src/main/java/org/jboss/identity/api/Role.java
===================================================================
--- trunk/identity-api/src/main/java/org/jboss/identity/api/Role.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-api/src/main/java/org/jboss/identity/api/Role.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -32,11 +32,6 @@
public interface Role
{
/**
- * @return id of this identity object
- */
- Object getId();
-
- /**
* @return description
*/
String getDescription();
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/AttributesManagerImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/AttributesManagerImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/AttributesManagerImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -31,6 +31,7 @@
import org.jboss.identity.api.Credential;
import org.jboss.identity.exception.IdentityException;
import org.jboss.identity.impl.NotYetImplementedException;
+import org.jboss.identity.spi.credential.IdentityObjectCredential;
import java.util.Set;
import java.util.Map;
@@ -42,6 +43,7 @@
*/
public class AttributesManagerImpl extends AbstractManager implements AttributesManager
{
+
public AttributesManagerImpl(IdentitySession session)
{
super(session);
@@ -104,42 +106,66 @@
public void removeAttributes(IdentityType identity, String[] attributes) throws IdentityException
{
getRepository().removeAttributes(getInvocationContext(), createIdentityObject(identity), attributes);
-
}
public boolean hasPasswordAttribute(Identity identity) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+ return getRepository().getSupportedFeatures().isCredentialSupported(createIdentityObject(identity).getIdentityType(), PasswordCredential.TYPE);
}
public boolean validatePasswordAttribute(Identity identity, String password) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+ return getRepository().validateCredential(getInvocationContext(), createIdentityObject(identity), new PasswordCredential(password));
}
public void updatePasswordAttribute(Identity identity, String password) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+ getRepository().updateCredential(getInvocationContext(), createIdentityObject(identity), new PasswordCredential(password));
}
- public void hasCredential(Identity identity, CredentialType credentialType)
+ public boolean hasCredential(Identity identity, CredentialType credentialType) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+ return getRepository().getSupportedFeatures().isCredentialSupported(createIdentityObject(identity).getIdentityType(), new SimpleCredentialTypeImpl(credentialType.getName()));
}
- public boolean validateCredentials(Identity identity, Credential[] credentials)
+ public boolean validateCredentials(Identity identity, Credential[] credentials) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+
+ for (Credential credential : credentials)
+ {
+ IdentityObjectCredential ioc = null;
+
+ //Handle only those credentials that implement SPI
+
+ if (credential instanceof IdentityObjectCredential)
+ {
+ ioc = (IdentityObjectCredential)ioc;
+ }
+ else
+ {
+ throw new IdentityException("Unsupported Credential implementation: " + credential.getClass());
+ }
+
+ // All credentials must pass
+
+ if (!getRepository().validateCredential(getInvocationContext(), createIdentityObject(identity), ioc))
+ {
+ return false;
+ }
+ }
+
+ return true;
}
- public void updateCredential(Identity identity, Credential credential)
+ public void updateCredential(Identity identity, Credential credential) throws IdentityException
{
- //TODO:NYI
- throw new NotYetImplementedException();
+ if (credential instanceof IdentityObjectCredential)
+ {
+ getRepository().updateCredential(getInvocationContext(), createIdentityObject(identity), (IdentityObjectCredential)credential);
+ }
+ else
+ {
+ throw new IdentityException("Unsupported Credential implementation: " + credential.getClass());
+ }
}
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/BinaryCredential.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/BinaryCredential.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/BinaryCredential.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -30,9 +30,11 @@
{
private final byte[] value;
+ public static final SimpleCredentialTypeImpl TYPE = new SimpleCredentialTypeImpl("BINARY");
+
public BinaryCredential(byte[] value)
{
- super(new SimpleCredentialTypeImpl("BINARY"));
+ super(TYPE);
this.value = value;
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/PasswordCredential.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/PasswordCredential.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/PasswordCredential.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -33,9 +33,11 @@
{
private final String value;
+ public static final SimpleCredentialTypeImpl TYPE = new SimpleCredentialTypeImpl("PASSWORD");
+
public PasswordCredential(String value)
{
- super(new SimpleCredentialTypeImpl("PASSWORD"));
+ super(TYPE);
this.value = value;
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RelationshipManagerImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RelationshipManagerImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RelationshipManagerImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -142,7 +142,7 @@
public <G extends IdentityType, I extends IdentityType> boolean isAssociated(Collection<G> parents, Collection<I> members) throws IdentityException
{
- //TODO: IdentityStore should have isRelationshipPresent method to improve this
+ //TODO: maybe IdentityStore should have isRelationshipPresent method to improve this?
for (Iterator<G> parentsIterator = parents.iterator(); parentsIterator.hasNext();)
{
@@ -152,21 +152,10 @@
{
IdentityType member = membersIterator.next();
- Collection<IdentityObjectRelationship> relationships = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(parent), createIdentityObject(member));
+ Collection<IdentityObjectRelationship> relationships = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(parent), createIdentityObject(member), MEMBER);
- boolean isRelated = false;
-
- for (Iterator<IdentityObjectRelationship> identityObjectRelationshipIterator = relationships.iterator(); identityObjectRelationshipIterator.hasNext();)
+ if (relationships.size() == 0)
{
- IdentityObjectRelationship rel = identityObjectRelationshipIterator.next();
- if (rel.getType().getName().equals(MEMBER.getName()))
- {
- isRelated = true;
- }
- }
-
- if (!isRelated)
- {
return false;
}
}
@@ -192,7 +181,7 @@
IdentityObjectType iot = getIdentityObjectType(groupType);
- //TODO inherited
+ //TODO Handle inherited
Collection<IdentityObject> ios = getRepository().findIdentityObject(getInvocationContext(), createIdentityObject(group), MEMBER, parent, convertSearchControls(controls));
@@ -260,10 +249,12 @@
{
List<Identity> identities = new LinkedList<Identity>();
- //TODO inherited
+ //TODO Handle inherited
Collection<IdentityObject> ios = getRepository().findIdentityObject(getInvocationContext(), createIdentityObject(group), MEMBER, true, convertSearchControls(controls));
+ //TODO: filter out groups....
+
for (IdentityObject io : ios)
{
identities.add(createIdentity(io));
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -34,6 +34,7 @@
import org.jboss.identity.exception.IdentityException;
import org.jboss.identity.spi.model.IdentityObjectRelationshipType;
import org.jboss.identity.spi.model.IdentityObjectRelationship;
+import org.jboss.identity.spi.model.IdentityObject;
import org.jboss.identity.spi.exception.OperationNotSupportedException;
import org.jboss.identity.impl.NotYetImplementedException;
@@ -145,7 +146,7 @@
IdentityObjectRelationship rel = getRepository().createRelationship(getInvocationContext(), createIdentityObject(identity), createIdentityObject(group), ROLE, roleType.getName(), false);
//TODO: null id - IdentityObjectRelationship doesn't have id
- return new SimpleRoleImpl(null, new SimpleRoleType(rel.getName()), createIdentity(rel.getFromIdentityObject()), createGroup(rel.getToIdentityObject()));
+ return new SimpleRoleImpl(new SimpleRoleType(rel.getName()), createIdentity(rel.getFromIdentityObject()), createGroup(rel.getToIdentityObject()));
}
@@ -161,9 +162,9 @@
public boolean hasRole(Identity identity, Group group, RoleType roleType) throws IdentityException
{
- //TODO: add hasRelationship to IdentityStore
+ //TODO: does separate hasRelationship method in IdentityStore makes sense?
- Set<IdentityObjectRelationship> rels = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identity), createIdentityObject(group));
+ Set<IdentityObjectRelationship> rels = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identity), createIdentityObject(group), ROLE);
for (IdentityObjectRelationship rel : rels)
{
@@ -183,18 +184,13 @@
public Collection<RoleType> findRoleTypes(Identity identity, Group group, IdentitySearchControl[] controls) throws IdentityException
{
- //TODO: improve IdentityStore SPI....
-
- Set<IdentityObjectRelationship> rels = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identity), createIdentityObject(group));
+ Set<IdentityObjectRelationship> rels = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identity), createIdentityObject(group), ROLE);
Set<RoleType> types = new HashSet<RoleType>();
for (IdentityObjectRelationship rel : rels)
{
- if (rel.getType().getName().equals(ROLE.getName()))
- {
- types.add(new SimpleRoleType(rel.getName()));
- }
+ types.add(new SimpleRoleType(rel.getName()));
}
return types;
@@ -265,6 +261,27 @@
public <T extends IdentityType> Collection<Role> findRoles(T identityType, RoleType roleType, IdentitySearchControl[] controls) throws IdentityException
{
- throw new NotYetImplementedException();
+ Set<Role> roles = new HashSet<Role>();
+
+ Set<IdentityObjectRelationship> relationships = null;
+
+ // If Identity then search for parent relationships
+ if (identityType instanceof Identity)
+ {
+ relationships = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identityType), ROLE, true, true, null);
+ }
+ // If Group then search for child relationships
+ else
+ {
+ relationships = getRepository().resolveRelationships(getInvocationContext(), createIdentityObject(identityType), ROLE, false, true, null);
+ }
+
+ for (IdentityObjectRelationship relationship : relationships)
+ {
+ roles.add(new SimpleRoleImpl(new SimpleRoleType(relationship.getName()), createIdentity(relationship.getFromIdentityObject()), createGroup(relationship.getToIdentityObject())));
+ }
+
+ return roles;
+
}
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/SimpleRoleImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/SimpleRoleImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/SimpleRoleImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -33,27 +33,19 @@
*/
public class SimpleRoleImpl implements Role
{
- private final Object id;
-
private final RoleType type;
private final Identity identity;
private final Group group;
- public SimpleRoleImpl(Object id, RoleType type, Identity identity, Group group)
+ public SimpleRoleImpl(RoleType type, Identity identity, Group group)
{
- this.id = id;
this.type = type;
this.identity = identity;
this.group = group;
}
- public Object getId()
- {
- return id;
- }
-
public Identity getIdentity()
{
return identity;
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -43,6 +43,8 @@
import org.jboss.identity.impl.api.SortByNameSearchControl;
import org.jboss.identity.impl.api.AttributeFilterSearchControl;
import org.jboss.identity.impl.api.NameFilterSearchControl;
+import org.jboss.identity.impl.NotYetImplementedException;
+import org.jboss.identity.impl.configuration.jaxb2.generated.RelationshipType;
import org.jboss.identity.api.Identity;
import java.util.Map;
@@ -91,6 +93,8 @@
private boolean allowNotDefinedAttributes = false;
+ private final Set<IdentityStore> configuredIdentityStores = new HashSet<IdentityStore>();
+
public FallbackIdentityStoreRepository(String id)
{
this.id = id;
@@ -102,6 +106,15 @@
{
super.bootstrap(configurationMD, bootstrappedIdentityStores, bootstrappedAttributeStores);
+ // Helper collection to keep all identity stores in use
+
+ if (getIdentityStoreMappings().size() > 0)
+ {
+ configuredIdentityStores.addAll(getIdentityStoreMappings().values());
+ }
+
+
+
this.configurationMD = configurationMD;
String asId = configurationMD.getDefaultAttributeStroeId();
@@ -115,6 +128,12 @@
if (isId != null && bootstrappedIdentityStores.keySet().contains(isId))
{
defaultIdentityStore = bootstrappedIdentityStores.get(isId);
+
+ if (!getIdentityStoreMappings().keySet().contains(defaultIdentityStore.getId()))
+ {
+ configuredIdentityStores.add(defaultIdentityStore);
+ }
+
}
String allowNotDefineAttributes = configurationMD.getOptionSingleValue(ALLOW_NOT_DEFINED_ATTRIBUTES);
@@ -523,7 +542,10 @@
defaultIdentityStore.removeRelationships(defaultTargetCtx, identity1, identity2, named);
}
- public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt, IdentityObject fromIdentity, IdentityObject toIdentity) throws IdentityException
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt,
+ IdentityObject fromIdentity,
+ IdentityObject toIdentity,
+ IdentityObjectRelationshipType relationshipType) throws IdentityException
{
IdentityStore fromStore = resolveIdentityStore(fromIdentity);
@@ -536,7 +558,7 @@
if (fromStore == toStore)
{
- return fromStore.resolveRelationships(toTargetCtx, fromIdentity, toIdentity);
+ return fromStore.resolveRelationships(toTargetCtx, fromIdentity, toIdentity, relationshipType);
}
@@ -550,30 +572,44 @@
defaultIdentityStore.createIdentityObject(defaultTargetCtx, toIdentity.getName(), toIdentity.getIdentityType());
}
- return defaultIdentityStore.resolveRelationships(defaultTargetCtx, fromIdentity, toIdentity);
- }
+ return defaultIdentityStore.resolveRelationships(defaultTargetCtx, fromIdentity, toIdentity, relationshipType);
+ }
- public String createRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx, IdentityObject identity, IdentityObjectRelationshipType relationshipType, boolean parent, boolean named, String name) throws IdentityException
{
- Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
+ IdentityStore store = resolveIdentityStore(identity);
+ Set<IdentityObjectRelationship> relationships = new HashSet<IdentityObjectRelationship>();
+
// For any IdentityStore that supports named relationships...
- for (IdentityStore identityStore : stores)
+ for (IdentityStore identityStore : configuredIdentityStores)
{
- if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ if (!identityStore.getSupportedFeatures().getSupportedRelationshipTypes().contains(relationshipType.getName()))
{
+ continue;
+ }
+
+ if (!named || (named && identityStore.getSupportedFeatures().isNamedRelationshipsSupported()))
+ {
IdentityStoreInvocationContext storeCtx = resolveInvocationContext(identityStore, ctx);
- identityStore.createRelationshipName(storeCtx, name);
-
+ relationships.addAll(identityStore.resolveRelationships(storeCtx, identity, relationshipType, parent, named, name));
}
}
- if (!getIdentityStoreMappings().values().contains(defaultIdentityStore) &&
- defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ return relationships;
+ }
+
+ public String createRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
+ {
+ // For any IdentityStore that supports named relationships...
+ for (IdentityStore identityStore : configuredIdentityStores)
{
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+ if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext storeCtx = resolveInvocationContext(identityStore, ctx);
+ identityStore.createRelationshipName(storeCtx, name);
- defaultIdentityStore.createRelationshipName(defaultCtx, name);
+ }
}
return name;
@@ -582,10 +618,8 @@
public String removeRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
{
- Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
-
// For any IdentityStore that supports named relationships...
- for (IdentityStore identityStore : stores)
+ for (IdentityStore identityStore : configuredIdentityStores)
{
if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
{
@@ -595,25 +629,15 @@
}
}
- if (!getIdentityStoreMappings().values().contains(defaultIdentityStore) &&
- defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
- {
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
-
- defaultIdentityStore.removeRelationshipName(defaultCtx, name);
- }
-
return name;
}
public Set<String> getRelationshipNames(IdentityStoreInvocationContext ctx, IdentityObjectSearchControl[] controls) throws IdentityException, OperationNotSupportedException
{
- Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
-
Set<String> results = new HashSet<String>();
// For any IdentityStore that supports named relationships...
- for (IdentityStore identityStore : stores)
+ for (IdentityStore identityStore : configuredIdentityStores)
{
if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
{
@@ -623,13 +647,6 @@
}
}
- if (defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
- {
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
-
- results.addAll(defaultIdentityStore.getRelationshipNames(defaultCtx, controls));
- }
-
return results;
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -55,6 +55,7 @@
import org.hibernate.ejb.HibernateEntityManagerFactory;
import org.hibernate.criterion.Restrictions;
import org.hibernate.HibernateException;
+import org.hibernate.Criteria;
import javax.persistence.NoResultException;
import javax.persistence.Query;
@@ -91,6 +92,29 @@
"select r from HibernateIdentityObjectRelationship r where r.fromIdentityObject like :fromIO and " +
"r.toIdentityObject like :toIO and r.type.name like :typeName and r.name.name like :name";
+// private final String QUERY_RELATIONSHIP_BY_FROM =
+// "select r from HibernateIdentityObjectRelationship r where r.fromIdentityObject like :fromIO";
+//
+// private final String QUERY_RELATIONSHIP_BY_FROM_NAMED =
+// "select r from HibernateIdentityObjectRelationship r where r.fromIdentityObject like :fromIO and " +
+// "r.name is not null";
+//
+// private final String QUERY_RELATIONSHIP_BY_FROM_NAME =
+// "select r from HibernateIdentityObjectRelationship r where r.fromIdentityObject like :fromIO and " +
+// "r.name.name = :name";
+//
+// private final String QUERY_RELATIONSHIP_BY_TO =
+// "select r from HibernateIdentityObjectRelationship r where r.toIdentityObject like :toIO";
+//
+// private final String QUERY_RELATIONSHIP_BY_TO_NAMED =
+// "select r from HibernateIdentityObjectRelationship r where r.toIdentityObject like :toIO and" +
+// "r.name is not null";
+//
+// private final String QUERY_RELATIONSHIP_BY_TO_NAME =
+// "select r from HibernateIdentityObjectRelationship r where r.toIdentityObject like :toIO and " +
+// "r.name.name = :name";
+
+
private final String QUERY_RELATIONSHIP_BY_IDENTITIES =
"select r from HibernateIdentityObjectRelationship r where " +
"(r.fromIdentityObject like :IO1 and r.toIdentityObject like :IO2) or " +
@@ -905,21 +929,83 @@
}
}
- public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx, IdentityObject fromIdentity, IdentityObject toIdentity) throws IdentityException
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx,
+ IdentityObject fromIdentity,
+ IdentityObject toIdentity,
+ IdentityObjectRelationshipType relationshipType) throws IdentityException
{
HibernateIdentityObject hio1 = safeGet(ctx, fromIdentity);
HibernateIdentityObject hio2 = safeGet(ctx, toIdentity);
- org.hibernate.Query query = getHibernateEntityManager(ctx).getSession().createQuery(QUERY_RELATIONSHIP_BY_FROM_TO)
- .setParameter("fromIO", hio1)
+ org.hibernate.Query query = null;
+
+ if (relationshipType == null)
+ {
+ query = getHibernateEntityManager(ctx).getSession().createQuery(QUERY_RELATIONSHIP_BY_FROM_TO);
+ }
+ else
+ {
+ query = getHibernateEntityManager(ctx).getSession().createQuery(QUERY_RELATIONSHIP_BY_FROM_TO_TYPE)
+ .setParameter("typeName", relationshipType.getName());
+
+ }
+
+ query.setParameter("fromIO", hio1)
.setParameter("toIO", hio2);
+
List<HibernateIdentityObjectRelationship> results = query.list();
return new HashSet<IdentityObjectRelationship>(results);
}
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx,
+ IdentityObject identity,
+ IdentityObjectRelationshipType type,
+ boolean parent,
+ boolean named,
+ String name) throws IdentityException
+ {
+ HibernateIdentityObject hio = safeGet(ctx, identity);
+
+
+ Criteria criteria = getHibernateEntityManager(ctx).getSession().createCriteria(HibernateIdentityObjectRelationship.class);
+
+ if (type != null)
+ {
+ HibernateIdentityObjectRelationshipType hibernateType = getHibernateIdentityObjectRelationshipType(ctx, type);
+
+ criteria.add(Restrictions.eq("type", hibernateType));
+ }
+
+ if (name != null)
+ {
+ criteria.add(Restrictions.eq("name.name", name));
+ }
+ else if (named)
+ {
+ criteria.add(Restrictions.isNotNull("name"));
+ }
+ else
+ {
+ criteria.add(Restrictions.isNull("name"));
+ }
+
+ if (parent)
+ {
+ criteria.add(Restrictions.eq("fromIdentityObject", hio));
+ }
+ else
+ {
+ criteria.add(Restrictions.eq("toIdentityObject", hio));
+ }
+
+ List<HibernateIdentityObjectRelationship> results = criteria.list();
+
+ return new HashSet<IdentityObjectRelationship>(results);
+ }
+
public String createRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
{
if (name == null)
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -722,6 +722,10 @@
public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext ctx, IdentityObject identity, IdentityObjectRelationshipType relationshipType, boolean parent, IdentityObjectSearchControl[] controls) throws IdentityException
{
+ //TODO: relationshipType is ignored - maybe check and allow only MEMBERSHIP?
+
+
+
checkControls(controls);
PageSearchControl pageSearchControl = null;
@@ -944,6 +948,164 @@
return objects;
}
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx,
+ IdentityObject identity,
+ IdentityObjectRelationshipType type,
+ boolean parent,
+ boolean named,
+ String name) throws IdentityException
+ {
+ //TODO: relationshipType is ignored - maybe check and allow only MEMBERSHIP?
+
+
+
+ LDAPIdentityObjectImpl ldapIO = getSafeLDAPIO(ctx, identity);
+
+ LDAPIdentityObjectTypeConfiguration typeConfig = getTypeConfiguration(ctx, identity.getIdentityType());
+
+ LdapContext ldapContext = getLDAPContext(ctx);
+
+ Set<IdentityObjectRelationship> relationships = new HashSet<IdentityObjectRelationship>();
+
+ try
+ {
+
+ // If parent simply look for all its members
+ if (parent)
+ {
+ Attributes attrs = ldapContext.getAttributes(ldapIO.getDn());
+ Attribute member = attrs.get(typeConfig.getMembershipAttributeName());
+
+ if (member != null)
+ {
+ NamingEnumeration memberValues = member.getAll();
+ while (memberValues.hasMoreElements())
+ {
+ String memberRef = memberValues.nextElement().toString();
+
+ if (typeConfig.isMembershipAttributeDN())
+ {
+ //TODO: use direct LDAP query instaed of other find method and add attributesFilter
+
+
+ relationships.add(new LDAPIdentityObjectRelationshipImpl(null, ldapIO, findIdentityObject(ctx, memberRef)));
+
+ }
+ else
+ {
+ //TODO: if relationships are not refered with DNs and only names its not possible to map
+ //TODO: them to proper IdentityType and keep name uniqnes per type. Workaround needed
+ throw new NotYetImplementedException("LDAP limitation. If relationship targets are not refered with FQDNs " +
+ "and only names, it's not possible to map them to proper IdentityType and keep name uniqnes per type. " +
+ "Workaround needed");
+ }
+ //break;
+ }
+ }
+ }
+
+ // if not parent then all parent entries need to be found
+ else
+ {
+ // Search in all other type contexts
+ for (IdentityObjectType parentType : configuration.getConfiguredTypes())
+ {
+ checkIOType(parentType);
+
+ LDAPIdentityObjectTypeConfiguration parentTypeConfiguration = getTypeConfiguration(ctx, parentType);
+
+ List<String> allowedTypes = Arrays.asList(parentTypeConfiguration.getAllowedMembershipTypes());
+
+ // Check if given identity type can be parent
+ if (!allowedTypes.contains(identity.getIdentityType().getName()))
+ {
+ continue;
+ }
+
+ String nameFilter = "*";
+
+ //Filter by name
+ Control[] requestControls = null;
+
+ StringBuilder af = new StringBuilder();
+
+
+ // Add filter to search only parents of the given entry
+ af.append("(")
+ .append(parentTypeConfiguration.getMembershipAttributeName())
+ .append("=");
+ if (parentTypeConfiguration.isMembershipAttributeDN())
+ {
+ af.append(ldapIO.getDn());
+ }
+ else
+ {
+ //TODO: this doesn't make much sense unless parent/child are same identity types and resides in the same LDAP context
+ af.append(ldapIO.getName());
+ }
+ af.append(")");
+
+
+ String filter = parentTypeConfiguration.getEntrySearchFilter();
+ List<SearchResult> sr = null;
+
+ String[] entryCtxs = parentTypeConfiguration.getCtxDNs();
+
+ if (filter != null && filter.length() > 0)
+ {
+
+ Object[] filterArgs = {nameFilter};
+ sr = searchIdentityObjects(ctx,
+ entryCtxs,
+ "(&(" + filter + ")" + af.toString() + ")",
+ filterArgs,
+ new String[]{parentTypeConfiguration.getIdAttributeName()},
+ requestControls);
+ }
+ else
+ {
+ filter = "(".concat(parentTypeConfiguration.getIdAttributeName()).concat("=").concat(nameFilter).concat(")");
+ sr = searchIdentityObjects(ctx,
+ entryCtxs,
+ "(&(" + filter + ")" + af.toString() + ")",
+ null,
+ new String[]{parentTypeConfiguration.getIdAttributeName()},
+ requestControls);
+ }
+
+ for (SearchResult res : sr)
+ {
+ LdapContext ldapCtx = (LdapContext)res.getObject();
+ String dn = ldapCtx.getNameInNamespace();
+
+ relationships.add(new LDAPIdentityObjectRelationshipImpl(null, createIdentityObjectInstance(ctx, parentType, res.getAttributes(), dn), ldapIO));
+ }
+ }
+
+
+ }
+
+ }
+ catch (NamingException e)
+ {
+ throw new IdentityException("Failed to resolve relationship", e);
+ }
+ finally
+ {
+ try
+ {
+ ldapContext.close();
+ }
+ catch (NamingException e)
+ {
+ throw new IdentityException("Failed to close LDAP connection", e);
+ }
+ }
+
+
+ return relationships;
+ }
+
public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext ctx,
IdentityObject identity,
IdentityObjectRelationshipType relationshipType,
@@ -1117,9 +1279,10 @@
}
- public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx, IdentityObject fromIdentity, IdentityObject toIdentity) throws IdentityException
+ public Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext ctx, IdentityObject fromIdentity, IdentityObject toIdentity, IdentityObjectRelationshipType relationshipType) throws IdentityException
{
// relationshipType is ignored for now
+
if (log.isLoggable(Level.FINER))
{
Modified: trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java
===================================================================
--- trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -256,26 +256,26 @@
testContext.flush();
- assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1).size());
- assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2).size());
+ assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1, null).size());
+ assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2, null).size());
testContext.getStore().removeRelationship(testContext.getCtx(), group2, user1, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, null);
testContext.flush();
- assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2).size());
+ assertEquals(1, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2, null).size());
testContext.getStore().removeRelationships(testContext.getCtx(), user1, group1, false);
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1).size());
- assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group1, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1, null).size());
+ assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2, null).size());
testContext.flush();
Modified: trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/IdentityStore.java
===================================================================
--- trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/IdentityStore.java 2008-12-16 17:33:03 UTC (rev 168)
+++ trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/IdentityStore.java 2008-12-17 17:15:21 UTC (rev 169)
@@ -216,19 +216,42 @@
throws IdentityException;
/**
- * Resolve relationship types between two identities. Relationships can be directional
+ * Resolve relationships between two identities. Relationships can be directional
* so order of parameters matters
*
* @param invocationCxt
* @param fromIdentity
* @param toIdentity
+ * @param relationshipType - may be null
* @return
* @throws IdentityException
*/
- Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt, IdentityObject fromIdentity, IdentityObject toIdentity)
+ Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt,
+ IdentityObject fromIdentity,
+ IdentityObject toIdentity,
+ IdentityObjectRelationshipType relationshipType)
throws IdentityException;
+ /**
+ * Resolve relationships for a given IdentityObject. Relationships can be directional and parent switch defines which
+ * role identity play in it.
+ * @param invocationCxt
+ * @param identity
+ * @param named
+ * @param name - can be null
+ * @return
+ * @throws IdentityException
+ */
+ Set<IdentityObjectRelationship> resolveRelationships(IdentityStoreInvocationContext invocationCxt,
+ IdentityObject identity,
+ IdentityObjectRelationshipType relationshipType,
+ boolean parent,
+ boolean named,
+ String name)
+ throws IdentityException;
+
+
// Named relationships
/**
17 years, 7 months
JBoss Identity SVN: r168 - in identity-federation/trunk: identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories and 1 other directories.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-16 12:33:03 -0500 (Tue, 16 Dec 2008)
New Revision: 168
Modified:
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/JBossSAMLBaseFactory.java
identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/SecurityActions.java
identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/DeflateUtil.java
identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
Log:
update javadoc
Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java 2008-12-16 02:36:57 UTC (rev 167)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java 2008-12-16 17:33:03 UTC (rev 168)
@@ -33,6 +33,14 @@
*/
public class HTTPRedirectUtil
{
+ /**
+ * Send the response to the redirected destination while
+ * adding the character encoding of "UTF-8" as well as
+ * adding headers for cache-control and Pragma
+ * @param destination Destination URI where the response needs to redirect
+ * @param response HttpServletResponse
+ * @throws IOException
+ */
public static void sendRedirect(String destination, HttpServletResponse response)
throws IOException
{
Modified: identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/JBossSAMLBaseFactory.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/JBossSAMLBaseFactory.java 2008-12-16 02:36:57 UTC (rev 167)
+++ identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/JBossSAMLBaseFactory.java 2008-12-16 17:33:03 UTC (rev 168)
@@ -64,14 +64,11 @@
return assertionObjectFactory.createAttributeStatementType();
}
- public static AttributeType createAttribute(String attributeValue)
- {
- AttributeType att = assertionObjectFactory.createAttributeType();
- JAXBElement<Object> attValue = assertionObjectFactory.createAttributeValue(attributeValue);
- att.getAttributeValue().add(attValue);
- return att;
- }
-
+ /**
+ * Create an attribute type given a role name
+ * @param roleName
+ * @return
+ */
public static AttributeType createAttributeForRole(String roleName)
{
AttributeType att = assertionObjectFactory.createAttributeType();
@@ -85,6 +82,11 @@
return att;
}
+ /**
+ * Create an AttributeStatement given an attribute
+ * @param attributeValue
+ * @return
+ */
public static AttributeStatementType createAttributeStatement(String attributeValue)
{
AttributeStatementType attribStatement = assertionObjectFactory.createAttributeStatementType();
Modified: identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/SecurityActions.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/SecurityActions.java 2008-12-16 02:36:57 UTC (rev 167)
+++ identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/saml/v2/factories/SecurityActions.java 2008-12-16 17:33:03 UTC (rev 168)
@@ -31,6 +31,10 @@
*/
class SecurityActions
{
+ /**
+ * Get the Thread Context ClassLoader
+ * @return
+ */
static ClassLoader getContextClassLoader()
{
return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
Modified: identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/DeflateUtil.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/DeflateUtil.java 2008-12-16 02:36:57 UTC (rev 167)
+++ identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/DeflateUtil.java 2008-12-16 17:33:03 UTC (rev 168)
@@ -38,6 +38,12 @@
*/
public class DeflateUtil
{
+ /**
+ * Apply DEFLATE encoding
+ * @param message
+ * @return
+ * @throws IOException
+ */
public static byte[] encode(byte[] message) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -49,14 +55,25 @@
return baos.toByteArray();
}
+ /**
+ * Apply DEFLATE encoding
+ * @param message
+ * @return
+ * @throws IOException
+ */
public static byte[] encode(String message) throws IOException
{
return encode(message.getBytes());
}
+ /**
+ * DEFLATE decoding
+ * @param msgToDecode the message that needs decoding
+ * @return
+ */
public static InputStream decode(byte[] msgToDecode)
{
ByteArrayInputStream bais = new ByteArrayInputStream(msgToDecode);
return new InflaterInputStream(bais, new Inflater(true));
}
-}
+}
\ No newline at end of file
Modified: identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java 2008-12-16 02:36:57 UTC (rev 167)
+++ identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java 2008-12-16 17:33:03 UTC (rev 168)
@@ -179,6 +179,13 @@
return doc;
}
+ /**
+ * Validate a signed document with the given public key
+ * @param signedDoc
+ * @param publicKey
+ * @return
+ * @throws Exception
+ */
public static boolean validate(Document signedDoc, Key publicKey) throws Exception
{
NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
@@ -193,14 +200,26 @@
return coreValidity;
}
-
+
+ /**
+ * Marshall a SignatureType to output stream
+ * @param signature
+ * @param os
+ * @throws Exception
+ */
public static void marshall(SignatureType signature, OutputStream os) throws Exception
{
JAXBElement<SignatureType> jsig = objectFactory.createSignature(signature);
Marshaller marshaller = JBossSAMLBaseFactory.getValidatingMarshaller(pkgName, schemaLocation);
marshaller.marshal(jsig, os);
}
-
+
+ /**
+ * Marshall the signed document to an output stream
+ * @param signedDocument
+ * @param os
+ * @throws Exception
+ */
public static void marshall(Document signedDocument, OutputStream os) throws Exception
{
TransformerFactory tf = TransformerFactory.newInstance();
17 years, 7 months
JBoss Identity SVN: r167 - in identity-federation/trunk: identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2 and 1 other directory.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-15 21:36:57 -0500 (Mon, 15 Dec 2008)
New Revision: 167
Modified:
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/DeflateEncodingDecodingUnitTestCase.java
identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnRequestUnitTestCase.java
identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnResponseUnitTestCase.java
Log:
remove sys out
Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java 2008-12-16 02:26:05 UTC (rev 166)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java 2008-12-16 02:36:57 UTC (rev 167)
@@ -21,6 +21,7 @@
*/
package org.jboss.identity.federation.bindings.tomcat.idp;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
@@ -149,8 +150,13 @@
if(authnRequestType == null)
throw new IllegalStateException("AuthnRequest is null");
- JBossSAMLAuthnRequestFactory.marshall(authnRequestType, System.out);
-
+ if(log.isTraceEnabled())
+ {
+ StringWriter sw = new StringWriter();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequestType, sw);
+ log.trace("IDPRedirectValve::AuthnRequest="+sw.toString());
+ }
+
//Create a response type
String id = "ID_" + JBossSAMLBaseFactory.createUUID();
@@ -178,7 +184,12 @@
log.debug("ResponseType = ");
//Lets see how the response looks like
- JBossSAMLAuthnResponseFactory.marshall(responseType, System.out);
+ if(log.isTraceEnabled())
+ {
+ StringWriter sw = new StringWriter();
+ JBossSAMLAuthnResponseFactory.marshall(responseType, sw);
+ log.trace("IDPRedirectValve::Response="+sw.toString());
+ }
return responseType;
}
Modified: identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/DeflateEncodingDecodingUnitTestCase.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/DeflateEncodingDecodingUnitTestCase.java 2008-12-16 02:26:05 UTC (rev 166)
+++ identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/DeflateEncodingDecodingUnitTestCase.java 2008-12-16 02:36:57 UTC (rev 167)
@@ -52,8 +52,6 @@
String base64Request = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES);
- System.out.println("Request="+base64Request);
-
//Decode
byte[] decodedMessage = Base64.decode(base64Request);
InputStream is = DeflateUtil.decode(decodedMessage);
Modified: identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnRequestUnitTestCase.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnRequestUnitTestCase.java 2008-12-16 02:26:05 UTC (rev 166)
+++ identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnRequestUnitTestCase.java 2008-12-16 02:36:57 UTC (rev 167)
@@ -21,6 +21,7 @@
*/
package org.jboss.test.identity.federation.api.saml.v2;
+import java.io.ByteArrayOutputStream;
import java.util.List;
import javax.xml.bind.JAXBElement;
@@ -87,8 +88,9 @@
assertEquals( "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
,requestedAuthnContext.getAuthnContextClassRef().get(0));
- //Let us marshall it back to System out
- JBossSAMLAuthnRequestFactory.marshall(authnRequestType, System.out);
+ //Let us marshall it back to an output stream
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequestType, baos);
}
/**
@@ -106,9 +108,9 @@
SignatureType signatureType = authnRequestType.getSignature();
assertNotNull("Signature is not null", signatureType);
- //Let us marshall it back to System out
- System.out.println(" ");
- JBossSAMLAuthnRequestFactory.marshall(authnRequestType, System.out);
+ //Let us marshall it back to an output stream
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequestType, baos);
}
/**
@@ -119,6 +121,8 @@
{
AuthnRequestType authnRequest = JBossSAMLAuthnRequestFactory.createAuthnRequestType(
"ID_" + JBossSAMLBaseFactory.createUUID(), "http://sp", "http://idp", "http://sp");
- JBossSAMLAuthnRequestFactory.marshall(authnRequest, System.out);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequest, baos);
}
}
\ No newline at end of file
Modified: identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnResponseUnitTestCase.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnResponseUnitTestCase.java 2008-12-16 02:26:05 UTC (rev 166)
+++ identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SAML2AuthnResponseUnitTestCase.java 2008-12-16 02:36:57 UTC (rev 167)
@@ -21,6 +21,8 @@
*/
package org.jboss.test.identity.federation.api.saml.v2;
+import java.io.ByteArrayOutputStream;
+
import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnResponseFactory;
import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
import org.jboss.identity.federation.saml.v2.jboss.IDPInfoHolder;
@@ -52,6 +54,7 @@
new SPInfoHolder(), idp, issuerHolder);
assertNotNull(rt);
- JBossSAMLAuthnResponseFactory.marshall(rt, System.out);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnResponseFactory.marshall(rt, baos);
}
}
\ No newline at end of file
17 years, 7 months
JBoss Identity SVN: r166 - in identity-federation/trunk: identity-fed-api/src/main/java/org/jboss/identity/federation/api/util and 3 other directories.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-15 21:26:05 -0500 (Mon, 15 Dec 2008)
New Revision: 166
Added:
identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SignatureValidationUnitTestCase.java
identity-federation/trunk/identity-fed-model/src/main/resources/schema/xmldsig-core-schema.xsd
Modified:
identity-federation/trunk/identity-fed-api/.classpath
identity-federation/trunk/identity-fed-model/src/main/java/org/jboss/identity/federation/saml/v2/jboss/JBossSAMLURIConstants.java
Log:
JBID-35: xml dsig
Modified: identity-federation/trunk/identity-fed-api/.classpath
===================================================================
--- identity-federation/trunk/identity-fed-api/.classpath 2008-12-16 02:23:36 UTC (rev 165)
+++ identity-federation/trunk/identity-fed-api/.classpath 2008-12-16 02:26:05 UTC (rev 166)
@@ -10,5 +10,6 @@
<classpathentry kind="var" path="M2_REPO/junit/junit/4.4/junit-4.4.jar"/>
<classpathentry kind="var" path="M2_REPO/sun-jaxb/jaxb-impl/2.1.9/jaxb-impl-2.1.9.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/apache/xmlsec/1.4.1/xmlsec-1.4.1.jar"/>
<classpathentry kind="output" path="target-eclipse"/>
</classpath>
Added: identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java (rev 0)
+++ identity-federation/trunk/identity-fed-api/src/main/java/org/jboss/identity/federation/api/util/XMLSignatureUtil.java 2008-12-16 02:26:05 UTC (rev 166)
@@ -0,0 +1,210 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.identity.federation.api.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.security.Key;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.util.Collections;
+
+import javax.security.cert.X509Certificate;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.Marshaller;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.keyinfo.KeyValue;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+import org.jboss.identity.federation.w3.xmldsig.ObjectFactory;
+import org.jboss.identity.federation.w3.xmldsig.SignatureType;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+/**
+ * Utility for XML Signature
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 15, 2008
+ */
+public class XMLSignatureUtil
+{
+ private static String pkgName = "org.jboss.identity.federation.w3.xmldsig";
+ private static String schemaLocation = "schema/xmldsig-core-schema.xsd";
+
+ private static ObjectFactory objectFactory = new ObjectFactory();
+
+ private static XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",
+ new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
+
+ /**
+ * Sign an AuthnRequestType
+ * @param request
+ * @param signingKey Private Key for signing
+ * @param cert X509Certificate public key certificate (may be null)
+ * @param digestMethod (Example: DigestMethod.SHA1)
+ * @param signatureMethod (Example: SignatureMethod.DSA_SHA1)
+ * @return
+ * @throws Exception
+ */
+ public static Document sign(AuthnRequestType request, PrivateKey signingKey,
+ X509Certificate certificate,
+ String digestMethod, String signatureMethod) throws Exception
+ {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(request, baos);
+
+ DocumentBuilder builder = dbf.newDocumentBuilder();
+ Document doc = builder.parse(new ByteArrayInputStream(baos.toByteArray()) );
+
+ DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
+
+ String referenceURI = "#" + request.getID();
+
+ Reference ref = fac.newReference
+ ( referenceURI, fac.newDigestMethod(digestMethod, null),
+ Collections.singletonList
+ (fac.newTransform(Transform.ENVELOPED,
+ (TransformParameterSpec) null)), null, null);
+
+ SignedInfo si = fac.newSignedInfo
+ (fac.newCanonicalizationMethod
+ (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
+ (C14NMethodParameterSpec) null),
+ fac.newSignatureMethod(signatureMethod, null),
+ Collections.singletonList(ref));
+
+ KeyInfo ki = null;
+ if(certificate != null)
+ {
+ KeyInfoFactory kif = fac.getKeyInfoFactory();
+ KeyValue kv = kif.newKeyValue(certificate.getPublicKey());
+ ki = kif.newKeyInfo(Collections.singletonList(kv));
+ }
+
+ XMLSignature signature = fac.newXMLSignature(si, ki);
+
+ signature.sign(dsc);
+
+ return doc;
+ }
+
+ /**
+ * Sign an AuthnRequestType
+ * @param request
+ * @param keypair Key Pair
+ * @param digestMethod (Example: DigestMethod.SHA1)
+ * @param signatureMethod (Example: SignatureMethod.DSA_SHA1)
+ * @return
+ * @throws Exception
+ */
+ public static Document sign(AuthnRequestType request, KeyPair keypair,
+ String digestMethod, String signatureMethod) throws Exception
+ {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(request, baos);
+
+ DocumentBuilder builder = dbf.newDocumentBuilder();
+ Document doc = builder.parse(new ByteArrayInputStream(baos.toByteArray()) );
+
+ DOMSignContext dsc = new DOMSignContext(keypair.getPrivate(), doc.getDocumentElement());
+
+ String referenceURI = "#" + request.getID();
+
+ Reference ref = fac.newReference
+ ( referenceURI, fac.newDigestMethod(digestMethod, null),
+ Collections.singletonList
+ (fac.newTransform(Transform.ENVELOPED,
+ (TransformParameterSpec) null)), null, null);
+
+ SignedInfo si = fac.newSignedInfo
+ (fac.newCanonicalizationMethod
+ (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
+ (C14NMethodParameterSpec) null),
+ fac.newSignatureMethod(signatureMethod, null),
+ Collections.singletonList(ref));
+
+ KeyInfoFactory kif = fac.getKeyInfoFactory();
+ KeyValue kv = kif.newKeyValue(keypair.getPublic());
+ KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv));
+
+ XMLSignature signature = fac.newXMLSignature(si, ki);
+
+ signature.sign(dsc);
+
+ return doc;
+ }
+
+ public static boolean validate(Document signedDoc, Key publicKey) throws Exception
+ {
+ NodeList nl = signedDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
+ if (nl.getLength() == 0)
+ {
+ throw new Exception("Cannot find Signature element");
+ }
+ DOMValidateContext valContext = new DOMValidateContext(publicKey, nl.item(0));
+
+ XMLSignature signature = fac.unmarshalXMLSignature(valContext);
+ boolean coreValidity = signature.validate(valContext);
+
+ return coreValidity;
+ }
+
+ public static void marshall(SignatureType signature, OutputStream os) throws Exception
+ {
+ JAXBElement<SignatureType> jsig = objectFactory.createSignature(signature);
+ Marshaller marshaller = JBossSAMLBaseFactory.getValidatingMarshaller(pkgName, schemaLocation);
+ marshaller.marshal(jsig, os);
+ }
+
+ public static void marshall(Document signedDocument, OutputStream os) throws Exception
+ {
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer trans = tf.newTransformer();
+ trans.transform(new DOMSource(signedDocument), new StreamResult(os));
+ }
+}
\ No newline at end of file
Added: identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SignatureValidationUnitTestCase.java
===================================================================
--- identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SignatureValidationUnitTestCase.java (rev 0)
+++ identity-federation/trunk/identity-fed-api/src/test/java/org/jboss/test/identity/federation/api/saml/v2/SignatureValidationUnitTestCase.java 2008-12-16 02:26:05 UTC (rev 166)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.test.identity.federation.api.saml.v2;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.SignatureMethod;
+
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.federation.api.util.XMLSignatureUtil;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+import org.junit.Test;
+import org.w3c.dom.Document;
+
+/**
+ * Signatures related unit test cases
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 15, 2008
+ */
+public class SignatureValidationUnitTestCase
+{
+ /**
+ * Test the creation of AuthnRequestType with signature creation
+ * with a private key and then validate the signature with a public
+ * key
+ * @throws Exception
+ */
+
+ @Test
+ public void testAuthnRequestCreationWithSignature() throws Exception
+ {
+ AuthnRequestType authnRequest = JBossSAMLAuthnRequestFactory.createAuthnRequestType(
+ "ID_" + JBossSAMLBaseFactory.createUUID(), "http://sp", "http://idp", "http://sp");
+ KeyPairGenerator kpg = KeyPairGenerator.getInstance("DSA");
+ KeyPair kp = kpg.genKeyPair();
+ Document signedDoc = XMLSignatureUtil.sign(authnRequest, kp.getPrivate(), null,
+ DigestMethod.SHA1, SignatureMethod.DSA_SHA1);
+
+ //Validate the signature
+ boolean isValid = XMLSignatureUtil.validate(signedDoc, kp.getPublic());
+ assertTrue(isValid);
+ }
+}
\ No newline at end of file
Modified: identity-federation/trunk/identity-fed-model/src/main/java/org/jboss/identity/federation/saml/v2/jboss/JBossSAMLURIConstants.java
===================================================================
--- identity-federation/trunk/identity-fed-model/src/main/java/org/jboss/identity/federation/saml/v2/jboss/JBossSAMLURIConstants.java 2008-12-16 02:23:36 UTC (rev 165)
+++ identity-federation/trunk/identity-fed-model/src/main/java/org/jboss/identity/federation/saml/v2/jboss/JBossSAMLURIConstants.java 2008-12-16 02:26:05 UTC (rev 166)
@@ -33,8 +33,12 @@
ATTRIBUTE_FORMAT_BASIC("urn:oasis:names:tc:SAML:2.0:attrname-format:basic"),
NAMEID_FORMAT_TRANSIENT("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"),
NAMEID_FORMAT_PERSISTENT("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"),
+ SIGNATURE_DSA_SHA1("http://www.w3.org/2000/09/xmldsig#dsa-sha1"),
+ SIGNATURE_RSA_SHA1("http://www.w3.org/2000/09/xmldsig#rsa-sha1"),
SUBJECT_CONFIRMATION_BEARER("urn:oasis:names:tc:SAML:2.0:cm:bearer"),
- STATUS_SUCCESS("urn:oasis:names:tc:SAML:2.0:status:Success");
+ STATUS_SUCCESS("urn:oasis:names:tc:SAML:2.0:status:Success"),
+ TRANSFORM_ENVELOPED_SIGNATURE("http://www.w3.org/2000/09/xmldsig#enveloped-signature"),
+ TRANSFORM_C14N_EXCL_OMIT_COMMENTS("http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
private String uri = null;
Added: identity-federation/trunk/identity-fed-model/src/main/resources/schema/xmldsig-core-schema.xsd
===================================================================
--- identity-federation/trunk/identity-fed-model/src/main/resources/schema/xmldsig-core-schema.xsd (rev 0)
+++ identity-federation/trunk/identity-fed-model/src/main/resources/schema/xmldsig-core-schema.xsd 2008-12-16 02:26:05 UTC (rev 166)
@@ -0,0 +1,318 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE schema
+ PUBLIC "-//W3C//DTD XMLSchema 200102//EN" "http://www.w3.org/2001/XMLSchema.dtd"
+ [
+ <!ATTLIST schema
+ xmlns:ds CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#">
+ <!ENTITY dsig 'http://www.w3.org/2000/09/xmldsig#'>
+ <!ENTITY % p ''>
+ <!ENTITY % s ''>
+ ]>
+
+<!-- Schema for XML Signatures
+ http://www.w3.org/2000/09/xmldsig#
+ $Revision: 1.1 $ on $Date: 2002/02/08 20:32:26 $ by $Author: reagle $
+
+ Copyright 2001 The Internet Society and W3C (Massachusetts Institute
+ of Technology, Institut National de Recherche en Informatique et en
+ Automatique, Keio University). All Rights Reserved.
+ http://www.w3.org/Consortium/Legal/
+
+ This document is governed by the W3C Software License [1] as described
+ in the FAQ [2].
+
+ [1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
+ [2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
+-->
+
+
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
+ targetNamespace="http://www.w3.org/2000/09/xmldsig#"
+ version="0.1" elementFormDefault="qualified">
+
+<!-- Basic Types Defined for Signatures -->
+
+<simpleType name="CryptoBinary">
+ <restriction base="base64Binary">
+ </restriction>
+</simpleType>
+
+<!-- Start Signature -->
+
+<element name="Signature" type="ds:SignatureType"/>
+<complexType name="SignatureType">
+ <sequence>
+ <element ref="ds:SignedInfo"/>
+ <element ref="ds:SignatureValue"/>
+ <element ref="ds:KeyInfo" minOccurs="0"/>
+ <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureValue" type="ds:SignatureValueType"/>
+ <complexType name="SignatureValueType">
+ <simpleContent>
+ <extension base="base64Binary">
+ <attribute name="Id" type="ID" use="optional"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+<!-- Start SignedInfo -->
+
+<element name="SignedInfo" type="ds:SignedInfoType"/>
+<complexType name="SignedInfoType">
+ <sequence>
+ <element ref="ds:CanonicalizationMethod"/>
+ <element ref="ds:SignatureMethod"/>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="CanonicalizationMethod" type="ds:CanonicalizationMethodType"/>
+ <complexType name="CanonicalizationMethodType" mixed="true">
+ <sequence>
+ <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+ <element name="SignatureMethod" type="ds:SignatureMethodType"/>
+ <complexType name="SignatureMethodType" mixed="true">
+ <sequence>
+ <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
+ <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
+ <!-- (0,unbounded) elements from (1,1) external namespace -->
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- Start Reference -->
+
+<element name="Reference" type="ds:ReferenceType"/>
+<complexType name="ReferenceType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ <element ref="ds:DigestMethod"/>
+ <element ref="ds:DigestValue"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="URI" type="anyURI" use="optional"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+</complexType>
+
+ <element name="Transforms" type="ds:TransformsType"/>
+ <complexType name="TransformsType">
+ <sequence>
+ <element ref="ds:Transform" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="Transform" type="ds:TransformType"/>
+ <complexType name="TransformType" mixed="true">
+ <choice minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ <element name="XPath" type="string"/>
+ </choice>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+ </complexType>
+
+<!-- End Reference -->
+
+<element name="DigestMethod" type="ds:DigestMethodType"/>
+<complexType name="DigestMethodType" mixed="true">
+ <sequence>
+ <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Algorithm" type="anyURI" use="required"/>
+</complexType>
+
+<element name="DigestValue" type="ds:DigestValueType"/>
+<simpleType name="DigestValueType">
+ <restriction base="base64Binary"/>
+</simpleType>
+
+<!-- End SignedInfo -->
+
+<!-- Start KeyInfo -->
+
+<element name="KeyInfo" type="ds:KeyInfoType"/>
+<complexType name="KeyInfoType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <element ref="ds:KeyName"/>
+ <element ref="ds:KeyValue"/>
+ <element ref="ds:RetrievalMethod"/>
+ <element ref="ds:X509Data"/>
+ <element ref="ds:PGPData"/>
+ <element ref="ds:SPKIData"/>
+ <element ref="ds:MgmtData"/>
+ <any processContents="lax" namespace="##other"/>
+ <!-- (1,1) elements from (0,unbounded) namespaces -->
+ </choice>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="KeyName" type="string"/>
+ <element name="MgmtData" type="string"/>
+
+ <element name="KeyValue" type="ds:KeyValueType"/>
+ <complexType name="KeyValueType" mixed="true">
+ <choice>
+ <element ref="ds:DSAKeyValue"/>
+ <element ref="ds:RSAKeyValue"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </complexType>
+
+ <element name="RetrievalMethod" type="ds:RetrievalMethodType"/>
+ <complexType name="RetrievalMethodType">
+ <sequence>
+ <element ref="ds:Transforms" minOccurs="0"/>
+ </sequence>
+ <attribute name="URI" type="anyURI"/>
+ <attribute name="Type" type="anyURI" use="optional"/>
+ </complexType>
+
+<!-- Start X509Data -->
+
+<element name="X509Data" type="ds:X509DataType"/>
+<complexType name="X509DataType">
+ <sequence maxOccurs="unbounded">
+ <choice>
+ <element name="X509IssuerSerial" type="ds:X509IssuerSerialType"/>
+ <element name="X509SKI" type="base64Binary"/>
+ <element name="X509SubjectName" type="string"/>
+ <element name="X509Certificate" type="base64Binary"/>
+ <element name="X509CRL" type="base64Binary"/>
+ <any namespace="##other" processContents="lax"/>
+ </choice>
+ </sequence>
+</complexType>
+
+<complexType name="X509IssuerSerialType">
+ <sequence>
+ <element name="X509IssuerName" type="string"/>
+ <element name="X509SerialNumber" type="integer"/>
+ </sequence>
+</complexType>
+
+<!-- End X509Data -->
+
+<!-- Begin PGPData -->
+
+<element name="PGPData" type="ds:PGPDataType"/>
+<complexType name="PGPDataType">
+ <choice>
+ <sequence>
+ <element name="PGPKeyID" type="base64Binary"/>
+ <element name="PGPKeyPacket" type="base64Binary" minOccurs="0"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ <sequence>
+ <element name="PGPKeyPacket" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"
+ maxOccurs="unbounded"/>
+ </sequence>
+ </choice>
+</complexType>
+
+<!-- End PGPData -->
+
+<!-- Begin SPKIData -->
+
+<element name="SPKIData" type="ds:SPKIDataType"/>
+<complexType name="SPKIDataType">
+ <sequence maxOccurs="unbounded">
+ <element name="SPKISexp" type="base64Binary"/>
+ <any namespace="##other" processContents="lax" minOccurs="0"/>
+ </sequence>
+</complexType>
+
+<!-- End SPKIData -->
+
+<!-- End KeyInfo -->
+
+<!-- Start Object (Manifest, SignatureProperty) -->
+
+<element name="Object" type="ds:ObjectType"/>
+<complexType name="ObjectType" mixed="true">
+ <sequence minOccurs="0" maxOccurs="unbounded">
+ <any namespace="##any" processContents="lax"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+ <attribute name="MimeType" type="string" use="optional"/> <!-- add a grep facet -->
+ <attribute name="Encoding" type="anyURI" use="optional"/>
+</complexType>
+
+<element name="Manifest" type="ds:ManifestType"/>
+<complexType name="ManifestType">
+ <sequence>
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+<element name="SignatureProperties" type="ds:SignaturePropertiesType"/>
+<complexType name="SignaturePropertiesType">
+ <sequence>
+ <element ref="ds:SignatureProperty" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Id" type="ID" use="optional"/>
+</complexType>
+
+ <element name="SignatureProperty" type="ds:SignaturePropertyType"/>
+ <complexType name="SignaturePropertyType" mixed="true">
+ <choice maxOccurs="unbounded">
+ <any namespace="##other" processContents="lax"/>
+ <!-- (1,1) elements from (1,unbounded) namespaces -->
+ </choice>
+ <attribute name="Target" type="anyURI" use="required"/>
+ <attribute name="Id" type="ID" use="optional"/>
+ </complexType>
+
+<!-- End Object (Manifest, SignatureProperty) -->
+
+<!-- Start Algorithm Parameters -->
+
+<simpleType name="HMACOutputLengthType">
+ <restriction base="integer"/>
+</simpleType>
+
+<!-- Start KeyValue Element-types -->
+
+<element name="DSAKeyValue" type="ds:DSAKeyValueType"/>
+<complexType name="DSAKeyValueType">
+ <sequence>
+ <sequence minOccurs="0">
+ <element name="P" type="ds:CryptoBinary"/>
+ <element name="Q" type="ds:CryptoBinary"/>
+ </sequence>
+ <element name="G" type="ds:CryptoBinary" minOccurs="0"/>
+ <element name="Y" type="ds:CryptoBinary"/>
+ <element name="J" type="ds:CryptoBinary" minOccurs="0"/>
+ <sequence minOccurs="0">
+ <element name="Seed" type="ds:CryptoBinary"/>
+ <element name="PgenCounter" type="ds:CryptoBinary"/>
+ </sequence>
+ </sequence>
+</complexType>
+
+<element name="RSAKeyValue" type="ds:RSAKeyValueType"/>
+<complexType name="RSAKeyValueType">
+ <sequence>
+ <element name="Modulus" type="ds:CryptoBinary"/>
+ <element name="Exponent" type="ds:CryptoBinary"/>
+ </sequence>
+</complexType>
+
+<!-- End KeyValue Element-types -->
+
+<!-- End Signature -->
+
+</schema>
17 years, 7 months
JBoss Identity SVN: r165 - in identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings: tomcat/sp and 1 other directories.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-15 21:23:36 -0500 (Mon, 15 Dec 2008)
New Revision: 165
Added:
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
Modified:
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
Log:
refactored util class
Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java 2008-12-15 18:10:32 UTC (rev 164)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java 2008-12-16 02:23:36 UTC (rev 165)
@@ -46,6 +46,7 @@
import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
import org.jboss.identity.federation.api.util.Base64;
import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
@@ -118,7 +119,8 @@
String destination = responseType.getDestination();
log.trace("IDP:Destination=" + destination);
base64Response = URLEncoder.encode(base64Response, "UTF-8");
- response.sendRedirect(destination + "?SAMLResponse=" + base64Response);
+
+ HTTPRedirectUtil.sendRedirect(destination + "?SAMLResponse=" + base64Response,response);
}
catch (Exception e)
{
Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java 2008-12-15 18:10:32 UTC (rev 164)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java 2008-12-16 02:23:36 UTC (rev 165)
@@ -47,6 +47,7 @@
import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
import org.jboss.identity.federation.api.util.Base64;
import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
@@ -157,10 +158,8 @@
base64Request = URLEncoder.encode(base64Request, "UTF-8");
String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request;
log.debug("Sending to destination="+destination);
- response.setCharacterEncoding("UTF-8");
- response.setHeader("Location", destination);
- response.setStatus(Response.SC_MOVED_TEMPORARILY);
- response.sendRedirect(destination);
+
+ HTTPRedirectUtil.sendRedirect(destination, response);
return;
}
Modified: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java 2008-12-15 18:10:32 UTC (rev 164)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java 2008-12-16 02:23:36 UTC (rev 165)
@@ -45,6 +45,7 @@
import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
import org.jboss.identity.federation.api.util.Base64;
import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.bindings.util.HTTPRedirectUtil;
import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
@@ -149,10 +150,8 @@
String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request;
log.trace("Sending to destination="+destination);
log.trace(" ");
- response.setCharacterEncoding("UTF-8");
- response.setHeader("Location", destination);
- response.setStatus(Response.SC_MOVED_TEMPORARILY);
- response.sendRedirect(destination);
+
+ HTTPRedirectUtil.sendRedirect(destination, response);
return;
}
}
Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/HTTPRedirectUtil.java 2008-12-16 02:23:36 UTC (rev 165)
@@ -0,0 +1,47 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.identity.federation.bindings.util;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletResponse;
+
+
+/**
+ * Utility Class for http/redirect
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 15, 2008
+ */
+public class HTTPRedirectUtil
+{
+ public static void sendRedirect(String destination, HttpServletResponse response)
+ throws IOException
+ {
+ response.setCharacterEncoding("UTF-8");
+ response.setHeader("Location", destination);
+ response.setHeader("Cache-Control", "no-cache, no-store");
+ response.setHeader("Pragma", "no-cache");
+
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.sendRedirect(destination);
+ }
+}
\ No newline at end of file
17 years, 7 months
JBoss Identity SVN: r164 - in trunk: identity-impl/src/main/java/org/jboss/identity/impl/repository and 5 other directories.
by jboss-identity-commits@lists.jboss.org
Author: bdaw
Date: 2008-12-15 13:10:32 -0500 (Mon, 15 Dec 2008)
New Revision: 164
Modified:
trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/FeaturesMetaDataImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
trunk/identity-impl/src/test/resources/organization-test-config.xml
trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/FeaturesMetaData.java
Log:
improvements to Fallback repository
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/api/RoleManagerImpl.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -225,7 +225,7 @@
}
catch (OperationNotSupportedException e)
{
- throw new IdentityException("Role management not supported");
+ throw new IdentityException("Role management not supported", e);
}
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/repository/FallbackIdentityStoreRepository.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -36,22 +36,46 @@
import org.jboss.identity.spi.configuration.metadata.IdentityStoreConfigurationMetaData;
import org.jboss.identity.spi.configuration.metadata.IdentityRepositoryConfigurationMetaData;
import org.jboss.identity.spi.credential.IdentityObjectCredential;
+import org.jboss.identity.spi.credential.IdentityObjectCredentialType;
import org.jboss.identity.exception.IdentityException;
import org.jboss.identity.impl.store.SimpleIdentityStoreInvocationContext;
+import org.jboss.identity.impl.api.PageSearchControl;
+import org.jboss.identity.impl.api.SortByNameSearchControl;
+import org.jboss.identity.impl.api.AttributeFilterSearchControl;
+import org.jboss.identity.impl.api.NameFilterSearchControl;
+import org.jboss.identity.api.Identity;
import java.util.Map;
import java.util.Collection;
import java.util.Set;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Arrays;
+import com.sun.corba.se.spi.activation._ActivatorImplBase;
+
/**
- * LADP + DB
+ * <p>In FallbackIdentityStoreRepository one IdentityStore plays the role of default store. Any operation that cannot be
+ * handled with other IdentityObjectType/IdentityStore mappings will fallback to such IdentityStore. The most common example
+ * is RDBMS + LDAP configuration. LDAP has limmited schema for possible profile attributes so for LDAP entries part of
+ * profile can be stored in RDBMS by syncing entries into default store.</p>
+ * <p>For any relationship that is not supported in other stores, or between entries persisted in two different stores,
+ * proper IdentityObjects will be synced to default store and if possible, such relationship will be created. </p>
*
+ *
* @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
* @version : 0.1 $
*/
public class FallbackIdentityStoreRepository extends AbstractIdentityStoreRepository
{
+ //TODO: filter out controls based on features MD before passing
+ //TODO: configuration option to store not mapped attributes in default store
+ //TODO: configuration option to fallback named relationships to default store when not supported in mapped one
+
private final String id;
private IdentityStore defaultIdentityStore;
@@ -61,6 +85,12 @@
//TODO: rewrite this to other config object?
private IdentityRepositoryConfigurationMetaData configurationMD;
+ public static final String ALLOW_NOT_DEFINED_ATTRIBUTES = "allowNotDefinedAttributes";
+
+ private FeaturesMetaData featuresMetaData;
+
+ private boolean allowNotDefinedAttributes = false;
+
public FallbackIdentityStoreRepository(String id)
{
this.id = id;
@@ -87,6 +117,94 @@
defaultIdentityStore = bootstrappedIdentityStores.get(isId);
}
+ String allowNotDefineAttributes = configurationMD.getOptionSingleValue(ALLOW_NOT_DEFINED_ATTRIBUTES);
+
+ if (allowNotDefineAttributes != null && allowNotDefineAttributes.equalsIgnoreCase("true"))
+ {
+ this.allowNotDefinedAttributes = true;
+ }
+
+ // A wrapper around all stores features meta data
+ featuresMetaData = new FeaturesMetaData()
+ {
+
+ public boolean isNamedRelationshipsSupported()
+ {
+ // If there is any IdentityStore that supports named relationships...
+ for (IdentityStore identityStore : getIdentityStoreMappings().values())
+ {
+ if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ return true;
+ }
+ }
+ return defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported();
+ }
+
+ public boolean isControlSupported(IdentityObjectType identityObjectType, IdentityObjectSearchControl control)
+ {
+ return resolveIdentityStore(identityObjectType).getSupportedFeatures().isControlSupported(identityObjectType, control);
+ }
+
+ public boolean isControlSupported(IdentityObjectType identityObjectType, Class controlClazz)
+ {
+ return resolveIdentityStore(identityObjectType).getSupportedFeatures().isControlSupported(identityObjectType, controlClazz);
+ }
+
+ public Set<String> getSupportedIdentityObjectTypes()
+ {
+ Set<String> supportedIOTs = new HashSet<String>();
+
+ for (IdentityStore identityStore : getIdentityStoreMappings().values())
+ {
+ supportedIOTs.addAll(identityStore.getSupportedFeatures().getSupportedIdentityObjectTypes());
+ }
+ supportedIOTs.addAll(defaultIdentityStore.getSupportedFeatures().getSupportedRelationshipTypes());
+
+ return supportedIOTs;
+ }
+
+ public boolean isIdentityObjectTypeSupported(IdentityObjectType identityObjectType)
+ {
+ return resolveIdentityStore(identityObjectType).getSupportedFeatures().isIdentityObjectTypeSupported(identityObjectType);
+ }
+
+ public boolean isRelationshipTypeSupported(IdentityObjectType fromType, IdentityObjectType toType, IdentityObjectRelationshipType relationshipType) throws IdentityException
+ {
+ IdentityStore fromStore = resolveIdentityStore(fromType);
+
+ IdentityStore toStore = resolveIdentityStore(toType);
+
+ if (fromStore == toStore)
+ {
+ return fromStore.getSupportedFeatures().isRelationshipTypeSupported(fromType, toType, relationshipType);
+ }
+ else
+ {
+ return defaultIdentityStore.getSupportedFeatures().isRelationshipTypeSupported(fromType, toType, relationshipType);
+ }
+
+ }
+
+ public Set<String> getSupportedRelationshipTypes()
+ {
+ Set<String> supportedRelTypes = new HashSet<String>();
+
+ for (IdentityStore identityStore : getIdentityStoreMappings().values())
+ {
+ supportedRelTypes.addAll(identityStore.getSupportedFeatures().getSupportedRelationshipTypes());
+ }
+ supportedRelTypes.addAll(defaultIdentityStore.getSupportedFeatures().getSupportedRelationshipTypes());
+
+ return supportedRelTypes;
+ }
+
+ public boolean isCredentialSupported(IdentityObjectType identityObjectType, IdentityObjectCredentialType credentialType)
+ {
+ return resolveIdentityStore(identityObjectType).getSupportedFeatures().isCredentialSupported(identityObjectType, credentialType);
+ }
+ };
+
}
public void bootstrap(IdentityStoreConfigurationMetaData configurationMD) throws IdentityException
@@ -131,8 +249,7 @@
public FeaturesMetaData getSupportedFeatures()
{
- //TODO: a wrapper around all stores metadata
- return null;
+ return featuresMetaData;
}
IdentityStore resolveIdentityStore(IdentityObject io)
@@ -221,7 +338,7 @@
public IdentityObject findIdentityObject(IdentityStoreInvocationContext invocationContext, String id) throws IdentityException
{
- //TODO: store
+ //TODO: information about the store mapping should be encoded in type as now its like random guess...
for (IdentityStore identityStore : getIdentityStoreMappings().values())
{
@@ -251,11 +368,63 @@
boolean parent,
IdentityObjectSearchControl[] controls) throws IdentityException
{
- //TODO:
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultIdentityStore, invocationCxt);
+ // Check in the mapped store and merge with default
- return defaultIdentityStore.findIdentityObject(targetCtx, identity, relationshipType, parent, controls);
+ IdentityStore mappedStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext mappedCtx = resolveInvocationContext(mappedStore, invocationCxt);
+
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, invocationCxt);
+
+
+ if (mappedStore == defaultIdentityStore)
+ {
+ return defaultIdentityStore.findIdentityObject(defaultCtx, identity, relationshipType, parent, controls);
+ }
+
+ Collection<IdentityObject> results = mappedStore.findIdentityObject(mappedCtx, identity, relationshipType, parent, controls);
+
+ Collection<IdentityObject> objects = defaultIdentityStore.findIdentityObject(defaultCtx, identity, relationshipType, parent, controls);
+
+ PageSearchControl pageSearchControl = null;
+ SortByNameSearchControl sortSearchControl = null;
+
+ if (controls != null)
+ {
+ for (IdentityObjectSearchControl control : controls)
+ {
+ if (control instanceof PageSearchControl)
+ {
+ pageSearchControl = (PageSearchControl)control;
+ }
+ else if (control instanceof SortByNameSearchControl)
+ {
+ sortSearchControl = (SortByNameSearchControl)control;
+ }
+ }
+ }
+
+
+ // If default store contain related relationships merge and sort/page once more
+ if (objects != null && objects.size() != 0)
+ {
+ results.addAll(objects);
+
+ //TODO: hardcoded List
+ if (pageSearchControl != null && results instanceof List)
+ {
+ results = cutPageFromResults((List<IdentityObject>)results, pageSearchControl);
+ }
+
+ //TODO: hardcoded List
+ if (sortSearchControl != null && results instanceof List)
+ {
+ sortByName((List<IdentityObject>)results, sortSearchControl.isAscending());
+ }
+ }
+
+ return results;
+
}
public IdentityObjectRelationship createRelationship(IdentityStoreInvocationContext invocationCxt, IdentityObject fromIdentity, IdentityObject toIdentity, IdentityObjectRelationshipType relationshipType, String relationshipName, boolean createNames) throws IdentityException
@@ -270,7 +439,12 @@
if (fromStore == toStore)
{
- return fromStore.createRelationship(toTargetCtx, fromIdentity, toIdentity, relationshipType, relationshipName, createNames);
+ // If relationship is named and target store doesn't support named relationships it need to be put in default store anyway
+ if (relationshipName == null ||
+ (relationshipName != null && fromStore.getSupportedFeatures().isNamedRelationshipsSupported()))
+ {
+ return fromStore.createRelationship(toTargetCtx, fromIdentity, toIdentity, relationshipType, relationshipName, createNames);
+ }
}
if (!hasIdentityObject(defaultTargetCtx, defaultIdentityStore, fromIdentity))
@@ -298,8 +472,12 @@
if (fromStore == toStore)
{
- fromStore.removeRelationship(toTargetCtx, fromIdentity, toIdentity, relationshipType, relationshipName);
- return;
+ if (relationshipName == null ||
+ (relationshipName != null && fromStore.getSupportedFeatures().isNamedRelationshipsSupported()))
+ {
+ fromStore.removeRelationship(toTargetCtx, fromIdentity, toIdentity, relationshipType, relationshipName);
+ return;
+ }
}
if (!hasIdentityObject(defaultTargetCtx, defaultIdentityStore, fromIdentity))
@@ -373,41 +551,101 @@
}
return defaultIdentityStore.resolveRelationships(defaultTargetCtx, fromIdentity, toIdentity);
- }
+ }
public String createRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
{
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+ Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
- //TODO: For now just assume that named relationships are in default one
- return defaultIdentityStore.createRelationshipName(defaultCtx, name);
+ // For any IdentityStore that supports named relationships...
+ for (IdentityStore identityStore : stores)
+ {
+ if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext storeCtx = resolveInvocationContext(identityStore, ctx);
+ identityStore.createRelationshipName(storeCtx, name);
+
+ }
+ }
+
+ if (!getIdentityStoreMappings().values().contains(defaultIdentityStore) &&
+ defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+
+ defaultIdentityStore.createRelationshipName(defaultCtx, name);
+ }
+
+ return name;
}
public String removeRelationshipName(IdentityStoreInvocationContext ctx, String name) throws IdentityException, OperationNotSupportedException
{
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+ Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
- //TODO: For now just assume that named relationships are in default one
- return defaultIdentityStore.removeRelationshipName(defaultCtx, name);
+ // For any IdentityStore that supports named relationships...
+ for (IdentityStore identityStore : stores)
+ {
+ if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext storeCtx = resolveInvocationContext(identityStore, ctx);
+ identityStore.removeRelationshipName(storeCtx, name);
+
+ }
+ }
+
+ if (!getIdentityStoreMappings().values().contains(defaultIdentityStore) &&
+ defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+
+ defaultIdentityStore.removeRelationshipName(defaultCtx, name);
+ }
+
+ return name;
}
public Set<String> getRelationshipNames(IdentityStoreInvocationContext ctx, IdentityObjectSearchControl[] controls) throws IdentityException, OperationNotSupportedException
{
- IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+ Set<IdentityStore> stores = new HashSet<IdentityStore>(getIdentityStoreMappings().values());
+ Set<String> results = new HashSet<String>();
- //TODO: For now just assume that named relationships are in default one
- return defaultIdentityStore.getRelationshipNames(defaultCtx, controls);
+ // For any IdentityStore that supports named relationships...
+ for (IdentityStore identityStore : stores)
+ {
+ if (identityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext storeCtx = resolveInvocationContext(identityStore, ctx);
+ results.addAll(identityStore.getRelationshipNames(storeCtx, controls));
+
+ }
+ }
+
+ if (defaultIdentityStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
+
+ results.addAll(defaultIdentityStore.getRelationshipNames(defaultCtx, controls));
+ }
+
+ return results;
}
public Set<String> getRelationshipNames(IdentityStoreInvocationContext ctx, IdentityObject identity, IdentityObjectSearchControl[] controls) throws IdentityException, OperationNotSupportedException
{
+
+ IdentityStore toStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, ctx);
+
+ if (toStore.getSupportedFeatures().isNamedRelationshipsSupported())
+ {
+ return toStore.getRelationshipNames(targetCtx, identity, controls);
+ }
IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultIdentityStore, ctx);
-
- //TODO: For now just assume that named relationships are in default one
- return defaultIdentityStore.getRelationshipNames(defaultCtx, identity, controls);
+ return defaultIdentityStore.getRelationshipNames(defaultCtx, identity, controls);
}
public boolean validateCredential(IdentityStoreInvocationContext ctx, IdentityObject identityObject, IdentityObjectCredential credential) throws IdentityException
@@ -427,55 +665,262 @@
}
- public <T extends IdentityObjectType> Set<String> getSupportedAttributeNames(IdentityStoreInvocationContext invocationContext, T identityType) throws IdentityException
+ public Set<String> getSupportedAttributeNames(IdentityStoreInvocationContext invocationContext, IdentityObjectType identityType) throws IdentityException
{
- //TODO: for profile stored in two stores this need to be merged with results from defaultAttributeStore. For now just use the default one.
+ Set<String> results;
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultAttributeStore, invocationContext);
+ IdentityStore toStore = resolveIdentityStore(identityType);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, invocationContext);
- return defaultAttributeStore.getSupportedAttributeNames(targetCtx, identityType);
- //return resolveIdentityStore(identityType).getSupportedAttributeNames(invocationContext, identityType);
+ results = toStore.getSupportedAttributeNames(targetCtx, identityType);
+
+ if (toStore != defaultAttributeStore)
+ {
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultAttributeStore, invocationContext);
+
+ results.addAll(defaultAttributeStore.getSupportedAttributeNames(defaultCtx, identityType));
+ }
+
+ return results;
}
public Map<String, String[]> getAttributes(IdentityStoreInvocationContext invocationContext, IdentityObject identity) throws IdentityException
{
- //TODO: for profile stored in two stores this need to be merged with results from defaultAttributeStore. For now just use the default one.
+ Map<String, String[]> results;
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultAttributeStore, invocationContext);
+ IdentityStore toStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, invocationContext);
- return defaultAttributeStore.getAttributes(targetCtx, identity);
- //return resolveIdentityStore(identity).getAttributes(invocationContext, identity);
+ results = toStore.getAttributes(targetCtx, identity);
+
+ if (toStore != defaultAttributeStore)
+ {
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultAttributeStore, invocationContext);
+
+ Map<String, String[]> defaultAttrs = defaultAttributeStore.getAttributes(defaultCtx, identity);
+
+ // Add only those attributes which are missing - don't overwrite or merge existing values
+ for (Map.Entry<String, String[]> entry : defaultAttrs.entrySet())
+ {
+ if (!results.keySet().contains(entry.getKey()))
+ {
+ results.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+
+ return results;
}
public void updateAttributes(IdentityStoreInvocationContext invocationCtx, IdentityObject identity, Map<String, String[]> attributes) throws IdentityException
{
- //TODO: for profile stored in two stores this need to be merged with results from defaultAttributeStore. For now just use the default one.
+ Map<String, String[]> filteredAttrs = new HashMap<String, String[]>();
+ Map<String, String[]> leftAttrs = new HashMap<String, String[]>();
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+ IdentityStore toStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, invocationCtx);
- defaultAttributeStore.updateAttributes(targetCtx, identity, attributes);
- //resolveIdentityStore(identity).updateAttributes(invocationCtx, identity, attributes);
+ // Put supported attrs to the main store
+ if (toStore != defaultAttributeStore)
+ {
+ Set<String> supportedAttrs = toStore.getSupportedAttributeNames(targetCtx, identity.getIdentityType());
+
+ // Filter out supported and not supported attributes
+ for (Map.Entry<String, String[]> entry : attributes.entrySet())
+ {
+ if (supportedAttrs.contains(entry.getKey()))
+ {
+ filteredAttrs.put(entry.getKey(), entry.getValue());
+ }
+ else
+ {
+ leftAttrs.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ toStore.updateAttributes(targetCtx, identity, filteredAttrs);
+
+
+ }
+ else
+ {
+ leftAttrs = attributes;
+ }
+
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+
+ if (isAllowNotDefinedAttributes())
+ {
+ defaultAttributeStore.updateAttributes(defaultCtx, identity, leftAttrs);
+ }
+ else
+ {
+ Set<String> supportedAttrs = defaultAttributeStore.getSupportedAttributeNames(defaultCtx, identity.getIdentityType());
+ for (Map.Entry<String, String[]> entry : leftAttrs.entrySet())
+ {
+ if (!supportedAttrs.contains(entry.getKey()))
+ {
+ throw new IdentityException("Cannot update not defined attribute. Use '"
+ + ALLOW_NOT_DEFINED_ATTRIBUTES + "' option to pass such attributes to default IdentityStore anyway." +
+ "Attribute name: " + entry.getKey());
+ }
+ }
+ defaultAttributeStore.updateAttributes(defaultCtx, identity, leftAttrs);
+ }
+
}
public void addAttributes(IdentityStoreInvocationContext invocationCtx, IdentityObject identity, Map<String, String[]> attributes) throws IdentityException
{
- //TODO: for profile stored in two stores this need to be merged with results from defaultAttributeStore. For now just use the default one.
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+ Map<String, String[]> filteredAttrs = new HashMap<String, String[]>();
+ Map<String, String[]> leftAttrs = new HashMap<String, String[]>();
- defaultAttributeStore.addAttributes(targetCtx, identity, attributes);
- //resolveIdentityStore(identity).addAttributes(invocationCtx, identity, attributes);
+ IdentityStore toStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, invocationCtx);
+
+ // Put supported attrs to the main store
+ if (toStore != defaultAttributeStore)
+ {
+ Set<String> supportedAttrs = toStore.getSupportedAttributeNames(targetCtx, identity.getIdentityType());
+
+ // Filter out supported and not supported attributes
+ for (Map.Entry<String, String[]> entry : attributes.entrySet())
+ {
+ if (supportedAttrs.contains(entry.getKey()))
+ {
+ filteredAttrs.put(entry.getKey(), entry.getValue());
+ }
+ else
+ {
+ leftAttrs.put(entry.getKey(), entry.getValue());
+ }
+ }
+
+ toStore.addAttributes(targetCtx, identity, filteredAttrs);
+
+
+ }
+ else
+ {
+ leftAttrs = attributes;
+ }
+
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+
+ if (isAllowNotDefinedAttributes())
+ {
+ defaultAttributeStore.addAttributes(defaultCtx, identity, leftAttrs);
+ }
+ else
+ {
+ Set<String> supportedAttrs = defaultAttributeStore.getSupportedAttributeNames(defaultCtx, identity.getIdentityType());
+ for (Map.Entry<String, String[]> entry : leftAttrs.entrySet())
+ {
+ // if we hit some unsupported attribute at this stage that we cannot store...
+ if (!supportedAttrs.contains(entry.getKey()))
+ {
+ throw new IdentityException("Cannot add not defined attribute. Use '"
+ + ALLOW_NOT_DEFINED_ATTRIBUTES + "' option to pass such attributes to default IdentityStore anyway." +
+ "Attribute name: " + entry.getKey());
+ }
+
+ }
+ defaultAttributeStore.addAttributes(defaultCtx, identity, filteredAttrs);
+ }
+
}
public void removeAttributes(IdentityStoreInvocationContext invocationCtx, IdentityObject identity, String[] attributes) throws IdentityException
{
- //TODO: for profile stored in two stores this need to be merged with results from defaultAttributeStore. For now just use the default one.
+ List<String> filteredAttrs = new LinkedList<String>();
+ List<String> leftAttrs = new LinkedList<String>();
- IdentityStoreInvocationContext targetCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+ IdentityStore toStore = resolveIdentityStore(identity);
+ IdentityStoreInvocationContext targetCtx = resolveInvocationContext(toStore, invocationCtx);
- defaultAttributeStore.removeAttributes(targetCtx, identity, attributes);
- //resolveIdentityStore(identity).removeAttributes(invocationCtx, identity, attributes);
+ // Put supported attrs to the main store
+ if (toStore != defaultAttributeStore)
+ {
+ Set<String> supportedAttrs = toStore.getSupportedAttributeNames(targetCtx, identity.getIdentityType());
+
+ // Filter out supported and not supported attributes
+ for (String name : attributes)
+ {
+ if (supportedAttrs.contains(name))
+ {
+ filteredAttrs.add(name);
+ }
+ else
+ {
+ leftAttrs.add(name);
+ }
+ }
+
+ toStore.removeAttributes(targetCtx, identity, filteredAttrs.toArray(new String[filteredAttrs.size()]));
+
+
+ }
+ else
+ {
+ leftAttrs = Arrays.asList(attributes);
+ }
+
+ IdentityStoreInvocationContext defaultCtx = resolveInvocationContext(defaultAttributeStore, invocationCtx);
+
+ if (isAllowNotDefinedAttributes())
+ {
+ defaultAttributeStore.removeAttributes(defaultCtx, identity, leftAttrs.toArray(new String[leftAttrs.size()]));
+ }
+ else
+ {
+ Set<String> supportedAttrs = defaultAttributeStore.getSupportedAttributeNames(defaultCtx, identity.getIdentityType());
+ for (String name : leftAttrs)
+ {
+ if (!supportedAttrs.contains(name))
+ {
+ throw new IdentityException("Cannot remove not defined attribute. Use '"
+ + ALLOW_NOT_DEFINED_ATTRIBUTES + "' option to pass such attributes to default IdentityStore anyway." +
+ "Attribute name: " + name);
+ }
+ }
+ defaultAttributeStore.removeAttributes(defaultCtx, identity, leftAttrs.toArray(new String[leftAttrs.size()]));
+ }
}
+ private void sortByName(List<IdentityObject> objects, final boolean ascending)
+ {
+ Collections.sort(objects, new Comparator<IdentityObject>(){
+ public int compare(IdentityObject o1, IdentityObject o2)
+ {
+ if (ascending)
+ {
+ return o1.getName().compareTo(o2.getName());
+ }
+ else
+ {
+ return o2.getName().compareTo(o1.getName());
+ }
+ }
+ });
+ }
+ //TODO: other way?
+ private List<IdentityObject> cutPageFromResults(List<IdentityObject> objects, PageSearchControl pageControl)
+ {
+ List<IdentityObject> results = new LinkedList<IdentityObject>();
+ for (int i = pageControl.getOffset(); i < pageControl.getOffset() + pageControl.getLimit(); i++)
+ {
+ if (i < objects.size())
+ {
+ results.add(objects.get(i));
+ }
+ }
+ return results;
+ }
+
+ public boolean isAllowNotDefinedAttributes()
+ {
+ return allowNotDefinedAttributes;
+ }
}
\ No newline at end of file
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/FeaturesMetaDataImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/FeaturesMetaDataImpl.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/FeaturesMetaDataImpl.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -52,15 +52,20 @@
private final Map<String, Set<String>> supportedCredentials;
+ private final boolean namedRelationshipsSupport;
+
// <Relationship Type, <From IdentityType, To IdentityType>>
private final Map<String, Map<String, Set<String>>> supportedRelationshipMappings = new HashMap<String, Map<String, Set<String>>>();
public FeaturesMetaDataImpl(IdentityStoreConfigurationMetaData configurationMD,
- Set<Class> supportedControls)
+ Set<Class> supportedControls,
+ boolean namedRelationshipsSupport)
{
- Map<String, Set<String>> supportedCredentials = new HashMap<String, Set<String>>();
+ this.namedRelationshipsSupport = namedRelationshipsSupport;
+ Map<String, Set<String>> supportedCredentials = new HashMap<String, Set<String>>();
+
for (IdentityObjectTypeMetaData typeMetaData : configurationMD.getSupportedIdentityTypes())
{
supportedTypeNames.add(typeMetaData.getName());
@@ -137,10 +142,11 @@
}
+ }
-
-
-
+ public boolean isNamedRelationshipsSupported()
+ {
+ return namedRelationshipsSupport;
}
public boolean isControlSupported(IdentityObjectType identityObjectType, IdentityObjectSearchControl control)
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -163,7 +163,7 @@
id = configurationMD.getId();
- supportedFeatures = new FeaturesMetaDataImpl(configurationMD, supportedIdentityObjectSearchControls);
+ supportedFeatures = new FeaturesMetaDataImpl(configurationMD, supportedIdentityObjectSearchControls, true);
String persistenceUnit = configurationMD.getOptionSingleValue(PERSISTENCE_UNIT);
@@ -1227,6 +1227,14 @@
throw new IdentityException("Cannot update readonly attribute: " + entry.getKey());
}
}
+ else
+ {
+ if (!isAllowNotDefinedAttributes)
+ {
+ throw new IdentityException("Cannot update not defined attribute. Use '" + ALLOW_NOT_DEFINED_ATTRIBUTES +
+ "' option if needed. Attribute name: " + entry.getKey());
+ }
+ }
}
HibernateIdentityObject hibernateObject = safeGet(ctx, identity);
@@ -1260,13 +1268,21 @@
AttributeMetaData amd = mdMap.get(entry.getKey());
if (amd != null && !amd.isMultivalued() && entry.getValue().length > 1)
{
- throw new IdentityException("Cannot assigned multiply values to single valued attribute: " + entry.getKey());
+ throw new IdentityException("Cannot add multiply values to single valued attribute: " + entry.getKey());
}
if (amd != null && amd.isReadonly())
{
- throw new IdentityException("Cannot update readonly attribute: " + entry.getKey());
+ throw new IdentityException("Cannot add readonly attribute: " + entry.getKey());
}
}
+ else
+ {
+ if (!isAllowNotDefinedAttributes)
+ {
+ throw new IdentityException("Cannot add not defined attribute. Use '" + ALLOW_NOT_DEFINED_ATTRIBUTES +
+ "' option if needed. Attribute name: " + entry.getKey());
+ }
+ }
}
HibernateIdentityObject hibernateObject = safeGet(ctx, identity);
@@ -1302,6 +1318,14 @@
throw new IdentityException("Cannot remove required attribute: " + attributes[i]);
}
}
+ else
+ {
+ if (!isAllowNotDefinedAttributes)
+ {
+ throw new IdentityException("Cannot remove not defined attribute. Use '" + ALLOW_NOT_DEFINED_ATTRIBUTES +
+ "' option if needed. Attribute name: " + attributes[i]);
+ }
+ }
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -88,6 +88,10 @@
public class LDAPIdentityStoreImpl implements IdentityStore
{
+ //TODO: external JNDI
+ //TODO: more options for connection configuration
+ //TODO: JNDI connection credentials encoding (pluggable?)
+
private static Logger log = Logger.getLogger(LDAPIdentityStoreImpl.class.getName());
private final String id;
@@ -106,7 +110,7 @@
static {
// List all supported controls classes
- //TODO:
+ //TODO: attribute filter
supportedSearchControls.add(SortByNameSearchControl.class);
supportedSearchControls.add(PageSearchControl.class);
supportedSearchControls.add(NameFilterSearchControl.class);
@@ -129,7 +133,7 @@
configuration = new SimpleLDAPIdentityStoreConfiguration(configurationMD);
- supportedFeatures = new FeaturesMetaDataImpl(configurationMD, supportedSearchControls);
+ supportedFeatures = new FeaturesMetaDataImpl(configurationMD, supportedSearchControls, false);
// Attribute mappings - helper structures
@@ -927,17 +931,16 @@
}
}
- if (sortSearchControl != null)
+ if (pageSearchControl != null)
{
- sortByName(objects, sortSearchControl.isAscending());
+ objects = cutPageFromResults(objects, pageSearchControl);
}
- if (pageSearchControl != null)
+ if (sortSearchControl != null)
{
- objects = cutPageFromResults(objects, pageSearchControl);
+ sortByName(objects, sortSearchControl.isAscending());
}
-
return objects;
}
Modified: trunk/identity-impl/src/test/resources/organization-test-config.xml
===================================================================
--- trunk/identity-impl/src/test/resources/organization-test-config.xml 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-impl/src/test/resources/organization-test-config.xml 2008-12-15 18:10:32 UTC (rev 164)
@@ -54,6 +54,12 @@
<options/>
</identity-store-mapping>
</identity-store-mappings>
+ <options>
+ <option>
+ <name>allowNotDefinedAttributes</name>
+ <value>true</value>
+ </option>
+ </options>
</repository>
<repository>
<id>Sample Portal Repository DB</id>
@@ -80,6 +86,12 @@
<options/>
</identity-store-mapping>
</identity-store-mappings>
+ <options>
+ <option>
+ <name>allowNotDefinedAttributes</name>
+ <value>true</value>
+ </option>
+ </options>
</repository>
<repository>
<id>RedHat Repository DB+LDAP</id>
@@ -108,6 +120,12 @@
<options/>
</identity-store-mapping>
</identity-store-mappings>
+ <options>
+ <option>
+ <name>allowNotDefinedAttributes</name>
+ <value>true</value>
+ </option>
+ </options>
</repository>
<repository>
<id>Sample Portal Repository DB+LDAP</id>
@@ -140,6 +158,12 @@
<options/>
</identity-store-mapping>
</identity-store-mappings>
+ <options>
+ <option>
+ <name>allowNotDefinedAttributes</name>
+ <value>true</value>
+ </option>
+ </options>
</repository>
</repositories>
<stores>
@@ -262,6 +286,10 @@
<name>isRealmAware</name>
<value>true</value>
</option>
+ <option>
+ <name>allowNotDefinedAttributes</name>
+ <value>true</value>
+ </option>
</options>
</identity-store>
<identity-store>
Modified: trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/FeaturesMetaData.java
===================================================================
--- trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/FeaturesMetaData.java 2008-12-15 09:53:22 UTC (rev 163)
+++ trunk/identity-spi/src/main/java/org/jboss/identity/spi/store/FeaturesMetaData.java 2008-12-15 18:10:32 UTC (rev 164)
@@ -81,6 +81,13 @@
throws IdentityException;
/**
+ *
+ * @return
+ */
+ boolean isNamedRelationshipsSupported();
+
+
+ /**
* @return Set of relationship type names supported in this store
*/
Set<String> getSupportedRelationshipTypes();
17 years, 7 months
JBoss Identity SVN: r163 - in trunk/identity-impl/src: main/java/org/jboss/identity/impl/store/hibernate and 4 other directories.
by jboss-identity-commits@lists.jboss.org
Author: bdaw
Date: 2008-12-15 04:53:22 -0500 (Mon, 15 Dec 2008)
New Revision: 163
Modified:
trunk/identity-impl/src/main/java/org/jboss/identity/impl/helper/Tools.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityObjectTypeConfiguration.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/SimpleLDAPIdentityObjectTypeConfiguration.java
trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java
trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreTestCase.java
trunk/identity-impl/src/test/resources/organization-test-config.xml
trunk/identity-impl/src/test/resources/store-test-config.xml
Log:
LDAP store updates
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/helper/Tools.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/helper/Tools.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/helper/Tools.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -47,5 +47,57 @@
return list;
}
+ public static String wildcardToRegex(String wildcard){
+ StringBuffer s = new StringBuffer(wildcard.length());
+ s.append('^');
+ for (int i = 0, is = wildcard.length(); i < is; i++) {
+ char c = wildcard.charAt(i);
+ switch(c) {
+ case '*':
+ s.append(".*");
+ break;
+// case '?':
+// s.append(".");
+// break;
+ // escape special regexp-characters
+ case '(': case ')': case '[': case ']': case '$':
+ case '^': case '.': case '{': case '}': case '|':
+ case '\\':
+ s.append("\\");
+ s.append(c);
+ break;
+ default:
+ s.append(c);
+ break;
+ }
+ }
+ s.append('$');
+ return(s.toString());
+ }
+ /**
+ * Process dn and retrieves a part from it:
+ * uid=xxx,dc=example,dc=org - retrieves xxx
+ *
+ * @param dn
+ * @return
+ */
+ public static String stripDnToName(String dn)
+ {
+ if (dn == null || dn.length() == 0)
+ {
+ throw new IllegalArgumentException("Cannot process empty dn");
+ }
+ String name = null;
+
+ String[] parts = dn.split(",");
+
+ parts = parts[0].split("=");
+ if (parts.length != 2)
+ {
+ throw new IllegalArgumentException("Wrong dn format: " + dn);
+ }
+
+ return parts[1];
+ }
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/hibernate/HibernateIdentityStoreImpl.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -1222,6 +1222,10 @@
{
throw new IdentityException("Cannot assigned multiply values to single valued attribute: " + entry.getKey());
}
+ if (amd != null && amd.isReadonly())
+ {
+ throw new IdentityException("Cannot update readonly attribute: " + entry.getKey());
+ }
}
}
@@ -1258,6 +1262,10 @@
{
throw new IdentityException("Cannot assigned multiply values to single valued attribute: " + entry.getKey());
}
+ if (amd != null && amd.isReadonly())
+ {
+ throw new IdentityException("Cannot update readonly attribute: " + entry.getKey());
+ }
}
}
@@ -1334,6 +1342,7 @@
}
else
{
+ //TODO: support for empty password should be configurable
value = credential.getValue();
}
@@ -1392,6 +1401,7 @@
}
else
{
+ //TODO: support for empty password should be configurable
value = credential.getValue();
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityObjectTypeConfiguration.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityObjectTypeConfiguration.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityObjectTypeConfiguration.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -34,6 +34,8 @@
{
String getIdAttributeName();
+ String getPasswordAttributeName();
+
String[] getCtxDNs();
String getEntrySearchFilter();
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreImpl.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -33,13 +33,16 @@
import org.jboss.identity.spi.model.IdentityObjectRelationship;
import org.jboss.identity.spi.exception.OperationNotSupportedException;
import org.jboss.identity.spi.configuration.metadata.IdentityStoreConfigurationMetaData;
+import org.jboss.identity.spi.configuration.metadata.IdentityObjectTypeMetaData;
import org.jboss.identity.spi.credential.IdentityObjectCredential;
+import org.jboss.identity.spi.attribute.AttributeMetaData;
import org.jboss.identity.exception.IdentityException;
import org.jboss.identity.impl.store.FeaturesMetaDataImpl;
import org.jboss.identity.impl.model.ldap.LDAPIdentityObjectImpl;
import org.jboss.identity.impl.model.ldap.LDAPIdentityObjectRelationshipImpl;
import org.jboss.identity.impl.helper.Tools;
import org.jboss.identity.impl.NotYetImplementedException;
+import org.jboss.identity.impl.types.SimpleIdentityObjectType;
import org.jboss.identity.impl.api.SortByNameSearchControl;
import org.jboss.identity.impl.api.PageSearchControl;
import org.jboss.identity.impl.api.AttributeFilterSearchControl;
@@ -49,6 +52,7 @@
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Control;
import javax.naming.ldap.SortControl;
+import javax.naming.ldap.InitialLdapContext;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
@@ -59,6 +63,7 @@
import javax.naming.NamingException;
import javax.naming.NamingEnumeration;
import javax.naming.Context;
+import javax.naming.InitialContext;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
@@ -70,6 +75,9 @@
import java.util.HashSet;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Comparator;
+import java.util.regex.Pattern;
import java.util.logging.Logger;
import java.util.logging.Level;
@@ -88,14 +96,20 @@
LDAPIdentityStoreConfiguration configuration;
+ IdentityStoreConfigurationMetaData configurationMD;
+
private static Set<Class> supportedSearchControls = new HashSet<Class>();
+ // <IdentityObjectType name, <Attribute name, MD>
+ private Map<String, Map<String, AttributeMetaData>> attributesMetaData = new HashMap<String, Map<String, AttributeMetaData>>();
+
static {
// List all supported controls classes
//TODO:
supportedSearchControls.add(SortByNameSearchControl.class);
- //supportedSearchControls.add(PageSearchControl.class);
+ supportedSearchControls.add(PageSearchControl.class);
+ supportedSearchControls.add(NameFilterSearchControl.class);
//supportedSearchControls.add(AttributeFilterSearchControl.class);
}
@@ -111,9 +125,25 @@
throw new IllegalArgumentException("Configuration is null");
}
+ this.configurationMD = configurationMD;
+
configuration = new SimpleLDAPIdentityStoreConfiguration(configurationMD);
supportedFeatures = new FeaturesMetaDataImpl(configurationMD, supportedSearchControls);
+
+ // Attribute mappings - helper structures
+
+ for (IdentityObjectTypeMetaData identityObjectTypeMetaData : configurationMD.getSupportedIdentityTypes())
+ {
+ Map<String, AttributeMetaData> metadataMap = new HashMap<String, AttributeMetaData>();
+ for (AttributeMetaData attributeMetaData : identityObjectTypeMetaData.getAttributes())
+ {
+ metadataMap.put(attributeMetaData.getName(), attributeMetaData);
+ }
+
+ attributesMetaData.put(identityObjectTypeMetaData.getName(), metadataMap);
+
+ }
}
public IdentityStoreSession createIdentityStoreSession()
@@ -300,7 +330,7 @@
if (filter != null && filter.length() > 0)
{
- //* chars are escaped in filterArgs so we must replace it manually
+ // chars are escaped in filterArgs so we must replace it manually
filter = filter.replaceAll("\\{0\\}", "*");
}
else
@@ -309,9 +339,12 @@
filter = "(".concat(getTypeConfiguration(ctx, identityType).getIdAttributeName()).concat("=").concat("*").concat(")");
}
+
+ String[] entryCtxs = getTypeConfiguration(ctx, identityType).getCtxDNs();
+
//log.debug("Search filter: " + filter);
List sr = searchIdentityObjects(ctx,
- identityType,
+ entryCtxs,
filter,
null,
new String[]{getTypeConfiguration(ctx, identityType).getIdAttributeName()},
@@ -353,11 +386,15 @@
String filter = getTypeConfiguration(invocationCtx, type).getEntrySearchFilter();
List sr = null;
+
+ String[] entryCtxs = getTypeConfiguration(invocationCtx, type).getCtxDNs();
+
+
if (filter != null && filter.length() > 0)
{
Object[] filterArgs = {name};
sr = searchIdentityObjects(invocationCtx,
- type,
+ entryCtxs,
filter,
filterArgs,
new String[]{getTypeConfiguration(invocationCtx, type).getIdAttributeName()},
@@ -368,7 +405,7 @@
//search all entries
filter = "(".concat(getTypeConfiguration(invocationCtx, type).getIdAttributeName()).concat("=").concat(name).concat(")");
sr = searchIdentityObjects(invocationCtx,
- type,
+ entryCtxs,
filter,
null,
new String[]{getTypeConfiguration(invocationCtx, type).getIdAttributeName()},
@@ -499,20 +536,10 @@
public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext invocationCtx, IdentityObjectType type, IdentityObjectSearchControl[] controls) throws IdentityException
{
-// if (log.isLoggable(Level.FINER))
-// {
-// log.finer(toString() + ".findIdentityObject with type: " + type
-// + "; nameFilter: " + nameFilter
-// + "; offset: " + offset
-// + "; limit: " + limit
-// + "; orderByName: " + orderByName
-// + "; ascending: " + ascending
-// );
-// }
checkControls(controls);
- //TODO: paged control
+ //TODO: page control with LDAP request control
PageSearchControl pageSearchControl = null;
SortByNameSearchControl sortSearchControl = null;
@@ -552,8 +579,6 @@
}
- //TODO: handle paged results
-
LdapContext ctx = getLDAPContext(invocationCtx);
@@ -601,12 +626,14 @@
String filter = getTypeConfiguration(invocationCtx, type).getEntrySearchFilter();
List<SearchResult> sr = null;
+ String[] entryCtxs = getTypeConfiguration(invocationCtx, type).getCtxDNs();
+
if (filter != null && filter.length() > 0)
{
Object[] filterArgs = {nameFilter};
sr = searchIdentityObjects(invocationCtx,
- type,
+ entryCtxs,
"(&(" + filter + ")" + af.toString() + ")",
filterArgs,
new String[]{typeConfiguration.getIdAttributeName()},
@@ -616,7 +643,7 @@
{
filter = "(".concat(typeConfiguration.getIdAttributeName()).concat("=").concat(nameFilter).concat(")");
sr = searchIdentityObjects(invocationCtx,
- type,
+ entryCtxs,
"(&(" + filter + ")" + af.toString() + ")",
null,
new String[]{typeConfiguration.getIdAttributeName()},
@@ -630,7 +657,8 @@
String dn = ctx.getNameInNamespace();
if (sortSearchControl != null)
{
- //TODO: It seams that sort control returns entries in descending order by default...
+ // It seams that the sort order is not configurable and
+ // sort control returns entries in descending order by default...
if (!sortSearchControl.isAscending())
{
objects.addFirst(createIdentityObjectInstance(invocationCtx, type, res.getAttributes(), dn));
@@ -648,7 +676,6 @@
ctx.close();
- return objects;
}
catch (NoSuchElementException e)
@@ -674,6 +701,11 @@
}
}
+ if (pageSearchControl != null)
+ {
+ objects = (LinkedList)cutPageFromResults(objects, pageSearchControl);
+ }
+
return objects;
}
@@ -685,25 +717,13 @@
public Collection<IdentityObject> findIdentityObject(IdentityStoreInvocationContext ctx, IdentityObject identity, IdentityObjectRelationshipType relationshipType, boolean parent, IdentityObjectSearchControl[] controls) throws IdentityException
{
- // relationshipType is ignored for now
-// if (log.isLoggable(Level.FINER))
-// {
-// log.finer(toString() + ".findIdentityObject with identity: " + identity
-// + "; relationshipType: " + relationshipType
-// + "; offset: " + offset
-// + "; limit: " + limit
-// + "; orderByName: " + orderByName
-// + "; ascending: " + ascending
-// );
-// }
-
- //TODO: handle paged results and sort
-
checkControls(controls);
PageSearchControl pageSearchControl = null;
SortByNameSearchControl sortSearchControl = null;
+ AttributeFilterSearchControl attributeFilterSearchControl = null;
+ NameFilterSearchControl nameFilterSearchControl = null;
if (controls != null)
{
@@ -717,11 +737,18 @@
{
sortSearchControl = (SortByNameSearchControl)control;
}
+ else if (control instanceof AttributeFilterSearchControl)
+ {
+ attributeFilterSearchControl = (AttributeFilterSearchControl)control;
+ }
+ else if (control instanceof NameFilterSearchControl)
+ {
+ nameFilterSearchControl = (NameFilterSearchControl)control;
+ }
+
}
}
- Set<IdentityObjectRelationship> relationships = new HashSet<IdentityObjectRelationship>();
-
LDAPIdentityObjectImpl ldapFromIO = getSafeLDAPIO(ctx, identity);
LDAPIdentityObjectTypeConfiguration typeConfig = getTypeConfiguration(ctx, identity.getIdentityType());
@@ -748,27 +775,139 @@
if (typeConfig.isMembershipAttributeDN())
{
- //TODO: improve
- objects.add(findIdentityObject(ctx, memberRef));
+ //TODO: use direct LDAP query instaed of other find method and add attributesFilter
+
+ if (nameFilterSearchControl != null)
+ {
+ String name = Tools.stripDnToName(memberRef);
+ String regex = Tools.wildcardToRegex(nameFilterSearchControl.getFilter());
+
+ if (Pattern.matches(regex, name))
+ {
+ objects.add(findIdentityObject(ctx, memberRef));
+ }
+ }
+ else
+ {
+ objects.add(findIdentityObject(ctx, memberRef));
+ }
}
else
{
- //TODO:
- throw new NotYetImplementedException();
+ //TODO: if relationships are not refered with DNs and only names its not possible to map
+ //TODO: them to proper IdentityType and keep name uniqnes per type. Workaround needed
+ throw new NotYetImplementedException("LDAP limitation. If relationship targets are not refered with FQDNs " +
+ "and only names, it's not possible to map them to proper IdentityType and keep name uniqnes per type. " +
+ "Workaround needed");
}
- break;
+ //break;
}
}
-
- //TODO: need to be sorted/paginated manually
}
// if not parent then all parent entries need to be found
else
{
- //TODO:
- //TODO: apply sort/pagination ldap control
- throw new NotYetImplementedException();
+ // Search in all other type contexts
+ for (IdentityObjectType parentType : configuration.getConfiguredTypes())
+ {
+ checkIOType(parentType);
+
+ LDAPIdentityObjectTypeConfiguration parentTypeConfiguration = getTypeConfiguration(ctx, parentType);
+
+ List<String> allowedTypes = Arrays.asList(parentTypeConfiguration.getAllowedMembershipTypes());
+
+ // Check if given identity type can be parent
+ if (!allowedTypes.contains(identity.getIdentityType().getName()))
+ {
+ continue;
+ }
+
+ String nameFilter = "*";
+
+ //Filter by name
+ if (nameFilterSearchControl != null)
+ {
+ nameFilter = nameFilterSearchControl.getFilter();
+ }
+
+ Control[] requestControls = null;
+
+ StringBuilder af = new StringBuilder();
+
+ // Filter by attribute values
+ if (attributeFilterSearchControl != null)
+ {
+ af.append("(&");
+
+ for (Map.Entry<String, String[]> stringEntry : attributeFilterSearchControl.getValues().entrySet())
+ {
+ for (String value : stringEntry.getValue())
+ {
+ af.append("(")
+ .append(stringEntry.getKey())
+ .append("=")
+ .append(value)
+ .append(")");
+ }
+ }
+
+ af.append(")");
+ }
+
+ // Add filter to search only parents of the given entry
+ af.append("(")
+ .append(parentTypeConfiguration.getMembershipAttributeName())
+ .append("=");
+ if (parentTypeConfiguration.isMembershipAttributeDN())
+ {
+ af.append(ldapFromIO.getDn());
+ }
+ else
+ {
+ //TODO: this doesn't make much sense unless parent/child are same identity types and resides in the same LDAP context
+ af.append(ldapFromIO.getName());
+ }
+ af.append(")");
+
+
+ String filter = parentTypeConfiguration.getEntrySearchFilter();
+ List<SearchResult> sr = null;
+
+ String[] entryCtxs = parentTypeConfiguration.getCtxDNs();
+
+ if (filter != null && filter.length() > 0)
+ {
+
+ Object[] filterArgs = {nameFilter};
+ sr = searchIdentityObjects(ctx,
+ entryCtxs,
+ "(&(" + filter + ")" + af.toString() + ")",
+ filterArgs,
+ new String[]{parentTypeConfiguration.getIdAttributeName()},
+ requestControls);
+ }
+ else
+ {
+ filter = "(".concat(parentTypeConfiguration.getIdAttributeName()).concat("=").concat(nameFilter).concat(")");
+ sr = searchIdentityObjects(ctx,
+ entryCtxs,
+ "(&(" + filter + ")" + af.toString() + ")",
+ null,
+ new String[]{parentTypeConfiguration.getIdAttributeName()},
+ requestControls);
+ }
+
+ for (SearchResult res : sr)
+ {
+ LdapContext ldapCtx = (LdapContext)res.getObject();
+ String dn = ldapCtx.getNameInNamespace();
+
+ objects.add(createIdentityObjectInstance(ctx, parentType, res.getAttributes(), dn));
+ }
+ }
+
+
}
}
@@ -787,6 +926,18 @@
throw new IdentityException("Failed to close LDAP connection", e);
}
}
+
+ if (sortSearchControl != null)
+ {
+ sortByName(objects, sortSearchControl.isAscending());
+ }
+
+ if (pageSearchControl != null)
+ {
+ objects = cutPageFromResults(objects, pageSearchControl);
+ }
+
+
return objects;
}
@@ -848,7 +999,7 @@
attrs.put(member);
- ldapContext.modifyAttributes(ldapFromIO.getDn(), DirContext.REPLACE_ATTRIBUTE, attrs);
+ ldapContext.modifyAttributes(ldapFromIO.getDn(), DirContext.ADD_ATTRIBUTE, attrs);
relationship = new LDAPIdentityObjectRelationshipImpl(name, ldapFromIO, ldapToIO);
@@ -984,6 +1135,7 @@
// If relationship is not allowed return empty set
//TODO: use features description instead
+
if (!Arrays.asList(fromTypeConfig.getAllowedMembershipTypes()).contains(ldapToIO.getIdentityType().getName()))
{
return relationships;
@@ -1065,14 +1217,142 @@
public boolean validateCredential(IdentityStoreInvocationContext ctx, IdentityObject identityObject, IdentityObjectCredential credential) throws IdentityException
{
- //TODO: NYI
- throw new NotYetImplementedException();
+ if (credential == null)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ LDAPIdentityObjectImpl ldapIO = getSafeLDAPIO(ctx, identityObject);
+
+ if (supportedFeatures.isCredentialSupported(ldapIO.getIdentityType(),credential.getType()))
+ {
+
+ String passwordString = null;
+
+ // Handle generic impl
+
+ if (credential.getValue() != null)
+ {
+ //TODO: support for empty password should be configurable
+ passwordString = credential.getValue().toString();
+ }
+ else
+ {
+ throw new IdentityException("Null password value");
+ }
+
+ LdapContext ldapContext = getLDAPContext(ctx);
+
+ try
+ {
+
+ Hashtable env = ldapContext.getEnvironment();
+
+ env.put(Context.SECURITY_PRINCIPAL, ldapIO.getDn());
+ env.put(Context.SECURITY_CREDENTIALS, passwordString);
+
+ InitialContext initialCtx = new InitialLdapContext(env, null);
+
+ if (initialCtx != null)
+ {
+ initialCtx.close();
+ return true;
+ }
+
+ }
+ catch (NamingException e)
+ {
+ //
+ }
+ finally
+ {
+ try
+ {
+ ldapContext.close();
+ }
+ catch (NamingException e)
+ {
+ throw new IdentityException("Failed to close LDAP connection", e);
+ }
+ }
+ return false;
+
+
+ }
+ else
+ {
+ throw new IdentityException("CredentialType not supported for a given IdentityObjectType");
+ }
}
public void updateCredential(IdentityStoreInvocationContext ctx, IdentityObject identityObject, IdentityObjectCredential credential) throws IdentityException
{
- //TODO: NYI
- throw new NotYetImplementedException();
+ if (credential == null)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ LDAPIdentityObjectImpl ldapIO = getSafeLDAPIO(ctx, identityObject);
+
+ if (supportedFeatures.isCredentialSupported(ldapIO.getIdentityType(),credential.getType()))
+ {
+
+ String passwordString = null;
+
+ // Handle generic impl
+
+ if (credential.getValue() != null)
+ {
+ //TODO: support for empty password should be configurable
+ passwordString = credential.getValue().toString();
+ }
+ else
+ {
+ throw new IdentityException("Null password value");
+ }
+
+ String attributeName = getTypeConfiguration(ctx, ldapIO.getIdentityType()).getPasswordAttributeName();
+
+ if (attributeName == null)
+ {
+ throw new IdentityException("IdentityType doesn't have passwordAttributeName option set: "
+ + ldapIO.getIdentityType().getName());
+ }
+
+ LdapContext ldapContext = getLDAPContext(ctx);
+
+ try
+ {
+ //TODO: maybe perform a schema check if this attribute is allowed for such entry
+
+ Attributes attrs = new BasicAttributes(true);
+ Attribute attr = new BasicAttribute(attributeName);
+ attr.add(passwordString);
+ attrs.put(attr);
+
+ ldapContext.modifyAttributes(ldapIO.getDn(), DirContext.REPLACE_ATTRIBUTE,attrs);
+ }
+ catch (NamingException e)
+ {
+ throw new IdentityException("Cannot set identity password value.", e);
+ }
+ finally
+ {
+ try
+ {
+ ldapContext.close();
+ }
+ catch (NamingException e)
+ {
+ throw new IdentityException("Failed to close LDAP connection", e);
+ }
+ }
+
+ }
+ else
+ {
+ throw new IdentityException("CredentialType not supported for a given IdentityObjectType");
+ }
}
@@ -1211,7 +1491,21 @@
String[] values = attributes.get(name);
+ Map<String, AttributeMetaData> mdMap = attributesMetaData.get(identity.getIdentityType().getName());
+ if (mdMap != null)
+ {
+ AttributeMetaData amd = mdMap.get(attributeName);
+ if (amd != null && !amd.isMultivalued() && values.length > 1)
+ {
+ throw new IdentityException("Cannot assigned multiply values to single valued attribute: " + attributeName);
+ }
+ if (amd != null && amd.isReadonly())
+ {
+ throw new IdentityException("Cannot update readonly attribute: " + attributeName);
+ }
+ }
+
if (values != null)
{
for (String value : values)
@@ -1291,7 +1585,22 @@
String[] values = attributes.get(name);
+ Map<String, AttributeMetaData> mdMap = attributesMetaData.get(identity.getIdentityType().getName());
+ if (mdMap != null)
+ {
+ AttributeMetaData amd = mdMap.get(attributeName);
+ if (amd != null && !amd.isMultivalued() && values.length > 1)
+ {
+ throw new IdentityException("Cannot assigned multiply values to single valued attribute: " + attributeName);
+ }
+ if (amd != null && amd.isReadonly())
+ {
+ throw new IdentityException("Cannot update readonly attribute: " + attributeName);
+ }
+ }
+
+
if (values != null)
{
for (String value : values)
@@ -1362,8 +1671,20 @@
continue;
}
- //TODO: maybe perform a schema check if this attribute is not required
+ Map<String, AttributeMetaData> mdMap = attributesMetaData.get(identity.getIdentityType().getName());
+ if (mdMap != null)
+ {
+ //TODO: maybe perform a schema check if this attribute is not required on the LDAP level
+ AttributeMetaData amd = mdMap.get(name);
+ if (amd != null && amd.isRequired())
+ {
+ throw new IdentityException("Cannot remove required attribute: " + name);
+ }
+ }
+
+
+
Attributes attrs = new BasicAttributes(true);
Attribute attr = new BasicAttribute(attributeName);
attrs.put(attr);
@@ -1420,7 +1741,7 @@
}
public List<SearchResult> searchIdentityObjects(IdentityStoreInvocationContext ctx,
- IdentityObjectType type,
+ String[] entryCtxs,
String filter,
Object[] filterArgs,
String[] returningAttributes,
@@ -1451,8 +1772,6 @@
}
- String[] entryCtxs = getTypeConfiguration(ctx, type).getCtxDNs();
-
if (entryCtxs.length == 1)
{
if (filterArgs == null)
@@ -1579,5 +1898,36 @@
}
}
}
-
+
+ private void sortByName(List<IdentityObject> objects, final boolean ascending)
+ {
+ Collections.sort(objects, new Comparator<IdentityObject>(){
+ public int compare(IdentityObject o1, IdentityObject o2)
+ {
+ if (ascending)
+ {
+ return o1.getName().compareTo(o2.getName());
+ }
+ else
+ {
+ return o2.getName().compareTo(o1.getName());
+ }
+ }
+ });
+ }
+
+ //TODO: dummy and inefficient temporary workaround. Need to be implemented with ldap request control
+ private List<IdentityObject> cutPageFromResults(List<IdentityObject> objects, PageSearchControl pageControl)
+ {
+ List<IdentityObject> results = new LinkedList<IdentityObject>();
+ for (int i = pageControl.getOffset(); i < pageControl.getOffset() + pageControl.getLimit(); i++)
+ {
+ if (i < objects.size())
+ {
+ results.add(objects.get(i));
+ }
+ }
+ return results;
+ }
+
}
Modified: trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/SimpleLDAPIdentityObjectTypeConfiguration.java
===================================================================
--- trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/SimpleLDAPIdentityObjectTypeConfiguration.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/main/java/org/jboss/identity/impl/store/ldap/SimpleLDAPIdentityObjectTypeConfiguration.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -41,6 +41,8 @@
{
private final String idAttributeName;
+ private final String passwordAttributeName;
+
private final String[] ctxDNs;
private final String entrySearchFilter;
@@ -64,6 +66,8 @@
public static final String ID_ATTRIBUTE_NAME = "idAttributeName";
+ public static final String PASSWORD_ATTRIBUTE_NAME = "passwordAttributeName";
+
public static final String CTX_DNS = "ctxDNs";
public static final String ENTRY_SEARCH_FILTER = "entrySearchFilter";
@@ -83,6 +87,7 @@
public SimpleLDAPIdentityObjectTypeConfiguration(IdentityObjectTypeMetaData objectTypeMD)
{
this.idAttributeName = objectTypeMD.getOptionSingleValue(ID_ATTRIBUTE_NAME);
+ this.passwordAttributeName = objectTypeMD.getOptionSingleValue(PASSWORD_ATTRIBUTE_NAME);
this.entrySearchFilter = objectTypeMD.getOptionSingleValue(ENTRY_SEARCH_FILTER);
this.membershipAttributeName = objectTypeMD.getOptionSingleValue(MEMBERSHIP_ATTRIBUTE_NAME);
String allowCreateEntry = objectTypeMD.getOptionSingleValue(ALLOW_CREATE_ENTRY);
@@ -196,6 +201,7 @@
}
public SimpleLDAPIdentityObjectTypeConfiguration(String idAttributeName,
+ String passwordAttributeName,
String[] ctxDNs,
String entrySearchFilter,
boolean allowCreateEntry,
@@ -207,6 +213,7 @@
Map<String, String> attributeNames)
{
this.idAttributeName = idAttributeName;
+ this.passwordAttributeName = passwordAttributeName;
this.ctxDNs = ctxDNs;
this.entrySearchFilter = entrySearchFilter;
this.allowCreateEntry = allowCreateEntry;
@@ -270,7 +277,12 @@
return attributeNames.get(name);
}
-// public void setIdAttributeName(String idAttributeName)
+ public String getPasswordAttributeName()
+ {
+ return passwordAttributeName;
+ }
+
+ // public void setIdAttributeName(String idAttributeName)
// {
// this.idAttributeName = idAttributeName;
// }
Modified: trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java
===================================================================
--- trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/CommonIdentityStoreTest.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -277,7 +277,22 @@
assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), group2, user1).size());
assertEquals(0, testContext.getStore().resolveRelationships(testContext.getCtx(), user1, group2).size());
+ testContext.flush();
+ // test find methods with relationships
+
+ testContext.getStore().createRelationship(testContext.getCtx(), group1, user1, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, null, false);
+ testContext.getStore().createRelationship(testContext.getCtx(), group1, user2, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, null, false);
+
+ testContext.flush();
+
+ assertEquals(2, testContext.getStore().findIdentityObject(testContext.getCtx(), group1, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, true, null).size());
+ assertEquals(0, testContext.getStore().findIdentityObject(testContext.getCtx(), group1, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, false, null).size());
+ assertEquals(1, testContext.getStore().findIdentityObject(testContext.getCtx(), user1, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, false, null).size());
+ assertEquals(1, testContext.getStore().findIdentityObject(testContext.getCtx(), user2, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, false, null).size());
+ assertEquals(0, testContext.getStore().findIdentityObject(testContext.getCtx(), group2, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, false, null).size());
+ assertEquals(0, testContext.getStore().findIdentityObject(testContext.getCtx(), group2, RelationshipTypeEnum.JBOSS_IDENTITY_MEMBERSHIP, true, null).size());
+
testContext.commit();
}
Modified: trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreTestCase.java
===================================================================
--- trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreTestCase.java 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/test/java/org/jboss/identity/impl/store/ldap/LDAPIdentityStoreTestCase.java 2008-12-15 09:53:22 UTC (rev 163)
@@ -58,7 +58,8 @@
* @author <a href="mailto:boleslaw.dawidowicz at redhat.com">Boleslaw Dawidowicz</a>
* @version : 0.1 $
*/
-public class LDAPIdentityStoreTestCase extends TestCase implements IdentityStoreTestContext
+public class
+ LDAPIdentityStoreTestCase extends TestCase implements IdentityStoreTestContext
{
public static final String LDAP_HOST = "localhost";
@@ -507,4 +508,12 @@
commonTest.testControls();
}
+
+ public void testCredentials() throws Exception
+ {
+ populateClean();
+
+ commonTest.testPasswordCredential();
+ }
+
}
Modified: trunk/identity-impl/src/test/resources/organization-test-config.xml
===================================================================
--- trunk/identity-impl/src/test/resources/organization-test-config.xml 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/test/resources/organization-test-config.xml 2008-12-15 09:53:22 UTC (rev 163)
@@ -305,6 +305,10 @@
<value>uid</value>
</option>
<option>
+ <name>passwordAttributeName</name>
+ <value>password</value>
+ </option>
+ <option>
<name>ctxDNs</name>
<value>ou=People,o=test,dc=portal,dc=example,dc=com</value>
</option>
Modified: trunk/identity-impl/src/test/resources/store-test-config.xml
===================================================================
--- trunk/identity-impl/src/test/resources/store-test-config.xml 2008-12-12 22:43:45 UTC (rev 162)
+++ trunk/identity-impl/src/test/resources/store-test-config.xml 2008-12-15 09:53:22 UTC (rev 163)
@@ -176,21 +176,21 @@
<name>phone</name>
<mapping>telephoneNumber</mapping>
<isRequired/>
- <isMultivalued/>
+ <isMultivalued>true</isMultivalued>
<isReadOnly/>
</attribute>
<attribute>
<name>description</name>
<mapping>description</mapping>
<isRequired/>
- <isMultivalued/>
+ <isMultivalued>true</isMultivalued>
<isReadOnly/>
</attribute>
<attribute>
<name>carLicense</name>
<mapping>carLicense</mapping>
<isRequired/>
- <isMultivalued/>
+ <isMultivalued>true</isMultivalued>
<isReadOnly/>
</attribute>
</attributes>
@@ -200,6 +200,10 @@
<value>uid</value>
</option>
<option>
+ <name>passwordAttributeName</name>
+ <value>userPassword</value>
+ </option>
+ <option>
<name>ctxDNs</name>
<value>ou=People,o=test,dc=portal,dc=example,dc=com</value>
</option>
17 years, 7 months
JBoss Identity SVN: r162 - identity-federation/trunk/assembly.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-12 17:43:45 -0500 (Fri, 12 Dec 2008)
New Revision: 162
Modified:
identity-federation/trunk/assembly/sources.xml
Log:
fix sources
Modified: identity-federation/trunk/assembly/sources.xml
===================================================================
--- identity-federation/trunk/assembly/sources.xml 2008-12-12 22:40:31 UTC (rev 161)
+++ identity-federation/trunk/assembly/sources.xml 2008-12-12 22:43:45 UTC (rev 162)
@@ -9,5 +9,14 @@
<directory>${basedir}/../identity-fed-model/src/main/java</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
+ <fileSet>
+ <directory>${basedir}/../identity-fed-api/src/main/java</directory>
+ <outputDirectory>/</outputDirectory>
+ </fileSet>
+ <fileSet>
+ <directory>${basedir}/../identity-bindings/src/main/java</directory>
+ <outputDirectory>/</outputDirectory>
+ </fileSet>
</fileSets>
+
</assembly>
17 years, 7 months
JBoss Identity SVN: r160 - in identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings: tomcat and 2 other directories.
by jboss-identity-commits@lists.jboss.org
Author: anil.saldhana(a)jboss.com
Date: 2008-12-12 17:40:02 -0500 (Fri, 12 Dec 2008)
New Revision: 160
Added:
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/util/
Log:
bindings
Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/idp/IDPRedirectValve.java 2008-12-12 22:40:02 UTC (rev 160)
@@ -0,0 +1,214 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.identity.federation.bindings.tomcat.idp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URLEncoder;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.catalina.Role;
+import org.apache.catalina.User;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.log4j.Logger;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnResponseFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.federation.api.util.Base64;
+import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
+import org.jboss.identity.federation.saml.v2.jboss.IDPInfoHolder;
+import org.jboss.identity.federation.saml.v2.jboss.IssuerInfoHolder;
+import org.jboss.identity.federation.saml.v2.jboss.JBossSAMLURIConstants;
+import org.jboss.identity.federation.saml.v2.jboss.SPInfoHolder;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
+
+/**
+ * Valve at the IDP that supports the HTTP/Redirect Binding
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 9, 2008
+ */
+public class IDPRedirectValve extends ValveBase
+{
+ private static Logger log = Logger.getLogger(IDPRedirectValve.class);
+
+ private String identityURL = null;
+
+ public void setIdentityURL(String url)
+ {
+ this.identityURL = url;
+ }
+
+ @Override
+ public void invoke(Request request, Response response) throws IOException, ServletException
+ {
+ //request.setCharacterEncoding("UTF-8");
+
+ boolean containsSAMLRequestMessage = this.isSAMLRequestMessage(request);
+
+ //Lets check if the user has been authenticated
+ Principal userPrincipal = request.getUserPrincipal();
+ if(userPrincipal == null)
+ {
+ //Send it for user authentication
+ try
+ {
+ //Next in the invocation chain
+ getNext().invoke(request, response);
+ }
+ finally
+ {
+ //TODO: send saml error
+ if(response.getStatus() == HttpServletResponse.SC_FORBIDDEN)
+ throw new RuntimeException("Unauthorized User");
+
+ //User is authenticated as we are on the return path
+ userPrincipal = request.getUserPrincipal();
+ if(userPrincipal != null)
+ {
+ //Send valid saml response after processing the request
+ if(containsSAMLRequestMessage)
+ {
+ try
+ {
+ ResponseType responseType = this.getResponse(request, userPrincipal);
+ StringWriter stringWriter = new StringWriter();
+ JBossSAMLAuthnResponseFactory.marshall(responseType, stringWriter);
+
+ String responseMessage = stringWriter.toString();
+
+ //Deflate encoding
+ byte[] deflatedMsg = DeflateUtil.encode(responseMessage);
+
+ String base64Response = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES);
+
+ String destination = responseType.getDestination();
+ log.trace("IDP:Destination=" + destination);
+ base64Response = URLEncoder.encode(base64Response, "UTF-8");
+ response.sendRedirect(destination + "?SAMLResponse=" + base64Response);
+ }
+ catch (Exception e)
+ {
+ log.error("Exception:" ,e);
+ throw new ServletException(e.getLocalizedMessage());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isSAMLRequestMessage(Request request)
+ {
+ return request.getParameter("SAMLRequest") != null;
+ }
+
+ private ResponseType getResponse(Request request, Principal userPrincipal) throws Exception
+ {
+ ResponseType responseType = null;
+
+ byte[] decodedMessage = Base64.decode(getSAMLMessage(request));
+
+ InputStream is = DeflateUtil.decode(decodedMessage);
+ AuthnRequestType authnRequestType = JBossSAMLAuthnRequestFactory.getAuthnRequestType(is);
+ if(authnRequestType == null)
+ throw new IllegalStateException("AuthnRequest is null");
+
+ JBossSAMLAuthnRequestFactory.marshall(authnRequestType, System.out);
+
+ //Create a response type
+ String id = "ID_" + JBossSAMLBaseFactory.createUUID();
+
+ IssuerInfoHolder issuerHolder = new IssuerInfoHolder(this.identityURL);
+ issuerHolder.setStatusCode(JBossSAMLURIConstants.STATUS_SUCCESS.get());
+
+ IDPInfoHolder idp = new IDPInfoHolder();
+ idp.setNameIDFormatValue(userPrincipal.getName());
+ idp.setNameIDFormat(JBossSAMLURIConstants.NAMEID_FORMAT_PERSISTENT.get());
+
+ SPInfoHolder sp = new SPInfoHolder();
+ sp.setResponseDestinationURI(authnRequestType.getAssertionConsumerServiceURL());
+ responseType = JBossSAMLAuthnResponseFactory.createResponseType(id, sp, idp, issuerHolder);
+ //Add information on the roles
+ List<String> roles = getRoles(userPrincipal);
+ AssertionType assertion = (AssertionType) responseType.getAssertionOrEncryptedAssertion().get(0);
+
+ AttributeStatementType attrStatement = JBossSAMLBaseFactory.createAttributeStatement();
+ for(String role: roles)
+ {
+ AttributeType attr = JBossSAMLBaseFactory.createAttributeForRole(role);
+ attrStatement.getAttributeOrEncryptedAttribute().add(attr);
+ }
+ assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement().add(attrStatement);
+
+ log.debug("ResponseType = ");
+ //Lets see how the response looks like
+ JBossSAMLAuthnResponseFactory.marshall(responseType, System.out);
+
+ return responseType;
+ }
+
+ private List<String> getRoles(Principal tomcatPrincipal)
+ {
+ List<String> userRoles = new ArrayList<String>();
+
+ if(tomcatPrincipal instanceof GenericPrincipal)
+ {
+ GenericPrincipal gp = (GenericPrincipal) tomcatPrincipal;
+ String[] roles = gp.getRoles();
+ if(roles.length > 0)
+ userRoles.addAll(Arrays.asList(roles));
+ }
+ else
+ if(tomcatPrincipal instanceof User)
+ {
+ User tomcatUser = (User) tomcatPrincipal;
+ Iterator<?> iter = tomcatUser.getRoles();
+ while(iter.hasNext())
+ {
+ Role tomcatRole = (Role) iter.next();
+ userRoles.add(tomcatRole.getRolename());
+ }
+ }
+ return userRoles;
+ }
+
+
+ private String getSAMLMessage(Request request)
+ {
+ return request.getParameter("SAMLRequest");
+ }
+}
\ No newline at end of file
Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectFormAuthenticator.java 2008-12-12 22:40:02 UTC (rev 160)
@@ -0,0 +1,216 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.identity.federation.bindings.tomcat.sp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.xml.bind.JAXBElement;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.authenticator.FormAuthenticator;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.log4j.Logger;
+import org.jboss.identity.federation.api.saml.v2.exceptions.AssertionExpiredException;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnResponseFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.federation.api.util.Base64;
+import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
+import org.jboss.identity.federation.saml.v2.assertion.NameIDType;
+import org.jboss.identity.federation.saml.v2.assertion.SubjectType;
+import org.jboss.identity.federation.saml.v2.jboss.JBossSAMLURIConstants;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
+import org.jboss.identity.federation.saml.v2.protocol.StatusType;
+
+/**
+ * Authenticator at the Service Provider
+ * that handles HTTP/Redirect binding of SAML 2
+ * but falls back on Form Authentication
+ *
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 12, 2008
+ */
+public class SPRedirectFormAuthenticator extends FormAuthenticator
+{
+ private static Logger log = Logger.getLogger(SPRedirectFormAuthenticator.class);
+
+ private String serviceURL = null;
+ private String identityURL = null;
+
+ public void setIdentityURL(String url)
+ {
+ this.identityURL = url;
+ }
+
+ public void setServiceURL(String url)
+ {
+ this.serviceURL = url;
+ }
+
+ @Override
+ public boolean authenticate(Request request, Response response, LoginConfig loginConfig) throws IOException
+ {
+ Principal principal = request.getUserPrincipal();
+ if (principal != null)
+ {
+ log.debug("Already authenticated '" + principal.getName() + "'");
+ return true;
+ }
+
+ Session session = request.getSessionInternal(true);
+
+ //Try to get the username
+ try
+ {
+ Principal p = process(request,response);
+ if(p == null)
+ {
+ createSAMLRequestMessage("someuser", response);
+ return false;
+ }
+ String username = p.getName();
+ String password = "FED_IDENTITY";
+ session.setNote(Constants.SESS_USERNAME_NOTE, username);
+ session.setNote(Constants.SESS_PASSWORD_NOTE, password);
+ request.setUserPrincipal(p);
+ register(request, response, p, Constants.FORM_METHOD, username, password);
+ return true;
+ }
+ catch(AssertionExpiredException aie)
+ {
+ log.debug("Assertion has expired. Issuing a new saml2 request to the IDP");
+ try
+ {
+ createSAMLRequestMessage("someuser", response);
+ }
+ catch (Exception e)
+ {
+ log.trace("Exception:",e);
+ e.printStackTrace();
+ }
+ return false;
+ }
+ catch(Exception e)
+ {
+ log.debug("Exception :",e);
+ e.printStackTrace();
+ }
+
+ //fallback
+ return super.authenticate(request, response, loginConfig);
+ }
+
+ private void createSAMLRequestMessage(String username, Response response)
+ throws Exception
+ {
+ //create a saml request
+ if(this.serviceURL == null)
+ throw new ServletException("serviceURL is not configured");
+
+ AuthnRequestType authnRequest = JBossSAMLAuthnRequestFactory.createAuthnRequestType(
+ "ID_" + JBossSAMLBaseFactory.createUUID(), serviceURL,
+ identityURL, serviceURL);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequest, baos);
+
+ //Deflate encoding
+ byte[] deflatedMsg = DeflateUtil.encode(baos.toByteArray());
+
+ String base64Request = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES);
+
+ base64Request = URLEncoder.encode(base64Request, "UTF-8");
+ String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request;
+ log.debug("Sending to destination="+destination);
+ response.setCharacterEncoding("UTF-8");
+ response.setHeader("Location", destination);
+ response.setStatus(Response.SC_MOVED_TEMPORARILY);
+ response.sendRedirect(destination);
+ return;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Principal process(Request request, Response response) throws Exception
+ {
+ Principal userPrincipal = null;
+
+ String samlResponse = request.getParameter("SAMLResponse");
+ if(samlResponse != null && samlResponse.length() > 0 )
+ {
+ //deal with saml response from IDP
+ byte[] base64DecodedResponse = Base64.decode(samlResponse);
+ InputStream is = DeflateUtil.decode(base64DecodedResponse);
+
+ ResponseType responseType = JBossSAMLAuthnResponseFactory.getResponseType(is);
+ StatusType statusType = responseType.getStatus();
+ if(statusType == null)
+ throw new Exception("Status Type from the IDP is null");
+
+ String statusValue = statusType.getStatusCode().getValue();
+ if(JBossSAMLURIConstants.STATUS_SUCCESS.get().equals(statusValue) == false)
+ throw new SecurityException("IDP forbid the user");
+
+ AssertionType assertion = (AssertionType) responseType.getAssertionOrEncryptedAssertion().get(0);
+ SubjectType subject = assertion.getSubject();
+ JAXBElement<NameIDType> jnameID = (JAXBElement<NameIDType>) subject.getContent().get(0);
+ NameIDType nameID = jnameID.getValue();
+ String userName = nameID.getValue();
+ List<String> roles = new ArrayList<String>();
+
+ //Let us get the roles
+ AttributeStatementType attributeStatement = (AttributeStatementType) assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement().get(0);
+ List<Object> attList = attributeStatement.getAttributeOrEncryptedAttribute();
+ for(Object obj:attList)
+ {
+ AttributeType attr = (AttributeType) obj;
+ String roleName = (String) attr.getAttributeValue().get(0);
+ roles.add(roleName);
+ }
+
+ userPrincipal = this.createGenericPrincipal(request, userName, roles);
+ }
+ return userPrincipal;
+ }
+
+
+ private Principal createGenericPrincipal(Request request, String username, List<String> roles)
+ {
+ Context ctx = request.getContext();
+ return new GenericPrincipal(ctx.getRealm(), username, null, roles);
+ }
+}
\ No newline at end of file
Added: identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java
===================================================================
--- identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java (rev 0)
+++ identity-federation/trunk/identity-bindings/src/main/java/org/jboss/identity/federation/bindings/tomcat/sp/SPRedirectValve.java 2008-12-12 22:40:02 UTC (rev 160)
@@ -0,0 +1,181 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.identity.federation.bindings.tomcat.sp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.xml.bind.JAXBElement;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Session;
+import org.apache.catalina.authenticator.Constants;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.log4j.Logger;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnRequestFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLAuthnResponseFactory;
+import org.jboss.identity.federation.api.saml.v2.factories.JBossSAMLBaseFactory;
+import org.jboss.identity.federation.api.util.Base64;
+import org.jboss.identity.federation.api.util.DeflateUtil;
+import org.jboss.identity.federation.saml.v2.assertion.AssertionType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeStatementType;
+import org.jboss.identity.federation.saml.v2.assertion.AttributeType;
+import org.jboss.identity.federation.saml.v2.assertion.NameIDType;
+import org.jboss.identity.federation.saml.v2.assertion.SubjectType;
+import org.jboss.identity.federation.saml.v2.jboss.JBossSAMLURIConstants;
+import org.jboss.identity.federation.saml.v2.protocol.AuthnRequestType;
+import org.jboss.identity.federation.saml.v2.protocol.ResponseType;
+import org.jboss.identity.federation.saml.v2.protocol.StatusType;
+
+/**
+ * Valve at the Service Provider for the HTTP/Redirect binding
+ * @author Anil.Saldhana(a)redhat.com
+ * @since Dec 11, 2008
+ */
+public class SPRedirectValve extends ValveBase
+{
+ private static Logger log = Logger.getLogger(SPRedirectValve.class);
+
+ private String serviceURL = null;
+ private String identityURL = null;
+
+ public void setIdentityURL(String url)
+ {
+ this.identityURL = url;
+ }
+
+ public void setServiceURL(String url)
+ {
+ this.serviceURL = url;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void invoke(Request request, Response response) throws IOException, ServletException
+ {
+ try
+ {
+ //Lets check if the user has been authenticated
+ Principal userPrincipal = request.getUserPrincipal();
+ if(userPrincipal == null)
+ {
+ String samlResponse = request.getParameter("SAMLResponse");
+ if(samlResponse != null && samlResponse.length() > 0 )
+ {
+ //deal with saml response from IDP
+ byte[] base64DecodedResponse = Base64.decode(samlResponse);
+ InputStream is = DeflateUtil.decode(base64DecodedResponse);
+
+ ResponseType responseType = JBossSAMLAuthnResponseFactory.getResponseType(is);
+ StatusType statusType = responseType.getStatus();
+ if(statusType == null)
+ throw new Exception("Status Type from the IDP is null");
+
+ String statusValue = statusType.getStatusCode().getValue();
+ if(JBossSAMLURIConstants.STATUS_SUCCESS.get().equals(statusValue) == false)
+ throw new SecurityException("IDP forbid the user");
+
+ AssertionType assertion = (AssertionType) responseType.getAssertionOrEncryptedAssertion().get(0);
+ SubjectType subject = assertion.getSubject();
+ JAXBElement<NameIDType> jnameID = (JAXBElement<NameIDType>) subject.getContent().get(0);
+ NameIDType nameID = jnameID.getValue();
+ String userName = nameID.getValue();
+ List<String> roles = new ArrayList<String>();
+
+ //Let us get the roles
+ AttributeStatementType attributeStatement = (AttributeStatementType) assertion.getStatementOrAuthnStatementOrAuthzDecisionStatement().get(0);
+ List<Object> attList = attributeStatement.getAttributeOrEncryptedAttribute();
+ for(Object obj:attList)
+ {
+ AttributeType attr = (AttributeType) obj;
+ String roleName = (String) attr.getAttributeValue().get(0);
+ roles.add(roleName);
+ }
+
+
+ Principal idpPrincipal = this.createGenericPrincipal(request, userName, roles);
+ Session session = request.getSessionInternal(true);
+ session.setNote(Constants.REQ_SSOID_NOTE, JBossSAMLBaseFactory.createUUID());
+ request.setUserPrincipal(idpPrincipal);
+ session.setPrincipal(idpPrincipal);
+ }
+ else
+ {
+ //create a saml request
+ if(this.serviceURL == null)
+ throw new ServletException("serviceURL is not configured");
+
+ AuthnRequestType authnRequest = JBossSAMLAuthnRequestFactory.createAuthnRequestType(
+ "ID_" + JBossSAMLBaseFactory.createUUID(), serviceURL,
+ identityURL, serviceURL);
+
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ JBossSAMLAuthnRequestFactory.marshall(authnRequest, baos);
+
+ //Deflate encoding
+ byte[] deflatedMsg = DeflateUtil.encode(baos.toByteArray());
+
+ String base64Request = Base64.encodeBytes(deflatedMsg, Base64.DONT_BREAK_LINES);
+
+ base64Request = URLEncoder.encode(base64Request, "UTF-8");
+ String destination = authnRequest.getDestination() + "?SAMLRequest=" + base64Request;
+ log.trace("Sending to destination="+destination);
+ log.trace(" ");
+ response.setCharacterEncoding("UTF-8");
+ response.setHeader("Location", destination);
+ response.setStatus(Response.SC_MOVED_TEMPORARILY);
+ response.sendRedirect(destination);
+ return;
+ }
+ }
+ }
+ catch(SecurityException e)
+ {
+ log.error("Security Exception:",e);
+ response.sendError(Response.SC_FORBIDDEN);
+ }
+ catch(Exception e)
+ {
+ log.error("Exception:",e);
+ response.sendError(Response.SC_INTERNAL_SERVER_ERROR, "Server Error");
+ }
+
+ //the user is already authenticated
+ response.recycle();
+ getNext().invoke(request, response);
+ }
+
+ private Principal createGenericPrincipal(Request request, String username, List<String> roles)
+ {
+ Context ctx = request.getContext();
+ return new GenericPrincipal(ctx.getRealm(), username, null, roles);
+ }
+}
\ No newline at end of file
17 years, 7 months