You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2014/06/12 13:35:28 UTC

svn commit: r1602129 - in /syncope/trunk: build-tools/src/main/resources/ common/src/main/java/org/apache/syncope/common/to/ common/src/main/java/org/apache/syncope/common/types/ core/src/main/java/org/apache/syncope/core/persistence/beans/ core/src/ma...

Author: ilgrosso
Date: Thu Jun 12 11:35:27 2014
New Revision: 1602129

URL: http://svn.apache.org/r1602129
Log:
[SYNCOPE-270] Implementation provided

Added:
    syncope/trunk/core/src/main/java/org/apache/syncope/core/util/Encryptor.java
      - copied, changed from r1602068, syncope/trunk/core/src/main/java/org/apache/syncope/core/util/PasswordEncoder.java
Removed:
    syncope/trunk/core/src/main/java/org/apache/syncope/core/util/PasswordEncoder.java
Modified:
    syncope/trunk/build-tools/src/main/resources/content.ldif
    syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AttributeSchemaType.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/CipherAlgorithm.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/EntityViolationType.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SchemaType.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/BasicValidator.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/InvalidAttrValueException.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SchemaValidator.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/SchemaDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/security/EncodePasswordCLI.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPPasswordSyncActions.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/security/PasswordEncoderTest.java
    syncope/trunk/core/src/test/resources/content.xml

Modified: syncope/trunk/build-tools/src/main/resources/content.ldif
URL: http://svn.apache.org/viewvc/syncope/trunk/build-tools/src/main/resources/content.ldif?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/build-tools/src/main/resources/content.ldif (original)
+++ syncope/trunk/build-tools/src/main/resources/content.ldif Thu Jun 12 11:35:27 2014
@@ -44,3 +44,4 @@ sn: Surname
 uid: syncFromLDAP
 userpassword:: cGFzc3dvcmQxMjM=
 givenname: syncFromLDAP
+registeredAddress:  5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/SchemaTO.java Thu Jun 12 11:35:27 2014
@@ -23,6 +23,7 @@ import javax.xml.bind.annotation.XmlType
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.types.AttributeSchemaType;
+import org.apache.syncope.common.types.CipherAlgorithm;
 
 @XmlRootElement(name = "schema")
 @XmlType
@@ -38,6 +39,10 @@ public class SchemaTO extends AbstractSc
 
     private String enumerationKeys;
 
+    private String secretKey;
+
+    private CipherAlgorithm cipherAlgorithm;
+
     private boolean multivalue;
 
     private boolean uniqueConstraint;
@@ -82,6 +87,22 @@ public class SchemaTO extends AbstractSc
         this.enumerationKeys = enumerationKeys;
     }
 
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(final String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public CipherAlgorithm getCipherAlgorithm() {
+        return cipherAlgorithm;
+    }
+
+    public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) {
+        this.cipherAlgorithm = cipherAlgorithm;
+    }
+
     public boolean isMultivalue() {
         return multivalue;
     }

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AttributeSchemaType.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AttributeSchemaType.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AttributeSchemaType.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AttributeSchemaType.java Thu Jun 12 11:35:27 2014
@@ -29,7 +29,8 @@ public enum AttributeSchemaType {
     Double(Double.class),
     Boolean(Boolean.class),
     Date(Date.class),
-    Enum(Enum.class);
+    Enum(Enum.class),
+    Encrypted(byte[].class);
 
     final private Class<?> type;
 

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/CipherAlgorithm.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/CipherAlgorithm.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/CipherAlgorithm.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/CipherAlgorithm.java Thu Jun 12 11:35:27 2014
@@ -51,8 +51,4 @@ public enum CipherAlgorithm {
     public boolean isInvertible() {
         return invertible;
     }
-
-    public static CipherAlgorithm fromString(final String value) {
-        return CipherAlgorithm.valueOf(value.toUpperCase());
-    }
 }

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/EntityViolationType.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/EntityViolationType.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/EntityViolationType.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/EntityViolationType.java Thu Jun 12 11:35:27 2014
@@ -43,6 +43,7 @@ public enum EntityViolationType {
     InvalidReport("org.apache.syncope.core.validation.report"),
     InvalidResource("org.apache.syncope.core.validation.externalresource"),
     InvalidRoleOwner("org.apache.syncope.core.validation.syncoperole.owner"),
+    InvalidSchemaEncrypted("org.apache.syncope.core.validation.schema.encrypted"),
     InvalidSchemaEnum("org.apache.syncope.core.validation.schema.enum"),
     InvalidSchemaMultivalueUnique("org.apache.syncope.core.validation.schema.multivalueUnique"),
     InvalidSchedTask("org.apache.syncope.core.validation.schedtask"),

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SchemaType.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SchemaType.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SchemaType.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/SchemaType.java Thu Jun 12 11:35:27 2014
@@ -42,7 +42,7 @@ public enum SchemaType {
 
     private final Class<? extends AbstractSchemaTO> toClass;
 
-    private SchemaType(final Class<? extends AbstractSchemaTO> toClass) {
+    SchemaType(final Class<? extends AbstractSchemaTO> toClass) {
         this.toClass = toClass;
     }
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttr.java Thu Jun 12 11:35:27 2014
@@ -36,16 +36,15 @@ public abstract class AbstractAttr exten
 
     public abstract Long getId();
 
-    @SuppressWarnings("unchecked")
-    public <T extends AbstractAttrValue> T addValue(final String value, final AttributableUtil attributableUtil)
+    public void addValue(final String value, final AttributableUtil attributableUtil)
             throws InvalidAttrValueException {
 
-        T attrValue;
+        AbstractAttrValue attrValue;
         if (getSchema().isUniqueConstraint()) {
-            attrValue = (T) attributableUtil.newAttrUniqueValue();
+            attrValue = attributableUtil.newAttrUniqueValue();
             ((AbstractAttrUniqueValue) attrValue).setSchema(getSchema());
         } else {
-            attrValue = (T) attributableUtil.newAttrValue();
+            attrValue = attributableUtil.newAttrValue();
         }
 
         attrValue.setAttribute(this);
@@ -59,8 +58,6 @@ public abstract class AbstractAttr exten
             }
             addValue(attrValue);
         }
-
-        return attrValue;
     }
 
     public abstract <T extends AbstractAttributable> T getOwner();
@@ -69,7 +66,7 @@ public abstract class AbstractAttr exten
 
     public abstract <T extends AbstractNormalSchema> T getSchema();
 
-    public abstract <T extends AbstractAttrValue> boolean addValue(T attrValue);
+    protected abstract <T extends AbstractAttrValue> boolean addValue(T attrValue);
 
     public abstract <T extends AbstractAttrValue> boolean removeValue(T attrValue);
 
@@ -89,8 +86,6 @@ public abstract class AbstractAttr exten
 
     public abstract <T extends AbstractAttrValue> List<T> getValues();
 
-    public abstract <T extends AbstractAttrValue> void setValues(List<T> attributeValues);
-
     public abstract <T extends AbstractAttrValue> T getUniqueValue();
 
     public abstract <T extends AbstractAttrValue> void setUniqueValue(T uniqueAttributeValue);

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractAttrValue.java Thu Jun 12 11:35:27 2014
@@ -31,6 +31,7 @@ import org.apache.syncope.common.types.A
 import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException;
 import org.apache.syncope.core.persistence.validation.entity.AttrValueCheck;
 import org.apache.syncope.core.util.DataFormat;
+import org.apache.syncope.core.util.Encryptor;
 
 @MappedSuperclass
 @AttrValueCheck
@@ -143,6 +144,14 @@ public abstract class AbstractAttrValue 
                 }
                 break;
 
+            case Encrypted:
+                try {
+                    this.setStringValue(Encryptor.getInstance(schema.getSecretKey()).
+                            encode(value, schema.getCipherAlgorithm()));
+                } catch (Exception pe) {
+                    exception = pe;
+                }
+                break;
 
             case String:
             case Enum:
@@ -201,8 +210,10 @@ public abstract class AbstractAttrValue 
                         : DataFormat.format(getDateValue(), false, getAttribute().getSchema().getConversionPattern());
                 break;
 
+            case String:
+            case Enum:
+            case Encrypted:
             default:
-                // applied to String and Enum SchemaType
                 result = getStringValue();
                 break;
         }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractNormalSchema.java Thu Jun 12 11:35:27 2014
@@ -30,6 +30,7 @@ import javax.persistence.Transient;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.Min;
 import org.apache.syncope.common.types.AttributeSchemaType;
+import org.apache.syncope.common.types.CipherAlgorithm;
 import org.apache.syncope.core.persistence.validation.attrvalue.AbstractValidator;
 import org.apache.syncope.core.persistence.validation.attrvalue.BasicValidator;
 import org.apache.syncope.core.persistence.validation.entity.SchemaCheck;
@@ -81,6 +82,13 @@ public abstract class AbstractNormalSche
     @Lob
     private String enumerationKeys;
 
+    @Column(nullable = true)
+    private String secretKey;
+
+    @Column(nullable = true)
+    @Enumerated(EnumType.STRING)
+    private CipherAlgorithm cipherAlgorithm;
+
     @Transient
     private AbstractValidator validator;
 
@@ -152,7 +160,7 @@ public abstract class AbstractNormalSche
         if (getValidatorClass() != null && getValidatorClass().length() > 0) {
             try {
                 Constructor<?> validatorConstructor = Class.forName(getValidatorClass()).
-                        getConstructor(new Class<?>[] {getClass().getSuperclass()});
+                        getConstructor(new Class<?>[] { getClass().getSuperclass() });
                 validator = (AbstractValidator) validatorConstructor.newInstance(this);
             } catch (Exception e) {
                 LOG.error("Could not instantiate validator of type {}, reverting to {}",
@@ -206,4 +214,21 @@ public abstract class AbstractNormalSche
 
         this.conversionPattern = conversionPattern;
     }
+
+    public String getSecretKey() {
+        return secretKey;
+    }
+
+    public void setSecretKey(final String secretKey) {
+        this.secretKey = secretKey;
+    }
+
+    public CipherAlgorithm getCipherAlgorithm() {
+        return cipherAlgorithm;
+    }
+
+    public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) {
+        this.cipherAlgorithm = cipherAlgorithm;
+    }
+
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/membership/MAttr.java Thu Jun 12 11:35:27 2014
@@ -124,18 +124,6 @@ public class MAttr extends AbstractAttr 
 
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractAttrValue> void setValues(final List<T> attributeValues) {
-        this.values.clear();
-        if (attributeValues != null && !attributeValues.isEmpty()) {
-            for (T mav : attributeValues) {
-                mav.setAttribute(this);
-            }
-            this.values.addAll((List<MAttrValue>) attributeValues);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
     public <T extends AbstractAttrValue> T getUniqueValue() {
         return (T) uniqueValue;
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/role/RAttr.java Thu Jun 12 11:35:27 2014
@@ -121,19 +121,6 @@ public class RAttr extends AbstractAttr 
 
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractAttrValue> void setValues(final List<T> attributeValues) {
-
-        this.values.clear();
-        if (attributeValues != null && !attributeValues.isEmpty()) {
-            for (T mav : attributeValues) {
-                mav.setAttribute(this);
-            }
-            this.values.addAll((List<RAttrValue>) attributeValues);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
     public <T extends AbstractAttrValue> T getUniqueValue() {
         return (T) uniqueValue;
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/SyncopeUser.java Thu Jun 12 11:35:27 2014
@@ -56,7 +56,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.membership.Membership;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.validation.entity.SyncopeUserCheck;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 import org.apache.syncope.core.util.SecureRandomUtil;
 
 /**
@@ -259,19 +259,20 @@ public class SyncopeUser extends Abstrac
         clearPassword = null;
     }
 
-    public void setEncodedPassword(final String password, final CipherAlgorithm cipherAlgoritm, final int historySize) {
+    public void setEncodedPassword(final String password, final CipherAlgorithm cipherAlgoritm) {
         // clear password
         this.clearPassword = null;
+
         this.password = password;
         this.cipherAlgorithm = cipherAlgoritm;
     }
-    
+
     public void setPassword(final String password, final CipherAlgorithm cipherAlgoritm, final int historySize) {
         // clear password
         this.clearPassword = password;
 
         try {
-            this.password = PasswordEncoder.encode(password, cipherAlgoritm);
+            this.password = Encryptor.getInstance().encode(password, cipherAlgoritm);
             this.cipherAlgorithm = cipherAlgoritm;
         } catch (Exception e) {
             LOG.error("Could not encode password", e);
@@ -495,8 +496,8 @@ public class SyncopeUser extends Abstrac
                 res = passwordHistory.subList(size >= passwordHistory.size()
                         ? 0
                         : passwordHistory.size() - size, passwordHistory.size()).contains(cipherAlgorithm == null
-                        ? password
-                        : PasswordEncoder.encode(password, cipherAlgorithm));
+                                ? password
+                                : Encryptor.getInstance().encode(password, cipherAlgorithm));
             } catch (Exception e) {
                 LOG.error("Error evaluating password history", e);
             }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/user/UAttr.java Thu Jun 12 11:35:27 2014
@@ -138,19 +138,6 @@ public class UAttr extends AbstractAttr 
 
     @SuppressWarnings("unchecked")
     @Override
-    public <T extends AbstractAttrValue> void setValues(final List<T> attributeValues) {
-
-        this.values.clear();
-        if (attributeValues != null && !attributeValues.isEmpty()) {
-            for (T mav : attributeValues) {
-                mav.setAttribute(this);
-            }
-            this.values.addAll((List<UAttrValue>) attributeValues);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    @Override
     public <T extends AbstractAttrValue> T getUniqueValue() {
         return (T) uniqueValue;
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/BasicValidator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/BasicValidator.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/BasicValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/BasicValidator.java Thu Jun 12 11:35:27 2014
@@ -18,7 +18,6 @@
  */
 package org.apache.syncope.core.persistence.validation.attrvalue;
 
-import java.util.Arrays;
 import org.apache.syncope.common.SyncopeConstants;
 import org.apache.syncope.common.types.AttributeSchemaType;
 import org.apache.syncope.core.persistence.beans.AbstractAttrValue;
@@ -34,9 +33,8 @@ public class BasicValidator extends Abst
 
     @Override
     protected void doValidate(final AbstractAttrValue attributeValue) throws InvalidAttrValueException {
-        if (AttributeSchemaType.Enum.equals(schema.getType())) {
+        if (AttributeSchemaType.Enum == schema.getType()) {
             final String[] enumeration = schema.getEnumerationValues().split(SyncopeConstants.ENUM_VALUES_SEPARATOR);
-
             final String value = attributeValue.getStringValue();
 
             boolean found = false;
@@ -47,7 +45,7 @@ public class BasicValidator extends Abst
             }
 
             if (!found) {
-                throw new InvalidAttrValueException("\"" + value + "\" is not one of: " + Arrays.toString(enumeration));
+                throw new InvalidAttrValueException("'" + value + "' is not one of: " + schema.getEnumerationValues());
             }
         }
     }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/InvalidAttrValueException.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/InvalidAttrValueException.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/InvalidAttrValueException.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/attrvalue/InvalidAttrValueException.java Thu Jun 12 11:35:27 2014
@@ -24,11 +24,11 @@ import org.apache.syncope.core.persisten
 
 public class InvalidAttrValueException extends ValidationException {
     
-    public InvalidAttrValueException(String errorMessage) {
+    public InvalidAttrValueException(final String errorMessage) {
         super(errorMessage);
     }
     
-    public InvalidAttrValueException(String errorMessage, Throwable t) {
+    public InvalidAttrValueException(final String errorMessage, final Throwable t) {
         super(errorMessage, t);
     }
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SchemaValidator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SchemaValidator.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SchemaValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SchemaValidator.java Thu Jun 12 11:35:27 2014
@@ -20,7 +20,6 @@ package org.apache.syncope.core.persiste
 
 import javax.validation.ConstraintValidatorContext;
 import org.apache.commons.lang3.StringUtils;
-
 import org.apache.syncope.common.types.EntityViolationType;
 import org.apache.syncope.common.types.AttributeSchemaType;
 import org.apache.syncope.core.persistence.beans.AbstractNormalSchema;
@@ -37,13 +36,23 @@ public class SchemaValidator extends Abs
                     getTemplate(EntityViolationType.InvalidSchemaEnum, "Enumeration values missing")).
                     addNode("enumerationValues").addConstraintViolation();
         } else {
-            isValid = !schema.isMultivalue() || !schema.isUniqueConstraint();
+            isValid = schema.getType() != AttributeSchemaType.Encrypted
+                    || (schema.getSecretKey() != null && schema.getCipherAlgorithm() != null);
             if (!isValid) {
                 context.disableDefaultConstraintViolation();
                 context.buildConstraintViolationWithTemplate(
-                        getTemplate(EntityViolationType.InvalidSchemaMultivalueUnique,
-                        "Cannot contemporary be multivalue and have unique constraint")).
-                        addNode("multiValue").addConstraintViolation();
+                        getTemplate(EntityViolationType.InvalidSchemaEncrypted,
+                                "SecretKey or CipherAlgorithm missing")).
+                        addNode("secretKey").addNode("cipherAlgorithm").addConstraintViolation();
+            } else {
+                isValid = !schema.isMultivalue() || !schema.isUniqueConstraint();
+                if (!isValid) {
+                    context.disableDefaultConstraintViolation();
+                    context.buildConstraintViolationWithTemplate(
+                            getTemplate(EntityViolationType.InvalidSchemaMultivalueUnique,
+                                    "Cannot contemporary be multivalue and have unique constraint")).
+                            addNode("multiValue").addConstraintViolation();
+                }
             }
         }
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/SchemaDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/SchemaDataBinder.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/SchemaDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/SchemaDataBinder.java Thu Jun 12 11:35:27 2014
@@ -90,6 +90,7 @@ public class SchemaDataBinder {
 
     public <T extends AbstractNormalSchema> SchemaTO getSchemaTO(
             final T schema, final AttributableUtil attributableUtil) {
+
         SchemaTO schemaTO = new SchemaTO();
         BeanUtils.copyProperties(schema, schemaTO);
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/UserDataBinder.java Thu Jun 12 11:35:27 2014
@@ -55,7 +55,7 @@ import org.apache.syncope.core.propagati
 import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.core.util.EntitlementUtil;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Component;
@@ -78,6 +78,8 @@ public class UserDataBinder extends Abst
     @Resource(name = "anonymousUser")
     private String anonymousUser;
 
+    private final Encryptor encryptor = Encryptor.getInstance();
+
     @Transactional(readOnly = true)
     public SyncopeUser getUserFromId(final Long userId) {
         if (userId == null) {
@@ -138,7 +140,7 @@ public class UserDataBinder extends Abst
 
     @Transactional(readOnly = true)
     public boolean verifyPassword(final SyncopeUser user, final String password) {
-        return PasswordEncoder.verify(password, user.getCipherAlgorithm(), user.getPassword());
+        return encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
     }
 
     @Transactional(readOnly = true)

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/security/EncodePasswordCLI.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/security/EncodePasswordCLI.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/security/EncodePasswordCLI.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/security/EncodePasswordCLI.java Thu Jun 12 11:35:27 2014
@@ -21,7 +21,7 @@ package org.apache.syncope.core.security
 import java.util.Arrays;
 
 import org.apache.syncope.common.types.CipherAlgorithm;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 
 /**
  * Command line version of encoder to encode the admin password.
@@ -36,14 +36,17 @@ public final class EncodePasswordCLI {
             System.exit(1);
         }
 
-        if (CipherAlgorithm.valueOf(args[1]).getAlgorithm().isEmpty()) {
+        CipherAlgorithm cipherAlgorithm = null;
+        try {
+            cipherAlgorithm = CipherAlgorithm.valueOf(args[1]);
+        } catch (IllegalArgumentException e) {
             System.err.println("Unsupported algorithm " + args[1]);
             usage();
             System.exit(2);
         }
 
         System.out.println("Encoding password '" + args[0] + "' with " + args[1]);
-        System.out.println(PasswordEncoder.encode(args[0], CipherAlgorithm.valueOf(args[1])));
+        System.out.println(Encryptor.getInstance().encode(args[0], cipherAlgorithm));
     }
 
     private static void usage() {

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java Thu Jun 12 11:35:27 2014
@@ -29,7 +29,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.UserDAO;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -73,6 +73,8 @@ public class SyncopeAuthenticationProvid
 
     private SyncopeUserDetailsService userDetailsService;
 
+    private final Encryptor encryptor = Encryptor.getInstance();
+
     /**
      * @param adminPassword the adminPassword to set
      */
@@ -194,7 +196,7 @@ public class SyncopeAuthenticationProvid
     protected boolean authenticate(final String password, final CipherAlgorithm cipherAlgorithm,
             final String digestedPassword) {
 
-        return PasswordEncoder.verify(password, cipherAlgorithm, digestedPassword);
+        return encryptor.verify(password, cipherAlgorithm, digestedPassword);
     }
 
     @Override

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/PushActions.java Thu Jun 12 11:35:27 2014
@@ -31,7 +31,7 @@ import org.quartz.JobExecutionException;
 public interface PushActions extends AbstractSyncActions<AbstractSyncopeResultHandler<?, ?>> {
 
     /**
-     * Action to be executed before to assign (link & provision) a synchronized user to the resource.
+     * Action to be executed before to assign (link & provision) a synchronized user / role to the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -45,7 +45,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to provision a synchronized user to the resource.
+     * Action to be executed before to provision a synchronized user / role to the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -59,7 +59,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to update a synchronized user on the resource.
+     * Action to be executed before to update a synchronized user / role on the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -73,7 +73,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to link a synchronized user to the resource.
+     * Action to be executed before to link a synchronized user / role to the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -87,7 +87,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unlink a synchronized user from the resource.
+     * Action to be executed before to unlink a synchronized user / role from the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -101,7 +101,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user from the resource.
+     * Action to be executed before to unassign a synchronized user / role from the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -115,7 +115,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to unassign a synchronized user from the resource.
+     * Action to be executed before to unassign a synchronized user / role from the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -129,7 +129,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before delete a synchronized user locally and from the resource.
+     * Action to be executed before delete a synchronized user / role locally and from the resource.
      *
      * @param handler synchronization handler being executed.
      * @param delta info to be pushed out (accountId, attributes).
@@ -143,7 +143,7 @@ public interface PushActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user synchronization.
+     * Action to be executed after each local user / role synchronization.
      *
      * @param handler synchronization handler being executed.
      * @param delta info pushed out (accountId, attributes)

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/SyncActions.java Thu Jun 12 11:35:27 2014
@@ -30,7 +30,7 @@ import org.quartz.JobExecutionException;
 public interface SyncActions extends AbstractSyncActions<AbstractSyncopeResultHandler<?, ?>> {
 
     /**
-     * Action to be executed before to create a synchronized user locally.
+     * Action to be executed before to create a synchronized user / role locally.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -44,7 +44,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before creating (and linking to the resource) a synchronized user locally.
+     * Action to be executed before creating (and linking to the resource) a synchronized user / role locally.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -58,7 +58,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before unlinking resource from the synchronized user and de-provisioning.
+     * Action to be executed before unlinking resource from the synchronized user / role and de-provisioning.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -86,7 +86,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before unlinking resource from the synchronized user.
+     * Action to be executed before unlinking resource from the synchronized user / role.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -100,7 +100,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before linking resource to the synchronized user.
+     * Action to be executed before linking resource to the synchronized user / role.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -114,7 +114,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed before to update a synchronized user locally.
+     * Action to be executed before to update a synchronized user / role locally.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -131,7 +131,7 @@ public interface SyncActions extends Abs
             throws JobExecutionException;
 
     /**
-     * Action to be executed before to delete a synchronized user locally.
+     * Action to be executed before to delete a synchronized user / role locally.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information
@@ -145,7 +145,7 @@ public interface SyncActions extends Abs
             final T subject) throws JobExecutionException;
 
     /**
-     * Action to be executed after each local user synchronization.
+     * Action to be executed after each local user / role synchronization.
      *
      * @param handler synchronization handler being executed.
      * @param delta retrieved synchronization information (may be modified by 'beforeCreate/beforeUpdate/beforeDelete')

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPPasswordSyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPPasswordSyncActions.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPPasswordSyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/LDAPPasswordSyncActions.java Thu Jun 12 11:35:27 2014
@@ -39,13 +39,14 @@ import org.springframework.transaction.a
  * that are hashed.
  */
 public class LDAPPasswordSyncActions extends DefaultSyncActions {
-    
+
     protected static final Logger LOG = LoggerFactory.getLogger(LDAPPasswordSyncActions.class);
 
     @Autowired
-    protected UserDAO userDAO;
+    private UserDAO userDAO;
 
     private String encodedPassword;
+
     private CipherAlgorithm cipher;
 
     @Transactional(readOnly = true)
@@ -54,22 +55,24 @@ public class LDAPPasswordSyncActions ext
             final AbstractSyncopeResultHandler<?, ?> handler,
             final SyncDelta delta,
             final T subject) throws JobExecutionException {
+
         if (subject instanceof UserTO) {
-            String password = ((UserTO)subject).getPassword();
+            String password = ((UserTO) subject).getPassword();
             if (password != null && password.startsWith("{")) {
                 int closingBracketIndex = password.indexOf('}');
                 String digest = password.substring(1, password.indexOf('}'));
-                CipherAlgorithm cipherAlgorithm = CipherAlgorithm.fromString(digest);
-                if (cipherAlgorithm != null) {
+                try {
                     encodedPassword = password.substring(closingBracketIndex + 1);
-                    cipher = cipherAlgorithm;
+                    cipher = CipherAlgorithm.valueOf(digest);
+                } catch (IllegalArgumentException e) {
+                    LOG.error("Cipher algorithm not allowed: {}", digest, e);
                 }
             }
         }
-        
+
         return delta;
     }
-    
+
     @Transactional(readOnly = true)
     @Override
     public <T extends AbstractAttributableTO> void after(
@@ -84,16 +87,12 @@ public class LDAPPasswordSyncActions ext
                 byte[] encodedPasswordBytes = Base64.decode(encodedPassword.getBytes());
                 char[] encodedHex = Hex.encode(encodedPasswordBytes);
                 String encodedHexStr = new String(encodedHex).toUpperCase();
-                
-                /*UserMod userMod = new UserMod();
-                userMod.setId(subject.getId());
-                userMod.setPassword(encodedHexStr);
-                uwfAdapter.update(userMod);*/
-                syncopeUser.setEncodedPassword(encodedHexStr, cipher, 0);
+
+                syncopeUser.setEncodedPassword(encodedHexStr, cipher);
             }
             encodedPassword = null;
             cipher = null;
         }
     }
-    
+
 }

Copied: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/Encryptor.java (from r1602068, syncope/trunk/core/src/main/java/org/apache/syncope/core/util/PasswordEncoder.java)
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/Encryptor.java?p2=syncope/trunk/core/src/main/java/org/apache/syncope/core/util/Encryptor.java&p1=syncope/trunk/core/src/main/java/org/apache/syncope/core/util/PasswordEncoder.java&r1=1602068&r2=1602129&rev=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/PasswordEncoder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/Encryptor.java Thu Jun 12 11:35:27 2014
@@ -22,7 +22,9 @@ import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
+import java.util.Map;
 import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
 import javax.crypto.IllegalBlockSizeException;
@@ -30,6 +32,8 @@ import javax.crypto.NoSuchPaddingExcepti
 import javax.crypto.spec.SecretKeySpec;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.SyncopeConstants;
 import org.apache.syncope.common.types.CipherAlgorithm;
 import org.jasypt.commons.CommonUtils;
 import org.jasypt.digest.StandardStringDigester;
@@ -38,48 +42,74 @@ import org.slf4j.LoggerFactory;
 import org.springframework.security.crypto.bcrypt.BCrypt;
 import org.springframework.security.crypto.codec.Base64;
 
-public final class PasswordEncoder {
+public class Encryptor {
 
-    private static final Logger LOG = LoggerFactory.getLogger(PasswordEncoder.class);
+    private static final Logger LOG = LoggerFactory.getLogger(Encryptor.class);
 
-    private static SecretKeySpec keySpec;
+    private static final Map<String, Encryptor> INSTANCES = new ConcurrentHashMap<String, Encryptor>();
 
-    static {
-        String secretKey = null;
+    private static final String DEFAULT_SECRET_KEY = "1abcdefghilmnopqrstuvz2!";
+
+    private static String PASSWORD_SECRET_KEY;
 
+    private SecretKeySpec keySpec;
+
+    static {
         InputStream propStream = null;
         try {
-            propStream = PasswordEncoder.class.getResourceAsStream("/security.properties");
+            propStream = Encryptor.class.getResourceAsStream("/security.properties");
             Properties props = new Properties();
             props.load(propStream);
-            secretKey = props.getProperty("secretKey");
+            PASSWORD_SECRET_KEY = props.getProperty("secretKey");
         } catch (Exception e) {
-            LOG.error("Could not read secretKey", e);
+            LOG.error("Could not read password secretKey", e);
         } finally {
             IOUtils.closeQuietly(propStream);
         }
 
-        if (secretKey == null) {
-            secretKey = "1abcdefghilmnopqrstuvz2!";
-            LOG.debug("secretKey not found, reverting to default");
-        }
-        if (secretKey.length() < 16) {
-            StringBuilder secretKeyPadding = new StringBuilder(secretKey);
-            for (int i = 0; i < 16 - secretKey.length(); i++) {
-                secretKeyPadding.append('0');
+        if (PASSWORD_SECRET_KEY == null) {
+            PASSWORD_SECRET_KEY = DEFAULT_SECRET_KEY;
+            LOG.debug("password secretKey not found, reverting to default");
+        }
+    }
+
+    public static Encryptor getInstance() {
+        return getInstance(PASSWORD_SECRET_KEY);
+    }
+
+    public static Encryptor getInstance(final String secretKey) {
+        String actualKey = StringUtils.isBlank(secretKey) ? DEFAULT_SECRET_KEY : secretKey;
+
+        Encryptor instance = INSTANCES.get(actualKey);
+        if (instance == null) {
+            instance = new Encryptor(actualKey);
+            INSTANCES.put(actualKey, instance);
+        }
+
+        return instance;
+    }
+
+    private Encryptor(final String secretKey) {
+        String actualKey = secretKey;
+        if (actualKey.length() < 16) {
+            StringBuilder actualKeyPadding = new StringBuilder(actualKey);
+            for (int i = 0; i < 16 - actualKey.length(); i++) {
+                actualKeyPadding.append('0');
             }
-            secretKey = secretKeyPadding.toString();
-            LOG.debug("secretKey too short, adding some random characters");
+            actualKey = actualKeyPadding.toString();
+            LOG.debug("actualKey too short, adding some random characters");
         }
 
         try {
-            keySpec = new SecretKeySpec(ArrayUtils.subarray(secretKey.getBytes("UTF8"), 0, 16), "AES");
+            keySpec = new SecretKeySpec(ArrayUtils.subarray(
+                    actualKey.getBytes(SyncopeConstants.DEFAULT_ENCODING), 0, 16),
+                    CipherAlgorithm.AES.getAlgorithm());
         } catch (Exception e) {
             LOG.error("Error during key specification", e);
         }
     }
 
-    public static String encode(final String password, final CipherAlgorithm cipherAlgorithm)
+    public String encode(final String password, final CipherAlgorithm cipherAlgorithm)
             throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
             IllegalBlockSizeException, BadPaddingException {
 
@@ -87,7 +117,7 @@ public final class PasswordEncoder {
 
         if (password != null) {
             if (cipherAlgorithm == null || cipherAlgorithm == CipherAlgorithm.AES) {
-                final byte[] cleartext = password.getBytes("UTF8");
+                final byte[] cleartext = password.getBytes(SyncopeConstants.DEFAULT_ENCODING);
 
                 final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
                 cipher.init(Cipher.ENCRYPT_MODE, keySpec);
@@ -103,7 +133,7 @@ public final class PasswordEncoder {
         return encodedPassword;
     }
 
-    public static boolean verify(final String password, final CipherAlgorithm cipherAlgorithm,
+    public boolean verify(final String password, final CipherAlgorithm cipherAlgorithm,
             final String digestedPassword) {
 
         boolean res = false;
@@ -125,14 +155,14 @@ public final class PasswordEncoder {
         return res;
     }
 
-    public static String decode(final String encodedPassword, final CipherAlgorithm cipherAlgorithm)
+    public String decode(final String encodedPassword, final CipherAlgorithm cipherAlgorithm)
             throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
             IllegalBlockSizeException, BadPaddingException {
 
         String password = null;
 
         if (encodedPassword != null && cipherAlgorithm == CipherAlgorithm.AES) {
-            final byte[] encoded = encodedPassword.getBytes("UTF8");
+            final byte[] encoded = encodedPassword.getBytes(SyncopeConstants.DEFAULT_ENCODING);
 
             final Cipher cipher = Cipher.getInstance(CipherAlgorithm.AES.getAlgorithm());
             cipher.init(Cipher.DECRYPT_MODE, keySpec);
@@ -143,7 +173,7 @@ public final class PasswordEncoder {
         return password;
     }
 
-    private static StandardStringDigester getDigester(final CipherAlgorithm cipherAlgorithm) {
+    private StandardStringDigester getDigester(final CipherAlgorithm cipherAlgorithm) {
         StandardStringDigester digester = new StandardStringDigester();
 
         if (cipherAlgorithm.getAlgorithm().startsWith("S-")) {
@@ -161,10 +191,4 @@ public final class PasswordEncoder {
         digester.setStringOutputType(CommonUtils.STRING_OUTPUT_TYPE_HEXADECIMAL);
         return digester;
     }
-
-    /**
-     * Private default constructor, for static-only classes.
-     */
-    private PasswordEncoder() {
-    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/util/MappingUtil.java Thu Jun 12 11:35:27 2014
@@ -79,6 +79,8 @@ public final class MappingUtil {
      */
     private static final Logger LOG = LoggerFactory.getLogger(MappingUtil.class);
 
+    private static final Encryptor ENCRYPTOR = Encryptor.getInstance();
+
     public static <T extends AbstractMappingItem> List<T> getMatchingMappingItems(
             final Collection<T> items, final IntMappingType type) {
 
@@ -339,7 +341,7 @@ public final class MappingUtil {
                     SyncopeUser user = (SyncopeUser) subject;
                     if (user.canDecodePassword()) {
                         try {
-                            passwordAttrValue = PasswordEncoder.decode(user.getPassword(), user.getCipherAlgorithm());
+                            passwordAttrValue = ENCRYPTOR.decode(user.getPassword(), user.getCipherAlgorithm());
                         } catch (Exception e) {
                             LOG.error("Could not decode password for {}", user, e);
                         }
@@ -636,6 +638,7 @@ public final class MappingUtil {
      * Get accountId internal value.
      *
      * @param attributable attributable
+     * @param accountIdItem accountId mapping item
      * @param resource external resource
      * @param accountIdItem accountid mapping item
      * @return accountId internal value

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java Thu Jun 12 11:35:27 2014
@@ -73,7 +73,7 @@ public class PasswordGeneratorTest exten
             fail(ex.getMessage());
         }
         assertNotNull(password);
-        user.setPassword(password, CipherAlgorithm.SHA1, 0);
+        user.setPassword(password, CipherAlgorithm.SHA, 0);
         userDAO.save(user);
     }
 

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/AttrTest.java Thu Jun 12 11:35:27 2014
@@ -18,13 +18,13 @@
  */
 package org.apache.syncope.core.persistence.dao;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import javax.validation.ValidationException;
-
 import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.EntityViolationType;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
@@ -33,6 +33,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.user.USchema;
 import org.apache.syncope.core.persistence.validation.entity.InvalidEntityException;
 import org.apache.syncope.core.util.AttributableUtil;
+import org.apache.syncope.core.util.Encryptor;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
@@ -96,7 +97,7 @@ public class AttrTest extends AbstractDA
     }
 
     @Test
-    public void checkForEnumType() throws ClassNotFoundException {
+    public void saveWithEnum() throws ClassNotFoundException {
         SyncopeUser user = userDAO.find(1L);
 
         USchema gender = userSchemaDAO.find("gender", USchema.class);
@@ -122,7 +123,7 @@ public class AttrTest extends AbstractDA
 
         InvalidEntityException iee = null;
         try {
-            user = userDAO.save(user);
+            userDAO.save(user);
         } catch (InvalidEntityException e) {
             iee = e;
         }
@@ -166,6 +167,30 @@ public class AttrTest extends AbstractDA
     }
 
     @Test
+    public void saveWithEncrypted() throws Exception {
+        SyncopeUser user = userDAO.find(1L);
+
+        final USchema obscureSchema = userSchemaDAO.find("obscure", USchema.class);
+        assertNotNull(obscureSchema);
+        assertNotNull(obscureSchema.getSecretKey());
+        assertNotNull(obscureSchema.getCipherAlgorithm());
+
+        UAttr attribute = new UAttr();
+        attribute.setSchema(obscureSchema);
+        attribute.addValue("testvalue", AttributableUtil.getInstance(AttributableType.USER));
+        attribute.setOwner(user);
+        user.addAttr(attribute);
+
+        userDAO.save(user);
+
+        UAttr obscure = user.getAttr("obscure");
+        assertNotNull(obscure);
+        assertEquals(1, obscure.getValues().size());
+        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
+                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
+    }
+
+    @Test
     public void delete() {
         UAttr attribute = attrDAO.find(104L, UAttr.class);
         String attrSchemaName = attribute.getSchema().getName();

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/SchemaTest.java Thu Jun 12 11:35:27 2014
@@ -50,7 +50,7 @@ public class SchemaTest extends Abstract
     @Test
     public void findAll() {
         List<USchema> userList = schemaDAO.findAll(USchema.class);
-        assertEquals(13, userList.size());
+        assertEquals(14, userList.size());
 
         List<RSchema> roleList = schemaDAO.findAll(RSchema.class);
         assertEquals(5, roleList.size());

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java Thu Jun 12 11:35:27 2014
@@ -64,7 +64,7 @@ import org.apache.syncope.common.types.A
 import org.apache.syncope.common.types.ConnConfProperty;
 import org.apache.syncope.common.types.RESTHeaders;
 import org.apache.syncope.common.types.SchemaType;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 import org.junit.BeforeClass;
 import org.junit.runner.RunWith;
 import org.slf4j.Logger;
@@ -179,7 +179,7 @@ public abstract class AbstractTest {
     public static void securitySetup() {
         InputStream propStream = null;
         try {
-            propStream = PasswordEncoder.class.getResourceAsStream("/security.properties");
+            propStream = Encryptor.class.getResourceAsStream("/security.properties");
             Properties props = new Properties();
             props.load(propStream);
 

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/SchemaTestITCase.java Thu Jun 12 11:35:27 2014
@@ -42,6 +42,7 @@ import org.apache.syncope.common.types.S
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.util.AttributableOperations;
 import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.types.CipherAlgorithm;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -114,12 +115,22 @@ public class SchemaTestITCase extends Ab
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidUSchema, e.getType());
 
-            assertTrue(e.getElements().iterator().next().toString().
-                    contains(EntityViolationType.InvalidSchemaEnum.name()));
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
         }
     }
 
     @Test
+    public void createEncrypted() {
+        SchemaTO schemaTO = new SchemaTO();
+        schemaTO.setName("encrypted");
+        schemaTO.setType(AttributeSchemaType.Encrypted);
+        schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
+        schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
+
+        createSchema(AttributableType.MEMBERSHIP, SchemaType.NORMAL, schemaTO);
+    }
+
+    @Test
     public void delete() {
         SchemaTO schemaTO = buildSchemaTO("todelete", AttributeSchemaType.String);
         schemaTO.setMandatoryCondition("false");
@@ -277,9 +288,7 @@ public class SchemaTestITCase extends Ab
             fail();
         } catch (SyncopeClientException e) {
             assertEquals(ClientExceptionType.InvalidRSchema, e.getType());
-
-            assertTrue(e.getElements().iterator().next().toString().
-                    contains(EntityViolationType.InvalidName.name()));
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
         }
     }
 

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java Thu Jun 12 11:35:27 2014
@@ -249,7 +249,7 @@ public class TaskTestITCase extends Abst
         assertNotNull(taskTO);
         assertNotNull(taskTO.getExecutions());
         assertTrue(taskTO.getExecutions().isEmpty());
-        
+
         final PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(13L);
         assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchigRule());
         assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchigRule());
@@ -484,8 +484,10 @@ public class TaskTestITCase extends Abst
         assertEquals(1, matchingUsers.getResult().size());
 
         // Check for SYNCOPE-436
-        assertEquals("syncFromLDAP", matchingUsers.getResult().get(0).getVirAttrMap().
-                get("virtualReadOnly").getValues().get(0));
+        assertEquals("syncFromLDAP",
+                matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+        // Check for SYNCOPE-270
+        assertNotNull(matchingUsers.getResult().get(0).getAttrMap().get("obscure"));
 
         final RoleTO roleTO = matchingRoles.getResult().iterator().next();
         assertNotNull(roleTO);

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java Thu Jun 12 11:35:27 2014
@@ -27,7 +27,6 @@ import static org.junit.Assert.assertTru
 import static org.junit.Assert.fail;
 
 import java.security.AccessControlException;
-import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Collections;
 import java.util.Date;
@@ -133,8 +132,7 @@ public class UserTestITCase extends Abst
         userTO.getAttrs().add(attributeTO("type", "a type"));
         userTO.getAttrs().add(attributeTO("userId", uid));
         userTO.getAttrs().add(attributeTO("email", uid));
-        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-        userTO.getAttrs().add(attributeTO("loginDate", sdf.format(new Date())));
+        userTO.getAttrs().add(attributeTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
         userTO.getDerAttrs().add(attributeTO("cn", null));
         userTO.getVirAttrs().add(attributeTO("virtualdata", "virtualvalue"));
         return userTO;
@@ -712,7 +710,7 @@ public class UserTestITCase extends Abst
         assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
 
         SyncopeUser passwordTestUser = new SyncopeUser();
-        passwordTestUser.setPassword("new2Password", CipherAlgorithm.SHA1, 0);
+        passwordTestUser.setPassword("new2Password", CipherAlgorithm.SHA, 0);
         assertEquals(passwordTestUser.getPassword(), userTO.getPassword());
 
         assertEquals(1, userTO.getMemberships().size());
@@ -1757,17 +1755,22 @@ public class UserTestITCase extends Abst
 
         // 2. create user with membership of the above role
         UserTO userTO = getUniqueSampleTO("syncope357@syncope.apache.org");
+        userTO.getAttrs().add(attributeTO("obscure", "valueToBeObscured"));
         MembershipTO membershipTO = new MembershipTO();
         membershipTO.setRoleId(roleTO.getId());
         userTO.getMemberships().add(membershipTO);
 
         userTO = createUser(userTO);
         assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+        assertNotNull(userTO.getAttrMap().get("obscure"));
 
         // 3. read user on resource
         ConnObjectTO connObj = resourceService.getConnectorObject(
                 RESOURCE_NAME_LDAP, AttributableType.USER, userTO.getId());
         assertNotNull(connObj);
+        AttributeTO registeredAddress = connObj.getAttrMap().get("registeredAddress");
+        assertNotNull(registeredAddress);
+        assertEquals(userTO.getAttrMap().get("obscure").getValues(), registeredAddress.getValues());
 
         // 4. remove role
         roleService.delete(roleTO.getId());

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/security/PasswordEncoderTest.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/security/PasswordEncoderTest.java?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/security/PasswordEncoderTest.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/security/PasswordEncoderTest.java Thu Jun 12 11:35:27 2014
@@ -23,38 +23,37 @@ import static org.junit.Assert.assertNot
 import static org.junit.Assert.assertTrue;
 
 import org.apache.syncope.common.types.CipherAlgorithm;
-import org.apache.syncope.core.util.PasswordEncoder;
+import org.apache.syncope.core.util.Encryptor;
 import org.junit.Test;
 
 /**
- * Testclass to test all encryption algorithms.
+ * Test class to test all encryption algorithms.
  */
 public class PasswordEncoderTest {
 
     private final String password = "password";
-    
+
+    private final Encryptor encryptor = Encryptor.getInstance();
+
     /**
-     * Verify all algorithms
+     * Verify all algorithms.
      */
     @Test
-    public void testEncoder()
-            throws Exception {
-
+    public void testEncoder() throws Exception {
         for (CipherAlgorithm cipherAlgorithm : CipherAlgorithm.values()) {
-            final String encPassword = PasswordEncoder.encode(password, cipherAlgorithm);
+            final String encPassword = encryptor.encode(password, cipherAlgorithm);
 
             assertNotNull(encPassword);
-            assertTrue(PasswordEncoder.verify(password, cipherAlgorithm, encPassword));
-            assertFalse(PasswordEncoder.verify("pass", cipherAlgorithm, encPassword));
+            assertTrue(encryptor.verify(password, cipherAlgorithm, encPassword));
+            assertFalse(encryptor.verify("pass", cipherAlgorithm, encPassword));
 
             // check that same password encoded with BCRYPT or Salted versions results in different digest
             if (cipherAlgorithm.equals(CipherAlgorithm.BCRYPT) || cipherAlgorithm.getAlgorithm().startsWith("S-")) {
-                final String encSamePassword = PasswordEncoder.encode(password, cipherAlgorithm);
+                final String encSamePassword = encryptor.encode(password, cipherAlgorithm);
                 assertNotNull(encSamePassword);
                 assertFalse(encSamePassword.equals(encPassword));
-                assertTrue(PasswordEncoder.verify(password, cipherAlgorithm, encSamePassword));
+                assertTrue(encryptor.verify(password, cipherAlgorithm, encSamePassword));
             }
         }
-
     }
 }

Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1602129&r1=1602128&r2=1602129&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Thu Jun 12 11:35:27 2014
@@ -173,6 +173,9 @@ under the License.
            mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
   <USchema name="makeItDouble" type="Long"
            mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <USchema name="obscure" type="Encrypted"
+           mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+           secretKey="7abcdefghilmnopqrstuvz9#" cipherAlgorithm="SHA"/>
 
   <UDerSchema name="csvuserid" expression="firstname + ',' + surname"/>
   <UDerSchema name="cn" expression="surname + ', ' + firstname"/>
@@ -753,6 +756,9 @@ under the License.
   <UMappingItem id="319" accountid="0" password="0" mapping_id="11"
                 extAttrName="givenname" intAttrName="virtualReadOnly" intMappingType="UserVirtualSchema"
                 mandatoryCondition="false" purpose="BOTH"/>
+  <UMappingItem id="320" accountid="0" password="0" mapping_id="11"
+                extAttrName="registeredAddress" intAttrName="obscure" intMappingType="UserSchema"
+                mandatoryCondition="false" purpose="BOTH"/>
   
   <RMapping id="1" resource_name="resource-ldap"
             accountlink="&apos;cn=&apos; + name + &apos;,ou=groups,o=isp&apos;"/>