Author: ilgrosso Date: Wed Jan 30 17:56:47 2013 New Revision: 1440561 URL: http://svn.apache.org/viewvc?rev=1440561&view=rev Log: [SYNCOPE-301] Merge from 1_0_X
Modified: syncope/trunk/ (props changed) syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.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/security/SyncopeAuthenticationProvider.java syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowResult.java syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/TaskTestITCase.java syncope/trunk/core/src/test/resources/content.xml Propchange: syncope/trunk/ ------------------------------------------------------------------------------ Merged /syncope/branches/1_0_X:r1439847-1440543 Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java?rev=1440561&r1=1440560&r2=1440561&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AbstractBaseBean.java Wed Jan 30 17:56:47 2013 @@ -26,7 +26,6 @@ import java.text.SimpleDateFormat; import java.util.Collections; import java.util.HashSet; import java.util.Set; - import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.syncope.common.SyncopeConstants; @@ -69,7 +68,7 @@ public abstract class AbstractBaseBean i * @param property the integer representing a boolean value * @return the boolean value corresponding to the property param */ - public final Boolean isBooleanAsInteger(final Integer property) { + public final boolean isBooleanAsInteger(final Integer property) { return property != null && property == 1; } @@ -99,7 +98,7 @@ public abstract class AbstractBaseBean i } } - return excludeFields.toArray(new String[] {}); + return excludeFields.toArray(new String[]{}); } @Override 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=1440561&r1=1440560&r2=1440561&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 Wed Jan 30 17:56:47 2013 @@ -492,7 +492,7 @@ public class SyncopeUser extends Abstrac } public Boolean isSuspended() { - return isBooleanAsInteger(suspended); + return suspended == null ? null : isBooleanAsInteger(suspended); } private String encodePassword(final String password, final CipherAlgorithm cipherAlgoritm) 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=1440561&r1=1440560&r2=1440561&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 Wed Jan 30 17:56:47 2013 @@ -19,7 +19,6 @@ package org.apache.syncope.core.security; import java.util.Date; - import org.apache.syncope.common.types.AuditElements.AuthenticationSubCategory; import org.apache.syncope.common.types.AuditElements.Category; import org.apache.syncope.common.types.AuditElements.Result; @@ -123,7 +122,7 @@ public class SyncopeAuthenticationProvid } else { user = userDAO.find(username); - if (user != null) { + if (user != null && user.isSuspended() != null) { if (user.isSuspended()) { throw new DisabledException("User " + user.getUsername() + " is suspended"); } Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java?rev=1440561&r1=1440560&r2=1440561&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/SyncopeSyncResultHandler.java Wed Jan 30 17:56:47 2013 @@ -18,14 +18,15 @@ */ package org.apache.syncope.core.sync.impl; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.apache.syncope.common.mod.AbstractAttributableMod; import org.apache.syncope.common.mod.AttributeMod; import org.apache.syncope.common.mod.RoleMod; import org.apache.syncope.common.mod.UserMod; @@ -58,6 +59,7 @@ import org.apache.syncope.core.persisten import org.apache.syncope.core.persistence.dao.SchemaDAO; import org.apache.syncope.core.persistence.dao.UserDAO; import org.apache.syncope.core.persistence.validation.attrvalue.ParsingValidationException; +import org.apache.syncope.core.propagation.PropagationByResource; import org.apache.syncope.core.propagation.PropagationException; import org.apache.syncope.core.propagation.PropagationTaskExecutor; import org.apache.syncope.core.propagation.SyncopeConnector; @@ -449,6 +451,18 @@ public class SyncopeSyncResultHandler im return result; } + protected Boolean readEnabled(final ConnectorObject connectorObject) { + Boolean enabled = null; + if (syncTask.isSyncStatus()) { + Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, connectorObject.getAttributes()); + if (status != null && status.getValue() != null && !status.getValue().isEmpty()) { + enabled = (Boolean) status.getValue().get(0); + } + } + + return enabled; + } + protected List<SyncResult> create(SyncDelta delta, final AttributableUtil attrUtil, final boolean dryRun) throws JobExecutionException { @@ -477,19 +491,7 @@ public class SyncopeSyncResultHandler im } else { try { if (AttributableType.USER == attrUtil.getType()) { - // -------------------------- - // Check for status synchronization ... - // -------------------------- - Boolean enabled = null; - if (syncTask.isSyncStatus()) { - Attribute status = AttributeUtil.find(OperationalAttributes.ENABLE_NAME, - delta.getObject().getAttributes()); - if (status != null && status.getValue() != null && !status.getValue().isEmpty()) { - enabled = (Boolean) status.getValue().get(0); - } - } - // -------------------------- - + Boolean enabled = readEnabled(delta.getObject()); WorkflowResult<Map.Entry<Long, Boolean>> created = uwfAdapter.create((UserTO) subjectTO, true, enabled); @@ -544,9 +546,106 @@ public class SyncopeSyncResultHandler im return Collections.singletonList(result); } + protected void updateUser(final Long id, SyncDelta delta, final boolean dryRun, final SyncResult result) + throws Exception { + + UserTO userTO = userDataBinder.getUserTO(id); + UserMod userMod = connObjectUtil.getAttributableMod( + id, delta.getObject(), userTO, syncTask, AttributableUtil.getInstance(AttributableType.USER)); + + delta = actions.beforeUpdate(this, delta, userTO, userMod); + + if (dryRun) { + return; + } + + WorkflowResult<Map.Entry<Long, Boolean>> updated; + try { + updated = uwfAdapter.update(userMod); + } catch (Exception e) { + LOG.error("Update of user {} failed, trying to sync its status anyway (if configured)", id, e); + + result.setStatus(SyncResult.Status.FAILURE); + result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage()); + + updated = new WorkflowResult<Map.Entry<Long, Boolean>>( + new AbstractMap.SimpleEntry<Long, Boolean>(id, false), new PropagationByResource(), + new HashSet<String>()); + } + + Boolean enabled = readEnabled(delta.getObject()); + if (enabled != null) { + WorkflowResult<Long> enableUpdate = null; + + SyncopeUser user = userDAO.find(id); + enableUpdate = user.isSuspended() == null + ? uwfAdapter.activate(id, null) + : enabled + ? uwfAdapter.reactivate(id) + : uwfAdapter.suspend(id); + + if (enableUpdate != null) { + if (enableUpdate.getPropByRes() != null) { + updated.getPropByRes().merge(enableUpdate.getPropByRes()); + updated.getPropByRes().purge(); + } + updated.getPerformedTasks().addAll(enableUpdate.getPerformedTasks()); + } + } + + List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated, + userMod.getPassword(), + userMod.getVirtualAttributesToBeRemoved(), + userMod.getVirtualAttributesToBeUpdated(), + Collections.singleton(syncTask.getResource().getName())); + + taskExecutor.execute(tasks); + + notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks()); + + userTO = userDataBinder.getUserTO(updated.getResult().getKey()); + + actions.after(this, delta, userTO, result); + } + + protected void updateRole(final Long id, SyncDelta delta, final boolean dryRun, final SyncResult result) + throws Exception { + + RoleTO roleTO = roleDataBinder.getRoleTO(id); + RoleMod roleMod = connObjectUtil.getAttributableMod( + id, delta.getObject(), roleTO, syncTask, AttributableUtil.getInstance(AttributableType.ROLE)); + + delta = actions.beforeUpdate(this, delta, roleTO, roleMod); + + if (dryRun) { + return; + } + + WorkflowResult<Long> updated = rwfAdapter.update(roleMod); + String roleOwner = null; + for (AttributeMod attrMod : roleMod.getAttributesToBeUpdated()) { + if (attrMod.getSchema().isEmpty()) { + roleOwner = attrMod.getValuesToBeAdded().iterator().next(); + } + } + if (roleOwner != null) { + roleOwnerMap.put(updated.getResult(), roleOwner); + } + + List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated, + roleMod.getVirtualAttributesToBeRemoved(), + roleMod.getVirtualAttributesToBeUpdated(), + Collections.singleton(syncTask.getResource().getName())); + + taskExecutor.execute(tasks); + + roleTO = roleDataBinder.getRoleTO(updated.getResult()); + + actions.after(this, delta, roleTO, result); + } + protected List<SyncResult> update(SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil, - final boolean dryRun) - throws JobExecutionException { + final boolean dryRun) throws JobExecutionException { if (!syncTask.isPerformUpdate()) { LOG.debug("SyncTask not configured for update"); @@ -558,79 +657,36 @@ public class SyncopeSyncResultHandler im List<SyncResult> updResults = new ArrayList<SyncResult>(); for (Long id : subjects) { + LOG.debug("About to update {}", id); + final SyncResult result = new SyncResult(); result.setOperation(ResourceOperation.UPDATE); result.setSubjectType(attrUtil.getType()); + result.setStatus(SyncResult.Status.SUCCESS); + result.setId(id); try { - AbstractAttributableTO subjectTO = AttributableType.USER == attrUtil.getType() - ? userDataBinder.getUserTO(id) - : roleDataBinder.getRoleTO(id); - try { - final AbstractAttributableMod mod = connObjectUtil.getAttributableMod( - id, delta.getObject(), subjectTO, syncTask, attrUtil); - delta = actions.beforeUpdate(this, delta, subjectTO, mod); - - result.setStatus(SyncResult.Status.SUCCESS); - result.setId(mod.getId()); - if (mod instanceof UserMod) { - result.setName(((UserMod) mod).getUsername()); - } - if (mod instanceof RoleMod) { - result.setName(((RoleMod) mod).getName()); - } - - if (!dryRun) { - if (AttributableType.USER == attrUtil.getType()) { - WorkflowResult<Map.Entry<Long, Boolean>> updated = uwfAdapter.update((UserMod) mod); - - List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(updated, - ((UserMod) mod).getPassword(), mod.getVirtualAttributesToBeRemoved(), - mod.getVirtualAttributesToBeUpdated(), - Collections.singleton(syncTask.getResource().getName())); - - taskExecutor.execute(tasks); - - notificationManager.createTasks(updated.getResult().getKey(), updated.getPerformedTasks()); - - subjectTO = userDataBinder.getUserTO(updated.getResult().getKey()); - } - if (AttributableType.ROLE == attrUtil.getType()) { - WorkflowResult<Long> updated = rwfAdapter.update((RoleMod) mod); - String roleOwner = null; - for (AttributeMod attrMod : mod.getAttributesToBeUpdated()) { - if (attrMod.getSchema().isEmpty()) { - roleOwner = attrMod.getValuesToBeAdded().iterator().next(); - } - } - if (roleOwner != null) { - roleOwnerMap.put(updated.getResult(), roleOwner); - } - - List<PropagationTask> tasks = propagationManager.getRoleUpdateTaskIds(updated, - mod.getVirtualAttributesToBeRemoved(), mod.getVirtualAttributesToBeUpdated(), - Collections.singleton(syncTask.getResource().getName())); - - taskExecutor.execute(tasks); + if (AttributableType.USER == attrUtil.getType()) { + updateUser(id, delta, dryRun, result); + } - subjectTO = roleDataBinder.getRoleTO(updated.getResult()); - } - } - } catch (PropagationException e) { - LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e); - } catch (Exception e) { - result.setStatus(SyncResult.Status.SUCCESS); - result.setMessage(e.getMessage()); - LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e); + if (AttributableType.ROLE == attrUtil.getType()) { + updateRole(id, delta, dryRun, result); } + } catch (PropagationException e) { + result.setStatus(SyncResult.Status.FAILURE); + result.setMessage(delta.getUid().getUidValue() + "updated but not propagated\n" + e.getMessage()); - actions.after(this, delta, subjectTO, result); - updResults.add(result); - } catch (NotFoundException e) { - LOG.error("Could not find {} {}", attrUtil.getType(), id, e); - } catch (UnauthorizedRoleException e) { - LOG.error("Not allowed to read {} {}", attrUtil.getType(), id, e); + LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e); + } catch (Exception e) { + result.setStatus(SyncResult.Status.FAILURE); + result.setMessage(e.getMessage()); + + LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e); } + results.add(result); + + LOG.debug("{} {} successfully updated", attrUtil.getType(), id); } return updResults; Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowResult.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowResult.java?rev=1440561&r1=1440560&r2=1440561&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowResult.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/WorkflowResult.java Wed Jan 30 17:56:47 2013 @@ -20,7 +20,6 @@ package org.apache.syncope.core.workflow import java.util.Collections; import java.util.Set; - import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ReflectionToStringBuilder; @@ -36,14 +35,12 @@ public class WorkflowResult<T> { private Set<String> performedTasks; public WorkflowResult(final T result, final PropagationByResource propByRes, final String performedTask) { - this.result = result; this.propByRes = propByRes; this.performedTasks = Collections.singleton(performedTask); } public WorkflowResult(final T result, final PropagationByResource propByRes, final Set<String> performedTasks) { - this.result = result; this.propByRes = propByRes; this.performedTasks = performedTasks; Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java?rev=1440561&r1=1440560&r2=1440561&view=diff ============================================================================== --- syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java (original) +++ syncope/trunk/core/src/main/java/org/apache/syncope/core/workflow/user/NoOpUserWorkflowAdapter.java Wed Jan 30 17:56:47 2013 @@ -18,11 +18,11 @@ */ package org.apache.syncope.core.workflow.user; +import java.util.AbstractMap; +import java.util.AbstractMap.SimpleEntry; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.AbstractMap; -import java.util.AbstractMap.SimpleEntry; import java.util.Map; import org.apache.syncope.common.mod.UserMod; import org.apache.syncope.common.to.UserTO; @@ -51,6 +51,7 @@ public class NoOpUserWorkflowAdapter ext @Override public WorkflowResult<Map.Entry<Long, Boolean>> create(final UserTO userTO, final boolean disablePwdPolicyCheck) throws WorkflowException { + return create(userTO, disablePwdPolicyCheck, null); } @@ -62,8 +63,7 @@ public class NoOpUserWorkflowAdapter ext SyncopeUser user = new SyncopeUser(); dataBinder.create(user, userTO); - // this will make SyncopeUserValidator not to consider - // password policies at all + // this will make SyncopeUserValidator not to consider password policies at all if (disablePwdPolicyCheck) { user.removeClearPassword(); } 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=1440561&r1=1440560&r2=1440561&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 Wed Jan 30 17:56:47 2013 @@ -27,9 +27,7 @@ import static org.junit.Assert.assertTru import java.util.Collections; import java.util.List; import java.util.Set; - import javax.ws.rs.core.Response; - import org.apache.syncope.common.search.AttributableCond; import org.apache.syncope.common.search.AttributeCond; import org.apache.syncope.common.search.MembershipCond; @@ -56,7 +54,6 @@ import org.apache.syncope.core.sync.Test import org.apache.syncope.core.sync.impl.SyncJob; import org.apache.syncope.core.workflow.ActivitiDetector; import org.junit.FixMethodOrder; -import org.junit.Ignore; import org.junit.Test; import org.junit.runners.MethodSorters; import org.springframework.http.HttpStatus; @@ -330,11 +327,11 @@ public class TaskTestITCase extends Abst @Test public void reconcileFromDB() { - // Update sync task + // update sync task SyncTaskTO task = taskService.read(TaskType.SYNCHRONIZATION, 7L); assertNotNull(task); - // add user template + // add user template UserTO template = new UserTO(); template.addAttribute(attributeTO("type", "'type a'")); template.addAttribute(attributeTO("userId", "'reconci...@syncope.apache.org'")); @@ -351,14 +348,26 @@ public class TaskTestITCase extends Abst assertEquals(new RoleTO(), actual.getRoleTemplate()); TaskExecTO execution = execSyncTask(actual.getId(), 20, false); + assertNotNull(execution.getStatus()); + assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful()); - final String status = execution.getStatus(); - assertNotNull(status); - assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful()); - - final UserTO userTO = userService.read("testuser1"); + UserTO userTO = userService.read("testuser1"); assertNotNull(userTO); assertEquals("reconci...@syncope.apache.org", userTO.getAttributeMap().get("userId").getValues().get(0)); + assertEquals("suspended", userTO.getStatus()); + + // enable user on external resource + JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource); + jdbcTemplate.execute("UPDATE TEST SET STATUS=TRUE"); + + // re-execute the same SyncTask: now user must be active + execution = execSyncTask(actual.getId(), 20, false); + assertNotNull(execution.getStatus()); + assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful()); + + userTO = userService.read("testuser1"); + assertNotNull(userTO); + assertEquals("active", userTO.getStatus()); } @Test @@ -716,19 +725,17 @@ public class TaskTestITCase extends Abst @Test public void issueSYNCOPE272() { + // create user with testdb resource + UserTO userTO = UserTestITCase.getUniqueSampleTO("syncope...@syncope.apache.org"); + userTO.addResource("resource-testdb"); - //Create user with testdb resource - UserTO userTO = UserTestITCase.getUniqueSampleTO("syncope...@syncope.apache.org"); - userTO.addResource("resource-testdb"); - - userTO = createUser(userTO); - try { - + userTO = createUser(userTO); + try { assertNotNull(userTO); assertEquals(1, userTO.getPropagationStatusTOs().size()); assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful()); - // Update sync task + // update sync task SyncTaskTO task = taskService.read(TaskType.SYNCHRONIZATION, SYNC_TASK_ID); assertNotNull(task); Modified: syncope/trunk/core/src/test/resources/content.xml URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1440561&r1=1440560&r2=1440561&view=diff ============================================================================== --- syncope/trunk/core/src/test/resources/content.xml (original) +++ syncope/trunk/core/src/test/resources/content.xml Wed Jan 30 17:56:47 2013 @@ -42,15 +42,15 @@ under the License. <Policy DTYPE="PasswordPolicy" id="8" description="sample password policy" type="PASSWORD" specification="%3Corg.apache.syncope.common.types.PasswordPolicySpec%3E%0A++%3ChistoryLength%3E0%3C%2FhistoryLength%3E%0A++%3CmaxLength%3E0%3C%2FmaxLength%3E%0A++%3CminLength%3E10%3C%2FminLength%3E%0A++%3CnonAlphanumericRequired%3Etrue%3C%2FnonAlphanumericRequired%3E%0A++%3CalphanumericRequired%3Efalse%3C%2FalphanumericRequired%3E%0A++%3CdigitRequired%3Etrue%3C%2FdigitRequired%3E%0A++%3ClowercaseRequired%3Etrue%3C%2FlowercaseRequired%3E%0A++%3CuppercaseRequired%3Etrue%3C%2FuppercaseRequired%3E%0A++%3CmustStartWithDigit%3Etrue%3C%2FmustStartWithDigit%3E%0A++%3CmustntStartWithDigit%3Efalse%3C%2FmustntStartWithDigit%3E%0A++%3CmustEndWithDigit%3Etrue%3C%2FmustEndWithDigit%3E%0A++%3CmustntEndWithDigit%3Efalse%3C%2FmustntEndWithDigit%3E%0A++%3CmustStartWithNonAlpha%3Efalse%3C%2FmustStartWithNonAlpha%3E%0A++%3CmustStartWithAlpha%3Efalse%3C%2FmustStartWithAlpha%3E%0A++%3CmustntStartWithNonAl pha%3Efalse%3C%2FmustntStartWithNonAlpha%3E%0A++%3CmustntStartWithAlpha%3Efalse%3C%2FmustntStartWithAlpha%3E%0A++%3CmustEndWithNonAlpha%3Efalse%3C%2FmustEndWithNonAlpha%3E%0A++%3CmustEndWithAlpha%3Efalse%3C%2FmustEndWithAlpha%3E%0A++%3CmustntEndWithNonAlpha%3Efalse%3C%2FmustntEndWithNonAlpha%3E%0A++%3CmustntEndWithAlpha%3Efalse%3C%2FmustntEndWithAlpha%3E%0A++%3CprefixesNotPermitted%3E%0A++++%3Cstring%3Enotpermitted1%3C%2Fstring%3E%0A++++%3Cstring%3Enotpermitted2%3C%2Fstring%3E%0A++%3C%2FprefixesNotPermitted%3E%0A%3C%2Forg.apache.syncope.common.types.PasswordPolicySpec%3E"/> <SyncopeUser id="1" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" - username="user1" creationDate="2010-10-20 11:00:00"/> + username="user1" creationDate="2010-10-20 11:00:00" suspended="0"/> <SyncopeUser id="2" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" - username="user2" creationDate="2010-10-20 11:00:00"/> + username="user2" creationDate="2010-10-20 11:00:00" suspended="0"/> <SyncopeUser id="3" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" - username="user3" creationDate="2010-10-20 11:00:00"/> + username="user3" creationDate="2010-10-20 11:00:00" suspended="0"/> <SyncopeUser id="4" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" - username="user4" creationDate="2010-10-20 11:00:00"/> + username="user4" creationDate="2010-10-20 11:00:00" suspended="0"/> <SyncopeUser id="5" workflowId="0" status="active" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" cipherAlgorithm="SHA1" - username="user5" creationDate="2010-10-20 11:00:00"/> + username="user5" creationDate="2010-10-20 11:00:00" suspended="0"/> <SyncopeRole id="1" name="root"/> <SyncopeRole id="2" name="child" parent_id="1"/>