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/09/19 10:53:25 UTC

svn commit: r1626148 [2/3] - in /syncope/branches/1_2_X: ./ common/src/main/java/org/apache/syncope/common/mod/ common/src/main/java/org/apache/syncope/common/services/ common/src/main/java/org/apache/syncope/common/to/ common/src/main/java/org/apache/...

Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/AbstractUserWorkflowAdapter.java Fri Sep 19 08:53:24 2014
@@ -119,6 +119,23 @@ public abstract class AbstractUserWorkfl
         return doReactivate(user);
     }
 
+    protected abstract void doRequestPasswordReset(SyncopeUser user) throws WorkflowException;
+
+    @Override
+    public void requestPasswordReset(final Long userId) throws UnauthorizedRoleException, WorkflowException {
+        doRequestPasswordReset(dataBinder.getUserFromId(userId));
+    }
+
+    protected abstract void doConfirmPasswordReset(SyncopeUser user, String token, String password) 
+            throws WorkflowException;
+
+    @Override
+    public void confirmPasswordReset(final Long userId, final String token, final String password)
+            throws UnauthorizedRoleException, WorkflowException {
+
+        doConfirmPasswordReset(dataBinder.getUserFromId(userId), token, password);
+    }
+
     protected abstract void doDelete(SyncopeUser user) throws WorkflowException;
 
     @Override

Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java Fri Sep 19 08:53:24 2014
@@ -30,12 +30,15 @@ import org.apache.syncope.common.to.User
 import org.apache.syncope.common.to.WorkflowFormTO;
 import org.apache.syncope.common.types.ResourceOperation;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.ConfDAO;
 import org.apache.syncope.core.persistence.dao.NotFoundException;
+import org.apache.syncope.core.persistence.dao.PolicyDAO;
 import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
 import org.apache.syncope.core.workflow.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.WorkflowException;
 import org.apache.syncope.core.workflow.WorkflowResult;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
 /**
@@ -44,7 +47,11 @@ import org.springframework.transaction.a
 @Transactional(rollbackFor = { Throwable.class })
 public class NoOpUserWorkflowAdapter extends AbstractUserWorkflowAdapter {
 
-    public static final String ENABLED = "enabled";
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private ConfDAO confDAO;
 
     @Override
     public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck,
@@ -124,9 +131,7 @@ public class NoOpUserWorkflowAdapter ext
     }
 
     @Override
-    protected WorkflowResult<Long> doSuspend(final SyncopeUser user)
-            throws WorkflowException {
-
+    protected WorkflowResult<Long> doSuspend(final SyncopeUser user) throws WorkflowException {
         user.setStatus("suspended");
         SyncopeUser updated = userDAO.save(user);
 
@@ -134,9 +139,7 @@ public class NoOpUserWorkflowAdapter ext
     }
 
     @Override
-    protected WorkflowResult<Long> doReactivate(final SyncopeUser user)
-            throws WorkflowException {
-
+    protected WorkflowResult<Long> doReactivate(final SyncopeUser user) throws WorkflowException {
         user.setStatus("active");
         SyncopeUser updated = userDAO.save(user);
 
@@ -144,9 +147,28 @@ public class NoOpUserWorkflowAdapter ext
     }
 
     @Override
-    protected void doDelete(final SyncopeUser user)
+    protected void doRequestPasswordReset(final SyncopeUser user) throws WorkflowException {
+        user.generateToken(
+                confDAO.find("token.length", "256").getValues().get(0).getLongValue().intValue(),
+                confDAO.find("token.expireTime", "60").getValues().get(0).getLongValue().intValue());
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doConfirmPasswordReset(final SyncopeUser user, final String token, final String password)
             throws WorkflowException {
 
+        if (!user.checkToken(token)) {
+            throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
+        }
+
+        user.removeToken();
+        user.setPassword(password, user.getCipherAlgorithm());
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doDelete(final SyncopeUser user) throws WorkflowException {
         userDAO.delete(user);
     }
 

Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/UserWorkflowAdapter.java Fri Sep 19 08:53:24 2014
@@ -135,6 +135,27 @@ public interface UserWorkflowAdapter ext
     WorkflowResult<Long> reactivate(Long userId) throws UnauthorizedRoleException, WorkflowException;
 
     /**
+     * Request password reset for an user.
+     *
+     * @param userId user requesting password reset
+     * @throws UnauthorizedRoleException authorization exception
+     * @throws WorkflowException workflow exception
+     */
+    void requestPasswordReset(Long userId) throws UnauthorizedRoleException, WorkflowException;
+
+    /**
+     * Confirm password reset for an user.
+     *
+     * @param userId user confirming password reset
+     * @param token security token
+     * @param password new password value
+     * @throws UnauthorizedRoleException authorization exception
+     * @throws WorkflowException workflow exception
+     */
+    void confirmPasswordReset(Long userId, String token, String password) 
+            throws UnauthorizedRoleException, WorkflowException;
+
+    /**
      * Delete an user.
      *
      * @param userId user to be deleted

Modified: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java (original)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/ActivitiUserWorkflowAdapter.java Fri Sep 19 08:53:24 2014
@@ -70,6 +70,7 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException;
 import org.apache.syncope.core.propagation.PropagationByResource;
 import org.apache.syncope.core.rest.controller.UnauthorizedRoleException;
+import org.apache.syncope.core.rest.data.UserDataBinder;
 import org.apache.syncope.core.util.EntitlementUtil;
 import org.apache.syncope.core.workflow.WorkflowDefinitionFormat;
 import org.apache.syncope.core.workflow.WorkflowException;
@@ -115,6 +116,8 @@ public class ActivitiUserWorkflowAdapter
 
     public static final String TOKEN = "token";
 
+    public static final String PASSWORD = "password";
+
     public static final String PROP_BY_RESOURCE = "propByResource";
 
     public static final String PROPAGATE_ENABLE = "propagateEnable";
@@ -127,6 +130,8 @@ public class ActivitiUserWorkflowAdapter
 
     public static final String STORE_PASSWORD = "storePassword";
 
+    public static final String EVENT = "event";
+
     @Resource(name = "adminUser")
     private String adminUser;
 
@@ -148,6 +153,9 @@ public class ActivitiUserWorkflowAdapter
     @Autowired
     private ActivitiImportUtils importUtils;
 
+    @Autowired
+    private UserDataBinder userDataBinder;
+
     @Override
     public Class<? extends WorkflowInstanceLoader> getLoaderClass() {
         return ActivitiWorkflowLoader.class;
@@ -355,9 +363,7 @@ public class ActivitiUserWorkflowAdapter
 
     @Override
     @Transactional(rollbackFor = { Throwable.class })
-    protected WorkflowResult<Long> doSuspend(final SyncopeUser user)
-            throws WorkflowException {
-
+    protected WorkflowResult<Long> doSuspend(final SyncopeUser user) throws WorkflowException {
         Set<String> performedTasks = doExecuteTask(user, "suspend", null);
         updateStatus(user);
         SyncopeUser updated = userDAO.save(user);
@@ -366,9 +372,7 @@ public class ActivitiUserWorkflowAdapter
     }
 
     @Override
-    protected WorkflowResult<Long> doReactivate(final SyncopeUser user)
-            throws WorkflowException {
-
+    protected WorkflowResult<Long> doReactivate(final SyncopeUser user) throws WorkflowException {
         Set<String> performedTasks = doExecuteTask(user, "reactivate", null);
         updateStatus(user);
 
@@ -378,9 +382,31 @@ public class ActivitiUserWorkflowAdapter
     }
 
     @Override
-    protected void doDelete(final SyncopeUser user)
+    protected void doRequestPasswordReset(final SyncopeUser user) throws WorkflowException {
+        Map<String, Object> variables = new HashMap<String, Object>(2);
+        variables.put(USER_TO, userDataBinder.getUserTO(user));
+        variables.put(EVENT, "requestPasswordReset");
+
+        doExecuteTask(user, "requestPasswordReset", variables);
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doConfirmPasswordReset(final SyncopeUser user, final String token, final String password)
             throws WorkflowException {
 
+        Map<String, Object> variables = new HashMap<String, Object>(4);
+        variables.put(TOKEN, token);
+        variables.put(PASSWORD, password);
+        variables.put(USER_TO, userDataBinder.getUserTO(user));
+        variables.put(EVENT, "confirmPasswordReset");
+
+        doExecuteTask(user, "confirmPasswordReset", variables);
+        userDAO.save(user);
+    }
+
+    @Override
+    protected void doDelete(final SyncopeUser user) throws WorkflowException {
         doExecuteTask(user, "delete", null);
 
         PropagationByResource propByRes = new PropagationByResource();

Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.workflow.user.activiti.task;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.to.UserTO;
+import org.apache.syncope.common.types.AuditElements;
+import org.apache.syncope.core.notification.NotificationManager;
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+/**
+ * General-purpose notification task for usage within workflow.
+ * It requires a pre-existing <tt>Notification</tt> with category <tt>CUSTOM</tt> and result <tt>SUCCESS</tt>.
+ * An <tt>event</tt> workflow variable needs to be provided as well.
+ */
+@Component
+public class Notify extends AbstractActivitiServiceTask {
+
+    @Autowired
+    private NotificationManager notificationManager;
+
+    @Override
+    protected void doExecute(final String executionId) {
+        SyncopeUser user =
+                (SyncopeUser) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER);
+        UserTO userTO =
+                (UserTO) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.USER_TO);
+        String event =
+                (String) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.EVENT);
+
+        if (StringUtils.isNotBlank(event)) {
+            notificationManager.createTasks(
+                    AuditElements.EventCategoryType.CUSTOM,
+                    null,
+                    null,
+                    event,
+                    AuditElements.Result.SUCCESS,
+                    userTO,
+                    null,
+                    user.getToken());
+        } else {
+            LOG.debug("Not sending any notification since no event was found");
+        }
+    }
+
+}

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/Notify.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java (added)
+++ syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.workflow.user.activiti.task;
+
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.workflow.WorkflowException;
+import org.apache.syncope.core.workflow.user.activiti.ActivitiUserWorkflowAdapter;
+import org.springframework.stereotype.Component;
+
+@Component
+public class PasswordReset extends AbstractActivitiServiceTask {
+
+    @Override
+    protected void doExecute(final String executionId) {
+        SyncopeUser user =
+                (SyncopeUser) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER);
+        String token =
+                (String) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.TOKEN);
+        String password =
+                (String) runtimeService.getVariable(executionId, ActivitiUserWorkflowAdapter.PASSWORD);
+
+        if (!user.checkToken(token)) {
+            throw new WorkflowException(new IllegalArgumentException("Wrong token: " + token + " for " + user));
+        }
+
+        user.removeToken();
+        user.setPassword(password, user.getCipherAlgorithm());
+        runtimeService.setVariable(executionId, ActivitiUserWorkflowAdapter.SYNCOPE_USER, user);
+    }
+
+}

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/java/org/apache/syncope/core/workflow/user/activiti/task/PasswordReset.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml (original)
+++ syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml Fri Sep 19 08:53:24 2014
@@ -344,4 +344,12 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity class="org.apache.syncope.core.persistence.beans.SecurityQuestion">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_SecurityQuestion" strategy="TABLE"/>
+        <table-generator name="SEQ_SecurityQuestion" pk-column-value="SEQ_SecurityQuestion" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>
 </entity-mappings>

Modified: syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.oracle
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.oracle?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.oracle (original)
+++ syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.oracle Fri Sep 19 08:53:24 2014
@@ -297,4 +297,12 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity class="org.apache.syncope.core.persistence.beans.SecurityQuestion">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_SecurityQuestion" strategy="TABLE"/>
+        <table-generator name="SEQ_SecurityQuestion" pk-column-value="SEQ_SecurityQuestion" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>  
 </entity-mappings>

Modified: syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.sqlserver
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.sqlserver?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.sqlserver (original)
+++ syncope/branches/1_2_X/core/src/main/resources/META-INF/orm.xml.sqlserver Fri Sep 19 08:53:24 2014
@@ -333,4 +333,12 @@ under the License.
       </id>
     </attributes>
   </entity>
+  <entity class="org.apache.syncope.core.persistence.beans.SecurityQuestion">
+    <attributes>
+      <id name="id">
+        <generated-value generator="SEQ_SecurityQuestion" strategy="TABLE"/>
+        <table-generator name="SEQ_SecurityQuestion" pk-column-value="SEQ_SecurityQuestion" initial-value="100"/>
+      </id>
+    </attributes>
+  </entity>  
 </entity-mappings>

Modified: syncope/branches/1_2_X/core/src/main/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/content.xml?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/content.xml (original)
+++ syncope/branches/1_2_X/core/src/main/resources/content.xml Fri Sep 19 08:53:24 2014
@@ -56,10 +56,16 @@ under the License.
   <CAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
   <CAttrValue id="6" attribute_id="6" booleanValue="1"/>
 
+  <CSchema name="passwordReset.allowed" type="Boolean"
+           mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
   <CSchema name="authentication.statuses" type="String"
            mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CAttr id="7" owner_id="1" schema_name="authentication.statuses"/>
-  <CAttrValue id="7" attribute_id="7" stringValue="active"/>
+  <CAttr id="8" owner_id="1" schema_name="authentication.statuses"/>
+  <CAttrValue id="8" attribute_id="8" stringValue="created"/>
+  <CAttrValue id="9" attribute_id="8" stringValue="active"/>
 
   <!-- Save user login date upon successful authentication -->
   <CSchema name="log.lastlogindate" type="Boolean"
@@ -67,6 +73,22 @@ under the License.
   <CAttr id="10" owner_id="1" schema_name="log.lastlogindate"/>
   <CAttrValue id="10" attribute_id="10" booleanValue="1"/>
     
+  <!-- User pre-defined schemas -->
+  <USchema name="email" type="String"
+           mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
+           validatorClass="org.apache.syncope.core.persistence.validation.attrvalue.EmailAddressValidator"/>  
+  
+  <!-- Password reset notifications -->
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES" userAbout="token!=$null"/> 
+  <Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES" userAbout="token!=$null"/> 
+  <Notification_events Notification_id="2" events="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>  
+  
   <!-- Authentication and authorization -->
   <Entitlement name="SCHEMA_LIST"/>
   <Entitlement name="SCHEMA_CREATE"/>
@@ -136,5 +158,10 @@ under the License.
   <Entitlement name="AUDIT_LIST"/>
   <Entitlement name="AUDIT_ENABLE"/>
   <Entitlement name="AUDIT_DISABLE"/>
+  <Entitlement name="SECURITY_QUESTION_LIST"/>
+  <Entitlement name="SECURITY_QUESTION_READ"/>
+  <Entitlement name="SECURITY_QUESTION_CREATE"/>
+  <Entitlement name="SECURITY_QUESTION_UPDATE"/>
+  <Entitlement name="SECURITY_QUESTION_DELETE"/>
 
 </dataset>

Modified: syncope/branches/1_2_X/core/src/main/resources/mail.properties
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/mail.properties?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/mail.properties (original)
+++ syncope/branches/1_2_X/core/src/main/resources/mail.properties Fri Sep 19 08:53:24 2014
@@ -16,9 +16,9 @@
 # under the License.
 smtpHost=none.syncope.apache.org
 smtpPort=25
-smtpUser=syncope
-smtpPassword=secret
+smtpUser=
+smtpPassword=
 smtpProtocol=smtp
 smtpEncoding=UTF-8
 smtpConnectionTimeout=3000
-mailDebug=false
+mailDebug=false
\ No newline at end of file

Added: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm (added)
+++ syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm Fri Sep 19 08:53:24 2014
@@ -0,0 +1,26 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html>
+<body>
+<p>Hi,</br>
+we are happy to inform you that the password request was execute successfully for your account.</p>
+
+<p>Best regards.</p>
+</body>
+</html>
\ No newline at end of file

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm (added)
+++ syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm Fri Sep 19 08:53:24 2014
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+Hi,
+we are happy to inform you that the password request was execute successfully for your account.
+
+Best regards.
\ No newline at end of file

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/confirmPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm (added)
+++ syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm Fri Sep 19 08:53:24 2014
@@ -0,0 +1,31 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<html>
+<body>
+<p>Hi,
+a password reset was request for $user.getUsername().</p>
+
+<p>In order to complete this request, you need to provide the token<br/><br/>
+$input.get(0)</p>
+
+<p>If you did not request this reset, just ignore the present e-mail.</p>
+
+<p>Best regards.</p>
+</body>
+</html>
\ No newline at end of file

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.html.vm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm (added)
+++ syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm Fri Sep 19 08:53:24 2014
@@ -0,0 +1,26 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+Hi,
+a password reset was request for $user.getUsername().
+
+In order to complete this request, you need to provide the token 
+
+$input.get(0)
+
+If you did not request this reset, just ignore the present e-mail.
+
+Best regards.
\ No newline at end of file

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/main/resources/mailTemplates/requestPasswordReset.txt.vm
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/branches/1_2_X/core/src/main/resources/userWorkflow.bpmn20.xml
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/main/resources/userWorkflow.bpmn20.xml?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/main/resources/userWorkflow.bpmn20.xml (original)
+++ syncope/branches/1_2_X/core/src/main/resources/userWorkflow.bpmn20.xml Fri Sep 19 08:53:24 2014
@@ -31,6 +31,7 @@ under the License.
     <startEvent id="theStart"/>
     <sequenceFlow id="flow1" sourceRef="theStart" targetRef="create"/>
     <serviceTask id="create" name="Create" activiti:expression="#{create.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8" sourceRef="create" targetRef="active"/>
     <userTask id="active" name="Active"/>
     <sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/>
     <exclusiveGateway id="activeGw"/>
@@ -42,8 +43,15 @@ under the License.
     </sequenceFlow>
     <sequenceFlow id="active2Delete" sourceRef="activeGw" targetRef="delete">
       <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'delete'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2RequestPasswordReset" sourceRef="activeGw" targetRef="generateToken4PasswordReset">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'requestPasswordReset'}]]></conditionExpression>
+    </sequenceFlow>
+    <sequenceFlow id="active2ConfirmPasswordReset" sourceRef="activeGw" targetRef="checkToken4ConfirmPasswordReset">
+      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${task == 'confirmPasswordReset'}]]></conditionExpression>
     </sequenceFlow>    
     <serviceTask id="update" name="Update" activiti:expression="#{update.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" sourceRef="update" targetRef="active"/>
     <serviceTask id="suspend" name="Suspend" activiti:expression="#{suspend.execute(execution.processInstanceId)}"/>
     <sequenceFlow id="flow10" sourceRef="suspend" targetRef="suspended"/>
     <userTask id="suspended" name="Suspended"/>
@@ -57,11 +65,20 @@ under the License.
     </sequenceFlow>
     <serviceTask id="reactivate" name="Reactivate" activiti:expression="#{reactivate.execute(execution.processInstanceId)}"/>
     <sequenceFlow id="flow12" sourceRef="reactivate" targetRef="active"/>
+    
+    <serviceTask id="generateToken4PasswordReset" name="Generate Token" activiti:expression="#{generateToken.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7" sourceRef="generateToken4PasswordReset" targetRef="notify4RequestPasswordReset"/>
+    <serviceTask id="notify4RequestPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F" sourceRef="notify4RequestPasswordReset" targetRef="active"/>
+
+    <serviceTask id="checkToken4ConfirmPasswordReset" name="Check token, remove and update password" activiti:expression="#{passwordReset.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6" sourceRef="checkToken4ConfirmPasswordReset" targetRef="notify4ConfirmPasswordReset"/>
+    <serviceTask id="notify4ConfirmPasswordReset" name="Notification" activiti:expression="#{notify.execute(execution.processInstanceId)}"/>
+    <sequenceFlow id="sid-A37806A7-6B7B-48A2-BB37-DAE640231144" sourceRef="notify4ConfirmPasswordReset" targetRef="active"/>    
+    
     <serviceTask id="delete" name="Delete" activiti:expression="#{delete.execute(execution.processInstanceId)}"/>
     <sequenceFlow id="flow99" sourceRef="delete" targetRef="theEnd"/>
-    <endEvent id="theEnd"/>
-    <sequenceFlow id="sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8" sourceRef="create" targetRef="active"/>
-    <sequenceFlow id="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" sourceRef="update" targetRef="active"/>
+    <endEvent id="theEnd"/>    
   </process>
   
   <bpmndi:BPMNDiagram id="BPMNDiagram_userWorkflow">
@@ -79,16 +96,16 @@ under the License.
         <omgdc:Bounds height="40.0" width="40.0" x="1400.0" y="520.0"/>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="update" id="BPMNShape_update">
-        <omgdc:Bounds height="60.0" width="100.0" x="1370.0" y="740.7407688427132"/>
+        <omgdc:Bounds height="60.0" width="100.0" x="1370.0" y="615.0"/>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="suspend" id="BPMNShape_suspend">
-        <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="280.0"/>
+        <omgdc:Bounds height="60.0" width="100.0" x="1490.0" y="370.0"/>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="suspended" id="BPMNShape_suspended">
-        <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="300.0"/>
+        <omgdc:Bounds height="60.0" width="100.0" x="1640.0" y="370.0"/>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="suspendedGw" id="BPMNShape_suspendedGw">
-        <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="360.0"/>
+        <omgdc:Bounds height="40.0" width="40.0" x="1820.0" y="380.0"/>
       </bpmndi:BPMNShape>
       <bpmndi:BPMNShape bpmnElement="reactivate" id="BPMNShape_reactivate">
         <omgdc:Bounds height="60.0" width="100.0" x="1940.0" y="290.0"/>
@@ -99,71 +116,106 @@ under the License.
       <bpmndi:BPMNShape bpmnElement="theEnd" id="BPMNShape_theEnd">
         <omgdc:Bounds height="28.0" width="28.0" x="2080.0" y="451.0"/>
       </bpmndi:BPMNShape>
-      <bpmndi:BPMNEdge bpmnElement="sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8" id="BPMNEdge_sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8">
-        <omgdi:waypoint x="920.0" y="540.2380952380952"/>
-        <omgdi:waypoint x="1030.0" y="540.7619047619048"/>
-      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNShape bpmnElement="generateToken4PasswordReset" id="BPMNShape_generateToken4PasswordReset">
+        <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="604.5"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="notify4RequestPasswordReset" id="BPMNShape_notify4RequestPasswordReset">
+        <omgdc:Bounds height="81.0" width="121.0" x="1515.0" y="750.0"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="checkToken4ConfirmPasswordReset" id="BPMNShape_checkToken4ConfirmPasswordReset">
+        <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="664.5"/>
+      </bpmndi:BPMNShape>
+      <bpmndi:BPMNShape bpmnElement="notify4ConfirmPasswordReset" id="BPMNShape_notify4ConfirmPasswordReset">
+        <omgdc:Bounds height="81.0" width="121.0" x="1725.0" y="810.0"/>
+      </bpmndi:BPMNShape>
       <bpmndi:BPMNEdge bpmnElement="flow12" id="BPMNEdge_flow12">
-        <omgdi:waypoint x="1940.0" y="312.6007228007171"/>
-        <omgdi:waypoint x="1470.3246893147616" y="243.09556645232908"/>
-        <omgdi:waypoint x="1198.7197373159865" y="359.6936452281102"/>
-        <omgdi:waypoint x="1099.6440556314785" y="511.0"/>
+        <omgdi:waypoint x="1990.0" y="290.0"/>
+        <omgdi:waypoint x="1990.0" y="261.0"/>
+        <omgdi:waypoint x="1080.0" y="261.0"/>
+        <omgdi:waypoint x="1080.0" y="511.0"/>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="flow11" id="BPMNEdge_flow11">
-        <omgdi:waypoint x="1740.0" y="330.0"/>
-        <omgdi:waypoint x="1752.0" y="330.0"/>
-        <omgdi:waypoint x="1752.0" y="380.0"/>
-        <omgdi:waypoint x="1820.0" y="380.0"/>
+        <omgdi:waypoint x="1740.0" y="400.0"/>
+        <omgdi:waypoint x="1820.0" y="400.0"/>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="flow10" id="BPMNEdge_flow10">
-        <omgdi:waypoint x="1590.0" y="310.0"/>
-        <omgdi:waypoint x="1602.0" y="310.0"/>
-        <omgdi:waypoint x="1602.0" y="330.0"/>
-        <omgdi:waypoint x="1640.0" y="330.0"/>
+        <omgdi:waypoint x="1590.0" y="400.0"/>
+        <omgdi:waypoint x="1640.0" y="400.0"/>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update">
-        <omgdi:waypoint x="1420.4586490458448" y="559.5413509541552"/>
-        <omgdi:waypoint x="1420.0651491917588" y="740.7407688427132"/>
+      <bpmndi:BPMNEdge bpmnElement="active2RequestPasswordReset" id="BPMNEdge_active2RequestPasswordReset">
+        <omgdi:waypoint x="1439.5" y="540.5"/>
+        <omgdi:waypoint x="1575.5" y="540.5"/>
+        <omgdi:waypoint x="1575.5" y="604.5"/>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" id="BPMNEdge_sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C">
-        <omgdi:waypoint x="1370.0" y="770.7407688427132"/>
-        <omgdi:waypoint x="1080.0" y="770.7407688427132"/>
+      <bpmndi:BPMNEdge bpmnElement="active2Suspend" id="BPMNEdge_active2Suspend">
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1540.0" y="540.0"/>
+        <omgdi:waypoint x="1540.0" y="430.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="suspended2Delete" id="BPMNEdge_suspended2Delete">
+        <omgdi:waypoint x="1860.0" y="400.0"/>
+        <omgdi:waypoint x="1990.0" y="400.0"/>
+        <omgdi:waypoint x="1990.0" y="438.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-A37806A7-6B7B-48A2-BB37-DAE640231144" id="BPMNEdge_sid-A37806A7-6B7B-48A2-BB37-DAE640231144">
+        <omgdi:waypoint x="1725.0" y="850.5"/>
+        <omgdi:waypoint x="1080.0" y="850.5"/>
         <omgdi:waypoint x="1080.0" y="571.0"/>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="active2Delete" id="BPMNEdge_active2Delete">
-        <omgdi:waypoint x="1439.5" y="540.5"/>
-        <omgdi:waypoint x="1990.0" y="540.5"/>
+        <omgdi:waypoint x="1440.0" y="540.0"/>
+        <omgdi:waypoint x="1990.0" y="540.0"/>
         <omgdi:waypoint x="1990.0" y="498.0"/>
       </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6" id="BPMNEdge_sid-3E9FE01D-CC60-4A95-B356-CA0DC000FAD6">
+        <omgdi:waypoint x="1785.5" y="745.5"/>
+        <omgdi:waypoint x="1785.5" y="810.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7" id="BPMNEdge_sid-7F78CE07-A7A1-467F-BB4B-40FB234AEFF7">
+        <omgdi:waypoint x="1575.5" y="685.5"/>
+        <omgdi:waypoint x="1575.5" y="750.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8" id="BPMNEdge_sid-EA94A12A-727F-414B-9D7E-AC576B0D6FA8">
+        <omgdi:waypoint x="920.0" y="540.2380952380952"/>
+        <omgdi:waypoint x="1030.0" y="540.7619047619048"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C" id="BPMNEdge_sid-EA22026A-25F0-4ED0-AB6E-9CE9CE74623C">
+        <omgdi:waypoint x="1370.0" y="645.0"/>
+        <omgdi:waypoint x="1080.0" y="645.0"/>
+        <omgdi:waypoint x="1080.0" y="571.0"/>
+      </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
         <omgdi:waypoint x="770.0" y="540.0"/>
         <omgdi:waypoint x="820.0" y="540.0"/>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="suspended2Delete" id="BPMNEdge_suspended2Delete">
-        <omgdi:waypoint x="1860.0" y="380.0"/>
-        <omgdi:waypoint x="1902.0" y="380.0"/>
-        <omgdi:waypoint x="1980.0" y="388.0"/>
-        <omgdi:waypoint x="1986.25" y="438.0"/>
+      <bpmndi:BPMNEdge bpmnElement="sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F" id="BPMNEdge_sid-CF9ACA40-7750-47C3-A508-7250D24D4F1F">
+        <omgdi:waypoint x="1515.0" y="790.5"/>
+        <omgdi:waypoint x="1080.0" y="790.5"/>
+        <omgdi:waypoint x="1080.0" y="571.0"/>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="suspended2Reactivate" id="BPMNEdge_suspended2Reactivate">
-        <omgdi:waypoint x="1860.0" y="380.0"/>
-        <omgdi:waypoint x="1902.0" y="380.0"/>
+        <omgdi:waypoint x="1860.0" y="400.0"/>
+        <omgdi:waypoint x="1902.0" y="400.0"/>
         <omgdi:waypoint x="1902.0" y="320.0"/>
         <omgdi:waypoint x="1940.0" y="320.0"/>
       </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="active2Suspend" id="BPMNEdge_active2Suspend">
+      <bpmndi:BPMNEdge bpmnElement="active2ConfirmPasswordReset" id="BPMNEdge_active2ConfirmPasswordReset">
         <omgdi:waypoint x="1439.5" y="540.5"/>
-        <omgdi:waypoint x="1540.0" y="540.5"/>
-        <omgdi:waypoint x="1540.0" y="340.0"/>
-      </bpmndi:BPMNEdge>
-      <bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99">
-        <omgdi:waypoint x="2040.0" y="466.5576923076923"/>
-        <omgdi:waypoint x="2080.005821071606" y="465.40367823831906"/>
+        <omgdi:waypoint x="1785.5" y="540.5"/>
+        <omgdi:waypoint x="1785.5" y="664.5"/>
       </bpmndi:BPMNEdge>
       <bpmndi:BPMNEdge bpmnElement="flow8" id="BPMNEdge_flow8">
         <omgdi:waypoint x="1130.0" y="540.8529411764706"/>
         <omgdi:waypoint x="1400.058651026393" y="540.0586510263929"/>
       </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="active2Update" id="BPMNEdge_active2Update">
+        <omgdi:waypoint x="1420.0" y="560.0"/>
+        <omgdi:waypoint x="1420.0" y="615.0"/>
+      </bpmndi:BPMNEdge>
+      <bpmndi:BPMNEdge bpmnElement="flow99" id="BPMNEdge_flow99">
+        <omgdi:waypoint x="2040.0" y="466.5576923076923"/>
+        <omgdi:waypoint x="2080.005821071606" y="465.40367823831906"/>
+      </bpmndi:BPMNEdge>
     </bpmndi:BPMNPlane>
   </bpmndi:BPMNDiagram>
 </definitions>
\ No newline at end of file

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/connid/PasswordGeneratorTest.java Fri Sep 19 08:53:24 2014
@@ -55,7 +55,7 @@ public class PasswordGeneratorTest exten
         }
         assertNotNull(password);
 
-        user.setPassword(password, CipherAlgorithm.AES, 0);
+        user.setPassword(password, CipherAlgorithm.AES);
 
         SyncopeUser actual = userDAO.save(user);
         assertNotNull(actual);
@@ -73,7 +73,7 @@ public class PasswordGeneratorTest exten
             fail(ex.getMessage());
         }
         assertNotNull(password);
-        user.setPassword(password, CipherAlgorithm.SHA, 0);
+        user.setPassword(password, CipherAlgorithm.SHA);
         userDAO.save(user);
     }
 

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java Fri Sep 19 08:53:24 2014
@@ -41,7 +41,7 @@ public class EntitlementTest extends Abs
     @Test
     public void findAll() {
         List<Entitlement> list = entitlementDAO.findAll();
-        assertEquals("did not get expected number of entitlements ", 84, list.size());
+        assertEquals("did not get expected number of entitlements ", 89, list.size());
     }
 
     @Test

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/NotificationTest.java Fri Sep 19 08:53:24 2014
@@ -37,7 +37,7 @@ public class NotificationTest extends Ab
 
     @Test
     public void find() {
-        Notification notification = notificationDAO.find(1L);
+        Notification notification = notificationDAO.find(10L);
         assertNotNull(notification);
         assertNotNull(notification.getEvents());
         assertFalse(notification.getEvents().isEmpty());
@@ -77,8 +77,8 @@ public class NotificationTest extends Ab
 
     @Test
     public void delete() {
-        notificationDAO.delete(1L);
-        assertNull(notificationDAO.find(1L));
+        notificationDAO.delete(10L);
+        assertNull(notificationDAO.find(10L));
     }
 
     @Test

Added: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java (added)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.dao;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.List;
+import org.apache.syncope.core.persistence.beans.SecurityQuestion;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class SecurityQuestionTest extends AbstractDAOTest {
+
+    @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Test
+    public void find() {
+        SecurityQuestion securityQuestion = securityQuestionDAO.find(1L);
+        assertNotNull(securityQuestion);
+        assertNotNull(securityQuestion.getContent());
+    }
+
+    @Test
+    public void findAll() {
+        List<SecurityQuestion> securityQuestions = securityQuestionDAO.findAll();
+        assertNotNull(securityQuestions);
+        assertFalse(securityQuestions.isEmpty());
+    }
+
+    @Test
+    public void save() {
+        SecurityQuestion securityQuestion = new SecurityQuestion();
+        securityQuestion.setContent("What is your favorite pet's name?");
+        
+        SecurityQuestion actual = securityQuestionDAO.save(securityQuestion);
+        assertNotNull(actual);
+        assertNotNull(actual.getId());
+    }
+
+    @Test
+    public void delete() {
+        securityQuestionDAO.delete(1L);
+        assertNull(securityQuestionDAO.find(1L));
+    }
+}

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/dao/UserTest.java Fri Sep 19 08:53:24 2014
@@ -138,7 +138,7 @@ public class UserTest extends AbstractDA
         user.setUsername("username");
         user.setCreationDate(new Date());
 
-        user.setPassword("pass", CipherAlgorithm.SHA256, 0);
+        user.setPassword("pass", CipherAlgorithm.SHA256);
 
         Throwable t = null;
         try {
@@ -148,7 +148,7 @@ public class UserTest extends AbstractDA
         }
         assertNotNull(t);
 
-        user.setPassword("password", CipherAlgorithm.SHA256, 1);
+        user.setPassword("password", CipherAlgorithm.SHA256);
 
         user.setUsername("username!");
 
@@ -183,7 +183,7 @@ public class UserTest extends AbstractDA
         user.setUsername("username");
         user.setCreationDate(new Date());
 
-        user.setPassword("password", CipherAlgorithm.AES, 0);
+        user.setPassword("password", CipherAlgorithm.AES);
 
         SyncopeUser actual = userDAO.save(user);
         assertNotNull(actual);
@@ -193,7 +193,7 @@ public class UserTest extends AbstractDA
     public void issueSYNCOPE391() {
         SyncopeUser user = new SyncopeUser();
         user.setUsername("username");
-        user.setPassword(null, CipherAlgorithm.AES, 0);
+        user.setPassword(null, CipherAlgorithm.AES);
 
         SyncopeUser actual = null;
         Throwable t = null;

Added: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java (added)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.relationships;
+
+import static org.junit.Assert.assertNull;
+
+import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
+import org.apache.syncope.core.persistence.dao.AbstractDAOTest;
+import org.apache.syncope.core.persistence.dao.SecurityQuestionDAO;
+import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+@Transactional
+public class SecurityQuestionTest extends AbstractDAOTest {
+
+    @Autowired
+    private SecurityQuestionDAO securityQuestionDAO;
+
+    @Autowired
+    private UserDAO userDAO;
+
+    @Test
+    public void test() {
+        SyncopeUser user = userDAO.find(4L);
+
+        user.setSecurityQuestion(securityQuestionDAO.find(1L));
+        user.setSecurityAnswer("Rossi");
+        userDAO.save(user);
+
+        userDAO.flush();
+
+        securityQuestionDAO.delete(1L);
+
+        userDAO.flush();
+
+        user = userDAO.find(4L);
+
+        assertNull(user.getSecurityQuestion());
+    }
+}

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/persistence/relationships/SecurityQuestionTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/AbstractTest.java Fri Sep 19 08:53:24 2014
@@ -33,7 +33,6 @@ import javax.ws.rs.core.Response;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.cxf.jaxrs.client.WebClient;
-
 import org.apache.syncope.client.SyncopeClient;
 import org.apache.syncope.client.SyncopeClientFactoryBean;
 import org.apache.syncope.common.mod.AttributeMod;
@@ -49,6 +48,7 @@ import org.apache.syncope.common.service
 import org.apache.syncope.common.services.ResourceService;
 import org.apache.syncope.common.services.RoleService;
 import org.apache.syncope.common.services.SchemaService;
+import org.apache.syncope.common.services.SecurityQuestionService;
 import org.apache.syncope.common.services.TaskService;
 import org.apache.syncope.common.services.UserSelfService;
 import org.apache.syncope.common.services.UserService;
@@ -172,9 +172,11 @@ public abstract class AbstractTest {
 
     protected static PolicyService policyService;
 
+    protected static SecurityQuestionService securityQuestionService;
+
     @Autowired
     protected DataSource testDataSource;
-    
+
     @BeforeClass
     public static void securitySetup() {
         InputStream propStream = null;
@@ -220,6 +222,7 @@ public abstract class AbstractTest {
         workflowService = adminClient.getService(WorkflowService.class);
         notificationService = adminClient.getService(NotificationService.class);
         schemaService = adminClient.getService(SchemaService.class);
+        securityQuestionService = adminClient.getService(SecurityQuestionService.class);
     }
 
     protected static String getUUIDString() {
@@ -243,7 +246,7 @@ public abstract class AbstractTest {
     protected UserTO createUser(final UserTO userTO) {
         return createUser(userTO, true);
     }
-    
+
     protected UserTO createUser(final UserTO userTO, final boolean storePassword) {
         Response response = userService.create(userTO, storePassword);
         if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/NotificationTestITCase.java Fri Sep 19 08:53:24 2014
@@ -59,7 +59,7 @@ public class NotificationTestITCase exte
 
     @Test
     public void read() {
-        NotificationTO notificationTO = notificationService.read(1L);
+        NotificationTO notificationTO = notificationService.read(10L);
         assertNotNull(notificationTO);
     }
 
@@ -90,7 +90,7 @@ public class NotificationTestITCase exte
 
     @Test
     public void update() {
-        NotificationTO notificationTO = notificationService.read(1L);
+        NotificationTO notificationTO = notificationService.read(10L);
         notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
 
         notificationService.update(notificationTO.getId(), notificationTO);

Added: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java?rev=1626148&view=auto
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java (added)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java Fri Sep 19 08:53:24 2014
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.rest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.services.SecurityQuestionService;
+import org.apache.syncope.common.to.SecurityQuestionTO;
+import org.apache.syncope.common.types.ClientExceptionType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SecurityQuestionTestITCase extends AbstractTest {
+
+    @Test
+    public void read() {
+        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
+        assertNotNull(securityQuestionTO);
+    }
+
+    @Test
+    public void list() {
+        List<SecurityQuestionTO> securityQuestionTOs = securityQuestionService.list();
+        assertNotNull(securityQuestionTOs);
+        assertFalse(securityQuestionTOs.isEmpty());
+        for (SecurityQuestionTO instance : securityQuestionTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void create() {
+        SecurityQuestionTO securityQuestionTO = new SecurityQuestionTO();
+        securityQuestionTO.setContent("What is your favorite pet's name?");
+
+        Response response = securityQuestionService.create(securityQuestionTO);
+        SecurityQuestionTO actual = getObject(response.getLocation(), SecurityQuestionService.class,
+                SecurityQuestionTO.class);
+
+        assertNotNull(actual);
+        assertNotNull(actual.getId());
+        securityQuestionTO.setId(actual.getId());
+        assertEquals(actual, securityQuestionTO);
+    }
+
+    @Test
+    public void update() {
+        SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
+        securityQuestionTO.setContent("What is your favorite color?");
+
+        securityQuestionService.update(securityQuestionTO.getId(), securityQuestionTO);
+        SecurityQuestionTO actual = securityQuestionService.read(securityQuestionTO.getId());
+        assertNotNull(actual);
+        assertEquals(actual, securityQuestionTO);
+    }
+
+    @Test
+    public void delete() {
+        SecurityQuestionTO securityQuestion = new SecurityQuestionTO();
+        securityQuestion.setContent("What is your first pet's name?");
+
+        Response response = securityQuestionService.create(securityQuestion);
+        securityQuestion = getObject(response.getLocation(), SecurityQuestionService.class, SecurityQuestionTO.class);
+
+        securityQuestionService.delete(securityQuestion.getId());
+
+        try {
+            securityQuestionService.read(securityQuestion.getId());
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        }
+    }
+
+}

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/SecurityQuestionTestITCase.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserSelfTestITCase.java Fri Sep 19 08:53:24 2014
@@ -21,6 +21,7 @@ package org.apache.syncope.core.rest;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
@@ -248,4 +249,48 @@ public class UserSelfTestITCase extends 
         assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
         assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
     }
+
+    @Test
+    public void passwordReset() {
+        // 1. create an user with security question and answer
+        UserTO user = UserTestITCase.getUniqueSampleTO("pwdReset@syncope.apache.org");
+        user.setSecurityQuestion(1L);
+        user.setSecurityAnswer("Rossi");
+        createUser(user);
+
+        // 2. verify that new user is able to authenticate
+        SyncopeClient authClient = clientFactory.create(user.getUsername(), "password123");
+        UserTO read = authClient.getService(UserSelfService.class).read();
+        assertNotNull(read);
+
+        // 3. request password reset (as anonymous) providing the expected security answer
+        SyncopeClient anonClient = clientFactory.createAnonymous();
+        try {
+            anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "WRONG");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidSecurityAnswer, e.getType());
+        }
+        anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), "Rossi");
+
+        // 4. get token (normally sent via e-mail, now reading as admin)
+        String token = userService.read(read.getId()).getToken();
+        assertNotNull(token);
+
+        // 5. confirm password reset
+        try {
+            anonClient.getService(UserSelfService.class).confirmPasswordReset("WRONG TOKEN", "newPassword");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+            assertTrue(e.getMessage().contains("WRONG TOKEN"));
+        }
+        anonClient.getService(UserSelfService.class).confirmPasswordReset(token, "newPassword");
+
+        // 6. verify that password was reset and token removed
+        authClient = clientFactory.create(user.getUsername(), "newPassword");
+        read = authClient.getService(UserSelfService.class).read();
+        assertNotNull(read);
+        assertNull(read.getToken());
+    }
 }

Modified: syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java (original)
+++ syncope/branches/1_2_X/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java Fri Sep 19 08:53:24 2014
@@ -705,7 +705,7 @@ public class UserTestITCase extends Abst
         assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
 
         SyncopeUser passwordTestUser = new SyncopeUser();
-        passwordTestUser.setPassword("new2Password", CipherAlgorithm.SHA, 0);
+        passwordTestUser.setPassword("new2Password", CipherAlgorithm.SHA);
         assertEquals(passwordTestUser.getPassword(), userTO.getPassword());
 
         assertEquals(1, userTO.getMemberships().size());

Modified: syncope/branches/1_2_X/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/resources/content.xml?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/resources/content.xml (original)
+++ syncope/branches/1_2_X/core/src/test/resources/content.xml Fri Sep 19 08:53:24 2014
@@ -54,11 +54,16 @@ under the License.
   <CAttr id="6" owner_id="1" schema_name="selfRegistration.allowed"/>
   <CAttrValue id="6" attribute_id="6" booleanValue="1"/>
 
+  <CSchema name="passwordReset.allowed" type="Boolean"
+           mandatoryCondition="true" multivalue="0" uniqueConstraint="0" readonly="0"/>
+  <CAttr id="7" owner_id="1" schema_name="passwordReset.allowed"/>
+  <CAttrValue id="7" attribute_id="7" booleanValue="1"/>
+
   <CSchema name="authentication.statuses" type="String"
            mandatoryCondition="true" multivalue="1" uniqueConstraint="0" readonly="0"/>
-  <CAttr id="7" owner_id="1" schema_name="authentication.statuses"/>
-  <CAttrValue id="7" attribute_id="7" stringValue="created"/>
-  <CAttrValue id="8" attribute_id="7" stringValue="active"/>
+  <CAttr id="8" owner_id="1" schema_name="authentication.statuses"/>
+  <CAttrValue id="8" attribute_id="8" stringValue="created"/>
+  <CAttrValue id="9" attribute_id="8" stringValue="active"/>
 
   <!-- Save user login date upon successful authentication -->
   <CSchema name="log.lastlogindate" type="Boolean"
@@ -68,7 +73,7 @@ under the License.
 
   <!-- sample policies -->
   <Policy DTYPE="SyncPolicy" id="1" description="global sync policy" type="GLOBAL_SYNC" 
-          specification='{"userJavaRule":null,"roleJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],":q!AltSearchSchemas":[]}'/>
+          specification='{"userJavaRule":null,"roleJavaRule":null,"conflictResolutionAction":"IGNORE","userAltSearchSchemas":[],"AltSearchSchemas":[]}'/>
   <Policy DTYPE="PasswordPolicy" id="2" description="global password policy" type="GLOBAL_PASSWORD" 
           specification='{"historyLength":1,"maxLength":0,"minLength":8,"nonAlphanumericRequired":false,"alphanumericRequired":false,"digitRequired":false,"lowercaseRequired":false,"uppercaseRequired":false,"mustStartWithDigit":false,"mustntStartWithDigit":false,"mustEndWithDigit":false,"mustntEndWithDigit":false,"mustStartWithNonAlpha":false,"mustStartWithAlpha":false,"mustntStartWithNonAlpha":false,"mustntStartWithAlpha":false,"mustEndWithNonAlpha":false,"mustEndWithAlpha":false,"mustntEndWithNonAlpha":false,"mustntEndWithAlpha":false,"wordsNotPermitted":[],"schemasNotPermitted":[],"prefixesNotPermitted":["notpermitted1","notpermitted2"],"suffixesNotPermitted":[],"allowNullPassword":true}'/>
   <Policy DTYPE="SyncPolicy" id="3" description="sync policy 2" type="SYNC" 
@@ -965,15 +970,26 @@ under the License.
         performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
         jobClassName="org.apache.syncope.core.sync.impl.SyncJob" unmatchingRule="ASSIGN" matchingRule="IGNORE"/>
 
-  <Notification id="1" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" traceLevel="ALL"
+  <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset request" template="requestPasswordReset" 
+                traceLevel="FAILURES" userAbout="token!=$null"/> 
+  <Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[requestPasswordReset]:[SUCCESS]"/>
+  
+  <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1" 
+                sender="admin@syncope.apache.org" subject="Password Reset successful" template="confirmPasswordReset" 
+                traceLevel="FAILURES" userAbout="token!=$null"/> 
+  <Notification_events Notification_id="2" events="[CUSTOM]:[]:[]:[confirmPasswordReset]:[SUCCESS]"/>
+
+  <Notification id="10" sender="test@syncope.apache.org" subject="Test subject" template="test" selfAsRecipient="0" 
+                traceLevel="FAILURES"
                 userAbout="fullname==*o*;fullname==*i*"
                 recipients="$roles==7"
                 recipientAttrType="UserSchema" recipientAttrName="email" active="1"/>
-  <Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]"/>
-  <Notification_events Notification_id="1" events="[CUSTOM]:[]:[]:[unexisting2]:[SUCCESS]"/>
+  <Notification_events Notification_id="10" events="[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]"/>
+  <Notification_events Notification_id="10" events="[CUSTOM]:[]:[]:[unexisting2]:[SUCCESS]"/>
     
-  <NotificationTask_recipients notificationtask_id="8" address="recipient@prova.org"/>
-
+  <NotificationTask_recipients notificationtask_id="8" address="recipient@prova.org"/>  
+  
   <Report id="1" name="test"/>
   <ReportletConfInstance id="1" Report_id="1" 
                          serializedInstance='{"@class":"org.apache.syncope.common.report.UserReportletConf","name":"testUserReportlet","matchingCond":null,"attributes":["fullname","gender"],"derivedAttributes":["cn"],"virtualAttributes":["virtualdata"],"features":["id","username","workflowId","status","creationDate","lastLoginDate","changePwdDate","passwordHistorySize","failedLoginCount","memberships","resources"]}'/>
@@ -1067,6 +1083,11 @@ under the License.
   <Entitlement name="AUDIT_LIST"/>
   <Entitlement name="AUDIT_ENABLE"/>
   <Entitlement name="AUDIT_DISABLE"/>
+  <Entitlement name="SECURITY_QUESTION_LIST"/>
+  <Entitlement name="SECURITY_QUESTION_READ"/>
+  <Entitlement name="SECURITY_QUESTION_CREATE"/>
+  <Entitlement name="SECURITY_QUESTION_UPDATE"/>
+  <Entitlement name="SECURITY_QUESTION_DELETE"/>
   <Entitlement name="ROLE_1"/>
   <Entitlement name="ROLE_2"/>
   <Entitlement name="ROLE_3"/>
@@ -1098,4 +1119,6 @@ under the License.
   <SyncopeRole_Entitlement entitlement_name="SCHEMA_READ" role_id="8"/>
   <SyncopeRole_Entitlement entitlement_name="ROLE_READ" role_id="8"/>
   <SyncopeRole_Entitlement entitlement_name="WORKFLOW_FORM_CLAIM" role_id="8"/>
+  
+  <SecurityQuestion id="1" content="What's your mother's maiden name?"/>
 </dataset>

Modified: syncope/branches/1_2_X/core/src/test/resources/mail.properties
URL: http://svn.apache.org/viewvc/syncope/branches/1_2_X/core/src/test/resources/mail.properties?rev=1626148&r1=1626147&r2=1626148&view=diff
==============================================================================
--- syncope/branches/1_2_X/core/src/test/resources/mail.properties (original)
+++ syncope/branches/1_2_X/core/src/test/resources/mail.properties Fri Sep 19 08:53:24 2014
@@ -21,4 +21,4 @@ smtpPassword=
 smtpProtocol=smtp
 smtpEncoding=UTF-8
 smtpConnectionTimeout=3000
-mailDebug=true
+mailDebug=true
\ No newline at end of file