You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2015/09/23 16:05:29 UTC
svn commit: r1704858 -
/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java
Author: elecharny
Date: Wed Sep 23 14:05:29 2015
New Revision: 1704858
URL: http://svn.apache.org/viewvc?rev=1704858&view=rev
Log:
Improved the way the anonymizer works
Modified:
directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java
Modified: directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java
URL: http://svn.apache.org/viewvc/directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java?rev=1704858&r1=1704857&r2=1704858&view=diff
==============================================================================
--- directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java (original)
+++ directory/shared/trunk/ldap/client/api/src/main/java/org/apache/directory/ldap/client/api/LdifAnonymizer.java Wed Sep 23 14:05:29 2015
@@ -24,10 +24,11 @@ package org.apache.directory.ldap.client
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Attribute;
@@ -36,6 +37,8 @@ import org.apache.directory.api.ldap.mod
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Value;
import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
+import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.ldif.LdifEntry;
import org.apache.directory.api.ldap.model.ldif.LdifReader;
import org.apache.directory.api.ldap.model.ldif.LdifUtils;
@@ -47,7 +50,9 @@ import org.apache.directory.api.ldap.mod
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.LdapSyntax;
import org.apache.directory.api.ldap.model.schema.SchemaManager;
+import org.apache.directory.api.ldap.model.schema.syntaxCheckers.DnSyntaxChecker;
import org.apache.directory.api.ldap.schema.manager.impl.DefaultSchemaManager;
@@ -96,26 +101,18 @@ import org.apache.directory.api.ldap.sch
*/
public class LdifAnonymizer
{
+ /** The map that stores the anonymized values associated to the original value */
+ Map<Value<?>, Value<?>> valueMap = new HashMap<Value<?>, Value<?>>();
+
/** The map of Attributes we want to anonymize. They are all associated with anonymizers */
Map<AttributeType, Anonymizer> attributeAnonymizers = new HashMap<AttributeType, Anonymizer>();
+
+ /** The list of existing NamingContexts */
+ Set<Dn> namingContexts = new HashSet<Dn>();
/** The schemaManager */
SchemaManager schemaManager;
- /** The list of CL options */
- //private static Options options = new Options();
-
- /** The configuration file option shot name */
- private static final String CONFIG_FILE_OPT = "f";
-
- /** The configuration file option */
- //private static final Option configFileOption = new Option( CONFIG_FILE_OPT, "config", true,
- // "Anonymizer configuration file" );
-
- /** the file containing the list of attributes and their anonymizers */
- private static String configFile;
-
-
/**
* Creates a default instance of LdifAnonymizer. The list of anonymized attribute
* is set to a default value.
@@ -134,6 +131,29 @@ public class LdifAnonymizer
System.exit( -1 );
}
+ init();
+ }
+
+
+ /**
+ * Creates a default instance of LdifAnonymizer. The list of anonymized attribute
+ * is set to a default value.
+ *
+ * @param schemaManager The SchemaManager instance we will use
+ */
+ public LdifAnonymizer( SchemaManager schemaManager )
+ {
+ this.schemaManager = schemaManager;
+
+ init();
+ }
+
+
+ /**
+ * Initialize the anonymizer, filling the maps we use.
+ */
+ private void init()
+ {
// Load the anonymizers
attributeAnonymizers.put( schemaManager.getAttributeType( SchemaConstants.CAR_LICENSE_AT ),
new StringAnonymizer() );
@@ -196,10 +216,182 @@ public class LdifAnonymizer
attributeAnonymizers.put( schemaManager.getAttributeType( SchemaConstants.X500_UNIQUE_IDENTIFIER_AT ),
new BinaryAnonymizer() );
}
+
+
+ /**
+ * Add an attributeType that has to be anonymized
+ *
+ * @param attributeType the AttributeType that has to be anonymized
+ * @throws LdapException If the attributeType cannot be added
+ */
+ public void addAnonAttributeType( AttributeType attributeType ) throws LdapException
+ {
+ schemaManager.add( attributeType );
+ LdapSyntax syntax = attributeType.getSyntax();
+
+ if ( syntax.isHumanReadable() )
+ {
+ if ( syntax.getOid().equals( SchemaConstants.INTEGER_SYNTAX ) )
+ {
+ attributeAnonymizers.put( attributeType, new IntegerAnonymizer() );
+ }
+ else
+ {
+ attributeAnonymizers.put( attributeType, new StringAnonymizer() );
+ }
+ }
+ else
+ {
+ attributeAnonymizers.put( attributeType, new BinaryAnonymizer() );
+ }
+ }
+
+
+ /**
+ * Remove an attributeType that has to be anonymized
+ *
+ * @param attributeType the AttributeType that we don't want to be anonymized
+ * @throws LdapException If the attributeType cannot be removed
+ */
+ public void removeAnonAttributeType( AttributeType attributeType ) throws LdapException
+ {
+ attributeAnonymizers.remove( attributeType );
+ }
+
+
+ /**
+ * Add a new NamingContext
+ *
+ * @param dn The naming context to add
+ * @throws LdapInvalidDnException if it's an invalid naming context
+ */
+ public void addNamingContext( String dn ) throws LdapInvalidDnException
+ {
+ Dn namingContext = new Dn( schemaManager, dn );
+ namingContexts.add( namingContext );
+ }
+
+
+ /**
+ * Anonymize an AVA
+ */
+ private Ava anonymizeAva( Ava ava ) throws LdapInvalidDnException, LdapInvalidAttributeValueException
+ {
+ Value<?> value = ava.getValue();
+ AttributeType attributeType = ava.getAttributeType();
+ Value<?> anonymizedValue = valueMap.get( value );
+ Ava anonymizedAva = null;
+
+ if ( anonymizedValue == null )
+ {
+ Attribute attribute = new DefaultAttribute( attributeType );
+ attribute.add( value );
+ Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType() );
+
+ if ( value.isHumanReadable() )
+ {
+ if ( anonymizer == null )
+ {
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), value.getString() );
+ }
+ else
+ {
+ Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, attribute );
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), anonymizedAttribute.getString() );
+ }
+ }
+ else
+ {
+ if ( anonymizer == null )
+ {
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), value.getBytes() );
+ }
+ else
+ {
+ Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, attribute );
+
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), anonymizedAttribute.getBytes() );
+ }
+ }
+ }
+ else
+ {
+ if ( value.isHumanReadable() )
+ {
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), anonymizedValue.getString() );
+ }
+ else
+ {
+ anonymizedAva = new Ava( schemaManager, attributeType.getName(), anonymizedValue.getBytes() );
+ }
+ }
+
+ return anonymizedAva;
+ }
+
+
+ /**
+ * Anonymize the entry's DN
+ */
+ private Dn anonymizeDn( Dn entryDn ) throws LdapException
+ {
+ // Search for the naming context
+ Dn descendant = entryDn;
+ Dn namingContext = null;
+
+ for ( Dn nc : namingContexts )
+ {
+ if ( entryDn.isDescendantOf( nc ) )
+ {
+ descendant = entryDn.getDescendantOf( nc );
+ namingContext = nc;
+ break;
+ }
+ }
+
+ Rdn[] anonymizedRdns = new Rdn[entryDn.size()];
+ int rdnPos = entryDn.size() - 1;
+
+ // Copy the naming contex
+ for ( Rdn ncRdn : namingContext )
+ {
+ anonymizedRdns[rdnPos] = ncRdn;
+ rdnPos--;
+ }
+
+ // Iterate on all the RDN
+ for ( Rdn rdn : descendant )
+ {
+ Ava[] anonymizedAvas = new Ava[rdn.size()];
+ int pos = 0;
+
+ // Iterate on the AVAs
+ for ( Ava ava : rdn )
+ {
+ Ava anonymizedAva = anonymizeAva( ava );
+ anonymizedAvas[pos] = anonymizedAva;
+ pos++;
+ }
+
+ Rdn anonymizedRdn = new Rdn( schemaManager, anonymizedAvas );
+ anonymizedRdns[rdnPos] = anonymizedRdn;
+ rdnPos--;
+ }
+
+ Dn anonymizedDn = new Dn( schemaManager, anonymizedRdns );
+
+ return anonymizedDn;
+ }
+
/**
- * {@inheritDoc}
+ * Anonymize a LDIF
+ *
+ * @param ldif The ldif content to anonymize
+ * @return an anonymized version of the given ldif
+ * @throws LdapException If we got some LDAP related exception
+ * @throws IOException If we had some issue during some IO operations
*/
public String anonymize( String ldif ) throws LdapException, IOException
{
@@ -216,107 +408,42 @@ public class LdifAnonymizer
Entry newEntry = new DefaultEntry( schemaManager );
// Process the DN first
- Dn dn = entry.getDn();
- Rdn rdns = dn.getRdn();
- List<Attribute> rdnAttributes = new ArrayList<Attribute>();
-
- // Iterate on all the RDN's AVAs
- List<Ava> avas = new ArrayList<Ava>();
- boolean dnAnonymized = false;
-
- for ( Ava ava : rdns )
- {
- // Get the entry's attribute that is used in the RDN
- Attribute rdnAttribute = entry.get( ava.getType() );
-
- // Create a new Attribute for this value specifically
- Attribute newRdnAttribute = new DefaultAttribute( rdnAttribute.getUpId(),
- rdnAttribute.getAttributeType() );
-
- // inject the value we just removed
- newRdnAttribute.add( rdnAttribute.get() );
-
- // Remove the RDN value from the entry's attribute
- rdnAttribute.remove( rdnAttribute.get() );
-
- if ( rdnAttribute.size() == 0 )
- {
- // The last value has been removed, remove the attribute from the entry
- entry.remove( rdnAttribute );
- }
-
- // And anonymize it
- Anonymizer anonymizer = attributeAnonymizers.get( rdnAttribute.getAttributeType() );
-
- if ( anonymizer != null )
- {
- Attribute anonymizedAttribute = anonymizer.anonymize( newRdnAttribute );
- dnAnonymized = true;
-
- // Keep it for later, we will reinject this value in the entry
- rdnAttributes.add( anonymizedAttribute );
-
- if ( anonymizedAttribute.isHumanReadable() )
- {
- avas.add( new Ava( schemaManager, rdnAttribute.getUpId(), anonymizedAttribute.getString() ) );
- }
- else
- {
- avas.add( new Ava( schemaManager, rdnAttribute.getUpId(), anonymizedAttribute.getBytes() ) );
- }
- }
- else
- {
- avas.add( ava );
- }
- }
-
- // Recreate the DN if needed
- if ( dnAnonymized )
- {
- Rdn newRdn = new Rdn( schemaManager, avas.toArray( new Ava[]
- {} ) );
- dn = new Dn( newRdn, dn.getParent() );
- }
+ Dn entryDn = entry.getDn();
+
+ Dn anonymizedDn = anonymizeDn( entryDn );
// Now, process the entry
for ( Attribute attribute : entry )
{
- Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType() );
-
- if ( anonymizer == null )
- {
- newEntry.add( attribute );
- }
- else
- {
- Attribute anonymizedAttribute = anonymizer.anonymize( attribute );
-
- newEntry.add( anonymizedAttribute );
- }
- }
-
- // Last, not least, inject the RDN attributes in the entry, if we have some
- for ( Attribute rdnAttribute : rdnAttributes )
- {
- Attribute attribute = newEntry.get( rdnAttribute.getAttributeType() );
-
- if ( attribute == null )
+ AttributeType attributeType = attribute.getAttributeType();
+
+ if ( attributeType.getSyntax().getSyntaxChecker() instanceof DnSyntaxChecker )
{
- // It has been completely remove, reinject it
- newEntry.add( rdnAttribute );
+ for ( Value<?> dnValue : attribute )
+ {
+ Dn dn = new Dn( schemaManager, dnValue.getString() );
+ Dn newdDn = anonymizeDn( dn );
+ newEntry.add( attributeType, newdDn.toString() );
+ }
}
else
{
- // Inject the rdn values in the newEntry attributes
- for ( Value<?> value : rdnAttribute )
+ Anonymizer anonymizer = attributeAnonymizers.get( attribute.getAttributeType() );
+
+ if ( anonymizer == null )
+ {
+ newEntry.add( attribute );
+ }
+ else
{
- attribute.add( value );
+ Attribute anonymizedAttribute = anonymizer.anonymize( valueMap, attribute );
+
+ newEntry.add( anonymizedAttribute );
}
}
}
- newEntry.setDn( dn );
+ newEntry.setDn( anonymizedDn );
result.append( LdifUtils.convertToLdif( newEntry ) );
result.append( "\n" );
}
@@ -330,6 +457,12 @@ public class LdifAnonymizer
}
+ /**
+ * The entry point, when used as a standalone application.
+ *
+ * @param args Contains the arguments : the file to convert. The anonymized
+ * LDIF will be printed on stdout
+ */
public static void main( String[] args ) throws IOException, LdapException
{
if ( ( args == null ) || ( args.length < 1 ) )