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 2015/01/23 17:41:23 UTC
[01/15] syncope git commit: [SYNCOPE-629] Format + safely delete role
Repository: syncope
Updated Branches:
refs/heads/2_0_X 8e45a8e67 -> 4e1ae7ac9
[SYNCOPE-629] Format + safely delete role
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4efca7c3
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4efca7c3
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4efca7c3
Branch: refs/heads/2_0_X
Commit: 4efca7c3ec3973ab4b774a1f43e4403daf3354b7
Parents: f2d45fd
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jan 21 06:54:34 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jan 21 06:54:34 2015 +0100
----------------------------------------------------------------------
.../core/rest/ConfigurationTestITCase.java | 79 +++++++++++---------
1 file changed, 42 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/4efca7c3/core/src/test/java/org/apache/syncope/core/rest/ConfigurationTestITCase.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/syncope/core/rest/ConfigurationTestITCase.java b/core/src/test/java/org/apache/syncope/core/rest/ConfigurationTestITCase.java
index cbe13d5..1f981ac 100644
--- a/core/src/test/java/org/apache/syncope/core/rest/ConfigurationTestITCase.java
+++ b/core/src/test/java/org/apache/syncope/core/rest/ConfigurationTestITCase.java
@@ -151,22 +151,22 @@ public class ConfigurationTestITCase extends AbstractTest {
assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
}
}
-
+
@Test
- public void issueSYNCOPE629() throws IOException{
+ public void issueSYNCOPE629() throws IOException {
SchemaTO membershipKey = new SchemaTO();
- membershipKey.setName("membershipKey"+getUUIDString());
+ membershipKey.setName("membershipKey" + getUUIDString());
membershipKey.setType(AttributeSchemaType.String);
createSchema(AttributableType.MEMBERSHIP, SchemaType.NORMAL, membershipKey);
-
+
SchemaTO roleKey = new SchemaTO();
- roleKey.setName("roleKey"+getUUIDString());
+ roleKey.setName("roleKey" + getUUIDString());
roleKey.setType(AttributeSchemaType.String);
- createSchema(AttributableType.ROLE, SchemaType.NORMAL, roleKey);
-
+ createSchema(AttributableType.ROLE, SchemaType.NORMAL, roleKey);
+
RoleTO roleTO = new RoleTO();
roleTO.setName("aRole" + getUUIDString());
- roleTO.setParent(8L);
+ roleTO.setParent(8L);
// verify inheritance password and account policies
roleTO.setInheritAccountPolicy(false);
// not inherited so setter execution shouldn't be ignored
@@ -176,39 +176,44 @@ public class ConfigurationTestITCase extends AbstractTest {
roleTO.setPasswordPolicy(2L);
roleTO.getRAttrTemplates().add("icon");
roleTO.getAttrs().add(attributeTO("icon", "anIcon"));
- roleTO.getResources().add(RESOURCE_NAME_LDAP);
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
roleTO.getMAttrTemplates().add(membershipKey.getName());
roleTO.getRAttrTemplates().add(roleKey.getName());
RoleTO testRole = createRole(roleTO);
-
- Response response = configurationService.export();
- assertNotNull(response);
- assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
- assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
- String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
- assertNotNull(contentDisposition);
- Object entity = response.getEntity();
- assertTrue(entity instanceof InputStream);
- String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
- assertFalse(configExport.isEmpty());
- assertTrue(configExport.length() > 1000);
-
- String[] result = StringUtils.substringsBetween(configExport, "<RATTRTEMPLATE", "/>");
- boolean rattrExists = false;
- for(String entry : result){
- if(entry.contains(roleKey.getName())) rattrExists = true;
- }
- assertTrue(rattrExists);
-
- result = StringUtils.substringsBetween(configExport, "<MATTRTEMPLATE", "/>");
- boolean mattrExists = false;
- for(String entry : result){
- if(entry.contains(membershipKey.getName())) mattrExists = true;
+ try {
+ Response response = configurationService.export();
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+ assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+ String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertNotNull(contentDisposition);
+
+ Object entity = response.getEntity();
+ assertTrue(entity instanceof InputStream);
+ String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+ assertFalse(configExport.isEmpty());
+ assertTrue(configExport.length() > 1000);
+
+ String[] result = StringUtils.substringsBetween(configExport, "<RATTRTEMPLATE", "/>");
+ boolean rattrExists = false;
+ for (String entry : result) {
+ if (entry.contains(roleKey.getName())) {
+ rattrExists = true;
+ }
+ }
+ assertTrue(rattrExists);
+
+ result = StringUtils.substringsBetween(configExport, "<MATTRTEMPLATE", "/>");
+ boolean mattrExists = false;
+ for (String entry : result) {
+ if (entry.contains(membershipKey.getName())) {
+ mattrExists = true;
+ }
+ }
+ assertTrue(mattrExists);
+ } finally {
+ deleteRole(testRole.getId());
}
- assertTrue(mattrExists);
-
- deleteRole(testRole.getId());
-
}
}
[13/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
new file mode 100644
index 0000000..9c18a4d
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AuthenticationITCase.java
@@ -0,0 +1,440 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.wrap.EntitlementTO;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.EntitlementService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.server.misc.security.Encryptor;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AuthenticationITCase extends AbstractITCase {
+
+ private int getFailedLogins(UserService testUserService, long userId) {
+ UserTO readUserTO = testUserService.read(userId);
+ assertNotNull(readUserTO);
+ assertNotNull(readUserTO.getFailedLogins());
+ return readUserTO.getFailedLogins();
+ }
+
+ private void assertReadFails(UserService userService, long id) {
+ try {
+ userService.read(id);
+ fail("access should not work");
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void testAdminEntitlements() {
+ // 1. as anonymous, read all available entitlements
+ List<EntitlementTO> allEntitlements = entitlementService.getAllEntitlements();
+ assertNotNull(allEntitlements);
+ assertFalse(allEntitlements.isEmpty());
+
+ // 2. as admin, read own entitlements
+ List<EntitlementTO> adminEntitlements = entitlementService.getOwnEntitlements();
+
+ assertEquals(new HashSet<String>(CollectionWrapper.unwrap(allEntitlements)),
+ new HashSet<String>(CollectionWrapper.unwrap(adminEntitlements)));
+ }
+
+ @Test
+ public void testUserSchemaAuthorization() {
+ // 0. create a role that can only read schemas
+ RoleTO authRoleTO = new RoleTO();
+ authRoleTO.setName("authRole" + getUUIDString());
+ authRoleTO.setParent(8L);
+ authRoleTO.getEntitlements().add("SCHEMA_READ");
+
+ authRoleTO = createRole(authRoleTO);
+ assertNotNull(authRoleTO);
+
+ String schemaName = "authTestSchema" + getUUIDString();
+
+ // 1. create a schema (as admin)
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey(schemaName);
+ schemaTO.setMandatoryCondition("false");
+ schemaTO.setType(AttrSchemaType.String);
+
+ PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ assertEquals(schemaTO, newPlainSchemaTO);
+
+ // 2. create an user with the role created above (as admin)
+ UserTO userTO = UserITCase.getUniqueSampleTO("auth@test.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(authRoleTO.getKey());
+ AttrTO testAttrTO = new AttrTO();
+ testAttrTO.setSchema("testAttribute");
+ testAttrTO.getValues().add("a value");
+ membershipTO.getPlainAttrs().add(testAttrTO);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 3. read the schema created above (as admin) - success
+ schemaTO = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+ assertNotNull(schemaTO);
+
+ // 4. read the schema created above (as user) - success
+ SchemaService schemaService2 = clientFactory.create(userTO.getUsername(), "password123").getService(
+ SchemaService.class);
+
+ schemaTO = schemaService2.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+ assertNotNull(schemaTO);
+
+ // 5. update the schema create above (as user) - failure
+ try {
+ schemaService2.update(AttributableType.ROLE, SchemaType.PLAIN, schemaName, schemaTO);
+ fail("Schemaupdate as user schould not work");
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
+ } catch (AccessControlException e) {
+ // CXF Service will throw this exception
+ assertNotNull(e);
+ }
+
+ assertEquals(0, getFailedLogins(userService, userTO.getKey()));
+ }
+
+ @Test
+ public void testUserRead() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("testuserread@test.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+ AttrTO testAttrTO = new AttrTO();
+ testAttrTO.setSchema("testAttribute");
+ testAttrTO.getValues().add("a value");
+ membershipTO.getPlainAttrs().add(testAttrTO);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+ getService(UserService.class);
+
+ UserTO readUserTO = userService2.read(1L);
+ assertNotNull(readUserTO);
+
+ UserService userService3 = clientFactory.create("verdi", ADMIN_PWD).getService(UserService.class);
+
+ SyncopeClientException exception = null;
+ try {
+ userService3.read(1L);
+ fail();
+ } catch (SyncopeClientException e) {
+ exception = e;
+ }
+ assertNotNull(exception);
+ assertEquals(ClientExceptionType.UnauthorizedRole, exception.getType());
+ }
+
+ @Test
+ public void testUserSearch() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("testusersearch@test.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+ AttrTO testAttrTO = new AttrTO();
+ testAttrTO.setSchema("testAttribute");
+ testAttrTO.getValues().add("a value");
+ membershipTO.getPlainAttrs().add(testAttrTO);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+ getService(UserService.class);
+
+ PagedResult<UserTO> matchedUsers = userService2.search(
+ SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+ assertNotNull(matchedUsers);
+ assertFalse(matchedUsers.getResult().isEmpty());
+ Set<Long> userIds = new HashSet<Long>(matchedUsers.getResult().size());
+ for (UserTO user : matchedUsers.getResult()) {
+ userIds.add(user.getKey());
+ }
+ assertTrue(userIds.contains(1L));
+
+ UserService userService3 = clientFactory.create("verdi", "password").getService(UserService.class);
+
+ matchedUsers = userService3.search(
+ SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+ assertNotNull(matchedUsers);
+
+ userIds = new HashSet<>(matchedUsers.getResult().size());
+
+ for (UserTO user : matchedUsers.getResult()) {
+ userIds.add(user.getKey());
+ }
+ assertFalse(userIds.contains(1L));
+ }
+
+ @Test
+ public void checkFailedLogins() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("checkFailedLogin@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+ AttrTO testAttrTO = new AttrTO();
+ testAttrTO.setSchema("testAttribute");
+ testAttrTO.getValues().add("a value");
+ membershipTO.getPlainAttrs().add(testAttrTO);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ long userId = userTO.getKey();
+
+ UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(
+ UserService.class);
+ assertEquals(0, getFailedLogins(userService2, userId));
+
+ // authentications failed ...
+ UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").getService(
+ UserService.class);
+ assertReadFails(userService3, userId);
+ assertReadFails(userService3, userId);
+
+ assertEquals(2, getFailedLogins(userService, userId));
+
+ UserService userService4 = clientFactory.create(userTO.getUsername(), "password123").getService(
+ UserService.class);
+ assertEquals(0, getFailedLogins(userService4, userId));
+ }
+
+ @Test
+ public void checkUserSuspension() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+ AttrTO testAttrTO = new AttrTO();
+ testAttrTO.setSchema("testAttribute");
+ testAttrTO.getValues().add("a value");
+ membershipTO.getPlainAttrs().add(testAttrTO);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ long userId = userTO.getKey();
+ assertNotNull(userTO);
+
+ UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+ getService(UserService.class);
+ assertEquals(0, getFailedLogins(userService2, userId));
+
+ // authentications failed ...
+ UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").
+ getService(UserService.class);
+ assertReadFails(userService3, userId);
+ assertReadFails(userService3, userId);
+ assertReadFails(userService3, userId);
+
+ assertEquals(3, getFailedLogins(userService, userId));
+
+ // last authentication before suspension
+ assertReadFails(userService3, userId);
+
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ assertNotNull(userTO.getFailedLogins());
+ assertEquals(3, userTO.getFailedLogins(), 0);
+ assertEquals("suspended", userTO.getStatus());
+
+ // Access with correct credentials should fail as user is suspended
+ userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(UserService.class);
+ assertReadFails(userService2, userId);
+
+ StatusMod reactivate = new StatusMod();
+ reactivate.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(userTO.getKey(), reactivate).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(UserService.class);
+ assertEquals(0, getFailedLogins(userService2, userId));
+ }
+
+ @Test
+ public void issueSYNCOPE48() {
+ // Parent role, able to create users with role 1
+ RoleTO parentRole = new RoleTO();
+ parentRole.setName("parentAdminRole" + getUUIDString());
+ parentRole.getEntitlements().add("USER_CREATE");
+ parentRole.getEntitlements().add("ROLE_1");
+ parentRole.setParent(1L);
+ parentRole = createRole(parentRole);
+ assertNotNull(parentRole);
+
+ // Child role, with no entitlements
+ RoleTO childRole = new RoleTO();
+ childRole.setName("childAdminRole");
+ childRole.setParent(parentRole.getKey());
+
+ childRole = createRole(childRole);
+ assertNotNull(childRole);
+
+ // User with child role, created by admin
+ UserTO role1Admin = UserITCase.getUniqueSampleTO("syncope48admin@apache.org");
+ role1Admin.setPassword("password");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(childRole.getKey());
+ role1Admin.getMemberships().add(membershipTO);
+
+ role1Admin = createUser(role1Admin);
+ assertNotNull(role1Admin);
+
+ UserService userService2 = clientFactory.create(role1Admin.getUsername(), "password").getService(
+ UserService.class);
+
+ // User with role 1, created by user with child role created above
+ UserTO role1User = UserITCase.getUniqueSampleTO("syncope48user@apache.org");
+ membershipTO = new MembershipTO();
+ membershipTO.setRoleId(1L);
+ role1User.getMemberships().add(membershipTO);
+
+ Response response = userService2.create(role1User, true);
+ assertNotNull(response);
+ role1User = response.readEntity(UserTO.class);
+ assertNotNull(role1User);
+ }
+
+ @Test
+ public void issueSYNCOPE434() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // 1. create user with role 9 (users with role 9 are defined in workflow as subject to approval)
+ UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(9L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals("createApproval", userTO.getStatus());
+
+ // 2. try to authenticate: fail
+ EntitlementService myEntitlementService = clientFactory.create(userTO.getUsername(), "password123").
+ getService(EntitlementService.class);
+ try {
+ myEntitlementService.getOwnEntitlements();
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ // 3. approve user
+ WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+ form = userWorkflowService.claimForm(form.getTaskId());
+ Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.TRUE.toString());
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+ userTO = userWorkflowService.submitForm(form);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ // 4. try to authenticate again: success
+ assertNotNull(myEntitlementService.getOwnEntitlements());
+ }
+
+ @Test
+ public void issueSYNCOPE164() throws Exception {
+ // 1. create user with db resource
+ UserTO user = UserITCase.getUniqueSampleTO("syncope164@syncope.apache.org");
+ user.setPassword("password1");
+ user.getResources().add(RESOURCE_NAME_TESTDB);
+ user = createUser(user);
+ assertNotNull(user);
+
+ // 2. unlink the resource from the created user
+ assertNotNull(userService.bulkDeassociation(user.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ // 3. change password on Syncope
+ UserMod userMod = new UserMod();
+ userMod.setKey(user.getKey());
+ userMod.setPassword("password2");
+ user = updateUser(userMod);
+ assertNotNull(user);
+
+ // 4. check that the db resource has still the initial password value
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ String value = jdbcTemplate.queryForObject(
+ "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+ assertEquals(Encryptor.getInstance().encode("password1", CipherAlgorithm.SHA1), value.toUpperCase());
+
+ // 5. successfully authenticate with old (on db resource) and new (on internal storage) password values
+ user = clientFactory.create(user.getUsername(), "password1").getService(UserSelfService.class).read();
+ assertNotNull(user);
+ user = clientFactory.create(user.getUsername(), "password2").getService(UserSelfService.class).read();
+ assertNotNull(user);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConfigurationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConfigurationITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConfigurationITCase.java
new file mode 100644
index 0000000..bf35a9c
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConfigurationITCase.java
@@ -0,0 +1,210 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConfTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConfigurationITCase extends AbstractITCase {
+
+ @Test
+ public void create() {
+ PlainSchemaTO testKey = new PlainSchemaTO();
+ testKey.setKey("testKey");
+ testKey.setType(AttrSchemaType.String);
+ createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, testKey);
+
+ AttrTO conf = new AttrTO();
+ conf.setSchema("testKey");
+ conf.getValues().add("testValue");
+
+ configurationService.set(conf.getSchema(), conf);
+
+ AttrTO actual = configurationService.read(conf.getSchema());
+ assertEquals(actual, conf);
+ }
+
+ @Test
+ public void delete() throws UnsupportedEncodingException {
+ try {
+ configurationService.delete("nonExistent");
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+
+ AttrTO tokenLength = configurationService.read("token.length");
+
+ configurationService.delete("token.length");
+ try {
+ configurationService.read("token.length");
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+
+ configurationService.set(tokenLength.getSchema(), tokenLength);
+
+ AttrTO actual = configurationService.read(tokenLength.getSchema());
+ assertEquals(actual, tokenLength);
+ }
+
+ @Test
+ public void list() {
+ ConfTO wholeConf = configurationService.list();
+ assertNotNull(wholeConf);
+ for (AttrTO conf : wholeConf.getPlainAttrs()) {
+ assertNotNull(conf);
+ }
+ }
+
+ @Test
+ public void read() {
+ AttrTO conf = configurationService.read("token.expireTime");
+ assertNotNull(conf);
+ }
+
+ @Test
+ public void update() {
+ AttrTO expireTime = configurationService.read("token.expireTime");
+ int value = Integer.parseInt(expireTime.getValues().get(0));
+ value++;
+ expireTime.getValues().set(0, value + "");
+
+ configurationService.set(expireTime.getSchema(), expireTime);
+
+ AttrTO newConfigurationTO = configurationService.read(expireTime.getSchema());
+ assertEquals(expireTime, newConfigurationTO);
+ }
+
+ @Test
+ public void dbExport() throws IOException {
+ Response response = configurationService.export();
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+ assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+ String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertNotNull(contentDisposition);
+
+ Object entity = response.getEntity();
+ assertTrue(entity instanceof InputStream);
+ String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+ assertFalse(configExport.isEmpty());
+ assertTrue(configExport.length() > 1000);
+ }
+
+ @Test
+ public void issueSYNCOPE418() {
+ PlainSchemaTO failing = new PlainSchemaTO();
+ failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+ failing.setType(AttrSchemaType.String);
+
+ try {
+ createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, failing);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+ assertNotNull(e.getElements());
+ assertEquals(1, e.getElements().size());
+ assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE629() throws IOException {
+ PlainSchemaTO membershipKey = new PlainSchemaTO();
+ membershipKey.setKey("membershipKey" + getUUIDString());
+ membershipKey.setType(AttrSchemaType.String);
+ createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, membershipKey);
+
+ PlainSchemaTO roleKey = new PlainSchemaTO();
+ roleKey.setKey("roleKey" + getUUIDString());
+ roleKey.setType(AttrSchemaType.String);
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, roleKey);
+
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("aRole" + getUUIDString());
+ roleTO.getMAttrTemplates().add(membershipKey.getKey());
+ roleTO.getRAttrTemplates().add(roleKey.getKey());
+ roleTO = createRole(roleTO);
+
+ try {
+ Response response = configurationService.export();
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+ assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+ String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+ assertNotNull(contentDisposition);
+
+ Object entity = response.getEntity();
+ assertTrue(entity instanceof InputStream);
+ String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+ assertFalse(configExport.isEmpty());
+ assertTrue(configExport.length() > 1000);
+
+ String[] result = StringUtils.substringsBetween(configExport, "<RPLAINATTRTEMPLATE", "/>");
+ assertNotNull(result);
+ boolean rattrExists = false;
+ for (String entry : result) {
+ if (entry.contains(roleKey.getKey())) {
+ rattrExists = true;
+ }
+ }
+ assertTrue(rattrExists);
+
+ result = StringUtils.substringsBetween(configExport, "<MPLAINATTRTEMPLATE", "/>");
+ assertNotNull(result);
+ boolean mattrExists = false;
+ for (String entry : result) {
+ if (entry.contains(membershipKey.getKey())) {
+ mattrExists = true;
+ }
+ }
+ assertTrue(mattrExists);
+ } finally {
+ deleteRole(roleTO.getKey());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java
new file mode 100644
index 0000000..e7d12d9
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ConnectorITCase.java
@@ -0,0 +1,723 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.common.security.GuardedString;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConnectorITCase extends AbstractITCase {
+
+ private static String connectorServerLocation;
+
+ private static String connidSoapVersion;
+
+ private static String connidDbTableVersion;
+
+ private static String testJDBCURL;
+
+ @BeforeClass
+ public static void setUpConnIdBundles() throws IOException {
+ InputStream propStream = null;
+ try {
+ Properties props = new Properties();
+ propStream = ConnectorITCase.class.getResourceAsStream("/connid.properties");
+ props.load(propStream);
+
+ for (String location : props.getProperty("connid.locations").split(",")) {
+ if (!location.startsWith("file")) {
+ connectorServerLocation = location;
+ }
+ }
+
+ connidSoapVersion = props.getProperty("connid.soap.version");
+ connidDbTableVersion = props.getProperty("connid.db.table.version");
+
+ testJDBCURL = props.getProperty("testdb.url");
+ } catch (Exception e) {
+ LOG.error("Could not load /connid.properties", e);
+ } finally {
+ IOUtils.closeQuietly(propStream);
+ }
+ assertNotNull(connectorServerLocation);
+ assertNotNull(connidSoapVersion);
+ assertNotNull(connidDbTableVersion);
+ assertNotNull(testJDBCURL);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithException() {
+ ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+ Response response = connectorService.create(connectorTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+ }
+ }
+
+ @Test
+ public void create() {
+ ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setLocation(connectorService.read(100L).getLocation());
+ connectorTO.setVersion(connidSoapVersion);
+ connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+ connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+ connectorTO.setDisplayName("Display name");
+ connectorTO.setConnRequestTimeout(15);
+
+ // set the connector configuration using PropertyTO
+ Set<ConnConfProperty> conf = new HashSet<>();
+
+ ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+ endpointSchema.setName("endpoint");
+ endpointSchema.setType(String.class.getName());
+ endpointSchema.setRequired(true);
+ ConnConfProperty endpoint = new ConnConfProperty();
+ endpoint.setSchema(endpointSchema);
+ endpoint.getValues().add("http://localhost:8888/wssample/services");
+ endpoint.getValues().add("Provisioning");
+ conf.add(endpoint);
+
+ ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+ servicenameSchema.setName("servicename");
+ servicenameSchema.setType(String.class.getName());
+ servicenameSchema.setRequired(true);
+ ConnConfProperty servicename = new ConnConfProperty();
+ servicename.setSchema(servicenameSchema);
+ conf.add(servicename);
+
+ // set connector configuration
+ connectorTO.getConfiguration().addAll(conf);
+
+ // set connector capabilities
+ connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_CREATE);
+ connectorTO.getCapabilities().add(ConnectorCapability.ONE_PHASE_CREATE);
+ connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_UPDATE);
+
+ // set connector pool conf
+ ConnPoolConfTO cpc = new ConnPoolConfTO();
+ cpc.setMaxObjects(1534);
+ connectorTO.setPoolConf(cpc);
+
+ Response response = connectorService.create(connectorTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+ }
+
+ ConnInstanceTO actual = getObject(
+ response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+ assertNotNull(actual);
+
+ assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+ assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+ assertEquals(actual.getVersion(), connectorTO.getVersion());
+ assertEquals("Display name", actual.getDisplayName());
+ assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
+ assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
+ assertNotNull(actual.getPoolConf());
+ assertEquals(1534, actual.getPoolConf().getMaxObjects().intValue());
+ assertEquals(10, actual.getPoolConf().getMaxIdle().intValue());
+
+ Throwable t = null;
+
+ // check update
+ actual.getCapabilities().remove(ConnectorCapability.TWO_PHASES_UPDATE);
+ actual.getPoolConf().setMaxObjects(null);
+
+ try {
+ connectorService.update(actual.getKey(), actual);
+ actual = connectorService.read(actual.getKey());
+ } catch (SyncopeClientException e) {
+ LOG.error("update failed", e);
+ t = e;
+ }
+
+ assertNull(t);
+ assertNotNull(actual);
+ assertEquals(EnumSet.of(ConnectorCapability.ONE_PHASE_CREATE, ConnectorCapability.TWO_PHASES_CREATE),
+ actual.getCapabilities());
+ assertEquals(10, actual.getPoolConf().getMaxObjects().intValue());
+
+ // check also for the deletion of the created object
+ try {
+ connectorService.delete(actual.getKey());
+ } catch (SyncopeClientException e) {
+ LOG.error("delete failed", e);
+ t = e;
+ }
+
+ assertNull(t);
+
+ // check the non existence
+ try {
+ connectorService.read(actual.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void update() {
+ ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+ // set connector instance id
+ connectorTO.setKey(103L);
+
+ // set connector version
+ connectorTO.setVersion(connidSoapVersion);
+
+ // set connector name
+ connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+ // set bundle name
+ connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+ connectorTO.setConnRequestTimeout(20);
+
+ // set the connector configuration using PropertyTO
+ Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+ ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+ endpointSchema.setName("endpoint");
+ endpointSchema.setType(String.class.getName());
+ endpointSchema.setRequired(true);
+ ConnConfProperty endpoint = new ConnConfProperty();
+ endpoint.setSchema(endpointSchema);
+ endpoint.getValues().add("http://localhost:8888/wssample/services");
+ conf.add(endpoint);
+
+ ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+ servicenameSchema.setName("servicename");
+ servicenameSchema.setType(String.class.getName());
+ servicenameSchema.setRequired(true);
+ ConnConfProperty servicename = new ConnConfProperty();
+ servicename.setSchema(servicenameSchema);
+ servicename.getValues().add("Provisioning");
+ conf.add(servicename);
+
+ // set connector configuration
+ connectorTO.getConfiguration().addAll(conf);
+
+ connectorService.update(connectorTO.getKey(), connectorTO);
+ ConnInstanceTO actual = connectorService.read(connectorTO.getKey());
+
+ assertNotNull(actual);
+
+ actual = connectorService.read(actual.getKey());
+
+ assertNotNull(actual);
+ assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+ assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+ assertEquals(actual.getVersion(), connectorTO.getVersion());
+ assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
+ }
+
+ @Test
+ public void issueSYNCOPE10() {
+ // ----------------------------------
+ // Copy resource and connector in order to create new objects.
+ // ----------------------------------
+ // Retrieve a connector instance template.
+ ConnInstanceTO connInstanceTO = connectorService.read(103L);
+
+ assertNotNull(connInstanceTO);
+
+ // check for resource
+ List<ResourceTO> resources = resourceService.list(Long.valueOf(103));
+
+ assertEquals(4, resources.size());
+
+ // Retrieve a resource TO template.
+ ResourceTO resourceTO = resources.get(0);
+
+ // Make it new.
+ resourceTO.setKey("newAbout103");
+
+ // Make it new.
+ connInstanceTO.setKey(0);
+ connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
+ // ----------------------------------
+
+ // ----------------------------------
+ // Create a new connector instance.
+ // ----------------------------------
+ Response response = connectorService.create(connInstanceTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+ }
+
+ connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+ assertNotNull(connInstanceTO);
+ assertTrue(connInstanceTO.getCapabilities().isEmpty());
+
+ long connId = connInstanceTO.getKey();
+
+ // Link resourceTO to the new connector instance.
+ resourceTO.setConnectorId(connId);
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for connector instance update after resource creation.
+ // ----------------------------------
+ response = resourceService.create(resourceTO);
+ resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(resourceTO);
+
+ resources = resourceService.list(connId);
+
+ assertEquals(1, resources.size());
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for spring bean.
+ // ----------------------------------
+ ConnInstanceTO connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+
+ assertNotNull(connInstanceBean);
+ assertTrue(connInstanceBean.getCapabilities().isEmpty());
+ // ----------------------------------
+
+ // ----------------------------------
+ // Check for spring bean update after connector instance update.
+ // ----------------------------------
+ connInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
+
+ connectorService.update(connInstanceTO.getKey(), connInstanceTO);
+ ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey());
+
+ assertNotNull(actual);
+ assertFalse(connInstanceTO.getCapabilities().isEmpty());
+
+ // check for spring bean update
+ connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+
+ assertFalse(connInstanceBean.getCapabilities().isEmpty());
+ // ----------------------------------
+ }
+
+ @Test
+ public void deleteWithException() {
+ try {
+ connectorService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void list() {
+ List<ConnInstanceTO> connectorInstanceTOs = connectorService.list(null);
+ assertNotNull(connectorInstanceTOs);
+ assertFalse(connectorInstanceTOs.isEmpty());
+ for (ConnInstanceTO instance : connectorInstanceTOs) {
+ assertNotNull(instance);
+ }
+ }
+
+ @Test
+ public void read() {
+ ConnInstanceTO connectorInstanceTO = connectorService.read(100L);
+ assertNotNull(connectorInstanceTO);
+ }
+
+ @Test
+ public void getBundles() {
+ List<ConnBundleTO> bundles = connectorService.getBundles(null);
+ assertNotNull(bundles);
+ assertFalse(bundles.isEmpty());
+ for (ConnBundleTO bundle : bundles) {
+ assertNotNull(bundle);
+ }
+ }
+
+ @Test
+ public void getConnectorConfiguration() {
+ List<ConnConfProperty> props = connectorService.getConfigurationProperties(104L);
+ assertNotNull(props);
+ assertFalse(props.isEmpty());
+ }
+
+ @Test
+ public void checkHiddenProperty() {
+ ConnInstanceTO connInstanceTO = connectorService.read(100L);
+
+ boolean check = false;
+
+ for (ConnConfProperty prop : connInstanceTO.getConfiguration()) {
+ if ("receiveTimeout".equals(prop.getSchema().getName())) {
+ check = true;
+ }
+ }
+ assertTrue(check);
+ }
+
+ @Test
+ public void checkSelectedLanguage() {
+ // 1. Check Italian
+ List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
+
+ Map<String, ConnConfProperty> instanceConfMap;
+ for (ConnInstanceTO instance : connectorInstanceTOs) {
+ if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+ instanceConfMap = instance.getConfigurationMap();
+ assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
+ }
+ }
+
+ // 2. Check English (default)
+ connectorInstanceTOs = connectorService.list(null);
+
+ for (ConnInstanceTO instance : connectorInstanceTOs) {
+ if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+ instanceConfMap = instance.getConfigurationMap();
+ assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
+ }
+ }
+ }
+
+ @Test
+ public void validate() {
+ ConnInstanceTO connectorTO = new ConnInstanceTO();
+ connectorTO.setLocation(connectorServerLocation);
+ connectorTO.setVersion(connidDbTableVersion);
+ connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
+ connectorTO.setBundleName("net.tirasa.connid.bundles.db.table");
+ connectorTO.setDisplayName("H2Test");
+
+ // set the connector configuration using PropertyTO
+ Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+ ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
+ jdbcDriverSchema.setName("jdbcDriver");
+ jdbcDriverSchema.setType(String.class.getName());
+ jdbcDriverSchema.setRequired(true);
+ ConnConfProperty jdbcDriver = new ConnConfProperty();
+ jdbcDriver.setSchema(jdbcDriverSchema);
+ jdbcDriver.getValues().add("org.h2.Driver");
+ conf.add(jdbcDriver);
+
+ ConnConfPropSchema jdbcUrlTemplateSchema = new ConnConfPropSchema();
+ jdbcUrlTemplateSchema.setName("jdbcUrlTemplate");
+ jdbcUrlTemplateSchema.setType(String.class.getName());
+ jdbcUrlTemplateSchema.setRequired(true);
+ ConnConfProperty jdbcUrlTemplate = new ConnConfProperty();
+ jdbcUrlTemplate.setSchema(jdbcUrlTemplateSchema);
+ jdbcUrlTemplate.getValues().add(testJDBCURL);
+ conf.add(jdbcUrlTemplate);
+
+ ConnConfPropSchema userSchema = new ConnConfPropSchema();
+ userSchema.setName("user");
+ userSchema.setType(String.class.getName());
+ userSchema.setRequired(false);
+ ConnConfProperty user = new ConnConfProperty();
+ user.setSchema(userSchema);
+ user.getValues().add("sa");
+ conf.add(user);
+
+ ConnConfPropSchema passwordSchema = new ConnConfPropSchema();
+ passwordSchema.setName("password");
+ passwordSchema.setType(GuardedString.class.getName());
+ passwordSchema.setRequired(true);
+ ConnConfProperty password = new ConnConfProperty();
+ password.setSchema(passwordSchema);
+ password.getValues().add("sa");
+ conf.add(password);
+
+ ConnConfPropSchema tableSchema = new ConnConfPropSchema();
+ tableSchema.setName("table");
+ tableSchema.setType(String.class.getName());
+ tableSchema.setRequired(true);
+ ConnConfProperty table = new ConnConfProperty();
+ table.setSchema(tableSchema);
+ table.getValues().add("test");
+ conf.add(table);
+
+ ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+ keyColumnSchema.setName("keyColumn");
+ keyColumnSchema.setType(String.class.getName());
+ keyColumnSchema.setRequired(true);
+ ConnConfProperty keyColumn = new ConnConfProperty();
+ keyColumn.setSchema(keyColumnSchema);
+ keyColumn.getValues().add("id");
+ conf.add(keyColumn);
+
+ ConnConfPropSchema passwordColumnSchema = new ConnConfPropSchema();
+ passwordColumnSchema.setName("passwordColumn");
+ passwordColumnSchema.setType(String.class.getName());
+ passwordColumnSchema.setRequired(true);
+ ConnConfProperty passwordColumn = new ConnConfProperty();
+ passwordColumn.setSchema(passwordColumnSchema);
+ passwordColumn.getValues().add("password");
+ conf.add(passwordColumn);
+
+ // set connector configuration
+ connectorTO.getConfiguration().addAll(conf);
+
+ assertTrue(connectorService.check(connectorTO));
+
+ conf.remove(password);
+ password.getValues().clear();
+ password.getValues().add("password");
+ conf.add(password);
+
+ assertFalse(connectorService.check(connectorTO));
+ }
+
+ @Test
+ public void getSchemaNames() {
+ ConnInstanceTO conn = connectorService.read(101L);
+
+ List<PlainSchemaTO> schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+ assertNotNull(schemaNames);
+ assertFalse(schemaNames.isEmpty());
+ assertNotNull(schemaNames.get(0).getKey());
+ assertNull(schemaNames.get(0).getEnumerationValues());
+
+ schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, false);
+
+ assertNotNull(schemaNames);
+ assertEquals(0, schemaNames.size());
+
+ conn = connectorService.read(104L);
+
+ // to be used with overridden properties
+ conn.getConfiguration().clear();
+
+ schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+ assertNotNull(schemaNames);
+ assertFalse(schemaNames.isEmpty());
+ }
+
+ @Test
+ public void getSupportedObjectClasses() {
+ ConnInstanceTO ldap = connectorService.read(105L);
+ assertNotNull(ldap);
+
+ List<ConnIdObjectClassTO> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
+ assertNotNull(objectClasses);
+ assertEquals(2, objectClasses.size());
+ assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+ assertTrue(objectClasses.contains(ConnIdObjectClassTO.GROUP));
+
+ ConnInstanceTO csv = connectorService.read(104L);
+ assertNotNull(csv);
+
+ objectClasses = connectorService.getSupportedObjectClasses(csv.getKey(), csv);
+ assertNotNull(objectClasses);
+ assertEquals(1, objectClasses.size());
+ assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+ }
+
+ @Test
+ public void issueSYNCOPE112() {
+ // ----------------------------------------
+ // Create a new connector
+ // ----------------------------------------
+ ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+ connectorTO.setLocation(connectorService.read(100L).getLocation());
+
+ // set connector version
+ connectorTO.setVersion(connidSoapVersion);
+
+ // set connector name
+ connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+ // set bundle name
+ connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+ // set display name
+ connectorTO.setDisplayName("WSSoap");
+
+ // set the connector configuration using PropertyTO
+ Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+ ConnConfPropSchema userSchema = new ConnConfPropSchema();
+ userSchema.setName("endpoint");
+ userSchema.setType(String.class.getName());
+ userSchema.setRequired(true);
+ ConnConfProperty endpoint = new ConnConfProperty();
+ endpoint.setSchema(userSchema);
+ endpoint.getValues().add("http://localhost:9080/does_not_work");
+ endpoint.setOverridable(true);
+
+ ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+ keyColumnSchema.setName("servicename");
+ keyColumnSchema.setType(String.class.getName());
+ keyColumnSchema.setRequired(true);
+ ConnConfProperty servicename = new ConnConfProperty();
+ servicename.setSchema(keyColumnSchema);
+ servicename.getValues().add("net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning");
+ servicename.setOverridable(false);
+
+ conf.add(endpoint);
+ conf.add(servicename);
+
+ // set connector configuration
+ connectorTO.getConfiguration().addAll(conf);
+
+ try {
+ assertFalse(connectorService.check(connectorTO));
+
+ Response response = connectorService.create(connectorTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+ }
+
+ connectorTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+ assertNotNull(connectorTO);
+ // ----------------------------------------
+
+ // ----------------------------------------
+ // create a resourceTO
+ // ----------------------------------------
+ String resourceName = "checkForPropOverriding";
+ ResourceTO resourceTO = new ResourceTO();
+
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(connectorTO.getKey());
+
+ conf = new HashSet<ConnConfProperty>();
+ endpoint.getValues().clear();
+ endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
+ conf.add(endpoint);
+
+ resourceTO.getConnConfProperties().addAll(conf);
+
+ MappingTO mapping = new MappingTO();
+ resourceTO.setUmapping(mapping);
+
+ MappingItemTO mapItem = new MappingItemTO();
+ mapItem.setExtAttrName("uid");
+ mapItem.setIntAttrName("userId");
+ mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
+ mapItem.setAccountid(true);
+ mapping.setAccountIdItem(mapItem);
+ // ----------------------------------------
+
+ // ----------------------------------------
+ // Check connection without saving the resource ....
+ // ----------------------------------------
+ assertTrue(resourceService.check(resourceTO));
+ // ----------------------------------------
+ } finally {
+ // Remove connector from db to make test re-runnable
+ connectorService.delete(connectorTO.getKey());
+ }
+ }
+
+ @Test
+ public void reload() {
+ connectorService.reload();
+ }
+
+ @Test
+ public void bulkAction() {
+ final BulkAction bulkAction = new BulkAction();
+ bulkAction.setOperation(BulkAction.Type.DELETE);
+
+ ConnInstanceTO conn = connectorService.read(101L);
+
+ conn.setKey(0);
+ conn.setDisplayName("forBulk1");
+
+ bulkAction.getTargets().add(String.valueOf(getObject(
+ connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+ conn.setDisplayName("forBulk2");
+
+ bulkAction.getTargets().add(String.valueOf(getObject(
+ connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+ Iterator<String> iter = bulkAction.getTargets().iterator();
+
+ assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+ assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+
+ connectorService.bulk(bulkAction);
+
+ iter = bulkAction.getTargets().iterator();
+
+ try {
+ connectorService.read(Long.valueOf(iter.next()));
+ fail();
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+
+ try {
+ connectorService.read(Long.valueOf(iter.next()));
+ fail();
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE605() {
+
+ ConnInstanceTO connectorInstanceTO = connectorService.read(103L);
+ assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
+
+ connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
+ connectorService.update(connectorInstanceTO.getKey(), connectorInstanceTO);
+
+ ConnInstanceTO updatedCapabilities = connectorService.read(connectorInstanceTO.getKey());
+ assertNotNull(updatedCapabilities.getCapabilities());
+ assertTrue(updatedCapabilities.getCapabilities().size() == 1);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
new file mode 100644
index 0000000..9ac24ea
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/DerSchemaITCase.java
@@ -0,0 +1,151 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DerSchemaITCase extends AbstractITCase {
+
+ @Test
+ public void list() {
+ List<DerSchemaTO> derivedSchemas = schemaService.list(AttributableType.USER, SchemaType.DERIVED);
+ assertFalse(derivedSchemas.isEmpty());
+ for (DerSchemaTO derivedSchemaTO : derivedSchemas) {
+ assertNotNull(derivedSchemaTO);
+ }
+ }
+
+ @Test
+ public void read() {
+ DerSchemaTO derivedSchemaTO = schemaService.read(AttributableType.USER, SchemaType.DERIVED,
+ "cn");
+ assertNotNull(derivedSchemaTO);
+ }
+
+ @Test
+ public void create() {
+ DerSchemaTO schema = new DerSchemaTO();
+ schema.setKey("derived");
+ schema.setExpression("derived_sx + '_' + derived_dx");
+
+ DerSchemaTO actual = createSchema(AttributableType.USER, SchemaType.DERIVED, schema);
+ assertNotNull(actual);
+
+ actual = schemaService.read(AttributableType.USER, SchemaType.DERIVED, actual.getKey());
+ assertNotNull(actual);
+ assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
+ }
+
+ @Test
+ public void delete() {
+ DerSchemaTO schema = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+ assertNotNull(schema);
+
+ schemaService.delete(AttributableType.ROLE, SchemaType.DERIVED, schema.getKey());
+
+ try {
+ schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ } finally {
+ // Recreate schema to make test re-runnable
+ schema = createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+ assertNotNull(schema);
+ }
+ }
+
+ @Test
+ public void update() {
+ DerSchemaTO schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+ "mderiveddata");
+ assertNotNull(schema);
+ assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
+ try {
+ schema.setExpression("mderived_sx + '.' + mderived_dx");
+
+ schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+ schema.getKey(), schema);
+
+ schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED, "mderiveddata");
+ assertNotNull(schema);
+ assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
+ } finally {
+ // Set updated back to make test re-runnable
+ schema.setExpression("mderived_sx + '-' + mderived_dx");
+ schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+ schema.getKey(), schema);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE323() {
+ DerSchemaTO actual = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+ assertNotNull(actual);
+
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.EntityExists, e.getType());
+ }
+
+ actual.setKey(null);
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE418() {
+ DerSchemaTO schema = new DerSchemaTO();
+ schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+ schema.setExpression("derived_sx + '_' + derived_dx");
+
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());
+ assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
new file mode 100644
index 0000000..68510bf
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/LoggerITCase.java
@@ -0,0 +1,215 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.text.ParseException;
+import java.util.List;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.server.logic.ReportLogic;
+import org.apache.syncope.server.logic.ResourceLogic;
+import org.apache.syncope.server.logic.RoleLogic;
+import org.apache.syncope.server.logic.UserLogic;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class LoggerITCase extends AbstractITCase {
+
+ @Test
+ public void listLogs() {
+ List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+ assertNotNull(loggers);
+ assertFalse(loggers.isEmpty());
+ for (LoggerTO logger : loggers) {
+ assertNotNull(logger);
+ }
+ }
+
+ @Test
+ public void listAudits() throws ParseException {
+ List<LoggerTO> audits = loggerService.list(LoggerType.AUDIT);
+
+ assertNotNull(audits);
+ assertFalse(audits.isEmpty());
+ for (LoggerTO audit : audits) {
+ assertNotNull(AuditLoggerName.fromLoggerName(audit.getKey()));
+ }
+ }
+
+ @Test
+ public void setLevel() {
+ List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+ assertNotNull(loggers);
+ int startSize = loggers.size();
+
+ LoggerTO logger = new LoggerTO();
+ logger.setKey("TEST");
+ logger.setLevel(LoggerLevel.INFO);
+ loggerService.update(LoggerType.LOG, logger.getKey(), logger);
+ logger = loggerService.read(LoggerType.LOG, logger.getKey());
+ assertNotNull(logger);
+ assertEquals(LoggerLevel.INFO, logger.getLevel());
+
+ loggers = loggerService.list(LoggerType.LOG);
+ assertNotNull(loggers);
+ assertEquals(startSize + 1, loggers.size());
+
+ // TEST Delete
+ loggerService.delete(LoggerType.LOG, "TEST");
+ loggers = loggerService.list(LoggerType.LOG);
+ assertNotNull(loggers);
+ assertEquals(startSize, loggers.size());
+ }
+
+ @Test
+ public void enableDisableAudit() {
+ AuditLoggerName auditLoggerName = new AuditLoggerName(
+ EventCategoryType.REST,
+ ReportLogic.class.getSimpleName(),
+ null,
+ "deleteExecution",
+ AuditElements.Result.FAILURE);
+
+ List<AuditLoggerName> audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+ assertNotNull(audits);
+ assertFalse(audits.contains(auditLoggerName));
+
+ LoggerTO loggerTO = new LoggerTO();
+ String name = auditLoggerName.toLoggerName();
+ loggerTO.setKey(name);
+ loggerTO.setLevel(LoggerLevel.DEBUG);
+ loggerService.update(LoggerType.AUDIT, name, loggerTO);
+
+ audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+ assertNotNull(audits);
+ assertTrue(audits.contains(auditLoggerName));
+
+ loggerService.delete(LoggerType.AUDIT, auditLoggerName.toLoggerName());
+
+ audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+ assertNotNull(audits);
+ assertFalse(audits.contains(auditLoggerName));
+ }
+
+ @Test
+ public void listAuditEvents() {
+ final List<EventCategoryTO> events = loggerService.events();
+
+ boolean found = false;
+
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (UserLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+ assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+ assertTrue(eventCategoryTO.getEvents().contains("create"));
+ assertTrue(eventCategoryTO.getEvents().contains("list"));
+ assertFalse(eventCategoryTO.getEvents().contains("doCreate"));
+ assertFalse(eventCategoryTO.getEvents().contains("setStatusOnWfAdapter"));
+ assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (RoleLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+ assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+ assertTrue(eventCategoryTO.getEvents().contains("create"));
+ assertTrue(eventCategoryTO.getEvents().contains("list"));
+ assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (ResourceLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+ assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+ assertTrue(eventCategoryTO.getEvents().contains("create"));
+ assertTrue(eventCategoryTO.getEvents().contains("read"));
+ assertTrue(eventCategoryTO.getEvents().contains("delete"));
+ assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+ if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
+ && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+ found = true;
+ }
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+ if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
+ && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+ assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+ found = true;
+ }
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (EventCategoryType.TASK == eventCategoryTO.getType()
+ && "SampleJob".equals(eventCategoryTO.getCategory())) {
+ found = true;
+ }
+ }
+ assertTrue(found);
+
+ found = false;
+ for (EventCategoryTO eventCategoryTO : events) {
+ if (EventCategoryType.TASK == eventCategoryTO.getType()
+ && "SyncJob".equals(eventCategoryTO.getCategory())) {
+ found = true;
+ }
+ }
+ assertTrue(found);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
new file mode 100644
index 0000000..cb09ea8
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/NotificationITCase.java
@@ -0,0 +1,172 @@
+/*
+ * 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.fit.server.reference;
+
+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.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class NotificationITCase extends AbstractITCase {
+
+ private NotificationTO buildNotificationTO() {
+ NotificationTO notificationTO = new NotificationTO();
+ notificationTO.setTraceLevel(TraceLevel.SUMMARY);
+ notificationTO.getEvents().add("create");
+
+ notificationTO.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().
+ is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
+
+ notificationTO.setRecipientAttrName("email");
+ notificationTO.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+ notificationTO.setSender("syncope@syncope.apache.org");
+ notificationTO.setSubject("Test notification");
+ notificationTO.setTemplate("test");
+ return notificationTO;
+ }
+
+ @Test
+ public void read() {
+ NotificationTO notificationTO = notificationService.read(10L);
+ assertNotNull(notificationTO);
+ }
+
+ @Test
+ public void list() {
+ List<NotificationTO> notificationTOs = notificationService.list();
+ assertNotNull(notificationTOs);
+ assertFalse(notificationTOs.isEmpty());
+ for (NotificationTO instance : notificationTOs) {
+ assertNotNull(instance);
+ }
+ }
+
+ @Test
+ public void create() {
+ NotificationTO notificationTO = buildNotificationTO();
+ notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+ Response response = notificationService.create(notificationTO);
+ NotificationTO actual = getObject(response.getLocation(), NotificationService.class,
+ NotificationTO.class);
+
+ assertNotNull(actual);
+ assertNotNull(actual.getKey());
+ notificationTO.setKey(actual.getKey());
+ assertEquals(actual, notificationTO);
+ }
+
+ @Test
+ public void update() {
+ NotificationTO notificationTO = notificationService.read(10L);
+ notificationTO.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+ notificationService.update(notificationTO.getKey(), notificationTO);
+ NotificationTO actual = notificationService.read(notificationTO.getKey());
+ assertNotNull(actual);
+ assertEquals(actual, notificationTO);
+ }
+
+ @Test
+ public void delete() {
+ NotificationTO notification = buildNotificationTO();
+ notification.setSelfAsRecipient(true);
+ Response response = notificationService.create(notification);
+ notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+
+ notificationService.delete(notification.getKey());
+
+ try {
+ notificationService.read(notification.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE83() {
+ NotificationTO notificationTO = buildNotificationTO();
+ notificationTO.setSelfAsRecipient(true);
+
+ NotificationTO actual = null;
+ try {
+ Response response = notificationService.create(notificationTO);
+ actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ assertNotNull(actual);
+ assertNotNull(actual.getKey());
+ notificationTO.setKey(actual.getKey());
+ assertEquals(actual, notificationTO);
+ }
+
+ @Test
+ public void issueSYNCOPE445() {
+ NotificationTO notificationTO = buildNotificationTO();
+ notificationTO.getStaticRecipients().add("syncope445@syncope.apache.org");
+
+ NotificationTO actual = null;
+ try {
+ Response response = notificationService.create(notificationTO);
+ actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ assertNotNull(actual);
+ assertNotNull(actual.getKey());
+ notificationTO.setKey(actual.getKey());
+ assertEquals(actual, notificationTO);
+ }
+
+ @Test
+ public void issueSYNCOPE446() {
+ NotificationTO notificationTO = buildNotificationTO();
+ notificationTO.getStaticRecipients().add("syncope446@syncope.apache.org");
+ notificationTO.setRoleAbout(SyncopeClient.getRoleSearchConditionBuilder().hasEntitlements("ROLE_READ").query());
+
+ NotificationTO actual = null;
+ try {
+ Response response = notificationService.create(notificationTO);
+ actual = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ assertNotNull(actual);
+ assertNotNull(actual.getKey());
+ notificationTO.setKey(actual.getKey());
+ assertEquals(actual, notificationTO);
+ }
+}
[03/15] syncope git commit: Merge branch 'master' into 2_0_X
Posted by il...@apache.org.
Merge branch 'master' into 2_0_X
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/b7d9addc
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/b7d9addc
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/b7d9addc
Branch: refs/heads/2_0_X
Commit: b7d9addc81adab2defe19e4fc4e6189a805aef2e
Parents: 961dfd3 336d8d6
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jan 21 06:56:10 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jan 21 06:56:10 2015 +0100
----------------------------------------------------------------------
.../core/rest/ConfigurationTestITCase.java | 79 +++++++++++---------
1 file changed, 42 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
[11/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SearchITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SearchITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SearchITCase.java
new file mode 100644
index 0000000..57dfbb0
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SearchITCase.java
@@ -0,0 +1,182 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SearchITCase extends AbstractITCase {
+
+ @Test
+ public void searchUser() {
+ // LIKE
+ PagedResult<UserTO> matchedUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().
+ is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query());
+ assertNotNull(matchedUsers);
+ assertFalse(matchedUsers.getResult().isEmpty());
+
+ for (UserTO user : matchedUsers.getResult()) {
+ assertNotNull(user);
+ }
+
+ // ISNULL
+ matchedUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query());
+ assertNotNull(matchedUsers);
+ assertFalse(matchedUsers.getResult().isEmpty());
+
+ Set<Long> userIds = new HashSet<Long>(matchedUsers.getResult().size());
+ for (UserTO user : matchedUsers.getResult()) {
+ userIds.add(user.getKey());
+ }
+ assertTrue(userIds.contains(2L));
+ assertTrue(userIds.contains(3L));
+ }
+
+ @Test
+ public void searchByUsernameAndKey() {
+ final PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().
+ is("username").equalTo("rossini").and("key").lessThan(2).query());
+
+ assertNotNull(matchingUsers);
+ assertEquals(1, matchingUsers.getResult().size());
+ assertEquals("rossini", matchingUsers.getResult().iterator().next().getUsername());
+ assertEquals(1L, matchingUsers.getResult().iterator().next().getKey());
+ }
+
+ @Test
+ public void searchByRolenameAndKey() {
+ final PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().
+ is("name").equalTo("root").and("key").lessThan(2).query());
+
+ assertNotNull(matchingRoles);
+ assertEquals(1, matchingRoles.getResult().size());
+ assertEquals("root", matchingRoles.getResult().iterator().next().getName());
+ assertEquals(1L, matchingRoles.getResult().iterator().next().getKey());
+ }
+
+ @Test
+ public void searchUserByResourceName() {
+ PagedResult<UserTO> matchedUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().hasResources(RESOURCE_NAME_MAPPINGS2).query());
+ assertNotNull(matchedUsers);
+ assertFalse(matchedUsers.getResult().isEmpty());
+
+ Set<Long> userIds = new HashSet<Long>(matchedUsers.getResult().size());
+ for (UserTO user : matchedUsers.getResult()) {
+ userIds.add(user.getKey());
+ }
+
+ assertEquals(1, userIds.size());
+ assertTrue(userIds.contains(2L));
+ }
+
+ @Test
+ public void paginatedSearch() {
+ // LIKE
+ PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().
+ is("fullname").equalTo("*o*").and("fullname").equalTo("*i*").query(), 1, 2);
+ assertNotNull(matchingUsers);
+
+ assertFalse(matchingUsers.getResult().isEmpty());
+ for (UserTO user : matchingUsers.getResult()) {
+ assertNotNull(user);
+ }
+
+ // ISNULL
+ matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().isNull("loginDate").query(), 1, 2);
+
+ assertNotNull(matchingUsers);
+ assertFalse(matchingUsers.getResult().isEmpty());
+ Set<Long> userIds = new HashSet<>(matchingUsers.getResult().size());
+ for (UserTO user : matchingUsers.getResult()) {
+ userIds.add(user.getKey());
+ }
+ assertEquals(2, userIds.size());
+ }
+
+ @Test
+ public void searchByBooleanSubjectCond() {
+ final PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().is("inheritPlainAttrs").equalTo("true").query());
+ assertNotNull(matchingRoles);
+ assertFalse(matchingRoles.getResult().isEmpty());
+ }
+
+ @Test
+ public void searchByEntitlement() {
+ final PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().hasEntitlements("USER_LIST", "USER_READ").query());
+ assertNotNull(matchingRoles);
+ assertFalse(matchingRoles.getResult().isEmpty());
+ }
+
+ @Test
+ public void searchByRelationshipSubjectCond() {
+ final PagedResult<RoleTO> matchingRoles = roleService.search(SyncopeClient.getRoleSearchConditionBuilder().
+ isNotNull("passwordPolicy").and("userOwner").equalTo(5).query());
+
+ assertNotNull(matchingRoles);
+ assertEquals(1, matchingRoles.getResult().size());
+ assertEquals("director", matchingRoles.getResult().iterator().next().getName());
+ assertEquals(6L, matchingRoles.getResult().iterator().next().getKey());
+ }
+
+ @Test
+ public void nested() {
+ PagedResult<UserTO> matchedUsers = userService.search(
+ "((fullname==*o*,fullname==*i*);$resources!=ws-target-resource-1)", 1, 2);
+ assertNotNull(matchedUsers);
+
+ assertFalse(matchedUsers.getResult().isEmpty());
+ for (UserTO user : matchedUsers.getResult()) {
+ assertNotNull(user);
+ }
+ }
+
+ @Test
+ public void orderBy() {
+ final PagedResult<UserTO> matchedUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().is("userId").equalTo("*@apache.org").query(),
+ SyncopeClient.getOrderByClauseBuilder().asc("status").desc("firstname").build());
+
+ assertFalse(matchedUsers.getResult().isEmpty());
+ for (UserTO user : matchedUsers.getResult()) {
+ assertNotNull(user);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SecurityQuestionITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SecurityQuestionITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SecurityQuestionITCase.java
new file mode 100644
index 0000000..da65d29
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/SecurityQuestionITCase.java
@@ -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.fit.server.reference;
+
+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.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.SecurityQuestionTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class SecurityQuestionITCase extends AbstractITCase {
+
+ @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.getKey());
+ securityQuestionTO.setKey(actual.getKey());
+ assertEquals(actual, securityQuestionTO);
+ }
+
+ @Test
+ public void update() {
+ SecurityQuestionTO securityQuestionTO = securityQuestionService.read(1L);
+ securityQuestionTO.setContent("What is your favorite color?");
+
+ securityQuestionService.update(securityQuestionTO.getKey(), securityQuestionTO);
+ SecurityQuestionTO actual = securityQuestionService.read(securityQuestionTO.getKey());
+ 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.getKey());
+
+ try {
+ securityQuestionService.read(securityQuestion.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
new file mode 100644
index 0000000..c144dbd
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/TaskITCase.java
@@ -0,0 +1,1385 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.NotificationTO;
+import org.apache.syncope.common.lib.to.NotificationTaskTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.PushTaskTO;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.SchedTaskTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.to.SyncTaskTO;
+import org.apache.syncope.common.lib.to.TaskExecTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.common.lib.wrap.JobClass;
+import org.apache.syncope.common.lib.wrap.PushActionClass;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.lib.wrap.SyncActionClass;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.server.misc.security.Encryptor;
+import org.apache.syncope.server.provisioning.api.job.SyncJob;
+import org.apache.syncope.server.provisioning.java.sync.DBPasswordSyncActions;
+import org.apache.syncope.server.provisioning.java.sync.LDAPPasswordSyncActions;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class TaskITCase extends AbstractITCase {
+
+ private static final Long SCHED_TASK_ID = 5L;
+
+ private static final Long SYNC_TASK_ID = 4L;
+
+ private static class ThreadExec implements Callable<TaskExecTO> {
+
+ private final TaskITCase test;
+
+ private final Long taskKey;
+
+ private final int maxWaitSeconds;
+
+ private final boolean dryRun;
+
+ public ThreadExec(TaskITCase test, Long taskKey, int maxWaitSeconds, boolean dryRun) {
+ this.test = test;
+ this.taskKey = taskKey;
+ this.maxWaitSeconds = maxWaitSeconds;
+ this.dryRun = dryRun;
+ }
+
+ @Override
+ public TaskExecTO call() throws Exception {
+ return test.execSyncTask(taskKey, maxWaitSeconds, dryRun);
+ }
+ }
+
+ @BeforeClass
+ public static void testSyncActionsSetup() {
+ SyncTaskTO syncTask = taskService.read(SYNC_TASK_ID);
+ syncTask.getActionsClassNames().add(TestSyncActions.class.getName());
+ taskService.update(SYNC_TASK_ID, syncTask);
+ }
+
+ /**
+ * Remove initial and synchronized users to make test re-runnable.
+ */
+ private void removeTestUsers() {
+ for (int i = 0; i < 10; i++) {
+ String cUserName = "test" + i;
+ try {
+ UserTO cUserTO = readUser(cUserName);
+ userService.delete(cUserTO.getKey());
+ } catch (Exception e) {
+ // Ignore
+ }
+ }
+ }
+
+ @Test
+ public void getJobClasses() {
+ List<JobClass> jobClasses = taskService.getJobClasses();
+ assertNotNull(jobClasses);
+ assertFalse(jobClasses.isEmpty());
+ }
+
+ @Test
+ public void getSyncActionsClasses() {
+ List<SyncActionClass> actions = taskService.getSyncActionsClasses();
+ assertNotNull(actions);
+ assertFalse(actions.isEmpty());
+ }
+
+ @Test
+ public void getPushActionsClasses() {
+ List<PushActionClass> actions = taskService.getPushActionsClasses();
+ assertNotNull(actions);
+ }
+
+ @Test
+ public void createSyncTask() {
+ SyncTaskTO task = new SyncTaskTO();
+ task.setName("Test create Sync");
+ task.setResource(RESOURCE_NAME_WS2);
+
+ UserTO userTemplate = new UserTO();
+ userTemplate.getResources().add(RESOURCE_NAME_WS2);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTemplate.getMemberships().add(membershipTO);
+ task.setUserTemplate(userTemplate);
+
+ RoleTO roleTemplate = new RoleTO();
+ roleTemplate.getResources().add(RESOURCE_NAME_LDAP);
+ task.setRoleTemplate(roleTemplate);
+
+ Response response = taskService.create(task);
+ SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals(actual.getKey(), task.getKey());
+ assertEquals(actual.getJobClassName(), task.getJobClassName());
+ assertEquals(userTemplate, task.getUserTemplate());
+ assertEquals(roleTemplate, task.getRoleTemplate());
+ }
+
+ @Test
+ public void createPushTask() {
+ PushTaskTO task = new PushTaskTO();
+ task.setName("Test create Push");
+ task.setResource(RESOURCE_NAME_WS2);
+ task.setUserFilter(
+ SyncopeClient.getUserSearchConditionBuilder().hasNotResources(RESOURCE_NAME_TESTDB2).query());
+ task.setRoleFilter(
+ SyncopeClient.getRoleSearchConditionBuilder().isNotNull("cool").query());
+ task.setMatchingRule(MatchingRule.LINK);
+
+ final Response response = taskService.create(task);
+ final PushTaskTO actual = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+ assertNotNull(actual);
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals(task.getKey(), actual.getKey());
+ assertEquals(task.getJobClassName(), actual.getJobClassName());
+ assertEquals(task.getUserFilter(), actual.getUserFilter());
+ assertEquals(task.getRoleFilter(), actual.getRoleFilter());
+ assertEquals(UnmatchingRule.ASSIGN, actual.getUnmatchingRule());
+ assertEquals(MatchingRule.LINK, actual.getMatchingRule());
+ }
+
+ @Test
+ public void update() {
+ SchedTaskTO task = taskService.read(SCHED_TASK_ID);
+ assertNotNull(task);
+
+ final SchedTaskTO taskMod = new SchedTaskTO();
+ taskMod.setKey(5);
+ taskMod.setCronExpression(null);
+
+ taskService.update(taskMod.getKey(), taskMod);
+ SchedTaskTO actual = taskService.read(taskMod.getKey());
+ assertNotNull(actual);
+ assertEquals(task.getKey(), actual.getKey());
+ assertNull(actual.getCronExpression());
+ }
+
+ @Test
+ public void listSchedTask() {
+ final PagedResult<SchedTaskTO> tasks = taskService.list(TaskType.SCHEDULED);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof SchedTaskTO) || task instanceof SyncTaskTO || task instanceof PushTaskTO) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void listSyncTask() {
+ final PagedResult<SyncTaskTO> tasks = taskService.list(TaskType.SYNCHRONIZATION);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof SyncTaskTO)) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void list() {
+ final PagedResult<PushTaskTO> tasks = taskService.list(TaskType.PUSH);
+ assertFalse(tasks.getResult().isEmpty());
+ for (AbstractTaskTO task : tasks.getResult()) {
+ if (!(task instanceof PushTaskTO)) {
+ fail();
+ }
+ }
+ }
+
+ @Test
+ public void paginatedList() {
+ PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 2);
+
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+ assertEquals(2, tasks.getResult().size());
+
+ for (AbstractTaskTO task : tasks.getResult()) {
+ assertNotNull(task);
+ }
+
+ tasks = taskService.list(TaskType.PROPAGATION, 2, 2);
+
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ for (AbstractTaskTO task : tasks.getResult()) {
+ assertNotNull(task);
+ }
+
+ tasks = taskService.list(TaskType.PROPAGATION, 1000, 2);
+
+ assertNotNull(tasks);
+ assertTrue(tasks.getResult().isEmpty());
+ }
+
+ @Test
+ public void read() {
+ final PropagationTaskTO taskTO = taskService.read(3L);
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+ assertTrue(taskTO.getExecutions().isEmpty());
+
+ final PushTaskTO pushTaskTO = taskService.<PushTaskTO>read(17L);
+ assertEquals(UnmatchingRule.ASSIGN, pushTaskTO.getUnmatchingRule());
+ assertEquals(MatchingRule.UPDATE, pushTaskTO.getMatchingRule());
+ }
+
+ @Test
+ public void readExecution() {
+ TaskExecTO taskTO = taskService.readExecution(6L);
+ assertNotNull(taskTO);
+ }
+
+ @Test
+ // Currently test is not re-runnable.
+ // To successfully run test second time it is necessary to restart cargo.
+ public void deal() {
+ try {
+ taskService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ TaskExecTO exec = taskService.execute(1L, false);
+ assertEquals(PropagationTaskExecStatus.SUBMITTED.name(), exec.getStatus());
+
+ ReportExecTO report = new ReportExecTO();
+ report.setStatus(PropagationTaskExecStatus.SUCCESS.name());
+ report.setMessage("OK");
+ taskService.report(exec.getKey(), report);
+ exec = taskService.readExecution(exec.getKey());
+ assertEquals(PropagationTaskExecStatus.SUCCESS.name(), exec.getStatus());
+ assertEquals("OK", exec.getMessage());
+
+ taskService.delete(1L);
+ try {
+ taskService.readExecution(exec.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void sync() throws Exception {
+ removeTestUsers();
+
+ // -----------------------------
+ // Create a new user ... it should be updated applying sync policy
+ // -----------------------------
+ UserTO inUserTO = new UserTO();
+ inUserTO.setPassword("password123");
+ String userName = "test9";
+ inUserTO.setUsername(userName);
+ inUserTO.getPlainAttrs().add(attrTO("firstname", "nome9"));
+ inUserTO.getPlainAttrs().add(attrTO("surname", "cognome"));
+ inUserTO.getPlainAttrs().add(attrTO("type", "a type"));
+ inUserTO.getPlainAttrs().add(attrTO("fullname", "nome cognome"));
+ inUserTO.getPlainAttrs().add(attrTO("userId", "puccini@syncope.apache.org"));
+ inUserTO.getPlainAttrs().add(attrTO("email", "puccini@syncope.apache.org"));
+ inUserTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ inUserTO = createUser(inUserTO);
+ assertNotNull(inUserTO);
+ assertFalse(inUserTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ // -----------------------------
+ try {
+ int usersPre = userService.list(1, 1).getTotalCount();
+ assertNotNull(usersPre);
+
+ execSyncTask(SYNC_TASK_ID, 50, false);
+
+ // after execution of the sync task the user data should be synced from
+ // csv datasource and processed by user template
+ UserTO userTO = userService.read(inUserTO.getKey());
+ assertNotNull(userTO);
+ assertEquals(userName, userTO.getUsername());
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "active" : "created", userTO.getStatus());
+ assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("email").getValues().get(0));
+ assertEquals("test9@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+ assertTrue(Integer.valueOf(userTO.getPlainAttrMap().get("fullname").getValues().get(0)) <= 10);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+
+ // Matching --> Update (no link)
+ assertFalse(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ // check for user template
+ userTO = readUser("test7");
+ assertNotNull(userTO);
+ assertEquals("TYPE_OTHER", userTO.getPlainAttrMap().get("type").getValues().get(0));
+ assertEquals(3, userTO.getResources().size());
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_WS2));
+ assertEquals(1, userTO.getMemberships().size());
+ assertTrue(userTO.getMemberships().get(0).getPlainAttrMap().containsKey("subscriptionDate"));
+
+ // Unmatching --> Assign (link)
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_CSV));
+
+ userTO = readUser("test8");
+ assertNotNull(userTO);
+ assertEquals("TYPE_8", userTO.getPlainAttrMap().get("type").getValues().get(0));
+
+ // check for sync results
+ int usersPost = userService.list(1, 1).getTotalCount();
+ assertNotNull(usersPost);
+ assertEquals(usersPre + 9, usersPost);
+
+ // Check for issue 215:
+ // * expected disabled user test1
+ // * expected enabled user test2
+ userTO = readUser("test1");
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ userTO = readUser("test3");
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ // SYNCOPE-317
+ execSyncTask(SYNC_TASK_ID, 50, false);
+
+ final Set<Long> pushTaskIds = new HashSet<Long>();
+ pushTaskIds.add(25L);
+ pushTaskIds.add(26L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+ // Matching --> UNLINK
+ assertFalse(readUser("test9").getResources().contains(RESOURCE_NAME_CSV));
+ assertFalse(readUser("test7").getResources().contains(RESOURCE_NAME_CSV));
+ } finally {
+ removeTestUsers();
+ }
+ }
+
+ @Test
+ public void reconcileFromDB() {
+ // update sync task
+ TaskExecTO execution = execSyncTask(7L, 50, false);
+ assertNotNull(execution.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
+
+ UserTO userTO = readUser("testuser1");
+ assertNotNull(userTO);
+ assertEquals("reconciled@syncope.apache.org", userTO.getPlainAttrMap().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(7L, 50, false);
+ assertNotNull(execution.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(execution.getStatus()).isSuccessful());
+
+ userTO = readUser("testuser1");
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ }
+
+ /**
+ * Clean Syncope and LDAP resource status.
+ */
+ private void ldapCleanup() {
+ PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+ if (matchingRoles.getSize() > 0) {
+ for (RoleTO role : matchingRoles.getResult()) {
+ roleService.bulkDeassociation(role.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+ roleService.delete(role.getKey());
+ }
+ }
+ PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+ if (matchingUsers.getSize() > 0) {
+ for (UserTO user : matchingUsers.getResult()) {
+ userService.bulkDeassociation(user.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class));
+ userService.delete(user.getKey());
+ }
+ }
+ }
+
+ @Test
+ public void reconcileFromLDAP() {
+ // First of all, clear any potential conflict with existing user / role
+ ldapCleanup();
+
+ // Update sync task
+ TaskExecTO execution = execSyncTask(11L, 50, false);
+
+ // 1. verify execution status
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 2. verify that synchronized role is found, with expected attributes
+ final PagedResult<RoleTO> matchingRoles = roleService.search(
+ SyncopeClient.getRoleSearchConditionBuilder().is("name").equalTo("testLDAPGroup").query());
+ assertNotNull(matchingRoles);
+ assertEquals(1, matchingRoles.getResult().size());
+
+ final PagedResult<UserTO> matchingUsers = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().is("username").equalTo("syncFromLDAP").query());
+ assertNotNull(matchingUsers);
+ assertEquals(1, matchingUsers.getResult().size());
+
+ // Check for SYNCOPE-436
+ assertEquals("syncFromLDAP",
+ matchingUsers.getResult().get(0).getVirAttrMap().get("virtualReadOnly").getValues().get(0));
+ // Check for SYNCOPE-270
+ assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("obscure"));
+ // Check for SYNCOPE-123
+ assertNotNull(matchingUsers.getResult().get(0).getPlainAttrMap().get("photo"));
+
+ final RoleTO roleTO = matchingRoles.getResult().iterator().next();
+ assertNotNull(roleTO);
+ assertEquals("testLDAPGroup", roleTO.getName());
+ assertEquals(8L, roleTO.getParent());
+ assertEquals("true", roleTO.getPlainAttrMap().get("show").getValues().get(0));
+ assertEquals(matchingUsers.getResult().iterator().next().getKey(), (long) roleTO.getUserOwner());
+ assertNull(roleTO.getRoleOwner());
+
+ // 3. verify that LDAP group membership is propagated as Syncope role membership
+ final PagedResult<UserTO> members = userService.search(
+ SyncopeClient.getUserSearchConditionBuilder().hasRoles(roleTO.getKey()).query());
+ assertNotNull(members);
+ assertEquals(1, members.getResult().size());
+ }
+
+ @Test
+ public void issue196() {
+ TaskExecTO exec = taskService.execute(6L, false);
+ assertNotNull(exec);
+ assertEquals(0, exec.getKey());
+ assertNotNull(exec.getTask());
+ }
+
+ @Test
+ public void dryRun() {
+ TaskExecTO execution = execSyncTask(SYNC_TASK_ID, 50, true);
+ assertEquals("Execution of task " + execution.getTask() + " failed with message " + execution.getMessage(),
+ "SUCCESS", execution.getStatus());
+ }
+
+ @Test
+ public void issueSYNCOPE81() {
+ String sender = "syncope81@syncope.apache.org";
+ createNotificationTask(sender);
+ NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+ assertNotNull(taskTO);
+
+ assertTrue(taskTO.getExecutions().isEmpty());
+
+ // generate an execution in order to verify the deletion of a notification task with one or more executions
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+ assertEquals("NOT_SENT", execution.getStatus());
+
+ int i = 0;
+ int maxit = 50;
+ int executions = 0;
+
+ // wait for task exec completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ taskTO = taskService.read(taskTO.getKey());
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ i++;
+ } while (executions == taskTO.getExecutions().size() && i < maxit);
+
+ assertFalse(taskTO.getExecutions().isEmpty());
+
+ taskService.delete(taskTO.getKey());
+ }
+
+ @Test
+ public void issueSYNCOPE86() {
+ // 1. create notification task
+ String sender = "syncope86@syncope.apache.org";
+ createNotificationTask(sender);
+
+ // 2. get NotificationTaskTO for user just created
+ NotificationTaskTO taskTO = findNotificationTaskBySender(sender);
+ assertNotNull(taskTO);
+ assertTrue(taskTO.getExecutions().isEmpty());
+
+ try {
+ // 3. execute the generated NotificationTask
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), false);
+ assertNotNull(execution);
+
+ // 4. verify
+ taskTO = taskService.read(taskTO.getKey());
+ assertNotNull(taskTO);
+ assertEquals(1, taskTO.getExecutions().size());
+ } finally {
+ // Remove execution to make test re-runnable
+ taskService.deleteExecution(taskTO.getExecutions().get(0).getKey());
+ }
+ }
+
+ private NotificationTaskTO findNotificationTaskBySender(final String sender) {
+ PagedResult<NotificationTaskTO> tasks = taskService.list(TaskType.NOTIFICATION);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+ NotificationTaskTO taskTO = null;
+ for (NotificationTaskTO task : tasks.getResult()) {
+ if (sender.equals(task.getSender())) {
+ taskTO = task;
+ }
+ }
+ return taskTO;
+ }
+
+ private void createNotificationTask(final String sender) {
+ // 1. Create notification
+ NotificationTO notification = new NotificationTO();
+ notification.setTraceLevel(TraceLevel.FAILURES);
+ notification.getEvents().add("[REST]:[UserLogic]:[]:[create]:[SUCCESS]");
+
+ notification.setUserAbout(SyncopeClient.getUserSearchConditionBuilder().hasRoles(7L).query());
+
+ notification.setRecipients(SyncopeClient.getUserSearchConditionBuilder().hasRoles(8L).query());
+ notification.setSelfAsRecipient(true);
+
+ notification.setRecipientAttrName("email");
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
+
+ notification.setSender(sender);
+ String subject = "Test notification";
+ notification.setSubject(subject);
+ notification.setTemplate("optin");
+ notification.setActive(true);
+
+ Response response = notificationService.create(notification);
+ notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class);
+ assertNotNull(notification);
+
+ // 2. create user
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope@syncope.apache.org");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE68() {
+ //-----------------------------
+ // Create a new user ... it should be updated applying sync policy
+ //-----------------------------
+ UserTO userTO = new UserTO();
+ userTO.setPassword("password123");
+ userTO.setUsername("testuser2");
+
+ userTO.getPlainAttrs().add(attrTO("firstname", "testuser2"));
+ userTO.getPlainAttrs().add(attrTO("surname", "testuser2"));
+ userTO.getPlainAttrs().add(attrTO("type", "a type"));
+ userTO.getPlainAttrs().add(attrTO("fullname", "a type"));
+ userTO.getPlainAttrs().add(attrTO("userId", "testuser2@syncope.apache.org"));
+ userTO.getPlainAttrs().add(attrTO("email", "testuser2@syncope.apache.org"));
+
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION2);
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals("testuser2", userTO.getUsername());
+ assertEquals(1, userTO.getMemberships().size());
+ assertEquals(3, userTO.getResources().size());
+ //-----------------------------
+
+ try {
+ //-----------------------------
+ // add user template
+ //-----------------------------
+ UserTO template = new UserTO();
+
+ membershipTO = new MembershipTO();
+ membershipTO.setRoleId(10L);
+
+ template.getMemberships().add(membershipTO);
+
+ template.getResources().add(RESOURCE_NAME_NOPROPAGATION4);
+ //-----------------------------
+
+ // Update sync task
+ SyncTaskTO task = taskService.read(9L);
+ assertNotNull(task);
+
+ task.setUserTemplate(template);
+
+ taskService.update(task.getKey(), task);
+ SyncTaskTO actual = taskService.read(task.getKey());
+ assertNotNull(actual);
+ assertEquals(task.getKey(), actual.getKey());
+ assertFalse(actual.getUserTemplate().getResources().isEmpty());
+ assertFalse(actual.getUserTemplate().getMemberships().isEmpty());
+
+ TaskExecTO execution = execSyncTask(actual.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ userTO = readUser("testuser2");
+ assertNotNull(userTO);
+ assertEquals("testuser2@syncope.apache.org", userTO.getPlainAttrMap().get("userId").getValues().get(0));
+ assertEquals(2, userTO.getMemberships().size());
+ assertEquals(4, userTO.getResources().size());
+ } finally {
+ UserTO dUserTO = deleteUser(userTO.getKey());
+ assertNotNull(dUserTO);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE144() {
+ SchedTaskTO task = new SchedTaskTO();
+ task.setName("issueSYNCOPE144");
+ task.setDescription("issueSYNCOPE144 Description");
+ task.setJobClassName(SyncJob.class.getName());
+
+ Response response = taskService.create(task);
+ SchedTaskTO actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+ assertNotNull(actual);
+ assertEquals("issueSYNCOPE144", actual.getName());
+ assertEquals("issueSYNCOPE144 Description", actual.getDescription());
+
+ task = taskService.read(actual.getKey());
+ assertNotNull(task);
+ assertEquals("issueSYNCOPE144", task.getName());
+ assertEquals("issueSYNCOPE144 Description", task.getDescription());
+
+ task.setName("issueSYNCOPE144_2");
+ task.setDescription("issueSYNCOPE144 Description_2");
+
+ response = taskService.create(task);
+ actual = getObject(response.getLocation(), TaskService.class, SchedTaskTO.class);
+ assertNotNull(actual);
+ assertEquals("issueSYNCOPE144_2", actual.getName());
+ assertEquals("issueSYNCOPE144 Description_2", actual.getDescription());
+ }
+
+ @Test
+ public void issueSYNCOPE230() {
+ // 1. read SyncTask for resource-db-sync (table TESTSYNC on external H2)
+ execSyncTask(10L, 50, false);
+
+ // 3. read e-mail address for user created by the SyncTask first execution
+ UserTO userTO = readUser("issuesyncope230");
+ assertNotNull(userTO);
+ String email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+ assertNotNull(email);
+
+ // 4. update TESTSYNC on external H2 by changing e-mail address
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ jdbcTemplate.execute("UPDATE TESTSYNC SET email='updatedSYNCOPE230@syncope.apache.org'");
+
+ // 5. re-execute the SyncTask
+ execSyncTask(10L, 50, false);
+
+ // 6. verify that the e-mail was updated
+ userTO = readUser("issuesyncope230");
+ assertNotNull(userTO);
+ email = userTO.getPlainAttrMap().get("email").getValues().iterator().next();
+ assertNotNull(email);
+ assertEquals("updatedSYNCOPE230@syncope.apache.org", email);
+ }
+
+ private TaskExecTO execSyncTask(final Long taskKey, final int maxWaitSeconds, final boolean dryRun) {
+ AbstractTaskTO taskTO = taskService.read(taskKey);
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ int preSyncSize = taskTO.getExecutions().size();
+ TaskExecTO execution = taskService.execute(taskTO.getKey(), dryRun);
+ assertEquals("JOB_FIRED", execution.getStatus());
+
+ int i = 0;
+ int maxit = maxWaitSeconds;
+
+ // wait for sync completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ taskTO = taskService.read(taskTO.getKey());
+
+ assertNotNull(taskTO);
+ assertNotNull(taskTO.getExecutions());
+
+ i++;
+ } while (preSyncSize == taskTO.getExecutions().size() && i < maxit);
+ if (i == maxit) {
+ fail("Timeout when executing task " + taskKey);
+ }
+ return taskTO.getExecutions().get(taskTO.getExecutions().size() - 1);
+ }
+
+ private Map<Long, TaskExecTO> execSyncTasks(
+ final Set<Long> taskKeys, final int maxWaitSeconds, final boolean dryRun) throws Exception {
+
+ final ExecutorService service = Executors.newFixedThreadPool(taskKeys.size());
+ final List<Future<TaskExecTO>> futures = new ArrayList<>();
+
+ for (final Long id : taskKeys) {
+ futures.add(service.submit(new ThreadExec(this, id, maxWaitSeconds, dryRun)));
+ }
+
+ final Map<Long, TaskExecTO> res = new HashMap<>();
+
+ for (Future<TaskExecTO> f : futures) {
+ TaskExecTO taskExecTO = f.get(100, TimeUnit.SECONDS);
+ res.put(taskExecTO.getTask(), taskExecTO);
+ }
+
+ service.shutdownNow();
+
+ return res;
+ }
+
+ @Test
+ public void issueSYNCOPE272() {
+ removeTestUsers();
+
+ // create user with testdb resource
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope272@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+ try {
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ TaskExecTO taskExecTO = execSyncTask(24L, 50, false);
+
+ assertNotNull(taskExecTO.getStatus());
+ assertTrue(PropagationTaskExecStatus.valueOf(taskExecTO.getStatus()).isSuccessful());
+
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ assertNotNull(userTO.getPlainAttrMap().get("firstname").getValues().get(0));
+ } finally {
+ removeTestUsers();
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE258() {
+ // -----------------------------
+ // Add a custom correlation rule
+ // -----------------------------
+ SyncPolicyTO policyTO = policyService.read(9L);
+ policyTO.getSpecification().setUserJavaRule(TestSyncRule.class.getName());
+
+ policyService.update(policyTO.getKey(), policyTO);
+ // -----------------------------
+
+ SyncTaskTO task = new SyncTaskTO();
+ task.setName("Test Sync Rule");
+ task.setResource(RESOURCE_NAME_WS2);
+ task.setFullReconciliation(true);
+ task.setPerformCreate(true);
+ task.setPerformDelete(true);
+ task.setPerformUpdate(true);
+
+ Response response = taskService.create(task);
+ SyncTaskTO actual = getObject(response.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("s258_1@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+
+ createUser(userTO);
+
+ userTO = UserITCase.getUniqueSampleTO("s258_2@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+
+ userTO = createUser(userTO);
+
+ // change email in order to unmatch the second user
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToRemove().add("email");
+ userMod.getPlainAttrsToUpdate().add(attrMod("email", "s258@apache.org"));
+
+ userService.update(userMod.getKey(), userMod);
+
+ execSyncTask(actual.getKey(), 50, false);
+
+ SyncTaskTO executed = taskService.read(actual.getKey());
+ assertEquals(1, executed.getExecutions().size());
+
+ // asser for just one match
+ assertTrue(executed.getExecutions().get(0).getMessage().substring(0, 55) + "...",
+ executed.getExecutions().get(0).getMessage().contains("[updated/failures]: 1/0"));
+ }
+
+ @Test
+ public void issueSYNCOPE307() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("s307@apache.org");
+
+ AttrTO csvuserid = new AttrTO();
+ csvuserid.setSchema("csvuserid");
+ userTO.getDerAttrs().add(csvuserid);
+
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ userTO = userService.read(userTO.getKey());
+ assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // Update sync task
+ SyncTaskTO task = taskService.read(12L);
+ assertNotNull(task);
+
+ // add user template
+ UserTO template = new UserTO();
+ template.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ AttrTO userId = attrTO("userId", "'s307@apache.org'");
+ template.getPlainAttrs().add(userId);
+
+ AttrTO email = attrTO("email", "'s307@apache.org'");
+ template.getPlainAttrs().add(email);
+
+ task.setUserTemplate(template);
+
+ taskService.update(task.getKey(), task);
+ execSyncTask(task.getKey(), 50, false);
+
+ // check for sync policy
+ userTO = userService.read(userTO.getKey());
+ assertEquals("virtualvalue", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ try {
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, userTO.getKey());
+ assertEquals("virtualvalue", value);
+ } catch (EmptyResultDataAccessException e) {
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void bulkAction() {
+ final PagedResult<PropagationTaskTO> before = taskService.list(TaskType.PROPAGATION);
+
+ // create user with testdb resource
+ final UserTO userTO = UserITCase.getUniqueSampleTO("taskBulk@apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ createUser(userTO);
+
+ final List<PropagationTaskTO> after = new ArrayList<PropagationTaskTO>(
+ taskService.<PropagationTaskTO>list(TaskType.PROPAGATION).getResult());
+
+ after.removeAll(before.getResult());
+
+ assertFalse(after.isEmpty());
+
+ final BulkAction bulkAction = new BulkAction();
+ bulkAction.setOperation(BulkAction.Type.DELETE);
+
+ for (AbstractTaskTO taskTO : after) {
+ bulkAction.getTargets().add(String.valueOf(taskTO.getKey()));
+ }
+
+ taskService.bulk(bulkAction);
+
+ assertFalse(taskService.list(TaskType.PROPAGATION).getResult().containsAll(after));
+ }
+
+ @Test
+ public void pushMatchingUnmatchingRoles() {
+ assertFalse(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+ execSyncTask(23L, 50, false);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, 3L));
+ assertTrue(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+
+ execSyncTask(23L, 50, false);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, 3L));
+ assertFalse(roleService.read(3L).getResources().contains(RESOURCE_NAME_LDAP));
+ }
+
+ @Test
+ public void pushUnmatchingUsers() throws Exception {
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertTrue(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+
+ // ------------------------------------------
+ // Unmatching --> Assign --> dryRuyn
+ // ------------------------------------------
+ execSyncTask(13L, 50, true);
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+ assertFalse(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+
+ final Set<Long> pushTaskIds = new HashSet<>();
+ pushTaskIds.add(13L);
+ pushTaskIds.add(14L);
+ pushTaskIds.add(15L);
+ pushTaskIds.add(16L);
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Unatching --> Ignore
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Assign
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='vivaldi'").size());
+ assertTrue(userService.read(3L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ jdbcTemplate.execute("DELETE FROM test2 WHERE ID='vivaldi'");
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Provision
+ // ------------------------------------------
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='bellini'").size());
+ assertFalse(userService.read(4L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ jdbcTemplate.execute("DELETE FROM test2 WHERE ID='bellini'");
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Unmatching --> Unlink
+ // ------------------------------------------
+ assertEquals(0, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='puccini'").size());
+ assertFalse(userService.read(5L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // ------------------------------------------
+ }
+
+ @Test
+ public void pushMatchingUser() throws Exception {
+ assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+
+ // ------------------------------------------
+ // Matching --> Deprovision --> dryRuyn
+ // ------------------------------------------
+ execSyncTask(19L, 50, true);
+ assertTrue(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+ // ------------------------------------------
+
+ final Set<Long> pushTaskIds = new HashSet<>();
+ pushTaskIds.add(18L);
+ pushTaskIds.add(19L);
+ pushTaskIds.add(16L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Matching --> Deprovision && Ignore
+ // ------------------------------------------
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // DELETE Capability not available ....
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Matching --> Unassign
+ // ------------------------------------------
+ assertFalse(userService.read(1L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ // DELETE Capability not available ....
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='rossini'").size());
+ // ------------------------------------------
+
+ // ------------------------------------------
+ // Matching --> Link
+ // ------------------------------------------
+ execSyncTask(20L, 50, false);
+ assertTrue(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+
+ pushTaskIds.clear();
+ pushTaskIds.add(21L);
+ pushTaskIds.add(22L);
+
+ execSyncTasks(pushTaskIds, 50, false);
+
+ // ------------------------------------------
+ // Matching --> Unlink && Update
+ // ------------------------------------------
+ assertFalse(userService.read(2L).getResources().contains(RESOURCE_NAME_TESTDB2));
+ assertEquals(1, jdbcTemplate.queryForList("SELECT ID FROM test2 WHERE ID='verdi'").size());
+ // ------------------------------------------
+ }
+
+ @Test
+ public void issueSYNCOPE313DB() throws Exception {
+ // 1. create user in DB
+ UserTO user = UserITCase.getUniqueSampleTO("syncope313-db@syncope.apache.org");
+ user.setPassword("security");
+ user.getResources().add(RESOURCE_NAME_TESTDB);
+ user = createUser(user);
+ assertNotNull(user);
+ assertFalse(user.getResources().isEmpty());
+
+ // 2. Check that the DB resource has the correct password
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ String value = jdbcTemplate.queryForObject(
+ "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+ assertEquals(Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1), value.toUpperCase());
+
+ // 3. Update the password in the DB
+ String newPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
+ jdbcTemplate.execute(
+ "UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'");
+
+ // 4. Sync the user from the resource
+ SyncTaskTO syncTask = new SyncTaskTO();
+ syncTask.setName("DB Sync Task");
+ syncTask.setPerformCreate(true);
+ syncTask.setPerformUpdate(true);
+ syncTask.setFullReconciliation(true);
+ syncTask.setResource(RESOURCE_NAME_TESTDB);
+ syncTask.getActionsClassNames().add(DBPasswordSyncActions.class.getName());
+ Response taskResponse = taskService.create(syncTask);
+
+ SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ syncTask = taskService.read(actual.getKey());
+ assertNotNull(syncTask);
+ assertEquals(actual.getKey(), syncTask.getKey());
+ assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+
+ TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 5. Test the sync'd user
+ UserTO updatedUser = userService.read(user.getKey());
+ assertEquals(newPassword, updatedUser.getPassword());
+
+ // 6. Delete SyncTask + user
+ taskService.delete(syncTask.getKey());
+ deleteUser(user.getKey());
+ }
+
+ @Test
+ public void issueSYNCOPE313LDAP() throws Exception {
+ // First of all, clear any potential conflict with existing user / role
+ ldapCleanup();
+
+ // 1. create user in LDAP
+ UserTO user = UserITCase.getUniqueSampleTO("syncope313-ldap@syncope.apache.org");
+ user.setPassword("security");
+ user.getResources().add(RESOURCE_NAME_LDAP);
+ user = createUser(user);
+ assertNotNull(user);
+ assertFalse(user.getResources().isEmpty());
+
+ // 2. request to change password only on Syncope and not on LDAP
+ UserMod userMod = new UserMod();
+ userMod.setKey(user.getKey());
+ userMod.setPassword("new-security");
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.setOnSyncope(true);
+ pwdPropRequest.getResourceNames().clear();
+ userMod.setPwdPropRequest(pwdPropRequest);
+ updateUser(userMod);
+
+ // 3. Check that the Syncope user now has the changed password
+ UserTO updatedUser = userService.read(user.getKey());
+ String encodedNewPassword = Encryptor.getInstance().encode("new-security", CipherAlgorithm.SHA1);
+ assertEquals(encodedNewPassword, updatedUser.getPassword());
+
+ // 4. Check that the LDAP resource has the old password
+ ConnObjectTO connObject =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, user.getKey());
+ assertNotNull(getLdapRemoteObject(
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+ "security",
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+ // 5. Update the LDAP Connector to retrieve passwords
+ ResourceTO ldapResource = resourceService.read(RESOURCE_NAME_LDAP);
+ ConnInstanceTO resourceConnector = connectorService.read(ldapResource.getConnectorId());
+ ConnConfProperty property = resourceConnector.getConfigurationMap().get("retrievePasswordsWithSearch");
+ property.getValues().clear();
+ property.getValues().add(Boolean.TRUE);
+ connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+
+ // 6. Sync the user from the resource
+ SyncTaskTO syncTask = new SyncTaskTO();
+ syncTask.setName("LDAP Sync Task");
+ syncTask.setPerformCreate(true);
+ syncTask.setPerformUpdate(true);
+ syncTask.setFullReconciliation(true);
+ syncTask.setResource(RESOURCE_NAME_LDAP);
+ syncTask.getActionsClassNames().add(LDAPPasswordSyncActions.class.getName());
+ Response taskResponse = taskService.create(syncTask);
+
+ SyncTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, SyncTaskTO.class);
+ assertNotNull(actual);
+
+ syncTask = taskService.read(actual.getKey());
+ assertNotNull(syncTask);
+ assertEquals(actual.getKey(), syncTask.getKey());
+ assertEquals(actual.getJobClassName(), syncTask.getJobClassName());
+
+ TaskExecTO execution = execSyncTask(syncTask.getKey(), 50, false);
+ final String status = execution.getStatus();
+ assertNotNull(status);
+ assertTrue(PropagationTaskExecStatus.valueOf(status).isSuccessful());
+
+ // 7. Test the sync'd user
+ String syncedPassword = Encryptor.getInstance().encode("security", CipherAlgorithm.SHA1);
+ updatedUser = userService.read(user.getKey());
+ assertEquals(syncedPassword, updatedUser.getPassword());
+
+ // 8. Delete SyncTask + user + reset the connector
+ taskService.delete(syncTask.getKey());
+ property.getValues().clear();
+ property.getValues().add(Boolean.FALSE);
+ connectorService.update(ldapResource.getConnectorId(), resourceConnector);
+ deleteUser(updatedUser.getKey());
+ }
+
+ @Test
+ public void issueSYNCOPE598() {
+ // create a new role schema
+ final PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("LDAPGroupName" + getUUIDString());
+ schemaTO.setType(AttrSchemaType.String);
+ schemaTO.setMandatoryCondition("true");
+
+ final PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+ assertEquals(schemaTO, newPlainSchemaTO);
+
+ // create a new sample role
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("all" + getUUIDString());
+ roleTO.setParent(8L);
+
+ roleTO.getRAttrTemplates().add(newPlainSchemaTO.getKey());
+ roleTO.getPlainAttrs().add(attrTO(newPlainSchemaTO.getKey(), "all"));
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ String resourceName = "resource-ldap-roleonly";
+ ResourceTO newResourceTO = null;
+
+ try {
+ // Create resource ad-hoc
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(105L);
+
+ final MappingTO umapping = new MappingTO();
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.Username);
+ item.setExtAttrName("cn");
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ item.setMandatoryCondition("true");
+ umapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName("surname");
+ item.setIntAttrName("sn");
+ item.setPurpose(MappingPurpose.BOTH);
+ umapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName("email");
+ item.setIntAttrName("mail");
+ item.setPurpose(MappingPurpose.BOTH);
+ umapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.Password);
+ item.setPassword(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ item.setMandatoryCondition("true");
+ umapping.addItem(item);
+
+ umapping.setAccountLink("'cn=' + username + ',ou=people,o=isp'");
+
+ final MappingTO rmapping = new MappingTO();
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.RolePlainSchema);
+ item.setExtAttrName("cn");
+ item.setIntAttrName(newPlainSchemaTO.getKey());
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ rmapping.setAccountIdItem(item);
+
+ rmapping.setAccountLink("'cn=' + " + newPlainSchemaTO.getKey() + " + ',ou=groups,o=isp'");
+
+ resourceTO.setRmapping(rmapping);
+
+ Response response = resourceService.create(resourceTO);
+ newResourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(newResourceTO);
+ assertNull(newResourceTO.getUmapping());
+ assertNotNull(newResourceTO.getRmapping());
+
+ // create push task ad-hoc
+ final PushTaskTO task = new PushTaskTO();
+ task.setName("issueSYNCOPE598");
+ task.setResource(resourceName);
+ task.setPerformCreate(true);
+ task.setPerformDelete(true);
+ task.setPerformUpdate(true);
+ task.setUnmatchingRule(UnmatchingRule.ASSIGN);
+ task.setMatchingRule(MatchingRule.UPDATE);
+
+ response = taskService.create(task);
+ final PushTaskTO push = getObject(response.getLocation(), TaskService.class, PushTaskTO.class);
+
+ assertNotNull(push);
+
+ // execute the new task
+ final TaskExecTO pushExec = execSyncTask(push.getKey(), 50, false);
+ assertTrue(PropagationTaskExecStatus.valueOf(pushExec.getStatus()).isSuccessful());
+ } finally {
+ roleService.delete(roleTO.getKey());
+ if (newResourceTO != null) {
+ resourceService.delete(resourceName);
+ }
+ }
+ }
+}
[14/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
FIT server integration tests
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/80589a1b
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/80589a1b
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/80589a1b
Branch: refs/heads/2_0_X
Commit: 80589a1b9b384f07670afe4f1581c3ceb2794501
Parents: b7d9add
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jan 23 17:40:48 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jan 23 17:40:48 2015 +0100
----------------------------------------------------------------------
.../syncope/core/util/ContentExporter.java | 8 +-
pom.xml | 1 +
.../common/lib/AttributableOperations.java | 28 +-
.../lib/annotation/FormAttributeField.java | 2 +-
.../common/lib/mod/AbstractAttributableMod.java | 4 +-
.../lib/report/AbstractReportletConf.java | 3 +-
.../common/lib/report/RoleReportletConf.java | 18 +-
.../common/lib/report/UserReportletConf.java | 18 +-
.../syncope/common/lib/to/ConnObjectTO.java | 2 +-
.../apache/syncope/common/lib/to/LoggerTO.java | 10 +-
.../apache/syncope/common/lib/to/RoleTO.java | 10 +-
.../common/lib/types/ClientExceptionType.java | 21 +-
.../common/lib/types/IntMappingType.java | 12 +-
syncope620/common/rest-api/pom.xml | 1 +
.../common/rest/api/CollectionWrapper.java | 4 +-
.../syncope/common/rest/api/RESTHeaders.java | 2 +-
.../common/rest/api/service/ReportService.java | 18 +-
.../rest/api/service/ResourceService.java | 2 +-
.../common/rest/api/service/RoleService.java | 5 +-
.../rest/api/service/UserSelfService.java | 6 +-
.../rest/api/service/WorkflowService.java | 4 +-
syncope620/fit/reference/pom.xml | 121 +
.../DoubleValueAttributableTransformer.java | 75 +
.../fit/server/reference/TestSyncActions.java | 83 +
.../fit/server/reference/TestSyncRule.java | 37 +
.../src/main/resources/connid.properties | 5 +
.../src/main/resources/logic.properties | 18 +
.../fit/server/reference/AbstractITCase.java | 365 +++
.../fit/server/reference/ActivitiDetector.java | 36 +
.../server/reference/AuthenticationITCase.java | 440 ++++
.../server/reference/ConfigurationITCase.java | 210 ++
.../fit/server/reference/ConnectorITCase.java | 723 ++++++
.../fit/server/reference/DerSchemaITCase.java | 151 ++
.../fit/server/reference/LoggerITCase.java | 215 ++
.../server/reference/NotificationITCase.java | 172 ++
.../fit/server/reference/PlainSchemaITCase.java | 317 +++
.../fit/server/reference/PolicyITCase.java | 238 ++
.../fit/server/reference/ReportITCase.java | 252 ++
.../fit/server/reference/ResourceITCase.java | 590 +++++
.../fit/server/reference/RoleITCase.java | 797 ++++++
.../fit/server/reference/SearchITCase.java | 182 ++
.../reference/SecurityQuestionITCase.java | 99 +
.../fit/server/reference/TaskITCase.java | 1385 ++++++++++
.../fit/server/reference/UserITCase.java | 2442 ++++++++++++++++++
.../fit/server/reference/UserSelfITCase.java | 342 +++
.../server/reference/UserWorkflowITCase.java | 299 +++
.../fit/server/reference/VirAttrITCase.java | 872 +++++++
.../fit/server/reference/VirSchemaITCase.java | 122 +
.../fit/server/reference/WorkflowITCase.java | 86 +
.../reference/src/test/resources/favicon.jpg | Bin 0 -> 557 bytes
.../fit/reference/src/test/resources/test.csv | 10 +
.../src/test/resources/testJDBCContext.xml | 33 +
syncope620/pom.xml | 144 +-
.../syncope/server/logic/LoggerLogic.java | 8 +-
.../syncope/server/logic/ReportLogic.java | 40 +-
.../server/logic/SpringBeanJobFactory.java | 97 -
.../apache/syncope/server/logic/TaskLogic.java | 6 +-
.../apache/syncope/server/logic/UserLogic.java | 2 +-
.../server/logic/init/JobInstanceLoader.java | 41 -
.../logic/init/JobInstanceLoaderImpl.java | 1 +
.../server/logic/report/RoleReportlet.java | 6 +-
.../server/logic/report/UserReportlet.java | 8 +-
.../syncope/server/logic/NotificationTest.java | 16 +-
.../logic/src/test/resources/logicTest.xml | 2 +-
.../syncope/server/misc/ConnObjectUtil.java | 8 +-
.../apache/syncope/server/misc/MappingUtil.java | 18 +-
.../misc/policy/AccountPolicyEnforcer.java | 1 +
.../misc/policy/PasswordPolicyEnforcer.java | 7 +-
.../server/misc/policy/UserSuspender.java | 26 -
.../server/misc/security/AuthContextUtil.java | 2 +-
.../jpa/content/XMLContentExporter.java | 9 +-
.../jpa/dao/JPASubjectSearchDAO.java | 29 +-
.../server/persistence/jpa/dao/JPATaskDAO.java | 2 +-
.../server/persistence/jpa/dao/JPAUserDAO.java | 3 +
.../jpa/entity/AbstractAttrTemplate.java | 14 -
.../jpa/entity/AbstractDerAttrTemplate.java | 41 +
.../jpa/entity/AbstractPlainAttrTemplate.java | 27 +
.../jpa/entity/AbstractPlainSchema.java | 3 +-
.../jpa/entity/AbstractVirAttrTemplate.java | 41 +
.../jpa/entity/JPAAttributableUtil.java | 12 +-
.../persistence/jpa/entity/JPAConnInstance.java | 4 +-
.../persistence/jpa/entity/JPAReport.java | 2 -
.../entity/membership/JPAMDerAttrTemplate.java | 4 +-
.../membership/JPAMPlainAttrTemplate.java | 13 +-
.../entity/membership/JPAMVirAttrTemplate.java | 4 +-
.../jpa/entity/role/JPARDerAttrTemplate.java | 4 +-
.../jpa/entity/role/JPARPlainAttrTemplate.java | 13 +-
.../jpa/entity/role/JPARVirAttrTemplate.java | 4 +-
.../jpa/entity/task/JPATaskUtil.java | 32 +-
.../entity/EntityValidationListener.java | 28 +-
.../src/main/resources/META-INF/orm.xml | 20 +-
.../jpa/entity/AttributableSearchTest.java | 30 +-
.../jpa/entity/NotificationTest.java | 6 +-
.../persistence/jpa/entity/ResourceTest.java | 10 +-
.../jpa/relationship/ResourceTest.java | 7 +-
.../src/test/resources/content.xml | 100 +-
.../server/provisioning/api/UserSuspender.java | 26 +
.../provisioning/api/job/JobInstanceLoader.java | 41 +
.../api/sync/ProvisioningActions.java | 5 +-
.../api/sync/RolePushResultHandler.java | 23 +
.../api/sync/RoleSyncResultHandler.java | 26 +
.../api/sync/SyncopePushResultHandler.java | 26 +
.../api/sync/SyncopeSyncResultHandler.java | 29 +
.../api/sync/UserPushResultHandler.java | 23 +
.../api/sync/UserSyncResultHandler.java | 23 +
.../provisioning/java/AsyncConnectorFacade.java | 26 +-
.../provisioning/java/ConnectorFacadeProxy.java | 13 +-
.../java/DefaultRoleProvisioningManager.java | 2 +-
.../java/DefaultUserProvisioningManager.java | 27 +-
.../provisioning/java/UserSuspenderImpl.java | 51 +
.../data/AbstractAttributableDataBinder.java | 8 +-
.../java/data/ReportDataBinderImpl.java | 14 +-
.../java/data/RoleDataBinderImpl.java | 12 +-
.../java/data/SchemaDataBinderImpl.java | 13 +-
.../java/data/TaskDataBinderImpl.java | 16 +-
.../java/job/SpringBeanJobFactory.java | 97 +
.../java/notification/NotificationManager.java | 2 +-
.../PriorityPropagationTaskExecutor.java | 4 +-
.../java/sync/AbstractProvisioningJob.java | 7 +-
.../java/sync/AbstractPushResultHandler.java | 374 +++
.../sync/AbstractSubjectPushResultHandler.java | 371 ---
.../sync/AbstractSubjectSyncResultHandler.java | 624 -----
.../java/sync/AbstractSyncResultHandler.java | 617 +++++
.../java/sync/DefaultPushActions.java | 6 +-
.../java/sync/DefaultSyncActions.java | 6 +-
.../java/sync/LDAPMembershipSyncActions.java | 16 +-
.../provisioning/java/sync/PushJobImpl.java | 28 +-
.../java/sync/RolePushResultHandler.java | 154 --
.../java/sync/RolePushResultHandlerImpl.java | 155 ++
.../java/sync/RoleSyncResultHandler.java | 167 --
.../java/sync/RoleSyncResultHandlerImpl.java | 169 ++
.../provisioning/java/sync/SyncJobImpl.java | 32 +-
.../provisioning/java/sync/SyncUtilities.java | 27 +-
.../java/sync/UserPushResultHandler.java | 159 --
.../java/sync/UserPushResultHandlerImpl.java | 160 ++
.../java/sync/UserSyncResultHandler.java | 155 --
.../java/sync/UserSyncResultHandlerImpl.java | 149 ++
.../main/resources/mailTemplates/optin.html.vm | 8 +-
.../main/resources/mailTemplates/optin.txt.vm | 8 +-
.../src/main/resources/provisioningContext.xml | 10 +-
.../java/data/ResourceDataBinderTest.java | 2 +-
.../rest/cxf/service/AbstractServiceImpl.java | 4 +-
.../rest/cxf/service/LoggerServiceImpl.java | 2 +-
.../rest/cxf/service/ReportServiceImpl.java | 12 +-
.../cxf/service/RestServiceExceptionMapper.java | 3 +-
145 files changed, 13494 insertions(+), 2229 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java b/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java
index e7fd35b..84e2bc4 100644
--- a/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java
+++ b/core/src/main/java/org/apache/syncope/core/util/ContentExporter.java
@@ -70,9 +70,9 @@ public class ContentExporter extends AbstractContentDealer {
"SYNCOPEUSER", "UATTR", "UATTRVALUE", "UATTRUNIQUEVALUE", "UDERATTR", "UVIRATTR",
"MEMBERSHIP", "MATTR", "MATTRVALUE", "MATTRUNIQUEVALUE", "MDERATTR", "MVIRATTR"
}));
-
+
protected final static Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =
- new HashSet<String>(Arrays.asList(new String[] {"TEMPLATE"}));
+ new HashSet<String>(Arrays.asList(new String[] { "TEMPLATE" }));
protected static final Map<String, String> TABLES_TO_BE_FILTERED =
Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
@@ -85,10 +85,10 @@ public class ContentExporter extends AbstractContentDealer {
for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) {
if (tableName.toUpperCase().startsWith(prefix)) {
for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) {
- if (!tableName.toUpperCase().endsWith(suffix)) {
+ if (!tableName.toUpperCase().endsWith(suffix)) {
allowed = false;
}
- }
+ }
}
}
return allowed;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 924b4aa..26a6cb2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1428,6 +1428,7 @@ under the License.
<exclude>**/.*</exclude>
<exclude>**/deb/control/conffiles</exclude>
<exclude>**/deb/control/control</exclude>
+ <exclude>**/syncope620/**</exclude>
</excludes>
</configuration>
<executions>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
index 983cee4..ad5d322 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
@@ -81,7 +81,7 @@ public final class AttributableOperations {
if (virtuals) {
result.getVirAttrsToUpdate().add(mod);
} else {
- result.getAttrsToUpdate().add(mod);
+ result.getPlainAttrsToUpdate().add(mod);
}
} else if (!updatedValues.equals(originalValues)) {
// avoid unwanted inputs
@@ -93,7 +93,7 @@ public final class AttributableOperations {
if (virtuals) {
result.getVirAttrsToRemove().add(mod.getSchema());
} else {
- result.getAttrsToRemove().add(mod.getSchema());
+ result.getPlainAttrsToRemove().add(mod.getSchema());
}
}
}
@@ -104,7 +104,7 @@ public final class AttributableOperations {
if (virtuals) {
result.getVirAttrsToUpdate().add(mod);
} else {
- result.getAttrsToUpdate().add(mod);
+ result.getPlainAttrsToUpdate().add(mod);
}
}
}
@@ -124,15 +124,15 @@ public final class AttributableOperations {
result.setKey(updated.getKey());
// 2. attributes
- Map<String, AttrTO> updatedAttrs = new HashMap<>(updated.getAttrMap());
- Map<String, AttrTO> originalAttrs = new HashMap<>(original.getAttrMap());
+ Map<String, AttrTO> updatedAttrs = new HashMap<>(updated.getPlainAttrMap());
+ Map<String, AttrTO> originalAttrs = new HashMap<>(original.getPlainAttrMap());
Set<String> originalAttrNames = new HashSet<>(originalAttrs.keySet());
originalAttrNames.removeAll(updatedAttrs.keySet());
if (!incremental) {
- result.getAttrsToRemove().clear();
- result.getAttrsToRemove().addAll(originalAttrNames);
+ result.getPlainAttrsToRemove().clear();
+ result.getPlainAttrsToRemove().addAll(originalAttrNames);
}
Set<String> emptyUpdatedAttrs = new HashSet<>();
@@ -144,7 +144,7 @@ public final class AttributableOperations {
}
for (String emptyUpdatedAttr : emptyUpdatedAttrs) {
updatedAttrs.remove(emptyUpdatedAttr);
- result.getAttrsToRemove().add(emptyUpdatedAttr);
+ result.getPlainAttrsToRemove().add(emptyUpdatedAttr);
}
populate(updatedAttrs, originalAttrs, result);
@@ -269,8 +269,8 @@ public final class AttributableOperations {
attrMod.getValuesToBeAdded().addAll(attr.getValues());
if (!attrMod.isEmpty()) {
- membMod.getAttrsToUpdate().add(attrMod);
- membMod.getAttrsToRemove().add(attrMod.getSchema());
+ membMod.getPlainAttrsToUpdate().add(attrMod);
+ membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
}
}
for (AttrTO attr : entry.getValue().getDerAttrs()) {
@@ -283,7 +283,7 @@ public final class AttributableOperations {
if (!attrMod.isEmpty()) {
membMod.getVirAttrsToUpdate().add(attrMod);
- membMod.getAttrsToRemove().add(attrMod.getSchema());
+ membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
}
}
}
@@ -333,7 +333,7 @@ public final class AttributableOperations {
result.setInheritTemplates(updated.isInheritTemplates());
result.setInheritAccountPolicy(updated.isInheritAccountPolicy());
result.setInheritPasswordPolicy(updated.isInheritPasswordPolicy());
- result.setInheritPlainAttrs(updated.isInheritAttrs());
+ result.setInheritPlainAttrs(updated.isInheritPlainAttrs());
result.setInheritDerAttrs(updated.isInheritDerAttrs());
result.setInheritVirAttrs(updated.isInheritVirAttrs());
@@ -448,8 +448,8 @@ public final class AttributableOperations {
final K mod, final T result) {
// 1. attributes
- result.getPlainAttrs().addAll(getUpdateValues(to.getAttrMap(),
- mod.getAttrsToRemove(), mod.getAttrsToUpdate()));
+ result.getPlainAttrs().addAll(getUpdateValues(to.getPlainAttrMap(),
+ mod.getPlainAttrsToRemove(), mod.getPlainAttrsToUpdate()));
// 2. derived attributes
Map<String, AttrTO> attrs = to.getDerAttrMap();
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
index f007020..2c1c980 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
@@ -32,5 +32,5 @@ public @interface FormAttributeField {
boolean roleSearch() default false;
- IntMappingType schema() default IntMappingType.UserSchema;
+ IntMappingType schema() default IntMappingType.UserPlainSchema;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
index 5d6b982..aa5d442 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
@@ -61,14 +61,14 @@ public abstract class AbstractAttributableMod extends AbstractBaseBean {
@XmlElementWrapper(name = "plainAttrsToRemove")
@XmlElement(name = "attribute")
@JsonProperty("plainAttrsToRemove")
- public Set<String> getAttrsToRemove() {
+ public Set<String> getPlainAttrsToRemove() {
return plainAttrsToRemove;
}
@XmlElementWrapper(name = "plainAttrsToUpdate")
@XmlElement(name = "attributeMod")
@JsonProperty("plainAttrsToUpdate")
- public Set<AttrMod> getAttrsToUpdate() {
+ public Set<AttrMod> getPlainAttrsToUpdate() {
return plainAttrsToUpdate;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
index 6efdb32..0082591 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.report;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.AbstractBaseBean;
@XmlType
@@ -31,7 +32,7 @@ public abstract class AbstractReportletConf extends AbstractBaseBean implements
private String name;
public AbstractReportletConf() {
- this("");
+ this(StringUtils.EMPTY);
setName(getClass().getName());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
index 295316b..e91252d 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
@@ -52,16 +52,16 @@ public class RoleReportletConf extends AbstractReportletConf {
@FormAttributeField(userSearch = true)
private String matchingCond;
- @FormAttributeField(schema = IntMappingType.RoleSchema)
- private final List<String> attrs = new ArrayList<String>();
+ @FormAttributeField(schema = IntMappingType.RolePlainSchema)
+ private final List<String> attrs = new ArrayList<>();
@FormAttributeField(schema = IntMappingType.RoleDerivedSchema)
- private final List<String> derAttrs = new ArrayList<String>();
+ private final List<String> derAttrs = new ArrayList<>();
@FormAttributeField(schema = IntMappingType.RoleVirtualSchema)
- private final List<String> virAttrs = new ArrayList<String>();
+ private final List<String> virAttrs = new ArrayList<>();
- private final List<Feature> features = new ArrayList<Feature>();
+ private final List<Feature> features = new ArrayList<>();
public RoleReportletConf() {
super();
@@ -71,10 +71,10 @@ public class RoleReportletConf extends AbstractReportletConf {
super(name);
}
- @XmlElementWrapper(name = "attributes")
- @XmlElement(name = "attribute")
- @JsonProperty("attributes")
- public List<String> getAttrs() {
+ @XmlElementWrapper(name = "plainAttributes")
+ @XmlElement(name = "plainAttribute")
+ @JsonProperty("plainAttributes")
+ public List<String> getPlainAttrs() {
return attrs;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
index afd806a..c82052c 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
@@ -57,16 +57,16 @@ public class UserReportletConf extends AbstractReportletConf {
@FormAttributeField(userSearch = true)
private String matchingCond;
- @FormAttributeField(schema = IntMappingType.UserSchema)
- private final List<String> attrs = new ArrayList<String>();
+ @FormAttributeField(schema = IntMappingType.UserPlainSchema)
+ private final List<String> attrs = new ArrayList<>();
@FormAttributeField(schema = IntMappingType.UserDerivedSchema)
- private final List<String> derAttrs = new ArrayList<String>();
+ private final List<String> derAttrs = new ArrayList<>();
@FormAttributeField(schema = IntMappingType.UserVirtualSchema)
- private final List<String> virAttrs = new ArrayList<String>();
+ private final List<String> virAttrs = new ArrayList<>();
- private final List<Feature> features = new ArrayList<Feature>();
+ private final List<Feature> features = new ArrayList<>();
public UserReportletConf() {
super();
@@ -76,10 +76,10 @@ public class UserReportletConf extends AbstractReportletConf {
super(name);
}
- @XmlElementWrapper(name = "attributes")
- @XmlElement(name = "attribute")
- @JsonProperty("attributes")
- public List<String> getAttrs() {
+ @XmlElementWrapper(name = "plainAttributes")
+ @XmlElement(name = "plainAttribute")
+ @JsonProperty("plainAttributes")
+ public List<String> getPlainAttrs() {
return attrs;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
index d298609..78256ba 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/ConnObjectTO.java
@@ -46,7 +46,7 @@ public class ConnObjectTO extends AbstractAnnotatedBean {
}
@JsonIgnore
- public Map<String, AttrTO> getAttrMap() {
+ public Map<String, AttrTO> getPlainAttrMap() {
Map<String, AttrTO> result = new HashMap<>(attrs.size());
for (AttrTO attributeTO : attrs) {
result.put(attributeTO.getSchema(), attributeTO);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
index 263ab97..810a143 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/LoggerTO.java
@@ -29,7 +29,7 @@ public class LoggerTO extends AbstractBaseBean {
private static final long serialVersionUID = -7794833835668648505L;
- private String name;
+ private String key;
private LoggerLevel level;
@@ -41,11 +41,11 @@ public class LoggerTO extends AbstractBaseBean {
this.level = level;
}
- public String getName() {
- return name;
+ public String getKey() {
+ return key;
}
- public void setName(final String name) {
- this.name = name;
+ public void setKey(final String key) {
+ this.key = key;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
index 6e24929..2a353cf 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/to/RoleTO.java
@@ -47,7 +47,7 @@ public class RoleTO extends AbstractSubjectTO {
private boolean inheritTemplates;
- private boolean inheritAttrs;
+ private boolean inheritPlainAttrs;
private boolean inheritDerAttrs;
@@ -123,12 +123,12 @@ public class RoleTO extends AbstractSubjectTO {
this.inheritTemplates = inheritTemplates;
}
- public boolean isInheritAttrs() {
- return inheritAttrs;
+ public boolean isInheritPlainAttrs() {
+ return inheritPlainAttrs;
}
- public void setInheritAttrs(final boolean inheritAttrs) {
- this.inheritAttrs = inheritAttrs;
+ public void setInheritPlainAttrs(final boolean inheritPlainAttrs) {
+ this.inheritPlainAttrs = inheritPlainAttrs;
}
public boolean isInheritDerAttrs() {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
index 0c272a9..c55cebd 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/ClientExceptionType.java
@@ -29,30 +29,25 @@ public enum ClientExceptionType {
EntityExists(Response.Status.CONFLICT),
GenericPersistence(Response.Status.BAD_REQUEST),
InvalidSecurityAnswer(Response.Status.BAD_REQUEST),
+ InvalidEntity(Response.Status.BAD_REQUEST),
InvalidLogger(Response.Status.BAD_REQUEST),
InvalidConnInstance(Response.Status.BAD_REQUEST),
InvalidConnIdConf(Response.Status.BAD_REQUEST),
InvalidPolicy(Response.Status.BAD_REQUEST),
- InvalidSyncopeConf(Response.Status.BAD_REQUEST),
- InvalidSyncopeRole(Response.Status.BAD_REQUEST),
+ InvalidConf(Response.Status.BAD_REQUEST),
+ InvalidRole(Response.Status.BAD_REQUEST),
+ InvalidReport(Response.Status.BAD_REQUEST),
InvalidReportExec(Response.Status.BAD_REQUEST),
InvalidRoles(Response.Status.BAD_REQUEST),
InvalidSchemaDefinition(Response.Status.BAD_REQUEST),
InvalidSearchExpression(Response.Status.BAD_REQUEST),
InvalidPageOrSize(Response.Status.BAD_REQUEST),
InvalidPropagationTaskExecReport(Response.Status.BAD_REQUEST),
- InvalidUSchema(Response.Status.BAD_REQUEST),
- InvalidUDerSchema(Response.Status.BAD_REQUEST),
- InvalidUVirSchema(Response.Status.BAD_REQUEST),
- InvalidRSchema(Response.Status.BAD_REQUEST),
- InvalidRDerSchema(Response.Status.BAD_REQUEST),
- InvalidRVirSchema(Response.Status.BAD_REQUEST),
- InvalidMSchema(Response.Status.BAD_REQUEST),
- InvalidMDerSchema(Response.Status.BAD_REQUEST),
- InvalidMVirSchema(Response.Status.BAD_REQUEST),
- InvalidCSchema(Response.Status.BAD_REQUEST),
+ InvalidPlainSchema(Response.Status.BAD_REQUEST),
+ InvalidDerSchema(Response.Status.BAD_REQUEST),
+ InvalidVirSchema(Response.Status.BAD_REQUEST),
InvalidSchemaMapping(Response.Status.BAD_REQUEST),
- InvalidSyncopeUser(Response.Status.BAD_REQUEST),
+ InvalidUser(Response.Status.BAD_REQUEST),
InvalidExternalResource(Response.Status.BAD_REQUEST),
InvalidNotification(Response.Status.BAD_REQUEST),
InvalidPropagationTask(Response.Status.BAD_REQUEST),
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
----------------------------------------------------------------------
diff --git a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
index 5fefcc9..7dd60d6 100644
--- a/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
+++ b/syncope620/common/lib/src/main/java/org/apache/syncope/common/lib/types/IntMappingType.java
@@ -35,7 +35,7 @@ public enum IntMappingType {
// -------------------------
// User attribute types (the same in UserMappingType)
// -------------------------
- UserSchema(AttributableType.USER),
+ UserPlainSchema(AttributableType.USER),
UserDerivedSchema(AttributableType.USER),
UserVirtualSchema(AttributableType.USER),
UserId(AttributableType.USER),
@@ -44,7 +44,7 @@ public enum IntMappingType {
// -------------------------
// Role attribute types (the same in RoleMappingType)
// -------------------------
- RoleSchema(AttributableType.ROLE),
+ RolePlainSchema(AttributableType.ROLE),
RoleDerivedSchema(AttributableType.ROLE),
RoleVirtualSchema(AttributableType.ROLE),
RoleId(AttributableType.ROLE),
@@ -53,7 +53,7 @@ public enum IntMappingType {
// -------------------------
// Membership attribute types (the same in MembershipMappingType)
// -------------------------
- MembershipSchema(AttributableType.MEMBERSHIP),
+ MembershipPlainSchema(AttributableType.MEMBERSHIP),
MembershipDerivedSchema(AttributableType.MEMBERSHIP),
MembershipVirtualSchema(AttributableType.MEMBERSHIP),
MembershipId(AttributableType.MEMBERSHIP);
@@ -164,7 +164,7 @@ public enum IntMappingType {
*/
private enum UserMappingType {
- UserSchema,
+ UserPlainSchema,
UserDerivedSchema,
UserVirtualSchema,
UserId,
@@ -178,7 +178,7 @@ public enum IntMappingType {
*/
private enum RoleMappingType {
- RoleSchema,
+ RolePlainSchema,
RoleDerivedSchema,
RoleVirtualSchema,
RoleId,
@@ -192,7 +192,7 @@ public enum IntMappingType {
*/
private enum MembershipMappingType {
- MembershipSchema,
+ MembershipPlainSchema,
MembershipDerivedSchema,
MembershipVirtualSchema,
MembershipId;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/pom.xml b/syncope620/common/rest-api/pom.xml
index 967573e..addc3b9 100644
--- a/syncope620/common/rest-api/pom.xml
+++ b/syncope620/common/rest-api/pom.xml
@@ -73,6 +73,7 @@ under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
+ <inherited>true</inherited>
<executions>
<execution>
<id>attach-javadocs</id>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
index 070f73c..1ab407d 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/CollectionWrapper.java
@@ -59,7 +59,7 @@ public final class CollectionWrapper {
List<AuditLoggerName> respons = new ArrayList<AuditLoggerName>();
for (LoggerTO l : logger) {
try {
- respons.add(AuditLoggerName.fromLoggerName(l.getName()));
+ respons.add(AuditLoggerName.fromLoggerName(l.getKey()));
} catch (Exception ignore) {
// ignore
}
@@ -71,7 +71,7 @@ public final class CollectionWrapper {
List<LoggerTO> respons = new ArrayList<LoggerTO>();
for (AuditLoggerName l : auditNames) {
LoggerTO loggerTO = new LoggerTO();
- loggerTO.setName(l.toLoggerName());
+ loggerTO.setKey(l.toLoggerName());
loggerTO.setLevel(LoggerLevel.DEBUG);
respons.add(loggerTO);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
index 715270b..20e58c6 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/RESTHeaders.java
@@ -77,7 +77,7 @@ public final class RESTHeaders {
/**
* Declares the type of exception being raised.
*
- * @see ClientExceptionType
+ * @see org.apache.syncope.common.lib.types.ClientExceptionType
*/
public static final String ERROR_CODE = "X-Application-Error-Code";
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
index b8f2826..1e9f943 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ReportService.java
@@ -72,13 +72,13 @@ public interface ReportService extends JAXRSService {
/**
* Returns report execution with matching key.
*
- * @param executionId report execution id to be selected
+ * @param executionKey report execution id to be selected
* @return report execution with matching key
*/
@GET
- @Path("executions/{executionId}")
+ @Path("executions/{executionKey}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- ReportExecTO readExecution(@NotNull @PathParam("executionId") Long executionId);
+ ReportExecTO readExecution(@NotNull @PathParam("executionKey") Long executionKey);
/**
* Returns a paged list of all existing reports.
@@ -163,11 +163,11 @@ public interface ReportService extends JAXRSService {
/**
* Deletes report execution with matching key.
*
- * @param executionId key of execution report to be deleted
+ * @param executionKey key of execution report to be deleted
*/
@DELETE
- @Path("executions/{executionId}")
- void deleteExecution(@NotNull @PathParam("executionId") Long executionId);
+ @Path("executions/{executionKey}")
+ void deleteExecution(@NotNull @PathParam("executionKey") Long executionKey);
/**
* Executes the report with matching key.
@@ -183,13 +183,13 @@ public interface ReportService extends JAXRSService {
/**
* Exports the report execution with matching key in the requested format.
*
- * @param executionId key of execution report to be selected
+ * @param executionKey key of execution report to be selected
* @param fmt file-format selection
* @return a stream for content download
*/
@GET
- @Path("executions/{executionId}/stream")
+ @Path("executions/{executionKey}/stream")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
- Response exportExecutionResult(@NotNull @PathParam("executionId") Long executionId,
+ Response exportExecutionResult(@NotNull @PathParam("executionKey") Long executionKey,
@QueryParam("format") ReportExecExportFormat fmt);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
index 9b62de3..044025b 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/ResourceService.java
@@ -58,7 +58,7 @@ public interface ResourceService extends JAXRSService {
* @return connector object from the external resource, for the given type and key
*/
@GET
- @Path("{resourceKey}/{type}/{id}")
+ @Path("{resourceKey}/{type}/{key}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
ConnObjectTO getConnectorObject(@NotNull @PathParam("resourceKey") String resourceKey,
@NotNull @PathParam("type") SubjectType type, @NotNull @PathParam("key") Long key);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
index f0bbf08..5d1b737 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/RoleService.java
@@ -264,7 +264,7 @@ public interface RoleService extends JAXRSService {
* @param type resource association action type
* @param resourceNames external resources to be used for propagation-related operations
* @return <tt>Response</tt> object featuring
- * {@link org.apache.syncope.common.reqres.BulkActionResult} as <tt>Entity</tt>
+ * {@link BulkActionResult} as <tt>Entity</tt>
*/
@Descriptions({
@Description(target = DocTarget.RESPONSE,
@@ -284,8 +284,7 @@ public interface RoleService extends JAXRSService {
* @param roleKey role id.
* @param type resource association action type
* @param resourceNames external resources to be used for propagation-related operations
- * @return <tt>Response</tt> object featuring {@link org.apache.syncope.common.reqres.BulkActionResult}
- * as <tt>Entity</tt>
+ * @return <tt>Response</tt> object featuring {@link BulkActionResult} as <tt>Entity</tt>
*/
@Descriptions({
@Description(target = DocTarget.RESPONSE,
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
index cd3a302..75b6af2 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/UserSelfService.java
@@ -48,9 +48,9 @@ public interface UserSelfService extends JAXRSService {
*
* @return <tt>Response</tt> contains special Syncope HTTP header indicating if user self registration and / or
* password reset is allowed
- * @see org.apache.syncope.common.types.RESTHeaders#SELFREG_ALLOWED
- * @see org.apache.syncope.common.types.RESTHeaders#PWDRESET_ALLOWED
- * @see org.apache.syncope.common.types.RESTHeaders#PWDRESET_NEEDS_SECURITYQUESTIONS
+ * @see org.apache.syncope.common.rest.api.RESTHeaders#SELFREG_ALLOWED
+ * @see org.apache.syncope.common.rest.api.RESTHeaders#PWDRESET_ALLOWED
+ * @see org.apache.syncope.common.rest.api.RESTHeaders#PWDRESET_NEEDS_SECURITYQUESTIONS
*/
@Descriptions({
@Description(target = DocTarget.RESPONSE,
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
----------------------------------------------------------------------
diff --git a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
index 709ab37..7b8aded 100644
--- a/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
+++ b/syncope620/common/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/WorkflowService.java
@@ -46,8 +46,8 @@ public interface WorkflowService extends JAXRSService {
* @param kind user or role
* @return <tt>Response</tt> contains special syncope HTTP header indicating if Activiti is enabled for
* users / roles
- * @see org.apache.syncope.common.types.RESTHeaders#ACTIVITI_USER_ENABLED
- * @see org.apache.syncope.common.types.RESTHeaders#ACTIVITI_ROLE_ENABLED
+ * @see org.apache.syncope.common.rest.api.RESTHeaders#ACTIVITI_USER_ENABLED
+ * @see org.apache.syncope.common.rest.api.RESTHeaders#ACTIVITI_ROLE_ENABLED
*/
@Descriptions({
@Description(target = DocTarget.RESPONSE,
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/pom.xml b/syncope620/fit/reference/pom.xml
index 148c71a..564d8f0 100644
--- a/syncope620/fit/reference/pom.xml
+++ b/syncope620/fit/reference/pom.xml
@@ -132,6 +132,24 @@ under the License.
<groupId>org.webjars</groupId>
<artifactId>highlightjs</artifactId>
</dependency>
+
+ <!-- TEST -->
+ <dependency>
+ <groupId>org.apache.syncope.client</groupId>
+ <artifactId>syncope-client-lib</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -161,6 +179,45 @@ under the License.
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <inherited>true</inherited>
+ <executions>
+ <execution>
+ <id>setupCSV</id>
+ <phase>pre-integration-test</phase>
+ <configuration>
+ <target>
+ <copy file="${project.build.directory}/test-classes/test.csv" todir="${test.csvdir.path}" overwrite="true"/>
+ </target>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <systemPropertyVariables>
+ <jaxrsContentType>${jaxrs.content.type}</jaxrsContentType>
+ </systemPropertyVariables>
+ </configuration>
+ <executions>
+ <execution>
+ <id>verify</id>
+ <goals>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<inherited>true</inherited>
@@ -270,12 +327,22 @@ under the License.
<filtering>true</filtering>
</resource>
</resources>
+ <testResources>
+ <testResource>
+ <directory>src/test/resources</directory>
+ <filtering>true</filtering>
+ </testResource>
+ </testResources>
</build>
<profiles>
<profile>
<id>debug</id>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+
<build>
<defaultGoal>clean verify cargo:run</defaultGoal>
@@ -306,5 +373,59 @@ under the License.
</plugins>
</build>
</profile>
+
+ <profile>
+ <id>skipTests</id>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <skipTests>${skipTests}</skipTests>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codehaus.cargo</groupId>
+ <artifactId>cargo-maven2-plugin</artifactId>
+ <inherited>true</inherited>
+ <configuration>
+ <deployables>
+ <deployable>
+ <location>${project.build.directory}/${project.build.finalName}.war</location>
+ </deployable>
+ </deployables>
+ </configuration>
+ <executions>
+ <execution>
+ <id>install-container</id>
+ <phase>package</phase>
+ <goals>
+ <goal>install</goal>
+ </goals>
+ </execution>
+ <execution>
+ <id>start-container</id>
+ <phase>none</phase>
+ </execution>
+ <execution>
+ <id>stop-container</id>
+ <phase>none</phase>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
</profiles>
</project>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/DoubleValueAttributableTransformer.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/DoubleValueAttributableTransformer.java b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/DoubleValueAttributableTransformer.java
new file mode 100644
index 0000000..da25a34
--- /dev/null
+++ b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/DoubleValueAttributableTransformer.java
@@ -0,0 +1,75 @@
+/*
+ * 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.fit.server.reference;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.server.provisioning.api.AttributableTransformer;
+
+/**
+ * Class for integration tests: transform (by making it double) any attribute value for defined schema.
+ */
+public class DoubleValueAttributableTransformer implements AttributableTransformer {
+
+ private static final String NAME = "makeItDouble";
+
+ @Override
+ public <T extends AbstractAttributableTO> T transform(final T input) {
+ for (AttrTO attr : input.getPlainAttrs()) {
+ if (NAME.equals(attr.getSchema())) {
+ List<String> values = new ArrayList<>(attr.getValues().size());
+ for (String value : attr.getValues()) {
+ try {
+ values.add(String.valueOf(2 * Long.valueOf(value)));
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ attr.getValues().clear();
+ attr.getValues().addAll(values);
+ }
+ }
+
+ return input;
+ }
+
+ @Override
+ public <T extends AbstractAttributableMod> T transform(final T input) {
+ for (AttrMod attr : input.getPlainAttrsToUpdate()) {
+ if (NAME.equals(attr.getSchema())) {
+ List<String> values = new ArrayList<>(attr.getValuesToBeAdded().size());
+ for (String value : attr.getValuesToBeAdded()) {
+ try {
+ values.add(String.valueOf(2 * Long.valueOf(value)));
+ } catch (NumberFormatException e) {
+ // ignore
+ }
+ }
+ attr.getValuesToBeAdded().clear();
+ attr.getValuesToBeAdded().addAll(values);
+ }
+ }
+
+ return input;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncActions.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncActions.java b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncActions.java
new file mode 100644
index 0000000..01da2c9
--- /dev/null
+++ b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncActions.java
@@ -0,0 +1,83 @@
+/*
+ * 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.fit.server.reference;
+
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
+import org.apache.syncope.server.provisioning.java.sync.DefaultSyncActions;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+
+public class TestSyncActions extends DefaultSyncActions {
+
+ private int counter = 0;
+
+ @Override
+ public <T extends AbstractSubjectTO> SyncDelta beforeProvision(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject) throws JobExecutionException {
+
+ AttrTO attrTO = null;
+ for (int i = 0; i < subject.getPlainAttrs().size(); i++) {
+ if ("fullname".equals(subject.getPlainAttrs().get(i).getSchema())) {
+ attrTO = subject.getPlainAttrs().get(i);
+ }
+ }
+ if (attrTO == null) {
+ attrTO = new AttrTO();
+ attrTO.setSchema("fullname");
+ subject.getPlainAttrs().add(attrTO);
+ }
+ attrTO.getValues().clear();
+ attrTO.getValues().add(String.valueOf(counter++));
+
+ return delta;
+ }
+
+ @Override
+ public <T extends AbstractSubjectTO, K extends AbstractSubjectMod> SyncDelta beforeUpdate(
+ final ProvisioningProfile<?, ?> profile,
+ final SyncDelta delta,
+ final T subject,
+ final K subjectMod) throws JobExecutionException {
+
+ subjectMod.getPlainAttrsToRemove().add("fullname");
+
+ AttrMod fullnameMod = null;
+ for (AttrMod attrMod : subjectMod.getPlainAttrsToUpdate()) {
+ if ("fullname".equals(attrMod.getSchema())) {
+ fullnameMod = attrMod;
+ }
+ }
+ if (fullnameMod == null) {
+ fullnameMod = new AttrMod();
+ fullnameMod.setSchema("fullname");
+ subjectMod.getPlainAttrsToUpdate().add(fullnameMod);
+ }
+
+ fullnameMod.getValuesToBeAdded().clear();
+ fullnameMod.getValuesToBeAdded().add(String.valueOf(counter++));
+
+ return delta;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncRule.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncRule.java b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncRule.java
new file mode 100644
index 0000000..8454ec6
--- /dev/null
+++ b/syncope620/fit/reference/src/main/java/org/apache/syncope/fit/server/reference/TestSyncRule.java
@@ -0,0 +1,37 @@
+/*
+ * 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.fit.server.reference;
+
+import org.apache.syncope.server.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.server.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.server.provisioning.api.sync.SyncCorrelationRule;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+
+public class TestSyncRule implements SyncCorrelationRule {
+
+ @Override
+ public SearchCond getSearchCond(ConnectorObject connObj) {
+ AttributeCond cond = new AttributeCond();
+ cond.setSchema("email");
+ cond.setType(AttributeCond.Type.EQ);
+ cond.setExpression(connObj.getName().getNameValue());
+
+ return SearchCond.getLeafCond(cond);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/main/resources/connid.properties
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/resources/connid.properties b/syncope620/fit/reference/src/main/resources/connid.properties
index 54d83c3..40d649c 100644
--- a/syncope620/fit/reference/src/main/resources/connid.properties
+++ b/syncope620/fit/reference/src/main/resources/connid.properties
@@ -16,3 +16,8 @@
# under the License.
connid.locations=${connid.location},\
connid://${testconnectorserver.key}@localhost:${testconnectorserver.port}
+
+## for test only
+testdb.url=${testdb.url}
+connid.soap.version=${connid.soap.version}
+connid.db.table.version=${connid.db.table.version}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/main/resources/logic.properties
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/main/resources/logic.properties b/syncope620/fit/reference/src/main/resources/logic.properties
new file mode 100644
index 0000000..2477c4b
--- /dev/null
+++ b/syncope620/fit/reference/src/main/resources/logic.properties
@@ -0,0 +1,18 @@
+# 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.
+attributableTransformer=org.apache.syncope.fit.server.reference.DoubleValueAttributableTransformer
+logicInvocationHandler=org.apache.syncope.server.logic.LogicInvocationHandler
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
new file mode 100644
index 0000000..fc81657
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/AbstractITCase.java
@@ -0,0 +1,365 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+import javax.naming.Context;
+import javax.naming.directory.InitialDirContext;
+import javax.sql.DataSource;
+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.lib.SyncopeClient;
+import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractPolicyTO;
+import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.ConfigurationService;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.EntitlementService;
+import org.apache.syncope.common.rest.api.service.LoggerService;
+import org.apache.syncope.common.rest.api.service.NotificationService;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.SecurityQuestionService;
+import org.apache.syncope.common.rest.api.service.TaskService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.apache.syncope.common.rest.api.service.WorkflowService;
+import org.identityconnectors.common.security.Encryptor;
+import org.junit.BeforeClass;
+import org.junit.runner.RunWith;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration(locations = { "classpath:testJDBCContext.xml" })
+public abstract class AbstractITCase {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(AbstractITCase.class);
+
+ protected static final String ADMIN_UNAME = "admin";
+
+ protected static final String ADMIN_PWD = "password";
+
+ private static final String ADDRESS = "http://localhost:9080/syncope/rest";
+
+ private static final String ENV_KEY_CONTENT_TYPE = "jaxrsContentType";
+
+ protected static final SyncopeClientFactoryBean clientFactory = new SyncopeClientFactoryBean().setAddress(ADDRESS);
+
+ protected static final String RESOURCE_NAME_WS1 = "ws-target-resource-1";
+
+ protected static final String RESOURCE_NAME_WS2 = "ws-target-resource-2";
+
+ protected static final String RESOURCE_NAME_LDAP = "resource-ldap";
+
+ protected static final String RESOURCE_NAME_TESTDB = "resource-testdb";
+
+ protected static final String RESOURCE_NAME_TESTDB2 = "resource-testdb2";
+
+ protected static final String RESOURCE_NAME_CSV = "resource-csv";
+
+ protected static final String RESOURCE_NAME_DBSYNC = "resource-db-sync";
+
+ protected static final String RESOURCE_NAME_DBVIRATTR = "resource-db-virattr";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION = "ws-target-resource-nopropagation";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION2 = "ws-target-resource-nopropagation2";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION3 = "ws-target-resource-nopropagation3";
+
+ protected static final String RESOURCE_NAME_NOPROPAGATION4 = "ws-target-resource-nopropagation4";
+
+ protected static final String RESOURCE_NAME_RESETSYNCTOKEN = "ws-target-resource-update-resetsynctoken";
+
+ protected static final String RESOURCE_NAME_TIMEOUT = "ws-target-resource-timeout";
+
+ protected static final String RESOURCE_NAME_MAPPINGS1 = "ws-target-resource-list-mappings-1";
+
+ protected static final String RESOURCE_NAME_MAPPINGS2 = "ws-target-resource-list-mappings-2";
+
+ protected static final String RESOURCE_NAME_CREATE = "ws-target-resource-create";
+
+ protected static final String RESOURCE_NAME_CREATE_SINGLE = "ws-target-resource-create-single";
+
+ protected static final String RESOURCE_NAME_CREATE_WRONG = "ws-target-resource-create-wrong";
+
+ protected static final String RESOURCE_NAME_DELETE = "ws-target-resource-delete";
+
+ protected static final String RESOURCE_NAME_UPDATE = "ws-target-resource-update";
+
+ protected static final String RESOURCE_NAME_CREATE_NONE = "ws-target-resource-create-none";
+
+ protected static String ANONYMOUS_UNAME;
+
+ protected static String ANONYMOUS_KEY;
+
+ protected static SyncopeClient adminClient;
+
+ protected static UserService userService;
+
+ protected static UserSelfService userSelfService;
+
+ protected static UserWorkflowService userWorkflowService;
+
+ protected static RoleService roleService;
+
+ protected static ResourceService resourceService;
+
+ protected static EntitlementService entitlementService;
+
+ protected static ConfigurationService configurationService;
+
+ protected static ConnectorService connectorService;
+
+ protected static LoggerService loggerService;
+
+ protected static ReportService reportService;
+
+ protected static TaskService taskService;
+
+ protected static WorkflowService workflowService;
+
+ protected static NotificationService notificationService;
+
+ protected static SchemaService schemaService;
+
+ protected static PolicyService policyService;
+
+ protected static SecurityQuestionService securityQuestionService;
+
+ @Autowired
+ protected DataSource testDataSource;
+
+ @BeforeClass
+ public static void securitySetup() {
+ InputStream propStream = null;
+ try {
+ propStream = Encryptor.class.getResourceAsStream("/security.properties");
+ Properties props = new Properties();
+ props.load(propStream);
+
+ ANONYMOUS_UNAME = props.getProperty("anonymousUser");
+ ANONYMOUS_KEY = props.getProperty("anonymousKey");
+ } catch (Exception e) {
+ LOG.error("Could not read secretKey", e);
+ } finally {
+ IOUtils.closeQuietly(propStream);
+ }
+
+ assertNotNull(ANONYMOUS_UNAME);
+ assertNotNull(ANONYMOUS_KEY);
+ }
+
+ @BeforeClass
+ public static void restSetup() {
+ final String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
+ if (StringUtils.isNotBlank(envContentType)) {
+ clientFactory.setContentType(envContentType);
+ }
+ LOG.info("Performing IT with content type {}", clientFactory.getContentType().getMediaType());
+
+ adminClient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+
+ userService = adminClient.getService(UserService.class);
+ userSelfService = adminClient.getService(UserSelfService.class);
+ userWorkflowService = adminClient.getService(UserWorkflowService.class);
+ roleService = adminClient.getService(RoleService.class);
+ resourceService = adminClient.getService(ResourceService.class);
+ entitlementService = adminClient.getService(EntitlementService.class);
+ configurationService = adminClient.getService(ConfigurationService.class);
+ connectorService = adminClient.getService(ConnectorService.class);
+ loggerService = adminClient.getService(LoggerService.class);
+ reportService = adminClient.getService(ReportService.class);
+ taskService = adminClient.getService(TaskService.class);
+ policyService = adminClient.getService(PolicyService.class);
+ workflowService = adminClient.getService(WorkflowService.class);
+ notificationService = adminClient.getService(NotificationService.class);
+ schemaService = adminClient.getService(SchemaService.class);
+ securityQuestionService = adminClient.getService(SecurityQuestionService.class);
+ }
+
+ protected static String getUUIDString() {
+ return UUID.randomUUID().toString().substring(0, 8);
+ }
+
+ protected static AttrTO attrTO(final String schema, final String value) {
+ AttrTO attr = new AttrTO();
+ attr.setSchema(schema);
+ attr.getValues().add(value);
+ return attr;
+ }
+
+ protected static AttrMod attrMod(final String schema, final String valueToBeAdded) {
+ AttrMod attr = new AttrMod();
+ attr.setSchema(schema);
+ attr.getValuesToBeAdded().add(valueToBeAdded);
+ return attr;
+ }
+
+ 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()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return response.readEntity(UserTO.class);
+ }
+
+ protected UserTO readUser(final String username) {
+ return userService.read(Long.valueOf(
+ userService.getUserId(username).getHeaderString(RESTHeaders.USER_ID)));
+ }
+
+ protected UserTO updateUser(final UserMod userMod) {
+ return userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+ }
+
+ protected UserTO deleteUser(final Long id) {
+ return userService.delete(id).readEntity(UserTO.class);
+ }
+
+ public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) {
+ WebClient webClient = WebClient.fromClient(WebClient.client(adminClient.getService(serviceClass)));
+ webClient.accept(clientFactory.getContentType().getMediaType()).to(location.toASCIIString(), false);
+
+ return webClient.get(resultClass);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T extends AbstractSchemaTO> T createSchema(final AttributableType kind,
+ final SchemaType type, final T schemaTO) {
+
+ Response response = schemaService.create(kind, type, schemaTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+
+ return (T) getObject(response.getLocation(), SchemaService.class, schemaTO.getClass());
+ }
+
+ protected RoleTO createRole(final RoleTO newRoleTO) {
+ Response response = roleService.create(newRoleTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return getObject(response.getLocation(), RoleService.class, RoleTO.class);
+ }
+
+ protected RoleTO updateRole(final RoleMod roleMod) {
+ return roleService.update(roleMod.getKey(), roleMod).readEntity(RoleTO.class);
+ }
+
+ protected RoleTO deleteRole(final Long id) {
+ return roleService.delete(id).readEntity(RoleTO.class);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected <T extends AbstractPolicyTO> T createPolicy(final T policy) {
+ Response response = policyService.create(policy);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return (T) getObject(response.getLocation(), PolicyService.class, policy.getClass());
+ }
+
+ protected ResourceTO createResource(final ResourceTO resourceTO) {
+ Response response = resourceService.create(resourceTO);
+ if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+ Exception ex = clientFactory.getExceptionMapper().fromResponse(response);
+ if (ex != null) {
+ throw (RuntimeException) ex;
+ }
+ }
+ return getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ }
+
+ protected Object getLdapRemoteObject(final String objectDn) {
+ return getLdapRemoteObject(null, null, objectDn);
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes", "UseOfObsoleteCollectionType" })
+ protected Object getLdapRemoteObject(final String bindDn, final String bindPwd, final String objectDn) {
+ ResourceTO ldapRes = resourceService.read(RESOURCE_NAME_LDAP);
+ final Map<String, ConnConfProperty> ldapConnConf =
+ connectorService.read(ldapRes.getConnectorId()).getConfigurationMap();
+
+ Hashtable env = new Hashtable();
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, "ldap://" + ldapConnConf.get("host").getValues().get(0)
+ + ":" + ldapConnConf.get("port").getValues().get(0) + "/");
+ env.put(Context.SECURITY_AUTHENTICATION, "simple");
+ env.put(Context.SECURITY_PRINCIPAL,
+ bindDn == null ? ldapConnConf.get("principal").getValues().get(0) : bindDn);
+ env.put(Context.SECURITY_CREDENTIALS,
+ bindPwd == null ? ldapConnConf.get("credentials").getValues().get(0) : bindPwd);
+
+ try {
+ final InitialDirContext ctx = new InitialDirContext(env);
+ return ctx.lookup(objectDn);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
new file mode 100644
index 0000000..ae35a23
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ActivitiDetector.java
@@ -0,0 +1,36 @@
+/*
+ * 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.fit.server.reference;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// TODO: REMOVE!!!
+public class ActivitiDetector {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ActivitiDetector.class);
+
+ public static boolean isActivitiEnabledForUsers() {
+ return false;
+ }
+
+ public static boolean isActivitiEnabledForRoles() {
+ return false;
+ }
+}
[06/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractPushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractPushResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractPushResultHandler.java
new file mode 100644
index 0000000..74cd5f0
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractPushResultHandler.java
@@ -0,0 +1,374 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.server.persistence.api.entity.Mapping;
+import org.apache.syncope.server.persistence.api.entity.MappingItem;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.VirAttr;
+import org.apache.syncope.server.persistence.api.entity.membership.Membership;
+import org.apache.syncope.server.persistence.api.entity.task.PushTask;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.server.provisioning.api.sync.PushActions;
+import org.apache.syncope.server.misc.MappingUtil;
+import org.apache.syncope.server.provisioning.api.sync.SyncopePushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.quartz.JobExecutionException;
+import org.springframework.transaction.annotation.Transactional;
+
+public abstract class AbstractPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions>
+ implements SyncopePushResultHandler {
+
+ protected abstract String getName(final Subject<?, ?, ?> subject);
+
+ protected abstract Mapping<?> getMapping();
+
+ protected abstract AbstractSubjectTO getSubjectTO(final long key);
+
+ protected abstract Subject<?, ?, ?> getSubject(final long key);
+
+ protected abstract Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj);
+
+ protected abstract Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled);
+
+ protected abstract Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink);
+
+ protected abstract Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj);
+
+ protected abstract Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, Boolean enabled);
+
+ protected abstract ConnectorObject getRemoteObject(final String accountId);
+
+ @Transactional
+ @Override
+ public boolean handle(final long subjectId) {
+ try {
+ doHandle(subjectId);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Synchronization failed", e);
+ return false;
+ }
+ }
+
+ protected final void doHandle(final long subjectId)
+ throws JobExecutionException {
+
+ final Subject<?, ?, ?> subject = getSubject(subjectId);
+
+ final AttributableUtil attrUtil = attrUtilFactory.getInstance(subject);
+
+ final ProvisioningResult result = new ProvisioningResult();
+ profile.getResults().add(result);
+
+ result.setId(subject.getKey());
+ result.setSubjectType(attrUtil.getType());
+ result.setName(getName(subject));
+
+ final Boolean enabled = subject instanceof User && profile.getTask().isSyncStatus()
+ ? ((User) subject).isSuspended() ? Boolean.FALSE : Boolean.TRUE
+ : null;
+
+ LOG.debug("Propagating {} with key {} towards {}",
+ attrUtil.getType(), subject.getKey(), profile.getTask().getResource());
+
+ Object output = null;
+ Result resultStatus = null;
+ ConnectorObject beforeObj = null;
+ String operation = null;
+
+ // Try to read remote object (user / group) BEFORE any actual operation
+ final String accountId = MappingUtil.getAccountIdValue(
+ subject, profile.getTask().getResource(), getMapping().getAccountIdItem());
+
+ beforeObj = getRemoteObject(accountId);
+
+ Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
+
+ if (profile.isDryRun()) {
+ if (beforeObj == null) {
+ result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+ } else {
+ result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+ }
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+ } else {
+ try {
+ if (beforeObj == null) {
+ operation = profile.getTask().getUnmatchingRule().name().toLowerCase();
+ result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
+
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ for (PushActions action : profile.getActions()) {
+ action.beforeAssign(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PushTask not configured for create");
+ } else {
+ assign(subject, status);
+ }
+
+ break;
+ case PROVISION:
+ for (PushActions action : profile.getActions()) {
+ action.beforeProvision(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("PushTask not configured for create");
+ } else {
+ provision(subject, status);
+ }
+
+ break;
+ case UNLINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(subject, true);
+ }
+
+ break;
+ default:
+ // do nothing
+ }
+
+ } else {
+ operation = profile.getTask().getMatchingRule().name().toLowerCase();
+ result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
+
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUpdate(this.getProfile(), subject);
+ }
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ update(subject, status);
+ }
+
+ break;
+ case DEPROVISION:
+ for (PushActions action : profile.getActions()) {
+ action.beforeDeprovision(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PushTask not configured for delete");
+ } else {
+ deprovision(subject);
+ }
+
+ break;
+ case UNASSIGN:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnassign(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("PushTask not configured for delete");
+ } else {
+ unassign(subject);
+ }
+
+ break;
+ case LINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeLink(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(subject, false);
+ }
+
+ break;
+ case UNLINK:
+ for (PushActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), subject);
+ }
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("PushTask not configured for update");
+ } else {
+ link(subject, true);
+ }
+
+ break;
+ default:
+ // do nothing
+ }
+ }
+
+ for (PushActions action : profile.getActions()) {
+ action.after(this.getProfile(), subject, result);
+ }
+
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+ resultStatus = AuditElements.Result.SUCCESS;
+ output = getRemoteObject(accountId);
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ resultStatus = AuditElements.Result.FAILURE;
+ output = e;
+
+ LOG.warn("Error pushing {} towards {}", subject, profile.getTask().getResource(), e);
+ throw new JobExecutionException(e);
+ } finally {
+ notificationManager.createTasks(
+ AuditElements.EventCategoryType.PUSH,
+ AttributableType.USER.name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ beforeObj,
+ output,
+ subject);
+ auditManager.audit(
+ AuditElements.EventCategoryType.PUSH,
+ AttributableType.USER.name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ operation,
+ resultStatus,
+ beforeObj,
+ output,
+ subject);
+ }
+ }
+ }
+
+ private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
+ switch (rule) {
+ case ASSIGN:
+ case PROVISION:
+ return ResourceOperation.CREATE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ private ResourceOperation getResourceOperation(final MatchingRule rule) {
+ switch (rule) {
+ case UPDATE:
+ return ResourceOperation.UPDATE;
+ case DEPROVISION:
+ case UNASSIGN:
+ return ResourceOperation.DELETE;
+ default:
+ return ResourceOperation.NONE;
+ }
+ }
+
+ protected Subject<?, ?, ?> update(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+
+ final Set<MembershipMod> membsToAdd = new HashSet<>();
+ final Set<String> vattrToBeRemoved = new HashSet<>();
+ final Set<String> membVattrToBeRemoved = new HashSet<>();
+ final Set<AttrMod> vattrToBeUpdated = new HashSet<>();
+
+ // Search for all mapped vattrs
+ final Mapping<?> umapping = getMapping();
+ for (MappingItem mappingItem : umapping.getItems()) {
+ if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) {
+ vattrToBeRemoved.add(mappingItem.getIntAttrName());
+ } else if (mappingItem.getIntMappingType() == IntMappingType.MembershipVirtualSchema) {
+ membVattrToBeRemoved.add(mappingItem.getIntAttrName());
+ }
+ }
+
+ // Search for all user's vattrs and:
+ // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed
+ // 2. add all vattrs owned by the user to the set of vattrs to be update
+ for (VirAttr vattr : sbj.getVirAttrs()) {
+ vattrToBeRemoved.remove(vattr.getSchema().getKey());
+ final AttrMod mod = new AttrMod();
+ mod.setSchema(vattr.getSchema().getKey());
+ mod.getValuesToBeAdded().addAll(vattr.getValues());
+ vattrToBeUpdated.add(mod);
+ }
+
+ final boolean changepwd;
+
+ if (sbj instanceof User) {
+ changepwd = true;
+
+ // Search for memberships
+ for (Membership membership : User.class.cast(sbj).getMemberships()) {
+ final MembershipMod membershipMod = new MembershipMod();
+ membershipMod.setKey(membership.getKey());
+ membershipMod.setRole(membership.getRole().getKey());
+
+ for (VirAttr vattr : membership.getVirAttrs()) {
+ membVattrToBeRemoved.remove(vattr.getSchema().getKey());
+ final AttrMod mod = new AttrMod();
+ mod.setSchema(vattr.getSchema().getKey());
+ mod.getValuesToBeAdded().addAll(vattr.getValues());
+ membershipMod.getVirAttrsToUpdate().add(mod);
+ }
+
+ membsToAdd.add(membershipMod);
+ }
+
+ if (!membsToAdd.isEmpty()) {
+ membsToAdd.iterator().next().getVirAttrsToRemove().addAll(membVattrToBeRemoved);
+ }
+ } else {
+ changepwd = false;
+ }
+
+ final List<String> noPropResources = new ArrayList<>(sbj.getResourceNames());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ final PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUpdateTaskIds(
+ sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources,
+ membsToAdd));
+
+ return userDAO.authFetch(sbj.getKey());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectPushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectPushResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectPushResultHandler.java
deleted file mode 100644
index f0b70cd..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectPushResultHandler.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.MembershipMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.IntMappingType;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.server.persistence.api.entity.Mapping;
-import org.apache.syncope.server.persistence.api.entity.MappingItem;
-import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.apache.syncope.server.persistence.api.entity.VirAttr;
-import org.apache.syncope.server.persistence.api.entity.membership.Membership;
-import org.apache.syncope.server.persistence.api.entity.task.PushTask;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
-import org.apache.syncope.server.provisioning.api.sync.PushActions;
-import org.apache.syncope.server.misc.MappingUtil;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.quartz.JobExecutionException;
-import org.springframework.transaction.annotation.Transactional;
-
-public abstract class AbstractSubjectPushResultHandler extends AbstractSyncopeResultHandler<PushTask, PushActions> {
-
- protected abstract String getName(final Subject<?, ?, ?> subject);
-
- protected abstract Mapping<?> getMapping();
-
- protected abstract AbstractSubjectTO getSubjectTO(final long key);
-
- protected abstract Subject<?, ?, ?> getSubject(final long key);
-
- protected abstract Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj);
-
- protected abstract Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled);
-
- protected abstract Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink);
-
- protected abstract Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj);
-
- protected abstract Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, Boolean enabled);
-
- protected abstract ConnectorObject getRemoteObject(final String accountId);
-
- @Transactional
- public boolean handle(final long subjectId) {
- try {
- doHandle(subjectId);
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Synchronization failed", e);
- return false;
- }
- }
-
- protected final void doHandle(final long subjectId)
- throws JobExecutionException {
-
- final Subject<?, ?, ?> subject = getSubject(subjectId);
-
- final AttributableUtil attrUtil = attrUtilFactory.getInstance(subject);
-
- final ProvisioningResult result = new ProvisioningResult();
- profile.getResults().add(result);
-
- result.setId(subject.getKey());
- result.setSubjectType(attrUtil.getType());
- result.setName(getName(subject));
-
- final Boolean enabled = subject instanceof User && profile.getTask().isSyncStatus()
- ? ((User) subject).isSuspended() ? Boolean.FALSE : Boolean.TRUE
- : null;
-
- LOG.debug("Propagating {} with key {} towards {}",
- attrUtil.getType(), subject.getKey(), profile.getTask().getResource());
-
- Object output = null;
- Result resultStatus = null;
- ConnectorObject beforeObj = null;
- String operation = null;
-
- // Try to read remote object (user / group) BEFORE any actual operation
- final String accountId = MappingUtil.getAccountIdValue(
- subject, profile.getTask().getResource(), getMapping().getAccountIdItem());
-
- beforeObj = getRemoteObject(accountId);
-
- Boolean status = profile.getTask().isSyncStatus() ? enabled : null;
-
- if (profile.isDryRun()) {
- if (beforeObj == null) {
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
- } else {
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
- }
- result.setStatus(ProvisioningResult.Status.SUCCESS);
- } else {
- try {
- if (beforeObj == null) {
- operation = profile.getTask().getUnmatchingRule().name().toLowerCase();
- result.setOperation(getResourceOperation(profile.getTask().getUnmatchingRule()));
-
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeAssign(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- assign(subject, status);
- }
-
- break;
- case PROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeProvision(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("PushTask not configured for create");
- } else {
- provision(subject, status);
- }
-
- break;
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(subject, true);
- }
-
- break;
- default:
- // do nothing
- }
-
- } else {
- operation = profile.getTask().getMatchingRule().name().toLowerCase();
- result.setOperation(getResourceOperation(profile.getTask().getMatchingRule()));
-
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- for (PushActions action : profile.getActions()) {
- action.beforeUpdate(this.getProfile(), subject);
- }
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- update(subject, status);
- }
-
- break;
- case DEPROVISION:
- for (PushActions action : profile.getActions()) {
- action.beforeDeprovision(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- deprovision(subject);
- }
-
- break;
- case UNASSIGN:
- for (PushActions action : profile.getActions()) {
- action.beforeUnassign(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("PushTask not configured for delete");
- } else {
- unassign(subject);
- }
-
- break;
- case LINK:
- for (PushActions action : profile.getActions()) {
- action.beforeLink(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(subject, false);
- }
-
- break;
- case UNLINK:
- for (PushActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), subject);
- }
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("PushTask not configured for update");
- } else {
- link(subject, true);
- }
-
- break;
- default:
- // do nothing
- }
- }
-
- for (PushActions action : profile.getActions()) {
- action.after(this.getProfile(), subject, result);
- }
-
- result.setStatus(ProvisioningResult.Status.SUCCESS);
- resultStatus = AuditElements.Result.SUCCESS;
- output = getRemoteObject(accountId);
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- resultStatus = AuditElements.Result.FAILURE;
- output = e;
-
- LOG.warn("Error pushing {} towards {}", subject, profile.getTask().getResource(), e);
- throw new JobExecutionException(e);
- } finally {
- notificationManager.createTasks(
- AuditElements.EventCategoryType.PUSH,
- AttributableType.USER.name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- subject);
- auditManager.audit(
- AuditElements.EventCategoryType.PUSH,
- AttributableType.USER.name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- operation,
- resultStatus,
- beforeObj,
- output,
- subject);
- }
- }
- }
-
- private ResourceOperation getResourceOperation(final UnmatchingRule rule) {
- switch (rule) {
- case ASSIGN:
- case PROVISION:
- return ResourceOperation.CREATE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- private ResourceOperation getResourceOperation(final MatchingRule rule) {
- switch (rule) {
- case UPDATE:
- return ResourceOperation.UPDATE;
- case DEPROVISION:
- case UNASSIGN:
- return ResourceOperation.DELETE;
- default:
- return ResourceOperation.NONE;
- }
- }
-
- protected Subject<?, ?, ?> update(final Subject<?, ?, ?> sbj, final Boolean enabled) {
-
- final Set<MembershipMod> membsToAdd = new HashSet<>();
- final Set<String> vattrToBeRemoved = new HashSet<>();
- final Set<String> membVattrToBeRemoved = new HashSet<>();
- final Set<AttrMod> vattrToBeUpdated = new HashSet<>();
-
- // Search for all mapped vattrs
- final Mapping<?> umapping = getMapping();
- for (MappingItem mappingItem : umapping.getItems()) {
- if (mappingItem.getIntMappingType() == IntMappingType.UserVirtualSchema) {
- vattrToBeRemoved.add(mappingItem.getIntAttrName());
- } else if (mappingItem.getIntMappingType() == IntMappingType.MembershipVirtualSchema) {
- membVattrToBeRemoved.add(mappingItem.getIntAttrName());
- }
- }
-
- // Search for all user's vattrs and:
- // 1. add mapped vattrs not owned by the user to the set of vattrs to be removed
- // 2. add all vattrs owned by the user to the set of vattrs to be update
- for (VirAttr vattr : sbj.getVirAttrs()) {
- vattrToBeRemoved.remove(vattr.getSchema().getKey());
- final AttrMod mod = new AttrMod();
- mod.setSchema(vattr.getSchema().getKey());
- mod.getValuesToBeAdded().addAll(vattr.getValues());
- vattrToBeUpdated.add(mod);
- }
-
- final boolean changepwd;
-
- if (sbj instanceof User) {
- changepwd = true;
-
- // Search for memberships
- for (Membership membership : User.class.cast(sbj).getMemberships()) {
- final MembershipMod membershipMod = new MembershipMod();
- membershipMod.setKey(membership.getKey());
- membershipMod.setRole(membership.getRole().getKey());
-
- for (VirAttr vattr : membership.getVirAttrs()) {
- membVattrToBeRemoved.remove(vattr.getSchema().getKey());
- final AttrMod mod = new AttrMod();
- mod.setSchema(vattr.getSchema().getKey());
- mod.getValuesToBeAdded().addAll(vattr.getValues());
- membershipMod.getVirAttrsToUpdate().add(mod);
- }
-
- membsToAdd.add(membershipMod);
- }
-
- if (!membsToAdd.isEmpty()) {
- membsToAdd.iterator().next().getVirAttrsToRemove().addAll(membVattrToBeRemoved);
- }
- } else {
- changepwd = false;
- }
-
- final List<String> noPropResources = new ArrayList<>(sbj.getResourceNames());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- final PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUpdateTaskIds(
- sbj, null, changepwd, enabled, vattrToBeRemoved, vattrToBeUpdated, propByRes, noPropResources,
- membsToAdd));
-
- return userDAO.authFetch(sbj.getKey());
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectSyncResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectSyncResultHandler.java
deleted file mode 100644
index 3c49eee..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSubjectSyncResultHandler.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import org.apache.commons.lang3.exception.ExceptionUtils;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.types.AuditElements;
-import org.apache.syncope.common.lib.types.AuditElements.Result;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.server.persistence.api.dao.NotFoundException;
-import org.apache.syncope.server.persistence.api.dao.UserDAO;
-import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
-import org.apache.syncope.server.provisioning.api.AttributableTransformer;
-import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
-import org.apache.syncope.server.provisioning.api.sync.SyncActions;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
-import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.identityconnectors.framework.common.objects.SyncDeltaType;
-import org.identityconnectors.framework.common.objects.SyncResultsHandler;
-import org.quartz.JobExecutionException;
-import org.springframework.beans.factory.annotation.Autowired;
-
-public abstract class AbstractSubjectSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
- implements SyncResultsHandler {
-
- @Autowired
- protected SyncUtilities syncUtilities;
-
- @Autowired
- protected AttributableTransformer attrTransformer;
-
- protected abstract AttributableUtil getAttributableUtil();
-
- protected abstract String getName(AbstractSubjectTO subjectTO);
-
- protected abstract AbstractSubjectTO getSubjectTO(long key);
-
- protected abstract AbstractSubjectMod getSubjectMod(AbstractSubjectTO subjectTO, SyncDelta delta);
-
- protected abstract AbstractSubjectTO create(AbstractSubjectTO subjectTO, SyncDelta _delta, ProvisioningResult result);
-
- protected abstract AbstractSubjectTO link(AbstractSubjectTO before, ProvisioningResult result, boolean unlink);
-
- protected abstract AbstractSubjectTO update(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
- SyncDelta delta, ProvisioningResult result);
-
- protected abstract void deprovision(Long key, boolean unlink);
-
- protected abstract void delete(Long key);
-
- @Override
- public boolean handle(final SyncDelta delta) {
- try {
- doHandle(delta, profile.getResults());
- return true;
- } catch (JobExecutionException e) {
- LOG.error("Synchronization failed", e);
- return false;
- }
- }
-
- protected List<ProvisioningResult> assign(final SyncDelta delta, final AttributableUtil attrUtil)
- throws JobExecutionException {
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("SyncTask not configured for create");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- final AbstractSubjectTO subjectTO =
- connObjectUtil.getSubjectTO(delta.getObject(), profile.getTask(), attrUtil);
-
- subjectTO.getResources().add(profile.getTask().getResource().getKey());
-
- final ProvisioningResult result = new ProvisioningResult();
- result.setOperation(ResourceOperation.CREATE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
-
- // Attributable transformation (if configured)
- AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
- LOG.debug("Transformed: {}", transformed);
-
- result.setName(getName(transformed));
-
- if (profile.isDryRun()) {
- result.setId(0L);
- } else {
- SyncDelta _delta = delta;
- for (SyncActions action : profile.getActions()) {
- _delta = action.beforeAssign(this.getProfile(), _delta, transformed);
- }
-
- create(transformed, _delta, attrUtil, "assign", result);
- }
-
- return Collections.singletonList(result);
- }
-
- protected List<ProvisioningResult> create(final SyncDelta delta, final AttributableUtil attrUtil)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformCreate()) {
- LOG.debug("SyncTask not configured for create");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- final AbstractSubjectTO subjectTO =
- connObjectUtil.getSubjectTO(delta.getObject(), profile.getTask(), attrUtil);
-
- // Attributable transformation (if configured)
- AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
- LOG.debug("Transformed: {}", transformed);
-
- final ProvisioningResult result = new ProvisioningResult();
- result.setOperation(ResourceOperation.CREATE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
-
- result.setName(getName(transformed));
-
- if (profile.isDryRun()) {
- result.setId(0L);
- } else {
- SyncDelta _delta = delta;
- for (SyncActions action : profile.getActions()) {
- _delta = action.beforeProvision(this.getProfile(), _delta, transformed);
- }
-
- create(transformed, _delta, attrUtil, "provision", result);
- }
-
- return Collections.<ProvisioningResult>singletonList(result);
- }
-
- private void create(
- final AbstractSubjectTO subjectTO,
- final SyncDelta delta,
- final AttributableUtil attrUtil,
- final String operation,
- final ProvisioningResult result)
- throws JobExecutionException {
-
- Object output;
- Result resultStatus;
-
- try {
- AbstractSubjectTO actual = create(subjectTO, delta, result);
- result.setName(getName(actual));
- output = actual;
- resultStatus = Result.SUCCESS;
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, actual, result);
- }
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not create {} {} ", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
-
- audit(operation, resultStatus, null, output, delta);
- }
-
- protected List<ProvisioningResult> update(SyncDelta delta, final List<Long> subjects,
- final AttributableUtil attrUtil)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- LOG.debug("About to update {}", subjects);
-
- List<ProvisioningResult> updResults = new ArrayList<>();
-
- for (Long id : subjects) {
- LOG.debug("About to update {}", id);
-
- Object output;
- AbstractSubjectTO before = null;
- Result resultStatus;
-
- final ProvisioningResult result = new ProvisioningResult();
- result.setOperation(ResourceOperation.UPDATE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
- result.setId(id);
-
- before = getSubjectTO(id);
-
- if (before == null) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), id));
- } else {
- result.setName(getName(before));
- }
-
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- try {
- final AbstractSubjectMod attributableMod = getSubjectMod(before, delta);
-
- // Attribute value transformation (if configured)
- final AbstractSubjectMod actual = attrTransformer.transform(attributableMod);
- LOG.debug("Transformed: {}", actual);
-
- for (SyncActions action : profile.getActions()) {
- delta = action.beforeUpdate(this.getProfile(), delta, before, attributableMod);
- }
-
- final AbstractSubjectTO updated = update(before, attributableMod, delta, result);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, updated, result);
- }
-
- output = updated;
- resultStatus = Result.SUCCESS;
- result.setName(getName(updated));
- LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- audit("update", resultStatus, before, output, delta);
- }
- updResults.add(result);
- }
- return updResults;
- }
-
- protected List<ProvisioningResult> deprovision(
- SyncDelta delta,
- final List<Long> subjects,
- final AttributableUtil attrUtil,
- final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- LOG.debug("About to update {}", subjects);
-
- final List<ProvisioningResult> updResults = new ArrayList<>();
-
- for (Long id : subjects) {
- LOG.debug("About to unassign resource {}", id);
-
- Object output;
- Result resultStatus;
-
- final ProvisioningResult result = new ProvisioningResult();
- result.setOperation(ResourceOperation.DELETE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
- result.setId(id);
-
- final AbstractSubjectTO before = getSubjectTO(id);
-
- if (before == null) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), id));
- }
-
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- result.setName(getName(before));
-
- try {
- if (unlink) {
- for (SyncActions action : profile.getActions()) {
- action.beforeUnassign(this.getProfile(), delta, before);
- }
- } else {
- for (SyncActions action : profile.getActions()) {
- action.beforeDeprovision(this.getProfile(), delta, before);
- }
- }
-
- deprovision(id, unlink);
- output = getSubjectTO(id);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
- }
-
- resultStatus = Result.SUCCESS;
- LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- audit(unlink ? "unassign" : "deprovision", resultStatus, before, output, delta);
- }
- updResults.add(result);
- }
-
- return updResults;
- }
-
- protected List<ProvisioningResult> link(
- SyncDelta delta,
- final List<Long> subjects,
- final AttributableUtil attrUtil,
- final boolean unlink)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformUpdate()) {
- LOG.debug("SyncTask not configured for update");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- LOG.debug("About to update {}", subjects);
-
- final List<ProvisioningResult> updResults = new ArrayList<>();
-
- for (Long id : subjects) {
- LOG.debug("About to unassign resource {}", id);
-
- Object output;
- Result resultStatus;
-
- final ProvisioningResult result = new ProvisioningResult();
- result.setOperation(ResourceOperation.NONE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
- result.setId(id);
-
- final AbstractSubjectTO before = getSubjectTO(id);
-
- if (before == null) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), id));
- }
-
- if (!profile.isDryRun()) {
- if (before == null) {
- resultStatus = Result.FAILURE;
- output = null;
- } else {
- result.setName(getName(before));
-
- try {
- if (unlink) {
- for (SyncActions action : profile.getActions()) {
- action.beforeUnlink(this.getProfile(), delta, before);
- }
- } else {
- for (SyncActions action : profile.getActions()) {
- action.beforeLink(this.getProfile(), delta, before);
- }
- }
-
- output = link(before, result, unlink);
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
- }
-
- resultStatus = Result.SUCCESS;
- LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
- } catch (PropagationException e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
- output = e;
- resultStatus = Result.FAILURE;
- }
- }
- audit(unlink ? "unlink" : "link", resultStatus, before, output, delta);
- }
- updResults.add(result);
- }
-
- return updResults;
- }
-
- protected List<ProvisioningResult> delete(
- SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil)
- throws JobExecutionException {
-
- if (!profile.getTask().isPerformDelete()) {
- LOG.debug("SyncTask not configured for delete");
- return Collections.<ProvisioningResult>emptyList();
- }
-
- LOG.debug("About to delete {}", subjects);
-
- List<ProvisioningResult> delResults = new ArrayList<>();
-
- for (Long id : subjects) {
- Object output;
- Result resultStatus = Result.FAILURE;
-
- AbstractSubjectTO before = null;
- final ProvisioningResult result = new ProvisioningResult();
-
- try {
- before = getSubjectTO(id);
-
- result.setId(id);
- result.setName(getName(before));
- result.setOperation(ResourceOperation.DELETE);
- result.setSubjectType(attrUtil.getType());
- result.setStatus(ProvisioningResult.Status.SUCCESS);
-
- if (!profile.isDryRun()) {
- for (SyncActions action : profile.getActions()) {
- delta = action.beforeDelete(this.getProfile(), delta, before);
- }
-
- try {
- delete(id);
- output = null;
- resultStatus = Result.SUCCESS;
- } catch (Exception e) {
- result.setStatus(ProvisioningResult.Status.FAILURE);
- result.setMessage(ExceptionUtils.getRootCauseMessage(e));
- LOG.error("Could not delete {} {}", attrUtil.getType(), id, e);
- output = e;
- }
-
- for (SyncActions action : profile.getActions()) {
- action.after(this.getProfile(), delta, before, result);
- }
-
- audit("delete", resultStatus, before, output, delta);
- }
-
- delResults.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);
- } catch (Exception e) {
- LOG.error("Could not delete {} {}", attrUtil.getType(), id, e);
- }
- }
-
- return delResults;
- }
-
- /**
- * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on user(s)/role(s).
- *
- * @param delta returned by the underlying profile.getConnector()
- * @throws JobExecutionException in case of synchronization failure.
- */
- protected final void doHandle(final SyncDelta delta, final Collection<ProvisioningResult> syncResults)
- throws JobExecutionException {
-
- final AttributableUtil attrUtil = getAttributableUtil();
-
- LOG.debug("Process {} for {} as {}",
- delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
-
- final String uid = delta.getPreviousUid() == null
- ? delta.getUid().getUidValue()
- : delta.getPreviousUid().getUidValue();
-
- try {
- List<Long> subjectIds = syncUtilities.findExisting(
- uid, delta.getObject(), profile.getTask().getResource(), attrUtil);
-
- if (subjectIds.size() > 1) {
- switch (profile.getResAct()) {
- case IGNORE:
- throw new IllegalStateException("More than one match " + subjectIds);
-
- case FIRSTMATCH:
- subjectIds = subjectIds.subList(0, 1);
- break;
-
- case LASTMATCH:
- subjectIds = subjectIds.subList(subjectIds.size() - 1, subjectIds.size());
- break;
-
- default:
- // keep subjectIds as is
- }
- }
-
- if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
- if (subjectIds.isEmpty()) {
- switch (profile.getTask().getUnmatchingRule()) {
- case ASSIGN:
- profile.getResults().addAll(assign(delta, attrUtil));
- break;
- case PROVISION:
- profile.getResults().addAll(create(delta, attrUtil));
- break;
- default:
- // do nothing
- }
- } else {
- switch (profile.getTask().getMatchingRule()) {
- case UPDATE:
- profile.getResults().addAll(update(delta, subjectIds, attrUtil));
- break;
- case DEPROVISION:
- profile.getResults().addAll(deprovision(delta, subjectIds, attrUtil, false));
- break;
- case UNASSIGN:
- profile.getResults().addAll(deprovision(delta, subjectIds, attrUtil, true));
- break;
- case LINK:
- profile.getResults().addAll(link(delta, subjectIds, attrUtil, false));
- break;
- case UNLINK:
- profile.getResults().addAll(link(delta, subjectIds, attrUtil, true));
- break;
- default:
- // do nothing
- }
- }
- } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
- if (subjectIds.isEmpty()) {
- LOG.debug("No match found for deletion");
- } else {
- profile.getResults().addAll(delete(delta, subjectIds, attrUtil));
- }
- }
- } catch (IllegalStateException e) {
- LOG.warn(e.getMessage());
- } catch (IllegalArgumentException e) {
- LOG.warn(e.getMessage());
- }
- }
-
- private void audit(
- final String event,
- final Result result,
- final Object before,
- final Object output,
- final Object... input) {
-
- notificationManager.createTasks(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- getAttributableUtil().getType().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- input);
-
- auditManager.audit(
- AuditElements.EventCategoryType.SYNCHRONIZATION,
- getAttributableUtil().getType().name().toLowerCase(),
- profile.getTask().getResource().getKey(),
- event,
- result,
- before,
- output,
- input);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncResultHandler.java
new file mode 100644
index 0000000..83377f3
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractSyncResultHandler.java
@@ -0,0 +1,617 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.Result;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.server.persistence.api.dao.NotFoundException;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.server.provisioning.api.AttributableTransformer;
+import org.apache.syncope.server.provisioning.api.propagation.PropagationException;
+import org.apache.syncope.server.provisioning.api.sync.SyncActions;
+import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
+import org.apache.syncope.server.provisioning.api.sync.SyncopeSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncDeltaType;
+import org.quartz.JobExecutionException;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public abstract class AbstractSyncResultHandler extends AbstractSyncopeResultHandler<SyncTask, SyncActions>
+ implements SyncopeSyncResultHandler {
+
+ @Autowired
+ protected SyncUtilities syncUtilities;
+
+ @Autowired
+ protected AttributableTransformer attrTransformer;
+
+ protected abstract AttributableUtil getAttributableUtil();
+
+ protected abstract String getName(AbstractSubjectTO subjectTO);
+
+ protected abstract AbstractSubjectTO getSubjectTO(long key);
+
+ protected abstract AbstractSubjectMod getSubjectMod(AbstractSubjectTO subjectTO, SyncDelta delta);
+
+ protected abstract AbstractSubjectTO create(AbstractSubjectTO subjectTO, SyncDelta _delta, ProvisioningResult result);
+
+ protected abstract AbstractSubjectTO link(AbstractSubjectTO before, ProvisioningResult result, boolean unlink);
+
+ protected abstract AbstractSubjectTO update(AbstractSubjectTO before, AbstractSubjectMod subjectMod,
+ SyncDelta delta, ProvisioningResult result);
+
+ protected abstract void deprovision(Long key, boolean unlink);
+
+ protected abstract void delete(Long key);
+
+ @Override
+ public boolean handle(final SyncDelta delta) {
+ try {
+ doHandle(delta);
+ return true;
+ } catch (JobExecutionException e) {
+ LOG.error("Synchronization failed", e);
+ return false;
+ }
+ }
+
+ protected List<ProvisioningResult> assign(final SyncDelta delta, final AttributableUtil attrUtil)
+ throws JobExecutionException {
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("SyncTask not configured for create");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ final AbstractSubjectTO subjectTO =
+ connObjectUtil.getSubjectTO(delta.getObject(), profile.getTask(), attrUtil);
+
+ subjectTO.getResources().add(profile.getTask().getResource().getKey());
+
+ final ProvisioningResult result = new ProvisioningResult();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+
+ // Attributable transformation (if configured)
+ AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+ LOG.debug("Transformed: {}", transformed);
+
+ result.setName(getName(transformed));
+
+ if (profile.isDryRun()) {
+ result.setId(0L);
+ } else {
+ SyncDelta _delta = delta;
+ for (SyncActions action : profile.getActions()) {
+ _delta = action.beforeAssign(this.getProfile(), _delta, transformed);
+ }
+
+ create(transformed, _delta, attrUtil, "assign", result);
+ }
+
+ return Collections.singletonList(result);
+ }
+
+ protected List<ProvisioningResult> create(final SyncDelta delta, final AttributableUtil attrUtil)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformCreate()) {
+ LOG.debug("SyncTask not configured for create");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ final AbstractSubjectTO subjectTO =
+ connObjectUtil.getSubjectTO(delta.getObject(), profile.getTask(), attrUtil);
+
+ // Attributable transformation (if configured)
+ AbstractSubjectTO transformed = attrTransformer.transform(subjectTO);
+ LOG.debug("Transformed: {}", transformed);
+
+ final ProvisioningResult result = new ProvisioningResult();
+ result.setOperation(ResourceOperation.CREATE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+
+ result.setName(getName(transformed));
+
+ if (profile.isDryRun()) {
+ result.setId(0L);
+ } else {
+ SyncDelta _delta = delta;
+ for (SyncActions action : profile.getActions()) {
+ _delta = action.beforeProvision(this.getProfile(), _delta, transformed);
+ }
+
+ create(transformed, _delta, attrUtil, "provision", result);
+ }
+
+ return Collections.<ProvisioningResult>singletonList(result);
+ }
+
+ private void create(
+ final AbstractSubjectTO subjectTO,
+ final SyncDelta delta,
+ final AttributableUtil attrUtil,
+ final String operation,
+ final ProvisioningResult result)
+ throws JobExecutionException {
+
+ Object output;
+ Result resultStatus;
+
+ try {
+ AbstractSubjectTO actual = create(subjectTO, delta, result);
+ result.setName(getName(actual));
+ output = actual;
+ resultStatus = Result.SUCCESS;
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, actual, result);
+ }
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not create {} {} ", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+
+ audit(operation, resultStatus, null, output, delta);
+ }
+
+ protected List<ProvisioningResult> update(SyncDelta delta, final List<Long> subjects,
+ final AttributableUtil attrUtil)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ LOG.debug("About to update {}", subjects);
+
+ List<ProvisioningResult> results = new ArrayList<>();
+
+ for (Long key : subjects) {
+ LOG.debug("About to update {}", key);
+
+ final ProvisioningResult result = new ProvisioningResult();
+ result.setOperation(ResourceOperation.UPDATE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+ result.setId(key);
+
+ AbstractSubjectTO before = getSubjectTO(key);
+ if (before == null) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), key));
+ } else {
+ result.setName(getName(before));
+ }
+
+ Result resultStatus;
+ Object output;
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ try {
+ final AbstractSubjectMod attributableMod = getSubjectMod(before, delta);
+
+ // Attribute value transformation (if configured)
+ final AbstractSubjectMod actual = attrTransformer.transform(attributableMod);
+ LOG.debug("Transformed: {}", actual);
+
+ for (SyncActions action : profile.getActions()) {
+ delta = action.beforeUpdate(this.getProfile(), delta, before, attributableMod);
+ }
+
+ final AbstractSubjectTO updated = update(before, attributableMod, delta, result);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, updated, result);
+ }
+
+ output = updated;
+ resultStatus = Result.SUCCESS;
+ result.setName(getName(updated));
+ LOG.debug("{} {} successfully updated", attrUtil.getType(), key);
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ audit("update", resultStatus, before, output, delta);
+ }
+ results.add(result);
+ }
+ return results;
+ }
+
+ protected List<ProvisioningResult> deprovision(
+ SyncDelta delta,
+ final List<Long> subjects,
+ final AttributableUtil attrUtil,
+ final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ LOG.debug("About to update {}", subjects);
+
+ final List<ProvisioningResult> updResults = new ArrayList<>();
+
+ for (Long id : subjects) {
+ LOG.debug("About to unassign resource {}", id);
+
+ Object output;
+ Result resultStatus;
+
+ final ProvisioningResult result = new ProvisioningResult();
+ result.setOperation(ResourceOperation.DELETE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+ result.setId(id);
+
+ final AbstractSubjectTO before = getSubjectTO(id);
+
+ if (before == null) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), id));
+ }
+
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ result.setName(getName(before));
+
+ try {
+ if (unlink) {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeUnassign(this.getProfile(), delta, before);
+ }
+ } else {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeDeprovision(this.getProfile(), delta, before);
+ }
+ }
+
+ deprovision(id, unlink);
+ output = getSubjectTO(id);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+ }
+
+ resultStatus = Result.SUCCESS;
+ LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ audit(unlink ? "unassign" : "deprovision", resultStatus, before, output, delta);
+ }
+ updResults.add(result);
+ }
+
+ return updResults;
+ }
+
+ protected List<ProvisioningResult> link(
+ SyncDelta delta,
+ final List<Long> subjects,
+ final AttributableUtil attrUtil,
+ final boolean unlink)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformUpdate()) {
+ LOG.debug("SyncTask not configured for update");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ LOG.debug("About to update {}", subjects);
+
+ final List<ProvisioningResult> updResults = new ArrayList<>();
+
+ for (Long id : subjects) {
+ LOG.debug("About to unassign resource {}", id);
+
+ Object output;
+ Result resultStatus;
+
+ final ProvisioningResult result = new ProvisioningResult();
+ result.setOperation(ResourceOperation.NONE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+ result.setId(id);
+
+ final AbstractSubjectTO before = getSubjectTO(id);
+
+ if (before == null) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(String.format("Subject '%s(%d)' not found", attrUtil.getType().name(), id));
+ }
+
+ if (!profile.isDryRun()) {
+ if (before == null) {
+ resultStatus = Result.FAILURE;
+ output = null;
+ } else {
+ result.setName(getName(before));
+
+ try {
+ if (unlink) {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeUnlink(this.getProfile(), delta, before);
+ }
+ } else {
+ for (SyncActions action : profile.getActions()) {
+ action.beforeLink(this.getProfile(), delta, before);
+ }
+ }
+
+ output = link(before, result, unlink);
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, AbstractSubjectTO.class.cast(output), result);
+ }
+
+ resultStatus = Result.SUCCESS;
+ LOG.debug("{} {} successfully updated", attrUtil.getType(), id);
+ } catch (PropagationException e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not update {} {}", attrUtil.getType(), delta.getUid().getUidValue(), e);
+ output = e;
+ resultStatus = Result.FAILURE;
+ }
+ }
+ audit(unlink ? "unlink" : "link", resultStatus, before, output, delta);
+ }
+ updResults.add(result);
+ }
+
+ return updResults;
+ }
+
+ protected List<ProvisioningResult> delete(
+ SyncDelta delta, final List<Long> subjects, final AttributableUtil attrUtil)
+ throws JobExecutionException {
+
+ if (!profile.getTask().isPerformDelete()) {
+ LOG.debug("SyncTask not configured for delete");
+ return Collections.<ProvisioningResult>emptyList();
+ }
+
+ LOG.debug("About to delete {}", subjects);
+
+ List<ProvisioningResult> delResults = new ArrayList<>();
+
+ for (Long id : subjects) {
+ Object output;
+ Result resultStatus = Result.FAILURE;
+
+ AbstractSubjectTO before = null;
+ final ProvisioningResult result = new ProvisioningResult();
+
+ try {
+ before = getSubjectTO(id);
+
+ result.setId(id);
+ result.setName(getName(before));
+ result.setOperation(ResourceOperation.DELETE);
+ result.setSubjectType(attrUtil.getType());
+ result.setStatus(ProvisioningResult.Status.SUCCESS);
+
+ if (!profile.isDryRun()) {
+ for (SyncActions action : profile.getActions()) {
+ delta = action.beforeDelete(this.getProfile(), delta, before);
+ }
+
+ try {
+ delete(id);
+ output = null;
+ resultStatus = Result.SUCCESS;
+ } catch (Exception e) {
+ result.setStatus(ProvisioningResult.Status.FAILURE);
+ result.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ LOG.error("Could not delete {} {}", attrUtil.getType(), id, e);
+ output = e;
+ }
+
+ for (SyncActions action : profile.getActions()) {
+ action.after(this.getProfile(), delta, before, result);
+ }
+
+ audit("delete", resultStatus, before, output, delta);
+ }
+
+ delResults.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);
+ } catch (Exception e) {
+ LOG.error("Could not delete {} {}", attrUtil.getType(), id, e);
+ }
+ }
+
+ return delResults;
+ }
+
+ /**
+ * Look into SyncDelta and take necessary profile.getActions() (create / update / delete) on user(s)/role(s).
+ *
+ * @param delta returned by the underlying profile.getConnector()
+ * @throws JobExecutionException in case of synchronization failure.
+ */
+ protected final void doHandle(final SyncDelta delta)
+ throws JobExecutionException {
+
+ final AttributableUtil attrUtil = getAttributableUtil();
+
+ LOG.debug("Process {} for {} as {}",
+ delta.getDeltaType(), delta.getUid().getUidValue(), delta.getObject().getObjectClass());
+
+ final String uid = delta.getPreviousUid() == null
+ ? delta.getUid().getUidValue()
+ : delta.getPreviousUid().getUidValue();
+
+ try {
+ List<Long> subjectKeys = syncUtilities.findExisting(
+ uid, delta.getObject(), profile.getTask().getResource(), attrUtil);
+
+ if (subjectKeys.size() > 1) {
+ switch (profile.getResAct()) {
+ case IGNORE:
+ throw new IllegalStateException("More than one match " + subjectKeys);
+
+ case FIRSTMATCH:
+ subjectKeys = subjectKeys.subList(0, 1);
+ break;
+
+ case LASTMATCH:
+ subjectKeys = subjectKeys.subList(subjectKeys.size() - 1, subjectKeys.size());
+ break;
+
+ default:
+ // keep subjectIds as is
+ }
+ }
+
+ if (SyncDeltaType.CREATE_OR_UPDATE == delta.getDeltaType()) {
+ if (subjectKeys.isEmpty()) {
+ switch (profile.getTask().getUnmatchingRule()) {
+ case ASSIGN:
+ profile.getResults().addAll(assign(delta, attrUtil));
+ break;
+ case PROVISION:
+ profile.getResults().addAll(create(delta, attrUtil));
+ break;
+ default:
+ // do nothing
+ }
+ } else {
+ switch (profile.getTask().getMatchingRule()) {
+ case UPDATE:
+ profile.getResults().addAll(update(delta, subjectKeys, attrUtil));
+ break;
+ case DEPROVISION:
+ profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtil, false));
+ break;
+ case UNASSIGN:
+ profile.getResults().addAll(deprovision(delta, subjectKeys, attrUtil, true));
+ break;
+ case LINK:
+ profile.getResults().addAll(link(delta, subjectKeys, attrUtil, false));
+ break;
+ case UNLINK:
+ profile.getResults().addAll(link(delta, subjectKeys, attrUtil, true));
+ break;
+ default:
+ // do nothing
+ }
+ }
+ } else if (SyncDeltaType.DELETE == delta.getDeltaType()) {
+ if (subjectKeys.isEmpty()) {
+ LOG.debug("No match found for deletion");
+ } else {
+ profile.getResults().addAll(delete(delta, subjectKeys, attrUtil));
+ }
+ }
+ } catch (IllegalStateException | IllegalArgumentException e) {
+ LOG.warn(e.getMessage());
+ }
+ }
+
+ private void audit(
+ final String event,
+ final Result result,
+ final Object before,
+ final Object output,
+ final Object... input) {
+
+ notificationManager.createTasks(
+ AuditElements.EventCategoryType.SYNCHRONIZATION,
+ getAttributableUtil().getType().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ input);
+
+ auditManager.audit(
+ AuditElements.EventCategoryType.SYNCHRONIZATION,
+ getAttributableUtil().getType().name().toLowerCase(),
+ profile.getTask().getResource().getKey(),
+ event,
+ result,
+ before,
+ output,
+ input);
+ }
+}
[05/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultPushActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultPushActions.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultPushActions.java
index a9ba96e..dbbdd2a 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultPushActions.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultPushActions.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.server.provisioning.java.sync;
-import java.util.List;
import org.apache.syncope.server.persistence.api.entity.Subject;
import org.apache.syncope.server.provisioning.api.sync.PushActions;
import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
@@ -78,11 +77,12 @@ public abstract class DefaultPushActions implements PushActions {
@Override
public <T extends Subject<?, ?, ?>> void after(
- final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result) throws JobExecutionException {
+ final ProvisioningProfile<?, ?> profile, final T subject, final ProvisioningResult result)
+ throws JobExecutionException {
}
@Override
- public void afterAll(final ProvisioningProfile<?, ?> profile, final List<ProvisioningResult> results)
+ public void afterAll(final ProvisioningProfile<?, ?> profile)
throws JobExecutionException {
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultSyncActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultSyncActions.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultSyncActions.java
index b957d2a..6589cdf 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultSyncActions.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/DefaultSyncActions.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.server.provisioning.java.sync;
-import java.util.List;
import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
import org.apache.syncope.common.lib.to.AbstractSubjectTO;
import org.apache.syncope.server.provisioning.api.sync.SyncActions;
@@ -104,12 +103,13 @@ public abstract class DefaultSyncActions implements SyncActions {
@Override
public <T extends AbstractSubjectTO> void after(
- final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject, final ProvisioningResult result)
+ final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final T subject,
+ final ProvisioningResult result)
throws JobExecutionException {
}
@Override
- public void afterAll(final ProvisioningProfile<?, ?> profile, final List<ProvisioningResult> results)
+ public void afterAll(final ProvisioningProfile<?, ?> profile)
throws JobExecutionException {
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
index b705c64..145cd4d 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/LDAPMembershipSyncActions.java
@@ -146,17 +146,17 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
/**
* Build UserMod for adding membership to given user, for given role.
*
- * @param userId user to be assigned membership to given role
+ * @param userKey user to be assigned membership to given role
* @param roleTO role for adding membership
* @return UserMod for user update
*/
- protected UserMod getUserMod(final Long userId, final RoleTO roleTO) {
+ protected UserMod getUserMod(final Long userKey, final RoleTO roleTO) {
UserMod userMod = new UserMod();
// no actual modification takes place when user has already the role assigned
- if (membersBeforeRoleUpdate.containsKey(userId)) {
- membersBeforeRoleUpdate.remove(userId);
+ if (membersBeforeRoleUpdate.containsKey(userKey)) {
+ membersBeforeRoleUpdate.remove(userKey);
} else {
- userMod.setKey(userId);
+ userMod.setKey(userKey);
MembershipMod membershipMod = new MembershipMod();
membershipMod.setRole(roleTO.getKey());
@@ -265,13 +265,13 @@ public class LDAPMembershipSyncActions extends DefaultSyncActions {
final Connector connector = profile.getConnector();
for (Object membValue : getMembAttrValues(delta, connector)) {
- Long userId = syncUtilities.findMatchingAttributableId(
+ Long userKey = syncUtilities.findMatchingAttributableKey(
ObjectClass.ACCOUNT,
membValue.toString(),
profile.getTask().getResource(),
profile.getConnector());
- if (userId != null) {
- UserMod userMod = getUserMod(userId, roleTO);
+ if (userKey != null) {
+ UserMod userMod = getUserMod(userKey, roleTO);
userUpdate(userMod, resource.getKey());
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/PushJobImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/PushJobImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/PushJobImpl.java
index d40b4be..3f7b291 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/PushJobImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/PushJobImpl.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.server.provisioning.java.sync;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@@ -36,11 +35,12 @@ import org.apache.syncope.server.persistence.api.entity.user.UMapping;
import org.apache.syncope.server.persistence.api.entity.user.User;
import org.apache.syncope.server.provisioning.api.Connector;
import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
import org.apache.syncope.server.provisioning.api.sync.PushActions;
import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
import org.apache.syncope.server.misc.search.SearchCondConverter;
import org.apache.syncope.server.provisioning.api.job.PushJob;
+import org.apache.syncope.server.provisioning.api.sync.RolePushResultHandler;
+import org.apache.syncope.server.provisioning.api.sync.UserPushResultHandler;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
@@ -50,6 +50,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
*
* @see AbstractProvisioningJob
* @see PushTask
+ * @see PushActions
*/
public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions> implements PushJob {
@@ -82,27 +83,26 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
final boolean dryRun) throws JobExecutionException {
LOG.debug("Execute synchronization (push) with resource {}", pushTask.getResource());
- final List<ProvisioningResult> results = new ArrayList<>();
-
final Set<Long> authorizations = RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll());
final ProvisioningProfile<PushTask, PushActions> profile = new ProvisioningProfile<>(connector, pushTask);
- profile.getActions().addAll(actions);
+ if (actions != null) {
+ profile.getActions().addAll(actions);
+ }
profile.setDryRun(dryRun);
profile.setResAct(null);
- profile.getResults().addAll(results);
final UserPushResultHandler uhandler =
- (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().createBean(
- UserPushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ (UserPushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+ createBean(UserPushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
uhandler.setProfile(profile);
final RolePushResultHandler rhandler =
- (RolePushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().createBean(
- RolePushResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ (RolePushResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+ createBean(RolePushResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
rhandler.setProfile(profile);
- if (!profile.isDryRun()) {
+ if (actions != null && !profile.isDryRun()) {
for (PushActions action : actions) {
action.beforeAll(profile);
}
@@ -139,13 +139,13 @@ public class PushJobImpl extends AbstractProvisioningJob<PushTask, PushActions>
}
}
- if (!profile.isDryRun()) {
+ if (actions != null && !profile.isDryRun()) {
for (PushActions action : actions) {
- action.afterAll(profile, results);
+ action.afterAll(profile);
}
}
- final String result = createReport(results, pushTask.getResource().getSyncTraceLevel(), dryRun);
+ final String result = createReport(profile.getResults(), pushTask.getResource().getSyncTraceLevel(), dryRun);
LOG.debug("Sync result: {}", result);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandler.java
deleted file mode 100644
index 60d6bdb..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandler.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.common.lib.mod.RoleMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.server.persistence.api.entity.Mapping;
-import org.apache.syncope.server.persistence.api.entity.MappingItem;
-import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.provisioning.api.TimeoutException;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-
-public class RolePushResultHandler extends AbstractSubjectPushResultHandler {
-
- @Override
- protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
- final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
-
- final List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getRoleDeleteTaskIds(before.getKey(), noPropResources));
-
- return roleDAO.authFetch(before.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
- final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
-
- final List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- final PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getRoleCreateTaskIds(
- before.getKey(),
- Collections.unmodifiableCollection(before.getVirAttrs()),
- propByRes,
- noPropResources));
-
- return roleDAO.authFetch(before.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
- final RoleMod roleMod = new RoleMod();
- roleMod.setKey(sbj.getKey());
-
- if (unlink) {
- roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- } else {
- roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- }
-
- rwfAdapter.update(roleMod);
-
- return roleDAO.authFetch(sbj.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
- final RoleMod roleMod = new RoleMod();
- roleMod.setKey(sbj.getKey());
- roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- rwfAdapter.update(roleMod);
- return deprovision(sbj);
- }
-
- @Override
- protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
- final RoleMod roleMod = new RoleMod();
- roleMod.setKey(sbj.getKey());
- roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- rwfAdapter.update(roleMod);
- return provision(sbj, enabled);
- }
-
- @Override
- protected String getName(final Subject<?, ?, ?> subject) {
- return Role.class.cast(subject).getName();
- }
-
- @Override
- protected AbstractSubjectTO getSubjectTO(final long key) {
- try {
- return roleTransfer.getRoleTO(roleDAO.authFetch(key));
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected Subject<?, ?, ?> getSubject(final long key) {
- try {
- return roleDAO.authFetch(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving role {}", key, e);
- return null;
- }
- }
-
- @Override
- protected ConnectorObject getRemoteObject(final String accountId) {
- ConnectorObject obj = null;
-
- try {
- final Uid uid = new Uid(accountId);
-
- obj = profile.getConnector().getObject(
- ObjectClass.GROUP,
- uid,
- profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", accountId, ignore);
- }
- return obj;
- }
-
- @Override
- protected Mapping<?> getMapping() {
- return profile.getTask().getResource().getRmapping();
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandlerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandlerImpl.java
new file mode 100644
index 0000000..112d8cc
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RolePushResultHandlerImpl.java
@@ -0,0 +1,155 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.server.persistence.api.entity.Mapping;
+import org.apache.syncope.server.persistence.api.entity.MappingItem;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.provisioning.api.TimeoutException;
+import org.apache.syncope.server.provisioning.api.sync.RolePushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class RolePushResultHandlerImpl extends AbstractPushResultHandler implements RolePushResultHandler {
+
+ @Override
+ protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
+ final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getRoleDeleteTaskIds(before.getKey(), noPropResources));
+
+ return roleDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final RoleTO before = roleTransfer.getRoleTO(Role.class.cast(sbj));
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ final PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getRoleCreateTaskIds(
+ before.getKey(),
+ Collections.unmodifiableCollection(before.getVirAttrs()),
+ propByRes,
+ noPropResources));
+
+ return roleDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+
+ if (unlink) {
+ roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ rwfAdapter.update(roleMod);
+
+ return roleDAO.authFetch(sbj.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+ roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ rwfAdapter.update(roleMod);
+ return deprovision(sbj);
+ }
+
+ @Override
+ protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(sbj.getKey());
+ roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ rwfAdapter.update(roleMod);
+ return provision(sbj, enabled);
+ }
+
+ @Override
+ protected String getName(final Subject<?, ?, ?> subject) {
+ return Role.class.cast(subject).getName();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return roleTransfer.getRoleTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected Subject<?, ?, ?> getSubject(final long key) {
+ try {
+ return roleDAO.authFetch(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving role {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected ConnectorObject getRemoteObject(final String accountId) {
+ ConnectorObject obj = null;
+
+ try {
+ final Uid uid = new Uid(accountId);
+
+ obj = profile.getConnector().getObject(
+ ObjectClass.GROUP,
+ uid,
+ profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", accountId, ignore);
+ }
+ return obj;
+ }
+
+ @Override
+ protected Mapping<?> getMapping() {
+ return profile.getTask().getResource().getRmapping();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandler.java
deleted file mode 100644
index d172077..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandler.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.AttrMod;
-import org.apache.syncope.common.lib.mod.RoleMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.RoleTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-
-public class RoleSyncResultHandler extends AbstractSubjectSyncResultHandler {
-
- protected Map<Long, String> roleOwnerMap = new HashMap<>();
-
- public Map<Long, String> getRoleOwnerMap() {
- return this.roleOwnerMap;
- }
-
- @Override
- protected AttributableUtil getAttributableUtil() {
- return attrUtilFactory.getInstance(AttributableType.ROLE);
- }
-
- @Override
- protected String getName(final AbstractSubjectTO subjectTO) {
- return RoleTO.class.cast(subjectTO).getName();
- }
-
- @Override
- protected AbstractSubjectTO getSubjectTO(final long key) {
- try {
- return roleTransfer.getRoleTO(roleDAO.authFetch(key));
- } catch (Exception e) {
- LOG.warn("Error retrieving role {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AbstractSubjectMod getSubjectMod(
- final AbstractSubjectTO subjectTO, final SyncDelta delta) {
-
- return connObjectUtil.getAttributableMod(
- subjectTO.getKey(),
- delta.getObject(),
- subjectTO,
- profile.getTask(),
- attrUtilFactory.getInstance(AttributableType.ROLE));
- }
-
- @Override
- protected AbstractSubjectTO create(
- final AbstractSubjectTO subjectTO, final SyncDelta _delta, final ProvisioningResult result) {
-
- RoleTO roleTO = RoleTO.class.cast(subjectTO);
-
- Map.Entry<Long, List<PropagationStatus>> created = roleProvisioningManager.create(roleTO, roleOwnerMap,
- Collections.singleton(profile.getTask().getResource().getKey()));
-
- roleTO = roleTransfer.getRoleTO(roleDAO.authFetch(created.getKey()));
-
- result.setId(created.getKey());
- result.setName(getName(subjectTO));
-
- return roleTO;
- }
-
- @Override
- protected AbstractSubjectTO link(
- final AbstractSubjectTO before,
- final ProvisioningResult result,
- final boolean unlink) {
-
- final RoleMod roleMod = new RoleMod();
- roleMod.setKey(before.getKey());
-
- if (unlink) {
- roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- } else {
- roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- }
-
- return roleTransfer.getRoleTO(roleDAO.authFetch(rwfAdapter.update(roleMod).getResult()));
- }
-
- @Override
- protected AbstractSubjectTO update(
- final AbstractSubjectTO before,
- final AbstractSubjectMod subjectMod,
- final SyncDelta delta,
- final ProvisioningResult result) {
-
- RoleMod roleMod = RoleMod.class.cast(subjectMod);
-
- Map.Entry<Long, List<PropagationStatus>> updated = roleProvisioningManager.update(roleMod);
-
- //moved after role provisioning manager
- String roleOwner = null;
- for (AttrMod attrMod : roleMod.getAttrsToUpdate()) {
- if (attrMod.getSchema().isEmpty()) {
- roleOwner = attrMod.getValuesToBeAdded().iterator().next();
- }
- }
- if (roleOwner != null) {
- roleOwnerMap.put(updated.getKey(), roleOwner);
- }
-
- final RoleTO after = roleTransfer.getRoleTO(roleDAO.authFetch(updated.getKey()));
-
- result.setName(getName(after));
-
- return after;
- }
-
- @Override
- protected void deprovision(final Long id, final boolean unlink) {
-
- taskExecutor.execute(
- propagationManager.getRoleDeleteTaskIds(id, profile.getTask().getResource().getKey()));
-
- if (unlink) {
- final UserMod userMod = new UserMod();
- userMod.setKey(id);
- userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- }
- }
-
- @Override
- protected void delete(final Long id) {
- try {
- taskExecutor.execute(
- propagationManager.getRoleDeleteTaskIds(id, profile.getTask().getResource().getKey()));
- } catch (Exception e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate user " + id, e);
- }
-
- roleProvisioningManager.delete(id);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandlerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandlerImpl.java
new file mode 100644
index 0000000..2cada75
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/RoleSyncResultHandlerImpl.java
@@ -0,0 +1,169 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.server.provisioning.api.sync.RoleSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class RoleSyncResultHandlerImpl extends AbstractSyncResultHandler implements RoleSyncResultHandler {
+
+ protected Map<Long, String> roleOwnerMap = new HashMap<>();
+
+ @Override
+ public Map<Long, String> getRoleOwnerMap() {
+ return this.roleOwnerMap;
+ }
+
+ @Override
+ protected AttributableUtil getAttributableUtil() {
+ return attrUtilFactory.getInstance(AttributableType.ROLE);
+ }
+
+ @Override
+ protected String getName(final AbstractSubjectTO subjectTO) {
+ return RoleTO.class.cast(subjectTO).getName();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return roleTransfer.getRoleTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving role {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AbstractSubjectMod getSubjectMod(
+ final AbstractSubjectTO subjectTO, final SyncDelta delta) {
+
+ return connObjectUtil.getAttributableMod(
+ subjectTO.getKey(),
+ delta.getObject(),
+ subjectTO,
+ profile.getTask(),
+ attrUtilFactory.getInstance(AttributableType.ROLE));
+ }
+
+ @Override
+ protected AbstractSubjectTO create(
+ final AbstractSubjectTO subjectTO, final SyncDelta _delta, final ProvisioningResult result) {
+
+ RoleTO roleTO = RoleTO.class.cast(subjectTO);
+
+ Map.Entry<Long, List<PropagationStatus>> created = roleProvisioningManager.create(roleTO, roleOwnerMap,
+ Collections.singleton(profile.getTask().getResource().getKey()));
+
+ roleTO = roleTransfer.getRoleTO(created.getKey());
+
+ result.setId(created.getKey());
+ result.setName(getName(subjectTO));
+
+ return roleTO;
+ }
+
+ @Override
+ protected AbstractSubjectTO link(
+ final AbstractSubjectTO before,
+ final ProvisioningResult result,
+ final boolean unlink) {
+
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(before.getKey());
+
+ if (unlink) {
+ roleMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ roleMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ return roleTransfer.getRoleTO(rwfAdapter.update(roleMod).getResult());
+ }
+
+ @Override
+ protected AbstractSubjectTO update(
+ final AbstractSubjectTO before,
+ final AbstractSubjectMod subjectMod,
+ final SyncDelta delta,
+ final ProvisioningResult result) {
+
+ RoleMod roleMod = RoleMod.class.cast(subjectMod);
+
+ Map.Entry<Long, List<PropagationStatus>> updated = roleProvisioningManager.update(roleMod);
+
+ //moved after role provisioning manager
+ String roleOwner = null;
+ for (AttrMod attrMod : roleMod.getPlainAttrsToUpdate()) {
+ if (attrMod.getSchema().isEmpty()) {
+ roleOwner = attrMod.getValuesToBeAdded().iterator().next();
+ }
+ }
+ if (roleOwner != null) {
+ roleOwnerMap.put(updated.getKey(), roleOwner);
+ }
+
+ final RoleTO after = roleTransfer.getRoleTO(updated.getKey());
+
+ result.setName(getName(after));
+
+ return after;
+ }
+
+ @Override
+ protected void deprovision(final Long id, final boolean unlink) {
+
+ taskExecutor.execute(
+ propagationManager.getRoleDeleteTaskIds(id, profile.getTask().getResource().getKey()));
+
+ if (unlink) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(id);
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ }
+ }
+
+ @Override
+ protected void delete(final Long id) {
+ try {
+ taskExecutor.execute(
+ propagationManager.getRoleDeleteTaskIds(id, profile.getTask().getResource().getKey()));
+ } catch (Exception e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate user " + id, e);
+ }
+
+ roleProvisioningManager.delete(id);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
index c47bff6..47a118f 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncJobImpl.java
@@ -18,8 +18,6 @@
*/
package org.apache.syncope.server.provisioning.java.sync;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.mod.ReferenceMod;
@@ -34,11 +32,12 @@ import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
import org.apache.syncope.server.persistence.api.entity.user.UMapping;
import org.apache.syncope.server.provisioning.api.Connector;
import org.apache.syncope.server.provisioning.api.sync.ProvisioningProfile;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
import org.apache.syncope.server.provisioning.api.sync.SyncActions;
import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
import org.apache.syncope.server.provisioning.api.job.SyncJob;
+import org.apache.syncope.server.provisioning.api.sync.RoleSyncResultHandler;
+import org.apache.syncope.server.provisioning.api.sync.UserSyncResultHandler;
import org.apache.syncope.server.workflow.api.RoleWorkflowAdapter;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.SyncToken;
@@ -74,14 +73,14 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
roleMod.setRoleOwner(null);
roleMod.setUserOwner(null);
} else {
- Long userId = syncUtilities.findMatchingAttributableId(
+ Long userId = syncUtilities.findMatchingAttributableKey(
ObjectClass.ACCOUNT,
entry.getValue(),
rhandler.getProfile().getTask().getResource(),
rhandler.getProfile().getConnector());
if (userId == null) {
- Long roleId = syncUtilities.findMatchingAttributableId(
+ Long roleId = syncUtilities.findMatchingAttributableKey(
ObjectClass.GROUP,
entry.getValue(),
rhandler.getProfile().getTask().getResource(),
@@ -109,27 +108,26 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
LOG.debug("Execute synchronization with token {}", syncTask.getResource().getUsyncToken());
- final List<ProvisioningResult> results = new ArrayList<>();
-
final ProvisioningProfile<SyncTask, SyncActions> profile = new ProvisioningProfile<>(connector, syncTask);
- profile.getActions().addAll(actions);
+ if (actions != null) {
+ profile.getActions().addAll(actions);
+ }
profile.setDryRun(dryRun);
profile.setResAct(getSyncPolicySpec(syncTask).getConflictResolutionAction());
- profile.getResults().addAll(results);
// Prepare handler for SyncDelta objects (users)
final UserSyncResultHandler uhandler =
- (UserSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().createBean(
- UserSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ (UserSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+ createBean(UserSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
uhandler.setProfile(profile);
// Prepare handler for SyncDelta objects (roles/groups)
final RoleSyncResultHandler rhandler =
- (RoleSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().createBean(
- RoleSyncResultHandler.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
+ (RoleSyncResultHandler) ApplicationContextProvider.getApplicationContext().getBeanFactory().
+ createBean(RoleSyncResultHandlerImpl.class, AbstractBeanDefinition.AUTOWIRE_BY_NAME, false);
rhandler.setProfile(profile);
- if (!profile.isDryRun()) {
+ if (actions != null && !profile.isDryRun()) {
for (SyncActions action : actions) {
action.beforeAll(profile);
}
@@ -189,13 +187,13 @@ public class SyncJobImpl extends AbstractProvisioningJob<SyncTask, SyncActions>
LOG.error("While setting role owners", e);
}
- if (!profile.isDryRun()) {
+ if (actions != null && !profile.isDryRun()) {
for (SyncActions action : actions) {
- action.afterAll(profile, results);
+ action.afterAll(profile);
}
}
- final String result = createReport(results, syncTask.getResource().getSyncTraceLevel(), dryRun);
+ final String result = createReport(profile.getResults(), syncTask.getResource().getSyncTraceLevel(), dryRun);
LOG.debug("Sync result: {}", result);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncUtilities.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncUtilities.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncUtilities.java
index 0d62487..299aba0 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncUtilities.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/SyncUtilities.java
@@ -115,11 +115,12 @@ public class SyncUtilities {
@Autowired
protected AttributableUtilFactory attrUtilFactory;
- public Long findMatchingAttributableId(
+ public Long findMatchingAttributableKey(
final ObjectClass oclass,
final String name,
final ExternalResource resource,
final Connector connector) {
+
Long result = null;
final AttributableUtil attrUtil = attrUtilFactory.getInstance(oclass);
@@ -137,15 +138,15 @@ public class SyncUtilities {
ConnectorObject connObj = found.iterator().next();
try {
- final List<Long> subjectIds = findExisting(connObj.getUid().getUidValue(), connObj, resource, attrUtil);
- if (subjectIds.isEmpty()) {
+ List<Long> subjectKeys = findExisting(connObj.getUid().getUidValue(), connObj, resource, attrUtil);
+ if (subjectKeys.isEmpty()) {
LOG.debug("No matching {} found for {}, aborting", attrUtil.getType(), connObj);
} else {
- if (subjectIds.size() > 1) {
- LOG.warn("More than one {} found {} - taking first only", attrUtil.getType(), subjectIds);
+ if (subjectKeys.size() > 1) {
+ LOG.warn("More than one {} found {} - taking first only", attrUtil.getType(), subjectKeys);
}
- result = subjectIds.iterator().next();
+ result = subjectKeys.iterator().next();
}
} catch (IllegalArgumentException e) {
LOG.warn(e.getMessage());
@@ -155,14 +156,14 @@ public class SyncUtilities {
return result;
}
- public List<Long> findByAccountIdItem(
+ private List<Long> findByAccountIdItem(
final String uid, final ExternalResource resource, final AttributableUtil attrUtil) {
final List<Long> result = new ArrayList<>();
final MappingItem accountIdItem = attrUtil.getAccountIdItem(resource);
switch (accountIdItem.getIntMappingType()) {
- case UserSchema:
- case RoleSchema:
+ case UserPlainSchema:
+ case RolePlainSchema:
final PlainAttrValue value = attrUtil.newPlainAttrValue();
PlainSchema schema = plainSchemaDAO.find(accountIdItem.getIntAttrName(), attrUtil.plainSchemaClass());
@@ -227,7 +228,7 @@ public class SyncUtilities {
return result;
}
- public List<Long> search(final SearchCond searchCond, final SubjectType type) {
+ private List<Long> search(final SearchCond searchCond, final SubjectType type) {
final List<Long> result = new ArrayList<>();
List<Subject<?, ?, ?>> subjects = searchDAO.search(
@@ -240,13 +241,13 @@ public class SyncUtilities {
return result;
}
- public List<Long> findByCorrelationRule(
+ private List<Long> findByCorrelationRule(
final ConnectorObject connObj, final SyncCorrelationRule rule, final SubjectType type) {
return search(rule.getSearchCond(connObj), type);
}
- public List<Long> findByAttributableSearch(
+ private List<Long> findByAttributableSearch(
final ConnectorObject connObj,
final List<String> altSearchSchemas,
final ExternalResource resource,
@@ -287,7 +288,7 @@ public class SyncUtilities {
SearchCond nodeCond;
// users: just id or username can be selected to be used
// roles: just id or name can be selected to be used
- if ("id".equalsIgnoreCase(schema)
+ if ("key".equalsIgnoreCase(schema)
|| "username".equalsIgnoreCase(schema) || "name".equalsIgnoreCase(schema)) {
SubjectCond cond = new SubjectCond();
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandler.java
deleted file mode 100644
index 3302388..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandler.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.PropagationByResource;
-import org.apache.syncope.common.lib.types.ResourceOperation;
-import org.apache.syncope.server.persistence.api.entity.Mapping;
-import org.apache.syncope.server.persistence.api.entity.MappingItem;
-import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.apache.syncope.server.persistence.api.entity.user.User;
-import org.apache.syncope.server.provisioning.api.TimeoutException;
-import org.identityconnectors.framework.common.objects.ConnectorObject;
-import org.identityconnectors.framework.common.objects.ObjectClass;
-import org.identityconnectors.framework.common.objects.Uid;
-
-public class UserPushResultHandler extends AbstractSubjectPushResultHandler {
-
- @Override
- protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
- final UserTO before = userTransfer.getUserTO(userDAO.authFetch(sbj.getKey()));
-
- final List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUserDeleteTaskIds(before.getKey(),
- Collections.singleton(profile.getTask().getResource().getKey()), noPropResources));
-
- return userDAO.authFetch(before.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
- final UserTO before = userTransfer.getUserTO(userDAO.authFetch(sbj.getKey()));
-
- final List<String> noPropResources = new ArrayList<>(before.getResources());
- noPropResources.remove(profile.getTask().getResource().getKey());
-
- final PropagationByResource propByRes = new PropagationByResource();
- propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
-
- taskExecutor.execute(propagationManager.getUserCreateTaskIds(
- before.getKey(),
- enabled,
- propByRes,
- null,
- Collections.unmodifiableCollection(before.getVirAttrs()),
- Collections.unmodifiableCollection(before.getMemberships()),
- noPropResources));
-
- return userDAO.authFetch(before.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
- final UserMod userMod = new UserMod();
- userMod.setKey(sbj.getKey());
-
- if (unlink) {
- userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- } else {
- userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- }
-
- uwfAdapter.update(userMod);
-
- return userDAO.authFetch(userMod.getKey());
- }
-
- @Override
- protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
- final UserMod userMod = new UserMod();
- userMod.setKey(sbj.getKey());
- userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- uwfAdapter.update(userMod);
- return deprovision(sbj);
- }
-
- @Override
- protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
- final UserMod userMod = new UserMod();
- userMod.setKey(sbj.getKey());
- userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- uwfAdapter.update(userMod);
- return provision(sbj, enabled);
- }
-
- @Override
- protected String getName(final Subject<?, ?, ?> subject) {
- return User.class.cast(subject).getUsername();
- }
-
- @Override
- protected AbstractSubjectTO getSubjectTO(final long key) {
- try {
- return userTransfer.getUserTO(userDAO.authFetch(key));
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected Subject<?, ?, ?> getSubject(final long key) {
- try {
- return userDAO.authFetch(key);
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected ConnectorObject getRemoteObject(final String accountId) {
- ConnectorObject obj = null;
-
- try {
- final Uid uid = new Uid(accountId);
-
- obj = profile.getConnector().getObject(
- ObjectClass.ACCOUNT,
- uid,
- profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
-
- } catch (TimeoutException toe) {
- LOG.debug("Request timeout", toe);
- throw toe;
- } catch (RuntimeException ignore) {
- LOG.debug("While resolving {}", accountId, ignore);
- }
- return obj;
- }
-
- @Override
- protected Mapping<?> getMapping() {
- return profile.getTask().getResource().getUmapping();
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandlerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandlerImpl.java
new file mode 100644
index 0000000..57fe4a7
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserPushResultHandlerImpl.java
@@ -0,0 +1,160 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.PropagationByResource;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.server.persistence.api.entity.Mapping;
+import org.apache.syncope.server.persistence.api.entity.MappingItem;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.TimeoutException;
+import org.apache.syncope.server.provisioning.api.sync.UserPushResultHandler;
+import org.identityconnectors.framework.common.objects.ConnectorObject;
+import org.identityconnectors.framework.common.objects.ObjectClass;
+import org.identityconnectors.framework.common.objects.Uid;
+
+public class UserPushResultHandlerImpl extends AbstractPushResultHandler implements UserPushResultHandler {
+
+ @Override
+ protected Subject<?, ?, ?> deprovision(final Subject<?, ?, ?> sbj) {
+ final UserTO before = userTransfer.getUserTO(sbj.getKey());
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUserDeleteTaskIds(before.getKey(),
+ Collections.singleton(profile.getTask().getResource().getKey()), noPropResources));
+
+ return userDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> provision(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final UserTO before = userTransfer.getUserTO(sbj.getKey());
+
+ final List<String> noPropResources = new ArrayList<>(before.getResources());
+ noPropResources.remove(profile.getTask().getResource().getKey());
+
+ final PropagationByResource propByRes = new PropagationByResource();
+ propByRes.add(ResourceOperation.CREATE, profile.getTask().getResource().getKey());
+
+ taskExecutor.execute(propagationManager.getUserCreateTaskIds(
+ before.getKey(),
+ enabled,
+ propByRes,
+ null,
+ Collections.unmodifiableCollection(before.getVirAttrs()),
+ Collections.unmodifiableCollection(before.getMemberships()),
+ noPropResources));
+
+ return userDAO.authFetch(before.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> link(final Subject<?, ?, ?> sbj, final Boolean unlink) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+
+ if (unlink) {
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ uwfAdapter.update(userMod);
+
+ return userDAO.authFetch(userMod.getKey());
+ }
+
+ @Override
+ protected Subject<?, ?, ?> unassign(final Subject<?, ?, ?> sbj) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ uwfAdapter.update(userMod);
+ return deprovision(sbj);
+ }
+
+ @Override
+ protected Subject<?, ?, ?> assign(final Subject<?, ?, ?> sbj, final Boolean enabled) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(sbj.getKey());
+ userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ uwfAdapter.update(userMod);
+ return provision(sbj, enabled);
+ }
+
+ @Override
+ protected String getName(final Subject<?, ?, ?> subject) {
+ return User.class.cast(subject).getUsername();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return userTransfer.getUserTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected Subject<?, ?, ?> getSubject(final long key) {
+ try {
+ return userDAO.authFetch(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected ConnectorObject getRemoteObject(final String accountId) {
+ ConnectorObject obj = null;
+
+ try {
+ final Uid uid = new Uid(accountId);
+
+ obj = profile.getConnector().getObject(
+ ObjectClass.ACCOUNT,
+ uid,
+ profile.getConnector().getOperationOptions(Collections.<MappingItem>emptySet()));
+
+ } catch (TimeoutException toe) {
+ LOG.debug("Request timeout", toe);
+ throw toe;
+ } catch (RuntimeException ignore) {
+ LOG.debug("While resolving {}", accountId, ignore);
+ }
+ return obj;
+ }
+
+ @Override
+ protected Mapping<?> getMapping() {
+ return profile.getTask().getResource().getUmapping();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandler.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandler.java
deleted file mode 100644
index 58e81ed..0000000
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandler.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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.server.provisioning.java.sync;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
-import org.apache.syncope.common.lib.mod.UserMod;
-import org.apache.syncope.common.lib.to.AbstractSubjectTO;
-import org.apache.syncope.common.lib.to.PropagationStatus;
-import org.apache.syncope.common.lib.to.UserTO;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
-import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
-import org.identityconnectors.framework.common.objects.SyncDelta;
-import org.quartz.JobExecutionException;
-
-public class UserSyncResultHandler extends AbstractSubjectSyncResultHandler {
-
- @Override
- protected AttributableUtil getAttributableUtil() {
- return attrUtilFactory.getInstance(AttributableType.USER);
- }
-
- @Override
- protected String getName(final AbstractSubjectTO subjectTO) {
- return UserTO.class.cast(subjectTO).getUsername();
- }
-
- @Override
- protected AbstractSubjectTO getSubjectTO(final long key) {
- try {
- return userTransfer.getUserTO(userDAO.authFetch(key));
- } catch (Exception e) {
- LOG.warn("Error retrieving user {}", key, e);
- return null;
- }
- }
-
- @Override
- protected AbstractSubjectMod getSubjectMod(
- final AbstractSubjectTO subjectTO, final SyncDelta delta) {
-
- return connObjectUtil.getAttributableMod(
- subjectTO.getKey(),
- delta.getObject(),
- subjectTO,
- profile.getTask(),
- getAttributableUtil());
- }
-
- @Override
- protected AbstractSubjectTO create(
- final AbstractSubjectTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
-
- UserTO userTO = UserTO.class.cast(subjectTO);
-
- Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
- //Delegate User Workflow Creation and its Propagation to provisioning manager
- Map.Entry<Long, List<PropagationStatus>> created = userProvisioningManager.create(userTO, true, true, enabled,
- Collections.singleton(profile.getTask().getResource().getKey()));
-
- userTO = userTransfer.getUserTO(userDAO.authFetch(created.getKey()));
-
- result.setId(created.getKey());
-
- return userTO;
- }
-
- @Override
- protected List<ProvisioningResult> link(SyncDelta delta, List<Long> subjects, AttributableUtil attrUtil,
- boolean unlink) throws JobExecutionException {
- return super.link(delta, subjects, attrUtil, unlink); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- protected AbstractSubjectTO link(
- final AbstractSubjectTO before,
- final ProvisioningResult result,
- final boolean unlink) {
-
- final UserMod userMod = new UserMod();
- userMod.setKey(before.getKey());
-
- if (unlink) {
- userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- } else {
- userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
- }
-
- return userTransfer.getUserTO(userDAO.authFetch(uwfAdapter.update(userMod).getResult().getKey().getKey()));
- }
-
- @Override
- protected AbstractSubjectTO update(
- final AbstractSubjectTO before,
- final AbstractSubjectMod subjectMod,
- final SyncDelta delta,
- final ProvisioningResult result) {
-
- final UserMod userMod = UserMod.class.cast(subjectMod);
- final Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
-
- Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(userMod, before.getKey(),
- result, enabled, Collections.singleton(profile.getTask().getResource().getKey()));
-
- return userTransfer.getUserTO(userDAO.authFetch(updated.getKey()));
- }
-
- @Override
- protected void deprovision(
- final Long key,
- final boolean unlink) {
-
- taskExecutor.execute(
- propagationManager.getUserDeleteTaskIds(key, profile.getTask().getResource().getKey()));
-
- if (unlink) {
- final UserMod userMod = new UserMod();
- userMod.setKey(key);
- userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
- }
- }
-
- @Override
- protected void delete(final Long key) {
- try {
- userProvisioningManager.
- delete(key, Collections.<String>singleton(profile.getTask().getResource().getKey()));
- } catch (Exception e) {
- // A propagation failure doesn't imply a synchronization failure.
- // The propagation exception status will be reported into the propagation task execution.
- LOG.error("Could not propagate user " + key, e);
- }
-
- uwfAdapter.delete(key);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandlerImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandlerImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandlerImpl.java
new file mode 100644
index 0000000..9a7e1ba
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/UserSyncResultHandlerImpl.java
@@ -0,0 +1,149 @@
+/*
+ * 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.server.provisioning.java.sync;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.server.persistence.api.entity.AttributableUtil;
+import org.apache.syncope.server.provisioning.api.sync.ProvisioningResult;
+import org.apache.syncope.server.provisioning.api.sync.UserSyncResultHandler;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+
+public class UserSyncResultHandlerImpl extends AbstractSyncResultHandler implements UserSyncResultHandler {
+
+ @Override
+ protected AttributableUtil getAttributableUtil() {
+ return attrUtilFactory.getInstance(AttributableType.USER);
+ }
+
+ @Override
+ protected String getName(final AbstractSubjectTO subjectTO) {
+ return UserTO.class.cast(subjectTO).getUsername();
+ }
+
+ @Override
+ protected AbstractSubjectTO getSubjectTO(final long key) {
+ try {
+ return userTransfer.getUserTO(key);
+ } catch (Exception e) {
+ LOG.warn("Error retrieving user {}", key, e);
+ return null;
+ }
+ }
+
+ @Override
+ protected AbstractSubjectMod getSubjectMod(
+ final AbstractSubjectTO subjectTO, final SyncDelta delta) {
+
+ return connObjectUtil.getAttributableMod(
+ subjectTO.getKey(),
+ delta.getObject(),
+ subjectTO,
+ profile.getTask(),
+ getAttributableUtil());
+ }
+
+ @Override
+ protected AbstractSubjectTO create(
+ final AbstractSubjectTO subjectTO, final SyncDelta delta, final ProvisioningResult result) {
+
+ UserTO userTO = UserTO.class.cast(subjectTO);
+
+ Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
+ //Delegate User Workflow Creation and its Propagation to provisioning manager
+ Map.Entry<Long, List<PropagationStatus>> created = userProvisioningManager.create(userTO, true, true, enabled,
+ Collections.singleton(profile.getTask().getResource().getKey()));
+
+ userTO = userTransfer.getUserTO(created.getKey());
+
+ result.setId(created.getKey());
+
+ return userTO;
+ }
+
+ @Override
+ protected AbstractSubjectTO link(
+ final AbstractSubjectTO before,
+ final ProvisioningResult result,
+ final boolean unlink) {
+
+ final UserMod userMod = new UserMod();
+ userMod.setKey(before.getKey());
+
+ if (unlink) {
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ } else {
+ userMod.getResourcesToAdd().add(profile.getTask().getResource().getKey());
+ }
+
+ return userTransfer.getUserTO(uwfAdapter.update(userMod).getResult().getKey().getKey());
+ }
+
+ @Override
+ protected AbstractSubjectTO update(
+ final AbstractSubjectTO before,
+ final AbstractSubjectMod subjectMod,
+ final SyncDelta delta,
+ final ProvisioningResult result) {
+
+ final UserMod userMod = UserMod.class.cast(subjectMod);
+ final Boolean enabled = syncUtilities.readEnabled(delta.getObject(), profile.getTask());
+
+ Map.Entry<Long, List<PropagationStatus>> updated = userProvisioningManager.update(userMod, before.getKey(),
+ result, enabled, Collections.singleton(profile.getTask().getResource().getKey()));
+
+ return userTransfer.getUserTO(updated.getKey());
+ }
+
+ @Override
+ protected void deprovision(
+ final Long key,
+ final boolean unlink) {
+
+ taskExecutor.execute(
+ propagationManager.getUserDeleteTaskIds(key, profile.getTask().getResource().getKey()));
+
+ if (unlink) {
+ final UserMod userMod = new UserMod();
+ userMod.setKey(key);
+ userMod.getResourcesToRemove().add(profile.getTask().getResource().getKey());
+ }
+ }
+
+ @Override
+ protected void delete(final Long key) {
+ try {
+ userProvisioningManager.
+ delete(key, Collections.<String>singleton(profile.getTask().getResource().getKey()));
+ } catch (Exception e) {
+ // A propagation failure doesn't imply a synchronization failure.
+ // The propagation exception status will be reported into the propagation task execution.
+ LOG.error("Could not propagate user " + key, e);
+ }
+
+ uwfAdapter.delete(key);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.html.vm
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.html.vm b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.html.vm
index 007b09b..8240c7b 100644
--- a/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.html.vm
+++ b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.html.vm
@@ -18,19 +18,19 @@ under the License.
-->
<html>
<body>
-<h3>Hi $user.getAttrMap().get("firstname").getValues().get(0) $user.getAttrMap().get("surname").getValues().get(0), welcome to Syncope!</h3>
+<h3>Hi $user.getPlainAttrMap().get("firstname").getValues().get(0) $user.getPlainAttrMap().get("surname").getValues().get(0), welcome to Syncope!</h3>
<p>
Your username is $user.getUsername().<br/>
- Your email address is $user.getAttrMap().get("email").getValues().get(0).
- Your email address inside a <a href="http://localhost/?email=$esc.url($user.getAttrMap().get("email").getValues().get(0))">link</a>.
+ Your email address is $user.getPlainAttrMap().get("email").getValues().get(0).
+ Your email address inside a <a href="http://localhost/?email=$esc.url($user.getPlainAttrMap().get("email").getValues().get(0))">link</a>.
</p>
<p>
This message was sent to the following recipients:
<ul>
#foreach($recipient in $recipients)
- <li>$recipient.getAttrMap().get("email").getValues().get(0)</li>
+ <li>$recipient.getPlainAttrMap().get("email").getValues().get(0)</li>
#end
</ul>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.txt.vm
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.txt.vm b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.txt.vm
index b79b317..fc8e398 100644
--- a/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.txt.vm
+++ b/syncope620/server/provisioning-java/src/main/resources/mailTemplates/optin.txt.vm
@@ -14,15 +14,15 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
-Hi $user.getAttrMap().get("firstname").getValues().get(0) $user.getAttrMap().get("surname").getValues().get(0), welcome to Syncope!
+Hi $user.getPlainAttrMap().get("firstname").getValues().get(0) $user.getPlainAttrMap().get("surname").getValues().get(0), welcome to Syncope!
Your username is $user.getUsername().
-Your email address is $user.getAttrMap().get("email").getValues().get(0).
-Your email address inside a link: http://localhost/?email=$esc.url($user.getAttrMap().get("email").getValues().get(0)) .
+Your email address is $user.getPlainAttrMap().get("email").getValues().get(0).
+Your email address inside a link: http://localhost/?email=$esc.url($user.getPlainAttrMap().get("email").getValues().get(0)) .
This message was sent to the following recipients:
#foreach($recipient in $recipients)
- * $recipient.getAttrMap().get("surname").getValues().get(0)
+ * $recipient.getPlainAttrMap().get("surname").getValues().get(0)
#end
because one of the following events occurred:
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/resources/provisioningContext.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/resources/provisioningContext.xml b/syncope620/server/provisioning-java/src/main/resources/provisioningContext.xml
index d3fa665..3b4301e 100644
--- a/syncope620/server/provisioning-java/src/main/resources/provisioningContext.xml
+++ b/syncope620/server/provisioning-java/src/main/resources/provisioningContext.xml
@@ -20,10 +20,16 @@ under the License.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
+ xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
- http://www.springframework.org/schema/context/spring-context.xsd">
+ http://www.springframework.org/schema/context/spring-context.xsd
+ http://www.springframework.org/schema/task
+ http://www.springframework.org/schema/task/spring-task.xsd">
+
+ <task:annotation-driven executor="connectorExecutor"/>
+ <task:executor id="connectorExecutor" pool-size="10"/>
<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
lazy-init="false" depends-on="nonJPAdbInitializer">
@@ -34,7 +40,7 @@ under the License.
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="jobFactory">
- <bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory"/>
+ <bean class="org.apache.syncope.server.provisioning.java.job.SpringBeanJobFactory"/>
</property>
<property name="quartzProperties">
<props>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/test/java/org/apache/syncope/server/provisioning/java/data/ResourceDataBinderTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/test/java/org/apache/syncope/server/provisioning/java/data/ResourceDataBinderTest.java b/syncope620/server/provisioning-java/src/test/java/org/apache/syncope/server/provisioning/java/data/ResourceDataBinderTest.java
index 8b8a39b..34d73fe 100644
--- a/syncope620/server/provisioning-java/src/test/java/org/apache/syncope/server/provisioning/java/data/ResourceDataBinderTest.java
+++ b/syncope620/server/provisioning-java/src/test/java/org/apache/syncope/server/provisioning/java/data/ResourceDataBinderTest.java
@@ -115,7 +115,7 @@ public class ResourceDataBinderTest extends AbstractTest {
MappingItemTO item = new MappingItemTO();
item.setIntAttrName("userId");
- item.setIntMappingType(IntMappingType.UserSchema);
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
item.setExtAttrName("campo1");
item.setAccountid(true);
item.setMandatoryCondition("false");
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/AbstractServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/AbstractServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/AbstractServiceImpl.java
index 9168ab1..94003ab 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/AbstractServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/AbstractServiceImpl.java
@@ -163,7 +163,7 @@ abstract class AbstractServiceImpl implements JAXRSService {
return Collections.<OrderByClause>emptyList();
}
- List<OrderByClause> result = new ArrayList<OrderByClause>();
+ List<OrderByClause> result = new ArrayList<>();
for (String clause : orderBy.split(",")) {
String[] elems = clause.split(" ");
@@ -195,7 +195,7 @@ abstract class AbstractServiceImpl implements JAXRSService {
protected <T extends AbstractBaseBean> PagedResult<T> buildPagedResult(
final List<T> list, final int page, final int size, final int totalCount) {
- PagedResult<T> result = new PagedResult<T>();
+ PagedResult<T> result = new PagedResult<>();
result.getResult().addAll(list);
result.setPage(page);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
index 09995b1..7651d05 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/LoggerServiceImpl.java
@@ -80,7 +80,7 @@ public class LoggerServiceImpl extends AbstractServiceImpl implements LoggerServ
public LoggerTO read(final LoggerType type, final String name) {
List<LoggerTO> logger = list(type);
for (LoggerTO l : logger) {
- if (l.getName().equals(name)) {
+ if (l.getKey().equals(name)) {
return l;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
index 3b30337..32306e9 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/ReportServiceImpl.java
@@ -92,14 +92,14 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
}
@Override
- public ReportExecTO readExecution(final Long executionId) {
- return logic.readExecution(executionId);
+ public ReportExecTO readExecution(final Long executionKey) {
+ return logic.readExecution(executionKey);
}
@Override
- public Response exportExecutionResult(final Long executionId, final ReportExecExportFormat fmt) {
+ public Response exportExecutionResult(final Long executionKey, final ReportExecExportFormat fmt) {
final ReportExecExportFormat format = (fmt == null) ? ReportExecExportFormat.XML : fmt;
- final ReportExec reportExec = logic.getAndCheckReportExec(executionId);
+ final ReportExec reportExec = logic.getAndCheckReportExec(executionKey);
StreamingOutput sout = new StreamingOutput() {
@Override
@@ -125,7 +125,7 @@ public class ReportServiceImpl extends AbstractServiceImpl implements ReportServ
}
@Override
- public void deleteExecution(final Long executionId) {
- logic.deleteExecution(executionId);
+ public void deleteExecution(final Long executionKey) {
+ logic.deleteExecution(executionKey);
}
}
[15/15] syncope git commit: Merge branch '2_0_X' of
https://git-wip-us.apache.org/repos/asf/syncope into 2_0_X
Posted by il...@apache.org.
Merge branch '2_0_X' of https://git-wip-us.apache.org/repos/asf/syncope into 2_0_X
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/4e1ae7ac
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/4e1ae7ac
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/4e1ae7ac
Branch: refs/heads/2_0_X
Commit: 4e1ae7ac91428ea1a4837f2f682e23c5c9d42a1c
Parents: 80589a1 8e45a8e
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Fri Jan 23 17:40:56 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Fri Jan 23 17:40:56 2015 +0100
----------------------------------------------------------------------
cli/pom.xml | 186 +++++++++++++++++++
.../java/org/apache/syncope/cli/SyncopeAdm.java | 78 ++++++++
.../org/apache/syncope/cli/SyncopeServices.java | 41 ++++
.../syncope/cli/commands/LoggerCommand.java | 117 ++++++++++++
.../cli/validators/DebugLevelValidator.java | 61 ++++++
cli/src/main/resources/log4j2.xml | 58 ++++++
cli/src/main/resources/syncope.properties | 19 ++
pom.xml | 9 +-
8 files changed, 568 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/4e1ae7ac/pom.xml
----------------------------------------------------------------------
[04/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
----------------------------------------------------------------------
diff --git a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
index 19a4a0d..fc78a54 100644
--- a/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
+++ b/syncope620/server/rest-cxf/src/main/java/org/apache/syncope/server/rest/cxf/service/RestServiceExceptionMapper.java
@@ -45,6 +45,7 @@ import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.server.persistence.api.attrvalue.validation.ParsingValidationException;
+import org.apache.syncope.server.persistence.api.dao.DuplicateException;
import org.apache.syncope.server.persistence.api.dao.NotFoundException;
import org.apache.syncope.server.workflow.api.WorkflowException;
import org.identityconnectors.framework.common.exceptions.ConfigurationException;
@@ -89,7 +90,7 @@ public class RestServiceExceptionMapper implements ExceptionMapper<Exception>, R
header(HttpHeaders.WWW_AUTHENTICATE, BASIC_REALM_UNAUTHORIZED);
} else if (ex instanceof UnauthorizedRoleException) {
builder = builder(Response.Status.UNAUTHORIZED, ClientExceptionType.UnauthorizedRole, getExMessage(ex));
- } else if (ex instanceof EntityExistsException) {
+ } else if (ex instanceof EntityExistsException || ex instanceof DuplicateException) {
builder = builder(Response.Status.CONFLICT, ClientExceptionType.EntityExists, getExMessage(ex));
} else if (ex instanceof DataIntegrityViolationException) {
builder = builder(Response.Status.CONFLICT, ClientExceptionType.DataIntegrityViolation, getExMessage(ex));
[08/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
index 47db825..3c9a614 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/LoggerLogic.java
@@ -80,9 +80,9 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
private List<LoggerTO> list(final LoggerType type) {
List<LoggerTO> result = new ArrayList<>();
- for (Logger syncopeLogger : loggerDAO.findAll(type)) {
+ for (Logger logger : loggerDAO.findAll(type)) {
LoggerTO loggerTO = new LoggerTO();
- BeanUtils.copyProperties(syncopeLogger, loggerTO);
+ BeanUtils.copyProperties(logger, loggerTO);
result.add(loggerTO);
}
@@ -102,9 +102,9 @@ public class LoggerLogic extends AbstractTransactionalLogic<LoggerTO> {
for (LoggerTO logger : list(LoggerType.AUDIT)) {
try {
- result.add(AuditLoggerName.fromLoggerName(logger.getName()));
+ result.add(AuditLoggerName.fromLoggerName(logger.getKey()));
} catch (Exception e) {
- LOG.warn("Unexpected audit logger name: {}", logger.getName(), e);
+ LOG.warn("Unexpected audit logger name: {}", logger.getKey(), e);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
index bb369ab..e8502ec 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/ReportLogic.java
@@ -55,7 +55,7 @@ import org.apache.syncope.server.persistence.api.entity.ReportExec;
import org.apache.syncope.server.provisioning.api.data.ReportDataBinder;
import org.apache.syncope.server.provisioning.api.job.JobNamer;
import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
import org.apache.syncope.server.logic.report.Reportlet;
import org.apache.syncope.server.logic.report.ReportletConfClass;
import org.apache.syncope.server.logic.report.TextSerializer;
@@ -206,20 +206,20 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
@PreAuthorize("hasRole('REPORT_READ')")
- public ReportTO read(final Long reportId) {
- Report report = reportDAO.find(reportId);
+ public ReportTO read(final Long reportKey) {
+ Report report = reportDAO.find(reportKey);
if (report == null) {
- throw new NotFoundException("Report " + reportId);
+ throw new NotFoundException("Report " + reportKey);
}
return binder.getReportTO(report);
}
@PreAuthorize("hasRole('REPORT_READ')")
@Transactional(readOnly = true)
- public ReportExecTO readExecution(final Long executionId) {
- ReportExec reportExec = reportExecDAO.find(executionId);
+ public ReportExecTO readExecution(final Long executionKey) {
+ ReportExec reportExec = reportExecDAO.find(executionKey);
if (reportExec == null) {
- throw new NotFoundException("Report execution " + executionId);
+ throw new NotFoundException("Report execution " + executionKey);
}
return binder.getReportExecTO(reportExec);
}
@@ -291,10 +291,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
@PreAuthorize("hasRole('REPORT_READ')")
- public ReportExec getAndCheckReportExec(final Long executionId) {
- ReportExec reportExec = reportExecDAO.find(executionId);
+ public ReportExec getAndCheckReportExec(final Long executionKey) {
+ ReportExec reportExec = reportExecDAO.find(executionKey);
if (reportExec == null) {
- throw new NotFoundException("Report execution " + executionId);
+ throw new NotFoundException("Report execution " + executionKey);
}
if (!ReportExecStatus.SUCCESS.name().equals(reportExec.getStatus()) || reportExec.getExecResult() == null) {
SyncopeClientException sce = SyncopeClientException.build(ClientExceptionType.InvalidReportExec);
@@ -307,10 +307,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
@PreAuthorize("hasRole('REPORT_EXECUTE')")
- public ReportExecTO execute(final Long reportId) {
- Report report = reportDAO.find(reportId);
+ public ReportExecTO execute(final Long reportKey) {
+ Report report = reportDAO.find(reportKey);
if (report == null) {
- throw new NotFoundException("Report " + reportId);
+ throw new NotFoundException("Report " + reportKey);
}
try {
@@ -327,7 +327,7 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
ReportExecTO result = new ReportExecTO();
- result.setReport(reportId);
+ result.setReport(reportKey);
result.setStartDate(new Date());
result.setStatus(ReportExecStatus.STARTED.name());
result.setMessage("Job fired; waiting for results...");
@@ -336,10 +336,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
@PreAuthorize("hasRole('REPORT_DELETE')")
- public ReportTO delete(final Long reportId) {
- Report report = reportDAO.find(reportId);
+ public ReportTO delete(final Long reportKey) {
+ Report report = reportDAO.find(reportKey);
if (report == null) {
- throw new NotFoundException("Report " + reportId);
+ throw new NotFoundException("Report " + reportKey);
}
ReportTO deletedReport = binder.getReportTO(report);
@@ -349,10 +349,10 @@ public class ReportLogic extends AbstractTransactionalLogic<ReportTO> {
}
@PreAuthorize("hasRole('REPORT_DELETE')")
- public ReportExecTO deleteExecution(final Long executionId) {
- ReportExec reportExec = reportExecDAO.find(executionId);
+ public ReportExecTO deleteExecution(final Long executionKey) {
+ ReportExec reportExec = reportExecDAO.find(executionKey);
if (reportExec == null) {
- throw new NotFoundException("Report execution " + executionId);
+ throw new NotFoundException("Report execution " + executionKey);
}
ReportExecTO reportExecToDelete = binder.getReportExecTO(reportExec);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
deleted file mode 100644
index 9eccaea..0000000
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/SpringBeanJobFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.server.logic;
-
-import org.apache.syncope.server.provisioning.api.job.JobNamer;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
-import org.quartz.SchedulerContext;
-import org.quartz.spi.TriggerFiredBundle;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.MutablePropertyValues;
-import org.springframework.beans.PropertyAccessorFactory;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ConfigurableApplicationContext;
-
-public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory {
-
- private String[] ignoredUnknownProperties;
-
- private SchedulerContext schedulerContext;
-
- @Override
- public void setIgnoredUnknownProperties(final String[] ignoredUnknownProperties) {
- String[] defensiveCopy = ignoredUnknownProperties.clone();
- super.setIgnoredUnknownProperties(defensiveCopy);
- this.ignoredUnknownProperties = defensiveCopy;
- }
-
- @Override
- public void setSchedulerContext(final SchedulerContext schedulerContext) {
- super.setSchedulerContext(schedulerContext);
- this.schedulerContext = schedulerContext;
- }
-
- /**
- * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
- * transactions work.
- *
- * {@inheritDoc}
- */
- @Override
- protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
- final ApplicationContext ctx = ((ConfigurableApplicationContext) schedulerContext.get("applicationContext"));
-
- // Try to re-create job bean from underlying task (useful for managing failover scenarios)
- if (!ctx.containsBean(bundle.getJobDetail().getKey().getName())) {
- Long taskId = JobNamer.getTaskIdFromJobName(bundle.getJobDetail().getKey().getName());
- if (taskId != null) {
- JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
- jobInstanceLoader.registerTaskJob(taskId);
- }
-
- Long reportId = JobNamer.getReportIdFromJobName(bundle.getJobDetail().getKey().getName());
- if (reportId != null) {
- JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
- jobInstanceLoader.registerReportJob(reportId);
- }
- }
-
- final Object job = ctx.getBean(bundle.getJobDetail().getKey().getName());
- final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(job);
- if (isEligibleForPropertyPopulation(wrapper.getWrappedInstance())) {
- final MutablePropertyValues pvs = new MutablePropertyValues();
- if (this.schedulerContext != null) {
- pvs.addPropertyValues(this.schedulerContext);
- }
- pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
- pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
- if (this.ignoredUnknownProperties == null) {
- wrapper.setPropertyValues(pvs, true);
- } else {
- for (String propName : this.ignoredUnknownProperties) {
- if (pvs.contains(propName) && !wrapper.isWritableProperty(propName)) {
- pvs.removePropertyValue(propName);
- }
- }
- wrapper.setPropertyValues(pvs);
- }
- }
- return job;
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
index 683cda6..f97bc83 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/TaskLogic.java
@@ -51,7 +51,7 @@ import org.apache.syncope.server.provisioning.api.job.JobNamer;
import org.apache.syncope.server.provisioning.api.job.TaskJob;
import org.apache.syncope.server.provisioning.api.propagation.PropagationTaskExecutor;
import org.apache.syncope.server.logic.init.ImplementationClassNamesLoader;
-import org.apache.syncope.server.logic.init.JobInstanceLoader;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
import org.apache.syncope.server.logic.notification.NotificationJob;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
@@ -305,6 +305,7 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
if (TaskType.SCHEDULED == taskUtil.getType()
|| TaskType.SYNCHRONIZATION == taskUtil.getType()
|| TaskType.PUSH == taskUtil.getType()) {
+
jobInstanceLoader.unregisterJob(task);
}
@@ -373,9 +374,6 @@ public class TaskLogic extends AbstractTransactionalLogic<AbstractTaskTO> {
return res;
}
- /**
- * {@inheritDoc}
- */
@Override
protected AbstractTaskTO resolveReference(final Method method, final Object... args)
throws UnresolvedReferenceException {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
index c3b01f6..3e0de7e 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/UserLogic.java
@@ -339,7 +339,7 @@ public class UserLogic extends AbstractSubjectLogic<UserTO, UserMod> {
public UserTO delete(final Long key) {
List<Role> ownedRoles = roleDAO.findOwnedByUser(key);
if (!ownedRoles.isEmpty()) {
- List<String> owned = new ArrayList<String>(ownedRoles.size());
+ List<String> owned = new ArrayList<>(ownedRoles.size());
for (Role role : ownedRoles) {
owned.add(role.getKey() + " " + role.getName());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
deleted file mode 100644
index 3f6f753..0000000
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoader.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.server.logic.init;
-
-import java.text.ParseException;
-import org.apache.syncope.server.persistence.api.entity.Report;
-import org.apache.syncope.server.persistence.api.entity.task.Task;
-import org.quartz.SchedulerException;
-
-public interface JobInstanceLoader {
-
- void registerJob(Task task, String jobClassName, String cronExpression)
- throws ClassNotFoundException, SchedulerException, ParseException;
-
- void registerJob(Report report) throws SchedulerException, ParseException;
-
- void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
-
- void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
-
- void unregisterJob(Task task);
-
- void unregisterJob(Report report);
-
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
index 48e7db4..e1d4c7d 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/init/JobInstanceLoaderImpl.java
@@ -35,6 +35,7 @@ import org.apache.syncope.server.persistence.api.entity.task.PushTask;
import org.apache.syncope.server.persistence.api.entity.task.SchedTask;
import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
import org.apache.syncope.server.persistence.api.entity.task.Task;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
import org.apache.syncope.server.provisioning.api.job.JobNamer;
import org.apache.syncope.server.provisioning.api.job.SyncJob;
import org.apache.syncope.server.provisioning.api.job.TaskJob;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
index 756f817..a6f698a 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/RoleReportlet.java
@@ -110,7 +110,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
AttributesImpl atts = new AttributesImpl();
if (!attrs.isEmpty()) {
- Map<String, AttrTO> attrMap = attributableTO.getAttrMap();
+ Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
handler.startElement("", "", "attributes", null);
for (String attrName : attrs) {
@@ -233,7 +233,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
// values to String is already encapsulated there
RoleTO roleTO = roleDataBinder.getRoleTO(role);
- doExtractAttributes(handler, roleTO, conf.getAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
+ doExtractAttributes(handler, roleTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
if (conf.getFeatures().contains(Feature.entitlements)) {
handler.startElement("", "", "entitlements", null);
@@ -292,7 +292,7 @@ public class RoleReportlet extends AbstractReportlet<RoleReportletConf> {
handler.endElement("", "", "feature");
}
- for (String attr : conf.getAttrs()) {
+ for (String attr : conf.getPlainAttrs()) {
atts.clear();
handler.startElement("", "", "attribute", atts);
handler.characters(attr.toCharArray(), 0, attr.length());
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
index ebdad43..61b7cd8 100644
--- a/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
+++ b/syncope620/server/logic/src/main/java/org/apache/syncope/server/logic/report/UserReportlet.java
@@ -117,7 +117,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
AttributesImpl atts = new AttributesImpl();
if (!attrs.isEmpty()) {
- Map<String, AttrTO> attrMap = attributableTO.getAttrMap();
+ Map<String, AttrTO> attrMap = attributableTO.getPlainAttrMap();
handler.startElement("", "", "attributes", null);
for (String attrName : attrs) {
@@ -271,7 +271,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
// values to String is already encapsulated there
UserTO userTO = userDataBinder.getUserTO(user);
- doExtractAttributes(handler, userTO, conf.getAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
+ doExtractAttributes(handler, userTO, conf.getPlainAttrs(), conf.getDerAttrs(), conf.getVirAttrs());
if (conf.getFeatures().contains(Feature.memberships)) {
handler.startElement("", "", "memberships", null);
@@ -284,7 +284,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
atts.addAttribute("", "", "roleName", ReportXMLConst.XSD_STRING, String.valueOf(memb.getRoleName()));
handler.startElement("", "", "membership", atts);
- doExtractAttributes(handler, memb, memb.getAttrMap().keySet(), memb.getDerAttrMap()
+ doExtractAttributes(handler, memb, memb.getPlainAttrMap().keySet(), memb.getDerAttrMap()
.keySet(), memb.getVirAttrMap().keySet());
if (conf.getFeatures().contains(Feature.resources)) {
@@ -324,7 +324,7 @@ public class UserReportlet extends AbstractReportlet<UserReportletConf> {
handler.endElement("", "", "feature");
}
- for (String attr : conf.getAttrs()) {
+ for (String attr : conf.getPlainAttrs()) {
atts.clear();
handler.startElement("", "", "attribute", atts);
handler.characters(attr.toCharArray(), 0, attr.length());
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
index de655d8..83a238f 100644
--- a/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
+++ b/syncope620/server/logic/src/test/java/org/apache/syncope/server/logic/NotificationTest.java
@@ -262,7 +262,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
Random random = new Random(System.currentTimeMillis());
String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -320,7 +320,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
Random random = new Random(System.currentTimeMillis());
String sender = "syncope192-" + random.nextLong() + "@syncope.apache.org";
@@ -372,7 +372,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
Random random = new Random(System.currentTimeMillis());
String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -422,7 +422,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
Random random = new Random(System.currentTimeMillis());
String sender = "syncopetest-" + random.nextLong() + "@syncope.apache.org";
@@ -491,7 +491,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.getStaticRecipients().add("syncope445@syncope.apache.org");
@@ -549,7 +549,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(true);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.getStaticRecipients().add("syncope492@syncope.apache.org");
@@ -593,7 +593,7 @@ public class NotificationTest {
notification.setSelfAsRecipient(false);
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.getStaticRecipients().add(MAIL_ADDRESS);
@@ -635,7 +635,7 @@ public class NotificationTest {
assertNotNull(taskId);
assertNotNull(textBody);
- assertTrue(recipients.contains(MAIL_ADDRESS));
+ assertTrue(recipients != null && recipients.contains(MAIL_ADDRESS));
// 5. execute Notification task and verify e-mail
taskLogic.execute(taskId, false);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/logic/src/test/resources/logicTest.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/logic/src/test/resources/logicTest.xml b/syncope620/server/logic/src/test/resources/logicTest.xml
index d3b1bd8..afb8730 100644
--- a/syncope620/server/logic/src/test/resources/logicTest.xml
+++ b/syncope620/server/logic/src/test/resources/logicTest.xml
@@ -41,5 +41,5 @@ under the License.
<property name="primary" value="file:${conf.directory}/content.xml"/>
<property name="fallback" value="classpath:content.xml"/>
</bean>
-
+
</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
index 831a981..592cd0c 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/ConnObjectUtil.java
@@ -304,8 +304,8 @@ public class ConnObjectUtil {
}
break;
- case UserSchema:
- case RoleSchema:
+ case UserPlainSchema:
+ case RolePlainSchema:
attributeTO = new AttrTO();
attributeTO.setSchema(item.getIntAttrName());
@@ -446,7 +446,7 @@ public class ConnObjectUtil {
((RoleTO) subjectTO).setInheritOwner(((RoleTO) template).isInheritOwner());
((RoleTO) subjectTO).setInheritTemplates(((RoleTO) template).isInheritTemplates());
- ((RoleTO) subjectTO).setInheritAttrs(((RoleTO) template).isInheritAttrs());
+ ((RoleTO) subjectTO).setInheritPlainAttrs(((RoleTO) template).isInheritPlainAttrs());
((RoleTO) subjectTO).setInheritDerAttrs(((RoleTO) template).isInheritDerAttrs());
((RoleTO) subjectTO).setInheritVirAttrs(((RoleTO) template).isInheritVirAttrs());
((RoleTO) subjectTO).setInheritPasswordPolicy(((RoleTO) template).isInheritPasswordPolicy());
@@ -700,7 +700,7 @@ public class ConnObjectUtil {
}
private void fillFromTemplate(final AbstractAttributableTO attributableTO, final AbstractAttributableTO template) {
- Map<String, AttrTO> currentAttrMap = attributableTO.getAttrMap();
+ Map<String, AttrTO> currentAttrMap = attributableTO.getPlainAttrMap();
for (AttrTO templateAttr : template.getPlainAttrs()) {
if (templateAttr.getValues() != null && !templateAttr.getValues().isEmpty()
&& (!currentAttrMap.containsKey(templateAttr.getSchema())
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
index 7ae586f..209c800 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/MappingUtil.java
@@ -303,9 +303,9 @@ public final class MappingUtil {
final Map.Entry<String, Attribute> result;
switch (mapItem.getIntMappingType()) {
- case UserSchema:
- case RoleSchema:
- case MembershipSchema:
+ case UserPlainSchema:
+ case RolePlainSchema:
+ case MembershipPlainSchema:
final PlainSchemaDAO plainSchemaDAO = context.getBean(PlainSchemaDAO.class);
schema = plainSchemaDAO.find(mapItem.getIntAttrName(),
MappingUtil.getIntMappingTypeClass(mapItem.getIntMappingType()));
@@ -487,9 +487,9 @@ public final class MappingUtil {
List<PlainAttrValue> values = new ArrayList<>();
PlainAttrValue attrValue;
switch (mappingItem.getIntMappingType()) {
- case UserSchema:
- case RoleSchema:
- case MembershipSchema:
+ case UserPlainSchema:
+ case RolePlainSchema:
+ case MembershipPlainSchema:
for (Attributable<?, ?, ?> attributable : attributables) {
final PlainAttr attr = attributable.getPlainAttr(mappingItem.getIntAttrName());
if (attr != null) {
@@ -687,15 +687,15 @@ public final class MappingUtil {
Class result;
switch (intMappingType) {
- case UserSchema:
+ case UserPlainSchema:
result = UPlainSchema.class;
break;
- case RoleSchema:
+ case RolePlainSchema:
result = RPlainSchema.class;
break;
- case MembershipSchema:
+ case MembershipPlainSchema:
result = MPlainSchema.class;
break;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
index f850b98..002a588 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/AccountPolicyEnforcer.java
@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import org.apache.syncope.common.lib.types.AccountPolicySpec;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.UserSuspender;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
index ac8513d..8bbc734 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/PasswordPolicyEnforcer.java
@@ -26,11 +26,6 @@ import org.springframework.stereotype.Component;
@Component
public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec, User> {
- /* (non-Javadoc)
- * @see
- * org.apache.syncope.core.policy.PasswordPolicyEnforcer#enforce(org.apache.syncope.common.types.PasswordPolicySpec,
- * org.apache.syncope.common.types.PolicyType, java.lang.String)
- */
@Override
public void enforce(final PasswordPolicySpec policy, final PolicyType type, final User user)
throws PasswordPolicyException, PolicyEnforceException {
@@ -43,7 +38,7 @@ public class PasswordPolicyEnforcer implements PolicyEnforcer<PasswordPolicySpec
}
if (password == null && !policy.isAllowNullPassword()) {
- throw new PolicyEnforceException("Password must not be null and must be stored internally");
+ throw new PolicyEnforceException("Password mandatory");
} else if (password != null && clearPassword != null) {
// check length
if (policy.getMinLength() > 0 && policy.getMinLength() > clearPassword.length()) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
deleted file mode 100644
index 1fbf6f6..0000000
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/policy/UserSuspender.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.server.misc.policy;
-
-import org.apache.syncope.server.persistence.api.entity.user.User;
-
-public interface UserSuspender {
-
- void suspend(User user, boolean propagateSuspension);
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
index e58a157..870b444 100644
--- a/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
+++ b/syncope620/server/misc/src/main/java/org/apache/syncope/server/misc/security/AuthContextUtil.java
@@ -59,7 +59,7 @@ public final class AuthContextUtil {
*/
public static void extendAuthContext(final Long roleKey, final String roleEntitlement) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
- List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>(auth.getAuthorities());
+ List<GrantedAuthority> authorities = new ArrayList<>(auth.getAuthorities());
authorities.add(new SimpleGrantedAuthority(roleEntitlement));
Authentication newAuth = new UsernamePasswordAuthenticationToken(
auth.getPrincipal(), auth.getCredentials(), authorities);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
index 90bbbee..3456431 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/content/XMLContentExporter.java
@@ -86,6 +86,9 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
JPAMDerAttr.TABLE, JPAMVirAttr.TABLE
}));
+ protected final static Set<String> TABLE_SUFFIXES_TO_BE_INCLUDED =
+ new HashSet<>(Arrays.asList(new String[] { "TEMPLATE" }));
+
protected static final Map<String, String> TABLES_TO_BE_FILTERED =
Collections.singletonMap("TASK", "DTYPE <> 'PropagationTask'");
@@ -96,7 +99,11 @@ public class XMLContentExporter extends AbstractContentDealer implements Content
boolean allowed = true;
for (String prefix : TABLE_PREFIXES_TO_BE_EXCLUDED) {
if (tableName.toUpperCase().startsWith(prefix)) {
- allowed = false;
+ for (String suffix : TABLE_SUFFIXES_TO_BE_INCLUDED) {
+ if (!tableName.toUpperCase().endsWith(suffix)) {
+ allowed = false;
+ }
+ }
}
}
return allowed;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
index f4475f8..36d48e7 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPASubjectSearchDAO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.server.persistence.jpa.dao;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
@@ -31,6 +32,7 @@ import javax.persistence.TemporalType;
import javax.validation.ValidationException;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
+import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.SubjectType;
@@ -50,7 +52,6 @@ import org.apache.syncope.server.persistence.api.entity.AttributableUtilFactory;
import org.apache.syncope.server.persistence.api.entity.PlainAttrValue;
import org.apache.syncope.server.persistence.api.entity.PlainSchema;
import org.apache.syncope.server.persistence.api.entity.Subject;
-import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.util.ReflectionUtils;
@@ -652,6 +653,11 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
final AttributableUtil attrUtil = attrUtilFactory.getInstance(type.asAttributableType());
+ // Keeps track of difference between entity's getKey() and JPA @Id fields
+ if ("key".equals(cond.getSchema())) {
+ cond.setSchema("id");
+ }
+
Field subjectField = ReflectionUtils.findField(attrUtil.attributableClass(), cond.getSchema());
if (subjectField == null) {
LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
@@ -685,13 +691,22 @@ public class JPASubjectSearchDAO extends AbstractDAO<Subject<?, ?, ?>, Long> imp
// Deal with subject fields representing relationships to other entities
if (subjectField.getType().getAnnotation(Entity.class) != null) {
- if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getId") != null) {
- cond.setSchema(cond.getSchema() + "_id");
- schema.setType(AttrSchemaType.Long);
+ Method relMethod = null;
+ try {
+ relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
+ } catch (Exception e) {
+ LOG.error("Could not find {}#getKey", subjectField.getType(), e);
}
- if (BeanUtils.findDeclaredMethodWithMinimalParameters(subjectField.getType(), "getName") != null) {
- cond.setSchema(cond.getSchema() + "_name");
- schema.setType(AttrSchemaType.String);
+
+ if (relMethod != null) {
+ if (Long.class.isAssignableFrom(relMethod.getReturnType())) {
+ cond.setSchema(cond.getSchema() + "_id");
+ schema.setType(AttrSchemaType.Long);
+ }
+ if (String.class.isAssignableFrom(relMethod.getReturnType())) {
+ cond.setSchema(cond.getSchema() + "_name");
+ schema.setType(AttrSchemaType.String);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
index 954697c..e0d2313 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPATaskDAO.java
@@ -144,7 +144,7 @@ public class JPATaskDAO extends AbstractDAO<Task, Long> implements TaskDAO {
@Override
public int count(final TaskType type) {
Query countQuery = entityManager.createNativeQuery("SELECT COUNT(id) FROM Task WHERE TYPE=?1");
- countQuery.setParameter(1, type.toString());
+ countQuery.setParameter(1, type.name());
return ((Number) countQuery.getSingleResult()).intValue();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
index 30fdca5..2a45ad3 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/dao/JPAUserDAO.java
@@ -51,6 +51,7 @@ import org.apache.syncope.server.misc.security.AuthContextUtil;
import org.apache.syncope.server.misc.security.UnauthorizedRoleException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
@Repository
public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAttr> implements UserDAO {
@@ -249,6 +250,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
}
}
+ @Transactional(readOnly = true)
@Override
public User authFetch(final Long key) {
if (key == null) {
@@ -265,6 +267,7 @@ public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAtt
return user;
}
+ @Transactional(readOnly = true)
@Override
public User authFetch(final String username) {
if (username == null) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
index 3c79c92..fe78889 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractAttrTemplate.java
@@ -18,25 +18,11 @@
*/
package org.apache.syncope.server.persistence.jpa.entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
import org.apache.syncope.server.persistence.api.entity.AttrTemplate;
import org.apache.syncope.server.persistence.api.entity.Schema;
-@MappedSuperclass
public abstract class AbstractAttrTemplate<S extends Schema> extends AbstractEntity<Long> implements AttrTemplate<S> {
private static final long serialVersionUID = 4829112252713766666L;
- @Id
- @GeneratedValue(strategy = GenerationType.AUTO)
- protected Long id;
-
- @Override
- public Long getKey() {
- return id;
- }
-
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
new file mode 100644
index 0000000..2dec16a
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractDerAttrTemplate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.server.persistence.api.entity.DerSchema;
+
+@MappedSuperclass
+public abstract class AbstractDerAttrTemplate<D extends DerSchema> extends AbstractAttrTemplate<D> {
+
+ private static final long serialVersionUID = 8871895736733379865L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ protected Long id;
+
+ @Override
+ public Long getKey() {
+ return id;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
new file mode 100644
index 0000000..f8b0150
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainAttrTemplate.java
@@ -0,0 +1,27 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import org.apache.syncope.server.persistence.api.entity.PlainSchema;
+
+public abstract class AbstractPlainAttrTemplate<P extends PlainSchema> extends AbstractAttrTemplate<P> {
+
+ private static final long serialVersionUID = -943169893494860655L;
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
index ecc6fd5..78356bf 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractPlainSchema.java
@@ -29,6 +29,7 @@ import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
+import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.common.lib.types.AttrSchemaType;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.server.persistence.api.attrvalue.validation.Validator;
@@ -231,7 +232,7 @@ public abstract class AbstractPlainSchema extends AbstractEntity<String> impleme
@Override
public void setConversionPattern(final String conversionPattern) {
- if (!getType().isConversionPatternNeeded()) {
+ if (StringUtils.isNotBlank(conversionPattern) && !getType().isConversionPatternNeeded()) {
LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
new file mode 100644
index 0000000..5a3b2e4
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/AbstractVirAttrTemplate.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.entity;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import org.apache.syncope.server.persistence.api.entity.VirSchema;
+
+@MappedSuperclass
+public abstract class AbstractVirAttrTemplate<V extends VirSchema> extends AbstractAttrTemplate<V> {
+
+ private static final long serialVersionUID = -943169893494860655L;
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ protected Long id;
+
+ @Override
+ public Long getKey() {
+ return id;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
index bf468ce..94f95a8 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAAttributableUtil.java
@@ -744,15 +744,15 @@ public class JPAAttributableUtil implements AttributableUtil {
switch (type) {
case ROLE:
- result = IntMappingType.RoleSchema;
+ result = IntMappingType.RolePlainSchema;
break;
case MEMBERSHIP:
- result = IntMappingType.MembershipSchema;
+ result = IntMappingType.MembershipPlainSchema;
break;
case USER:
- result = IntMappingType.UserSchema;
+ result = IntMappingType.UserPlainSchema;
break;
case CONFIGURATION:
@@ -768,15 +768,15 @@ public class JPAAttributableUtil implements AttributableUtil {
switch (type) {
case ROLE:
- result = IntMappingType.RoleSchema;
+ result = IntMappingType.RoleDerivedSchema;
break;
case MEMBERSHIP:
- result = IntMappingType.MembershipSchema;
+ result = IntMappingType.MembershipDerivedSchema;
break;
case USER:
- result = IntMappingType.UserSchema;
+ result = IntMappingType.UserDerivedSchema;
break;
case CONFIGURATION:
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
index 2c1e956..28e1c87 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAConnInstance.java
@@ -186,7 +186,7 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc
if (!StringUtils.isBlank(jsonConf)) {
ConnConfProperty[] deserialized = POJOHelper.deserialize(jsonConf, ConnConfProperty[].class);
if (ArrayUtils.isNotEmpty(deserialized)) {
- configuration = new HashSet<ConnConfProperty>(Arrays.asList(deserialized));
+ configuration = new HashSet<>(Arrays.asList(deserialized));
}
}
@@ -195,7 +195,7 @@ public class JPAConnInstance extends AbstractEntity<Long> implements ConnInstanc
@Override
public void setConfiguration(final Set<ConnConfProperty> configuration) {
- jsonConf = POJOHelper.serialize(new HashSet<ConnConfProperty>(configuration));
+ jsonConf = POJOHelper.serialize(new HashSet<>(configuration));
}
@Override
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
index d045bcf..8b01c60 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/JPAReport.java
@@ -113,8 +113,6 @@ public class JPAReport extends AbstractEntity<Long> implements Report {
return false;
}
- checkType(reportletConf, JPAReportletConfInstance.class);
-
JPAReportletConfInstance found = null;
for (JPAReportletConfInstance instance : reportletConfs) {
if (reportletConf.equals(instance.getInstance())) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
index a106453..f52627c 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMDerAttrTemplate.java
@@ -25,12 +25,12 @@ import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.membership.MDerAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.membership.MDerSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerAttrTemplate;
import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
@Entity
@Table(name = JPAMDerAttrTemplate.TABLE)
-public class JPAMDerAttrTemplate extends AbstractAttrTemplate<MDerSchema> implements MDerAttrTemplate {
+public class JPAMDerAttrTemplate extends AbstractDerAttrTemplate<MDerSchema> implements MDerAttrTemplate {
private static final long serialVersionUID = -4465930976210263434L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
index 5fdf9ec..5f33b8c 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMPlainAttrTemplate.java
@@ -19,23 +19,27 @@
package org.apache.syncope.server.persistence.jpa.entity.membership;
import javax.persistence.Entity;
+import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.membership.MPlainAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.membership.MPlainSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrTemplate;
import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
@Entity
@Table(name = JPAMPlainAttrTemplate.TABLE)
-public class JPAMPlainAttrTemplate extends AbstractAttrTemplate<MPlainSchema> implements MPlainAttrTemplate {
+public class JPAMPlainAttrTemplate extends AbstractPlainAttrTemplate<MPlainSchema> implements MPlainAttrTemplate {
private static final long serialVersionUID = -8768086609963244514L;
public static final String TABLE = "MPlainAttrTemplate";
+ @Id
+ private Long id;
+
@ManyToOne
private JPARole owner;
@@ -44,6 +48,11 @@ public class JPAMPlainAttrTemplate extends AbstractAttrTemplate<MPlainSchema> im
private JPAMPlainSchema schema;
@Override
+ public Long getKey() {
+ return id;
+ }
+
+ @Override
public MPlainSchema getSchema() {
return schema;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
index 241d28c..1d7e184 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/membership/JPAMVirAttrTemplate.java
@@ -25,12 +25,12 @@ import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.membership.MVirAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.membership.MVirSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractVirAttrTemplate;
import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
@Entity
@Table(name = JPAMVirAttrTemplate.TABLE)
-public class JPAMVirAttrTemplate extends AbstractAttrTemplate<MVirSchema> implements MVirAttrTemplate {
+public class JPAMVirAttrTemplate extends AbstractVirAttrTemplate<MVirSchema> implements MVirAttrTemplate {
private static final long serialVersionUID = 6618560912535667392L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
index 3686f48..7ddc20f 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARDerAttrTemplate.java
@@ -25,11 +25,11 @@ import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.role.RDerAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.role.RDerSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractDerAttrTemplate;
@Entity
@Table(name = JPARDerAttrTemplate.TABLE)
-public class JPARDerAttrTemplate extends AbstractAttrTemplate<RDerSchema> implements RDerAttrTemplate {
+public class JPARDerAttrTemplate extends AbstractDerAttrTemplate<RDerSchema> implements RDerAttrTemplate {
private static final long serialVersionUID = 624868884107016649L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
index 9c0e603..fa6e8ee 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARPlainAttrTemplate.java
@@ -19,25 +19,34 @@
package org.apache.syncope.server.persistence.jpa.entity.role;
import javax.persistence.Entity;
+import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.role.RPlainAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractPlainAttrTemplate;
@Entity
@Table(name = JPARPlainAttrTemplate.TABLE)
-public class JPARPlainAttrTemplate extends AbstractAttrTemplate<RPlainSchema> implements RPlainAttrTemplate {
+public class JPARPlainAttrTemplate extends AbstractPlainAttrTemplate<RPlainSchema> implements RPlainAttrTemplate {
private static final long serialVersionUID = 6943917051517266268L;
public static final String TABLE = "RPlainAttrTemplate";
+ @Id
+ private Long id;
+
@ManyToOne
private JPARole owner;
+ @Override
+ public Long getKey() {
+ return id;
+ }
+
@ManyToOne
@JoinColumn(name = "schema_name")
private JPARPlainSchema schema;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
index 1de733a..74200db 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/role/JPARVirAttrTemplate.java
@@ -25,11 +25,11 @@ import javax.persistence.Table;
import org.apache.syncope.server.persistence.api.entity.role.RVirAttrTemplate;
import org.apache.syncope.server.persistence.api.entity.role.RVirSchema;
import org.apache.syncope.server.persistence.api.entity.role.Role;
-import org.apache.syncope.server.persistence.jpa.entity.AbstractAttrTemplate;
+import org.apache.syncope.server.persistence.jpa.entity.AbstractVirAttrTemplate;
@Entity
@Table(name = JPARVirAttrTemplate.TABLE)
-public class JPARVirAttrTemplate extends AbstractAttrTemplate<RVirSchema> implements RVirAttrTemplate {
+public class JPARVirAttrTemplate extends AbstractVirAttrTemplate<RVirSchema> implements RVirAttrTemplate {
private static final long serialVersionUID = 4896495904794493479L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
index 4086018..178d2b0 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/entity/task/JPATaskUtil.java
@@ -80,12 +80,33 @@ public final class JPATaskUtil implements TaskUtil {
@Override
public <T extends Task> T newTask() {
- final Class<T> taskClass = taskClass();
- try {
- return taskClass == null ? null : taskClass.newInstance();
- } catch (Exception e) {
- return null;
+ T result = null;
+
+ switch (type) {
+ case PROPAGATION:
+ result = (T) new JPAPropagationTask();
+ break;
+
+ case SCHEDULED:
+ result = (T) new JPASchedTask();
+ break;
+
+ case SYNCHRONIZATION:
+ result = (T) new JPASyncTask();
+ break;
+
+ case PUSH:
+ result = (T) new JPAPushTask();
+ break;
+
+ case NOTIFICATION:
+ result = (T) new JPANotificationTask();
+ break;
+
+ default:
}
+
+ return result;
}
@Override
@@ -119,7 +140,6 @@ public final class JPATaskUtil implements TaskUtil {
return result;
}
- @SuppressWarnings("unchecked")
@Override
public <T extends AbstractTaskTO> T newTaskTO() {
final Class<T> taskClass = taskTOClass();
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
index bd40a4c..5f8c89d 100644
--- a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/EntityValidationListener.java
@@ -23,8 +23,17 @@ import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
+import org.apache.commons.lang3.ClassUtils;
import org.apache.syncope.server.persistence.api.attrvalue.validation.InvalidEntityException;
import org.apache.syncope.server.misc.spring.ApplicationContextProvider;
+import org.apache.syncope.server.persistence.api.entity.AnnotatedEntity;
+import org.apache.syncope.server.persistence.api.entity.Attr;
+import org.apache.syncope.server.persistence.api.entity.Attributable;
+import org.apache.syncope.server.persistence.api.entity.Entity;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.Schema;
+import org.apache.syncope.server.persistence.api.entity.Subject;
+import org.apache.syncope.server.persistence.api.entity.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,7 +54,24 @@ public class EntityValidationListener {
Set<ConstraintViolation<Object>> violations = validator.validate(object);
if (!violations.isEmpty()) {
LOG.warn("Bean validation errors found: {}", violations);
- throw new InvalidEntityException(object.getClass().getSimpleName(), violations);
+
+ Class<?> entityInt = null;
+ for (Class<?> interf : ClassUtils.getAllInterfaces(object.getClass())) {
+ if (!Entity.class.equals(interf)
+ && !AnnotatedEntity.class.equals(interf)
+ && !Schema.class.equals(interf)
+ && !Attr.class.equals(interf)
+ && !Task.class.equals(interf)
+ && !Policy.class.equals(interf)
+ && !Attributable.class.equals(interf)
+ && !Subject.class.equals(interf)
+ && Entity.class.isAssignableFrom(interf)) {
+
+ entityInt = interf;
+ }
+ }
+
+ throw new InvalidEntityException(entityInt == null ? "Entity" : entityInt.getSimpleName(), violations);
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
index 9a828d4..93bc24d 100644
--- a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
+++ b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
@@ -124,11 +124,27 @@ under the License.
</id>
</attributes>
</entity>
+ <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrTemplate">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_RPlainAttrTemplate" strategy="TABLE"/>
+ <table-generator name="SEQ_RPlainAttrTemplate" pk-column-value="SEQ_RPlainAttrTemplate" initial-value="1000"/>
+ </id>
+ </attributes>
+ </entity>
<entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttr">
<attributes>
<id name="id">
- <generated-value generator="SEQ_MAttrPlain" strategy="TABLE"/>
- <table-generator name="SEQ_MAttrPlain" pk-column-value="SEQ_MAttrPlain" initial-value="1000"/>
+ <generated-value generator="SEQ_MPlainAttr" strategy="TABLE"/>
+ <table-generator name="SEQ_MPlainAttr" pk-column-value="SEQ_MPlainAttr" initial-value="1000"/>
+ </id>
+ </attributes>
+ </entity>
+ <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrTemplate">
+ <attributes>
+ <id name="id">
+ <generated-value generator="SEQ_MPlainAttrTemplate" strategy="TABLE"/>
+ <table-generator name="SEQ_MPlainAttrTemplate" pk-column-value="SEQ_MPlainAttrTemplate" initial-value="1000"/>
</id>
</attributes>
</entity>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
index 4b6345b..9eaa312 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/AttributableSearchTest.java
@@ -131,7 +131,7 @@ public class AttributableSearchTest extends AbstractTest {
assertNotNull(users);
assertEquals(4, users.size());
- Set<Long> ids = new HashSet<Long>(users.size());
+ Set<Long> ids = new HashSet<>(users.size());
for (User user : users) {
ids.add(user.getKey());
}
@@ -254,16 +254,30 @@ public class AttributableSearchTest extends AbstractTest {
}
@Test
- public void searchByUsernameAndId() {
- SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
+ public void searchByBooleanSubjectCond() {
+ SubjectCond booleanCond = new SubjectCond(SubjectCond.Type.EQ);
+ booleanCond.setSchema("inheritPlainAttrs");
+ booleanCond.setExpression("true");
+
+ SearchCond searchCondition = SearchCond.getLeafCond(booleanCond);
+
+ List<Role> matchingRoles = searchDAO.search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
+ searchCondition, SubjectType.ROLE);
+ assertNotNull(matchingRoles);
+ assertFalse(matchingRoles.isEmpty());
+ }
+
+ @Test
+ public void searchByUsernameAndKey() {
+ SubjectCond usernameLeafCond = new SubjectCond(SubjectCond.Type.LIKE);
usernameLeafCond.setSchema("username");
- usernameLeafCond.setExpression("rossini");
+ usernameLeafCond.setExpression("%ini");
SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
- idRightCond.setSchema("id");
+ idRightCond.setSchema("key");
idRightCond.setExpression("2");
- SearchCond searchCondition = SearchCond.getOrCond(SearchCond.getLeafCond(usernameLeafCond),
+ SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getLeafCond(usernameLeafCond),
SearchCond.getLeafCond(idRightCond));
List<User> matchingUsers = searchDAO.search(RoleEntitlementUtil.getRoleKeys(entitlementDAO.findAll()),
@@ -276,13 +290,13 @@ public class AttributableSearchTest extends AbstractTest {
}
@Test
- public void searchByRolenameAndId() {
+ public void searchByRolenameAndKey() {
SubjectCond rolenameLeafCond = new SubjectCond(SubjectCond.Type.EQ);
rolenameLeafCond.setSchema("name");
rolenameLeafCond.setExpression("root");
SubjectCond idRightCond = new SubjectCond(SubjectCond.Type.LT);
- idRightCond.setSchema("id");
+ idRightCond.setSchema("key");
idRightCond.setExpression("2");
SearchCond searchCondition = SearchCond.getAndCond(SearchCond.getLeafCond(rolenameLeafCond),
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
index 7cd9eae..91ad890 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/NotificationTest.java
@@ -65,7 +65,7 @@ public class NotificationTest extends AbstractTest {
notification.setRecipients("fake search condition");
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.setSender("syncope@syncope.apache.org");
notification.setSubject("Test notification");
@@ -92,7 +92,7 @@ public class NotificationTest extends AbstractTest {
notification.setRecipients("fake search condition");
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.addStaticRecipient("syncope445@syncope.apache.org");
@@ -115,7 +115,7 @@ public class NotificationTest extends AbstractTest {
notification.setRoleAbout("fake search condition");
notification.setRecipientAttrName("email");
- notification.setRecipientAttrType(IntMappingType.UserSchema);
+ notification.setRecipientAttrType(IntMappingType.UserPlainSchema);
notification.addStaticRecipient("syncope446@syncope.apache.org");
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
index c1c2355..68d1516 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/entity/ResourceTest.java
@@ -133,7 +133,7 @@ public class ResourceTest extends AbstractTest {
UMappingItem accountId = entityFactory.newEntity(UMappingItem.class);
accountId.setAccountid(true);
- accountId.setIntMappingType(IntMappingType.UserSchema);
+ accountId.setIntMappingType(IntMappingType.UserPlainSchema);
mapping.addItem(accountId);
// save the resource
@@ -176,12 +176,12 @@ public class ResourceTest extends AbstractTest {
UMappingItem item = entityFactory.newEntity(UMappingItem.class);
item.setAccountid(true);
item.setIntAttrName("fullname");
- item.setIntMappingType(IntMappingType.UserSchema);
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
mapping.addItem(item);
item = entityFactory.newEntity(UMappingItem.class);
item.setIntAttrName("userId");
- item.setIntMappingType(IntMappingType.UserSchema);
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
mapping.addItem(item);
ExternalResource actual = resourceDAO.save(resource);
@@ -202,14 +202,14 @@ public class ResourceTest extends AbstractTest {
UMappingItem item = entityFactory.newEntity(UMappingItem.class);
item.setIntAttrName("fullname");
item.setExtAttrName("fullname");
- item.setIntMappingType(IntMappingType.UserSchema);
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
item.setPurpose(MappingPurpose.BOTH);
mapping.setAccountIdItem(item);
item = entityFactory.newEntity(UMappingItem.class);
item.setIntAttrName("icon");
item.setExtAttrName("icon");
- item.setIntMappingType(IntMappingType.RoleSchema);
+ item.setIntMappingType(IntMappingType.RolePlainSchema);
item.setPurpose(MappingPurpose.BOTH);
mapping.addItem(item);
[09/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
new file mode 100644
index 0000000..8795f06
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserSelfITCase.java
@@ -0,0 +1,342 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlException;
+import java.util.Map;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserSelfITCase extends AbstractITCase {
+
+ @Test
+ public void selfRegistrationAllowed() {
+ assertTrue(clientFactory.createAnonymous().isSelfRegAllowed());
+ }
+
+ @Test
+ public void create() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // 1. self-registration as admin: failure
+ try {
+ userSelfService.create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true);
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ // 2. self-registration as anonymous: works
+ SyncopeClient anonClient = clientFactory.createAnonymous();
+ UserTO self = anonClient.getService(UserSelfService.class).
+ create(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"), true).
+ readEntity(UserTO.class);
+ assertNotNull(self);
+ assertEquals("createApproval", self.getStatus());
+ }
+
+ @Test
+ public void createAndApprove() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // self-create user with membership: goes 'createApproval' with resources and membership but no propagation
+ UserTO userTO = UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org");
+ MembershipTO membership = new MembershipTO();
+ membership.setRoleId(3L);
+ userTO.getMemberships().add(membership);
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ SyncopeClient anonClient = clientFactory.createAnonymous();
+ userTO = anonClient.getService(UserSelfService.class).
+ create(userTO, true).
+ readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("createApproval", userTO.getStatus());
+ assertFalse(userTO.getMemberships().isEmpty());
+ assertFalse(userTO.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+
+ // now approve and verify that propagation has happened
+ WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+ form = userWorkflowService.claimForm(form.getTaskId());
+ Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.TRUE.toString());
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+ userTO = userWorkflowService.submitForm(form);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey()));
+ }
+
+ @Test
+ public void read() {
+ UserService userService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserService.class);
+
+ try {
+ userService2.read(1L);
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ UserSelfService userSelfService2 = clientFactory.create("rossini", ADMIN_PWD).getService(UserSelfService.class);
+ UserTO userTO = userSelfService2.read();
+ assertEquals("rossini", userTO.getUsername());
+ }
+
+ @Test
+ public void updateWithoutApproval() {
+ // 1. create user as admin
+ UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
+ assertNotNull(created);
+ assertFalse(created.getUsername().endsWith("XX"));
+
+ // 2. self-update (username) - works
+ UserMod userMod = new UserMod();
+ userMod.setUsername(created.getUsername() + "XX");
+
+ SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+ UserTO updated = authClient.getService(UserSelfService.class).update(created.getKey(), userMod).
+ readEntity(UserTO.class);
+ assertNotNull(updated);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "active" : "created", updated.getStatus());
+ assertTrue(updated.getUsername().endsWith("XX"));
+ }
+
+ @Test
+ public void updateWitApproval() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // 1. create user as admin
+ UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
+ assertNotNull(created);
+ assertFalse(created.getUsername().endsWith("XX"));
+
+ // 2. self-update (username + memberships + resource) - works but needs approval
+ MembershipMod membershipMod = new MembershipMod();
+ membershipMod.setRole(7L);
+ AttrMod testAttrMod = new AttrMod();
+ testAttrMod.setSchema("testAttribute");
+ testAttrMod.getValuesToBeAdded().add("a value");
+ membershipMod.getPlainAttrsToUpdate().add(testAttrMod);
+
+ UserMod userMod = new UserMod();
+ userMod.setUsername(created.getUsername() + "XX");
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+ userMod.setPassword("newPassword123");
+ StatusMod statusMod = new StatusMod();
+ statusMod.setOnSyncope(false);
+ statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(statusMod);
+
+ SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+ UserTO updated = authClient.getService(UserSelfService.class).update(created.getKey(), userMod).
+ readEntity(UserTO.class);
+ assertNotNull(updated);
+ assertEquals("updateApproval", updated.getStatus());
+ assertFalse(updated.getUsername().endsWith("XX"));
+ assertTrue(updated.getMemberships().isEmpty());
+
+ // no propagation happened
+ assertTrue(updated.getResources().isEmpty());
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, updated.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+
+ // 3. approve self-update as admin
+ WorkflowFormTO form = userWorkflowService.getFormForUser(updated.getKey());
+ form = userWorkflowService.claimForm(form.getTaskId());
+ Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.TRUE.toString());
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+ updated = userWorkflowService.submitForm(form);
+ assertNotNull(updated);
+ assertEquals("active", updated.getStatus());
+ assertTrue(updated.getUsername().endsWith("XX"));
+ assertEquals(1, updated.getMemberships().size());
+
+ // check that propagation also happened
+ assertTrue(updated.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, updated.getKey()));
+ }
+
+ @Test
+ public void delete() {
+ UserTO created = createUser(UserITCase.getUniqueSampleTO("anonymous@syncope.apache.org"));
+ assertNotNull(created);
+
+ SyncopeClient authClient = clientFactory.create(created.getUsername(), "password123");
+ UserTO deleted = authClient.getService(UserSelfService.class).delete().readEntity(UserTO.class);
+ assertNotNull(deleted);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers() ? "deleteApproval" : null, deleted.getStatus());
+ }
+
+ @Test
+ public void issueSYNCOPE373() {
+ UserTO userTO = userSelfService.read();
+ assertEquals(ADMIN_UNAME, userTO.getUsername());
+ }
+
+ @Test
+ public void noContent() throws IOException {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ SyncopeClient anonClient = clientFactory.createAnonymous();
+ UserSelfService noContentService = anonClient.prefer(UserSelfService.class, Preference.RETURN_NO_CONTENT);
+
+ UserTO user = UserITCase.getUniqueSampleTO("nocontent-anonymous@syncope.apache.org");
+
+ Response response = noContentService.create(user, true);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+ 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 = UserITCase.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.getKey()).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());
+ }
+
+ @Test
+ public void passwordResetWithoutSecurityQuestion() {
+ // 0. disable security question for password reset
+ configurationService.set("passwordReset.securityQuestion",
+ attrTO("passwordReset.securityQuestion", "false"));
+
+ // 1. create an user with security question and answer
+ UserTO user = UserITCase.getUniqueSampleTO("pwdResetNoSecurityQuestion@syncope.apache.org");
+ 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) with no security answer
+ SyncopeClient anonClient = clientFactory.createAnonymous();
+ anonClient.getService(UserSelfService.class).requestPasswordReset(user.getUsername(), null);
+
+ // 4. get token (normally sent via e-mail, now reading as admin)
+ String token = userService.read(read.getKey()).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());
+
+ // 7. re-enable security question for password reset
+ configurationService.set("passwordReset.securityQuestion",
+ attrTO("passwordReset.securityQuestion", "true"));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
new file mode 100644
index 0000000..9c81d0f
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserWorkflowITCase.java
@@ -0,0 +1,299 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.rest.api.service.UserWorkflowService;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserWorkflowITCase extends AbstractITCase {
+
+ @Test
+ public void createWithReject() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ // User with role 9 are defined in workflow as subject to approval
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(9L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user with role 9
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getMemberships().size());
+ assertEquals(9, userTO.getMemberships().get(0).getRoleId());
+ assertEquals("createApproval", userTO.getStatus());
+
+ // 2. request if there is any pending task for user just created
+ WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+ assertNotNull(form);
+ assertNotNull(form.getUserKey());
+ assertEquals(userTO.getKey(), form.getUserKey());
+ assertNotNull(form.getTaskId());
+ assertNull(form.getOwner());
+
+ // 3. claim task from rossini, not in role 7 (designated for approval in workflow definition): fail
+ UserWorkflowService userService2 = clientFactory.create(
+ "rossini", ADMIN_PWD).getService(UserWorkflowService.class);
+
+ try {
+ userService2.claimForm(form.getTaskId());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.Workflow, e.getType());
+ }
+
+ // 4. claim task from bellini, in role 7
+ UserWorkflowService userService3 = clientFactory.create(
+ "bellini", ADMIN_PWD).getService(UserWorkflowService.class);
+
+ form = userService3.claimForm(form.getTaskId());
+ assertNotNull(form);
+ assertNotNull(form.getTaskId());
+ assertNotNull(form.getOwner());
+
+ // 5. reject user
+ Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.FALSE.toString());
+ props.get("rejectReason").setValue("I don't like him.");
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+ userTO = userService3.submitForm(form);
+ assertNotNull(userTO);
+ assertEquals("rejected", userTO.getStatus());
+
+ // 6. check that rejected user was not propagated to external resource (SYNCOPE-364)
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+ Exception exception = null;
+ try {
+ jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+ new String[] { userTO.getUsername() }, Integer.class);
+ } catch (EmptyResultDataAccessException e) {
+ exception = e;
+ }
+ assertNotNull(exception);
+ }
+
+ @Test
+ public void createWithApproval() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // read forms *before* any operation
+ List<WorkflowFormTO> forms = userWorkflowService.getForms();
+ assertNotNull(forms);
+ int preForms = forms.size();
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("createWithApproval@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ // User with role 9 are defined in workflow as subject to approval
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(9L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user with role 9 (and verify that no propagation occurred)
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getMemberships().size());
+ assertEquals(9, userTO.getMemberships().get(0).getRoleId());
+ assertEquals("createApproval", userTO.getStatus());
+ assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+ assertTrue(userTO.getPropagationStatusTOs().isEmpty());
+
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ Exception exception = null;
+ try {
+ jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?",
+ new String[] { userTO.getUsername() }, Integer.class);
+ } catch (EmptyResultDataAccessException e) {
+ exception = e;
+ }
+ assertNotNull(exception);
+
+ // 2. request if there is any pending form for user just created
+ forms = userWorkflowService.getForms();
+ assertNotNull(forms);
+ assertEquals(preForms + 1, forms.size());
+
+ WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+ assertNotNull(form);
+ assertNotNull(form.getTaskId());
+ assertNull(form.getOwner());
+
+ // 4. claim task (from admin)
+ form = userWorkflowService.claimForm(form.getTaskId());
+ assertNotNull(form);
+ assertNotNull(form.getTaskId());
+ assertNotNull(form.getOwner());
+
+ // 5. approve user (and verify that propagation occurred)
+ Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.TRUE.toString());
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+ userTO = userWorkflowService.submitForm(form);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ assertEquals(Collections.singleton(RESOURCE_NAME_TESTDB), userTO.getResources());
+
+ exception = null;
+ try {
+ final String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
+ userTO.getUsername());
+ assertEquals(userTO.getUsername(), username);
+ } catch (EmptyResultDataAccessException e) {
+ exception = e;
+ }
+ assertNull(exception);
+
+ // 6. update user
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("anotherPassword123");
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE15() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ // read forms *before* any operation
+ List<WorkflowFormTO> forms = userWorkflowService.getForms();
+ assertNotNull(forms);
+ int preForms = forms.size();
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("issueSYNCOPE15@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getMemberships().clear();
+
+ // User with role 9 are defined in workflow as subject to approval
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(9L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user with role 9 (and verify that no propagation occurred)
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertNotEquals(0L, userTO.getKey());
+ assertNotNull(userTO.getCreationDate());
+ assertNotNull(userTO.getCreator());
+ assertNotNull(userTO.getLastChangeDate());
+ assertNotNull(userTO.getLastModifier());
+ assertEquals(userTO.getCreationDate(), userTO.getLastChangeDate());
+
+ // 2. request if there is any pending form for user just created
+ forms = userWorkflowService.getForms();
+ assertEquals(preForms + 1, forms.size());
+
+ WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+ assertNotNull(form);
+
+ // 3. first claim ny bellini ....
+ UserWorkflowService userService3 = clientFactory.create(
+ "bellini", ADMIN_PWD).getService(UserWorkflowService.class);
+
+ form = userService3.claimForm(form.getTaskId());
+ assertNotNull(form);
+ assertNotNull(form.getTaskId());
+ assertNotNull(form.getOwner());
+
+ // 4. second claim task by admin
+ form = userWorkflowService.claimForm(form.getTaskId());
+ assertNotNull(form);
+
+ // 5. approve user
+ final Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+ props.get("approve").setValue(Boolean.TRUE.toString());
+ form.getProperties().clear();
+ form.getProperties().addAll(props.values());
+
+ // 6. submit approve
+ userTO = userWorkflowService.submitForm(form);
+ assertNotNull(userTO);
+ assertEquals(preForms, userWorkflowService.getForms().size());
+ assertNull(userWorkflowService.getFormForUser(userTO.getKey()));
+
+ // 7. search approval into the history as well
+ forms = userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
+ assertFalse(forms.isEmpty());
+
+ int count = 0;
+ for (WorkflowFormTO hform : forms) {
+ if (form.getTaskId().equals(hform.getTaskId())) {
+ count++;
+
+ assertEquals("createApproval", hform.getKey());
+ assertNotNull(hform.getCreateTime());
+ assertNotNull(hform.getDueDate());
+ assertTrue(Boolean.parseBoolean(hform.getPropertyMap().get("approve").getValue()));
+ assertNull(hform.getPropertyMap().get("rejectReason").getValue());
+ }
+ }
+ assertEquals(1, count);
+
+ userService.delete(userTO.getKey());
+
+ try {
+ userService.read(userTO.getKey());
+ fail();
+ } catch (Exception ignore) {
+ assertNotNull(ignore);
+ }
+
+ try {
+ userWorkflowService.getFormsByName(userTO.getKey(), "Create approval");
+ fail();
+ } catch (Exception ignore) {
+ assertNotNull(ignore);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirAttrITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirAttrITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirAttrITCase.java
new file mode 100644
index 0000000..1dc6f20
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirAttrITCase.java
@@ -0,0 +1,872 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.Map;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class VirAttrITCase extends AbstractITCase {
+
+ @Test
+ public void issueSYNCOPE16() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("issue16@apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+
+ // 2. check for virtual attribute value
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertEquals("virtualvalue", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+ userMod.getVirAttrsToRemove().add("virtualdata");
+ userMod.getVirAttrsToUpdate().add(attrMod("virtualdata", "virtualupdated"));
+
+ // 3. update virtual attribute
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+
+ // 4. check for virtual attribute value
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE260() {
+ // ----------------------------------
+ // create user and check virtual attribute value propagation
+ // ----------------------------------
+ UserTO userTO = UserITCase.getUniqueSampleTO("260@a.com");
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
+ // ----------------------------------
+
+ // ----------------------------------
+ // update user virtual attribute and check virtual attribute value update propagation
+ // ----------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ AttrMod attrMod = new AttrMod();
+ attrMod.setSchema("virtualdata");
+ attrMod.getValuesToBeRemoved().add("virtualvalue");
+ attrMod.getValuesToBeAdded().add("virtualvalue2");
+
+ userMod.getVirAttrsToUpdate().add(attrMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals("ws-target-resource-2", userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
+ // ----------------------------------
+
+ // ----------------------------------
+ // suspend/reactivate user and check virtual attribute value (unchanged)
+ // ----------------------------------
+ StatusMod statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+ assertEquals("suspended", userTO.getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
+ assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
+
+ statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+ assertEquals("active", userTO.getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
+ assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
+ // ----------------------------------
+
+ // ----------------------------------
+ // update user attribute and check virtual attribute value (unchanged)
+ // ----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ attrMod = new AttrMod();
+ attrMod.setSchema("surname");
+ attrMod.getValuesToBeRemoved().add("Surname");
+ attrMod.getValuesToBeAdded().add("Surname2");
+
+ userMod.getPlainAttrsToUpdate().add(attrMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("Surname2", connObjectTO.getPlainAttrMap().get("SURNAME").getValues().get(0));
+
+ // attribute "name" mapped on virtual attribute "virtualdata" shouldn't be changed
+ assertFalse(connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
+ assertEquals("virtualvalue2", connObjectTO.getPlainAttrMap().get("NAME").getValues().get(0));
+ // ----------------------------------
+
+ // ----------------------------------
+ // remove user virtual attribute and check virtual attribute value (reset)
+ // ----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getVirAttrsToRemove().add("virtualdata");
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertTrue(userTO.getVirAttrs().isEmpty());
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_WS2, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_WS2, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+
+ // attribute "name" mapped on virtual attribute "virtualdata" should be reset
+ assertTrue(connObjectTO.getPlainAttrMap().get("NAME").getValues() == null
+ || connObjectTO.getPlainAttrMap().get("NAME").getValues().isEmpty());
+ // ----------------------------------
+ }
+
+ @Test
+ public void virAttrCache() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("virattrcache@apache.org");
+ userTO.getVirAttrs().clear();
+
+ AttrTO virAttrTO = new AttrTO();
+ virAttrTO.setSchema("virtualdata");
+ virAttrTO.getValues().add("virattrcache");
+ userTO.getVirAttrs().add(virAttrTO);
+
+ userTO.getMemberships().clear();
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ // 1. create user
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+
+ // 2. check for virtual attribute value
+ actual = userService.read(actual.getKey());
+ assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // 3. update virtual attribute directly
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+ assertEquals("virattrcache", value);
+
+ jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
+
+ value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+ assertEquals("virattrcache2", value);
+
+ // 4. check for cached attribute value
+ actual = userService.read(actual.getKey());
+ assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ AttrMod virtualdata = new AttrMod();
+ virtualdata.setSchema("virtualdata");
+ virtualdata.getValuesToBeAdded().add("virtualupdated");
+
+ userMod.getVirAttrsToRemove().add("virtualdata");
+ userMod.getVirAttrsToUpdate().add(virtualdata);
+
+ // 5. update virtual attribute
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+
+ // 6. check for virtual attribute value
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertEquals("virtualupdated", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE397() {
+ ResourceTO csv = resourceService.read(RESOURCE_NAME_CSV);
+ final MappingTO origMapping = SerializationUtils.clone(csv.getUmapping());
+ try {
+ // change mapping of resource-csv
+ assertNotNull(origMapping);
+ for (MappingItemTO item : csv.getUmapping().getItems()) {
+ if ("email".equals(item.getIntAttrName())) {
+ // unset internal attribute mail and set virtual attribute virtualdata as mapped to external email
+ item.setIntMappingType(IntMappingType.UserVirtualSchema);
+ item.setIntAttrName("virtualdata");
+ item.setPurpose(MappingPurpose.BOTH);
+ item.setExtAttrName("email");
+ }
+ }
+
+ resourceService.update(csv.getKey(), csv);
+ csv = resourceService.read(RESOURCE_NAME_CSV);
+ assertNotNull(csv.getUmapping());
+
+ boolean found = false;
+ for (MappingItemTO item : csv.getUmapping().getItems()) {
+ if ("email".equals(item.getExtAttrName()) && "virtualdata".equals(item.getIntAttrName())) {
+ found = true;
+ }
+ }
+
+ assertTrue(found);
+
+ // create a new user
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope397@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getDerAttrs().add(attrTO("cn", null));
+ userTO.getVirAttrs().add(attrTO("virtualdata", "test@testone.org"));
+ // assign resource-csv to user
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+ // save user
+ UserTO created = createUser(userTO);
+ // make std controls about user
+ assertNotNull(created);
+ assertTrue(RESOURCE_NAME_CSV.equals(created.getResources().iterator().next()));
+ // update user
+ UserTO toBeUpdated = userService.read(created.getKey());
+ UserMod userMod = new UserMod();
+ userMod.setKey(toBeUpdated.getKey());
+ userMod.setPassword("password2");
+ // assign new resource to user
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS2);
+ //modify virtual attribute
+ userMod.getVirAttrsToRemove().add("virtualdata");
+ userMod.getVirAttrsToUpdate().add(attrMod("virtualdata", "test@testoneone.com"));
+
+ // check Syncope change password
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.setOnSyncope(true);
+ pwdPropRequest.getResourceNames().add(RESOURCE_NAME_WS2);
+ userMod.setPwdPropRequest(pwdPropRequest);
+
+ toBeUpdated = updateUser(userMod);
+ assertNotNull(toBeUpdated);
+ assertEquals("test@testoneone.com", toBeUpdated.getVirAttrs().get(0).getValues().get(0));
+ // check if propagates correctly with assertEquals on size of tasks list
+ assertEquals(2, toBeUpdated.getPropagationStatusTOs().size());
+ } finally {
+ // restore mapping of resource-csv
+ csv.setUmapping(origMapping);
+ resourceService.update(csv.getKey(), csv);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE442() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope442@apache.org");
+ userTO.getVirAttrs().clear();
+
+ AttrTO virAttrTO = new AttrTO();
+ virAttrTO.setSchema("virtualdata");
+ virAttrTO.getValues().add("virattrcache");
+ userTO.getVirAttrs().add(virAttrTO);
+
+ userTO.getMemberships().clear();
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ // 1. create user
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+
+ // 2. check for virtual attribute value
+ actual = userService.read(actual.getKey());
+ assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // ----------------------------------------
+ // 3. force cache expiring without any modification
+ // ----------------------------------------
+ String jdbcURL = null;
+ ConnInstanceTO connInstanceBean = connectorService.readByResource(RESOURCE_NAME_DBVIRATTR);
+ for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
+ if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+ jdbcURL = prop.getValues().iterator().next().toString();
+ prop.getValues().clear();
+ prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
+ }
+ }
+
+ connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ AttrMod virtualdata = new AttrMod();
+ virtualdata.setSchema("virtualdata");
+ virtualdata.getValuesToBeAdded().add("virtualupdated");
+
+ userMod.getVirAttrsToRemove().add("virtualdata");
+ userMod.getVirAttrsToUpdate().add(virtualdata);
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ // ----------------------------------------
+
+ // ----------------------------------------
+ // 4. update virtual attribute
+ // ----------------------------------------
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+ assertEquals("virattrcache", value);
+
+ jdbcTemplate.update("UPDATE testsync set USERNAME='virattrcache2' WHERE ID=?", actual.getKey());
+
+ value = jdbcTemplate.queryForObject(
+ "SELECT USERNAME FROM testsync WHERE ID=?", String.class, actual.getKey());
+ assertEquals("virattrcache2", value);
+ // ----------------------------------------
+
+ actual = userService.read(actual.getKey());
+ assertEquals("virattrcache", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // ----------------------------------------
+ // 5. restore connector
+ // ----------------------------------------
+ for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
+ if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+ prop.getValues().clear();
+ prop.getValues().add(jdbcURL);
+ }
+ }
+
+ connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+ // ----------------------------------------
+
+ actual = userService.read(actual.getKey());
+ assertEquals("virattrcache2", actual.getVirAttrMap().get("virtualdata").getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE436() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope436@syncope.apache.org");
+ userTO.getMemberships().clear();
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ userTO.getVirAttrs().add(attrTO("virtualReadOnly", "readOnly"));
+ userTO = createUser(userTO);
+ //Finding no values because the virtual attribute is readonly
+ assertTrue(userTO.getVirAttrMap().get("virtualReadOnly").getValues().isEmpty());
+ }
+
+ @Test
+ public void issueSYNCOPE453() {
+ final String resourceName = "issueSYNCOPE453-Res-" + getUUIDString();
+ final String roleName = "issueSYNCOPE453-Role-" + getUUIDString();
+
+ // -------------------------------------------
+ // Create a resource ad-hoc
+ // -------------------------------------------
+ final ResourceTO resourceTO = new ResourceTO();
+
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(107L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntAttrName("aLong");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName(roleName);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ item.setAccountid(true);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("USERNAME");
+ item.setIntAttrName("username");
+ item.setIntMappingType(IntMappingType.Username);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ mapping.getItems().add(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("EMAIL");
+ item.setIntAttrName("rvirtualdata");
+ item.setIntMappingType(IntMappingType.RoleVirtualSchema);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ mapping.getItems().add(item);
+
+ resourceTO.setUmapping(mapping);
+ assertNotNull(getObject(
+ resourceService.create(resourceTO).getLocation(), ResourceService.class, ResourceTO.class));
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Create a role ad-hoc
+ // -------------------------------------------
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName(roleName);
+ roleTO.setParent(8L);
+ roleTO.getRVirAttrTemplates().add("rvirtualdata");
+ roleTO.getVirAttrs().add(attrTO("rvirtualdata", "ml@role.it"));
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
+ roleTO = createRole(roleTO);
+ assertEquals(1, roleTO.getVirAttrs().size());
+ assertEquals("ml@role.it", roleTO.getVirAttrs().get(0).getValues().get(0));
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Create new user
+ // -------------------------------------------
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope453@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("aLong", "123"));
+ userTO.getResources().clear();
+ userTO.getResources().add(resourceName);
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getMemberships().clear();
+
+ final MembershipTO membership = new MembershipTO();
+ membership.setRoleId(roleTO.getKey());
+ membership.getVirAttrs().add(attrTO("mvirtualdata", "mvirtualvalue"));
+ userTO.getMemberships().add(membership);
+
+ userTO = createUser(userTO);
+ assertEquals(2, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ assertTrue(userTO.getPropagationStatusTOs().get(1).getStatus().isSuccessful());
+
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ final Map<String, Object> actuals = jdbcTemplate.queryForMap(
+ "SELECT id, surname, email FROM testsync WHERE id=?",
+ new Object[] { Integer.parseInt(userTO.getPlainAttrMap().get("aLong").getValues().get(0)) });
+
+ assertEquals(userTO.getPlainAttrMap().get("aLong").getValues().get(0), actuals.get("id").toString());
+ assertEquals("ml@role.it", actuals.get("email"));
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Delete resource and role ad-hoc
+ // -------------------------------------------
+ resourceService.delete(resourceName);
+ roleService.delete(roleTO.getKey());
+ // -------------------------------------------
+ }
+
+ @Test
+ public void issueSYNCOPE459() {
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope459@apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getVirAttrs().clear();
+
+ final AttrTO virtualReadOnly = attrTO("virtualReadOnly", "");
+ virtualReadOnly.getValues().clear();
+
+ userTO.getVirAttrs().add(virtualReadOnly);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO.getVirAttrMap().get("virtualReadOnly"));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ AttrMod virtualdata = new AttrMod();
+ virtualdata.setSchema("virtualdata");
+
+ userMod.getVirAttrsToUpdate().add(virtualdata);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
+ }
+
+ @Test
+ public void issueSYNCOPE458() {
+ // -------------------------------------------
+ // Create a role ad-hoc
+ // -------------------------------------------
+ final String roleName = "issueSYNCOPE458-Role-" + getUUIDString();
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName(roleName);
+ roleTO.setParent(2L);
+ roleTO.setInheritTemplates(true);
+ roleTO = createRole(roleTO);
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Update resource-db-virattr mapping adding new membership virtual schema mapping
+ // -------------------------------------------
+ ResourceTO resourceDBVirAttr = resourceService.read(RESOURCE_NAME_DBVIRATTR);
+ assertNotNull(resourceDBVirAttr);
+
+ final MappingTO resourceUMapping = resourceDBVirAttr.getUmapping();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntAttrName("mvirtualdata");
+ item.setIntMappingType(IntMappingType.MembershipVirtualSchema);
+ item.setExtAttrName("EMAIL");
+ item.setPurpose(MappingPurpose.BOTH);
+
+ resourceUMapping.addItem(item);
+
+ resourceDBVirAttr.setUmapping(resourceUMapping);
+
+ resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Create new user
+ // -------------------------------------------
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope458@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getMemberships().clear();
+
+ // add membership, with virtual attribute populated, to user
+ MembershipTO membership = new MembershipTO();
+ membership.setRoleId(roleTO.getKey());
+ membership.getVirAttrs().add(attrTO("mvirtualdata", "syncope458@syncope.apache.org"));
+ userTO.getMemberships().add(membership);
+
+ //propagate user
+ userTO = createUser(userTO);
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ // -------------------------------------------
+
+ // 1. check if membership has virtual attribute populated
+ assertNotNull(userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata"));
+ assertEquals("syncope458@syncope.apache.org",
+ userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata").getValues().get(0));
+ // -------------------------------------------
+
+ // 2. update membership virtual attribute
+ MembershipMod membershipMod = new MembershipMod();
+ membershipMod.setRole(roleTO.getKey());
+ membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope458_NEW@syncope.apache.org"));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ // 3. check again after update if membership has virtual attribute populated with new value
+ assertNotNull(userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata"));
+ assertEquals("syncope458_NEW@syncope.apache.org", userTO.getMemberships().get(0).getVirAttrMap().get(
+ "mvirtualdata").getValues().get(0));
+
+ // ----------------------------------------
+ // force cache expiring without any modification
+ // ----------------------------------------
+ String jdbcURL = null;
+ ConnInstanceTO connInstanceBean = connectorService.readByResource(RESOURCE_NAME_DBVIRATTR);
+ for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
+ if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+ jdbcURL = prop.getValues().iterator().next().toString();
+ prop.getValues().clear();
+ prop.getValues().add("jdbc:h2:tcp://localhost:9092/xxx");
+ }
+ }
+
+ connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+
+ membershipMod = new MembershipMod();
+ membershipMod.setRole(roleTO.getKey());
+ membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope458_updated@syncope.apache.org"));
+
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ // ----------------------------------
+
+ // change attribute value directly on resource
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String value = jdbcTemplate.queryForObject(
+ "SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
+ assertEquals("syncope458_NEW@syncope.apache.org", value);
+
+ jdbcTemplate.update("UPDATE testsync set EMAIL='syncope458_NEW_TWO@syncope.apache.org' WHERE ID=?", userTO.
+ getKey());
+
+ value = jdbcTemplate.queryForObject("SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
+ assertEquals("syncope458_NEW_TWO@syncope.apache.org", value);
+ // ----------------------------------------
+
+ // ----------------------------------------
+ // restore connector
+ // ----------------------------------------
+ for (ConnConfProperty prop : connInstanceBean.getConfiguration()) {
+ if ("jdbcUrlTemplate".equals(prop.getSchema().getName())) {
+ prop.getValues().clear();
+ prop.getValues().add(jdbcURL);
+ }
+ }
+ connectorService.update(connInstanceBean.getKey(), connInstanceBean);
+ // ----------------------------------------
+
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ // 4. check virtual attribute synchronization after direct update on resource
+ assertEquals("syncope458_NEW_TWO@syncope.apache.org", userTO.getMemberships().get(0).getVirAttrMap().get(
+ "mvirtualdata").getValues().get(0));
+
+ // 5. remove membership virtual attribute
+ membershipMod = new MembershipMod();
+ membershipMod.setRole(roleTO.getKey());
+ membershipMod.getVirAttrsToRemove().add("mvirtualdata");
+
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ // check again after update if membership hasn't any virtual attribute
+ assertTrue(userTO.getMemberships().get(0).getVirAttrMap().isEmpty());
+
+ // -------------------------------------------
+ // Delete role ad-hoc and restore resource mapping
+ // -------------------------------------------
+ roleService.delete(roleTO.getKey());
+
+ resourceUMapping.removeItem(item);
+ resourceDBVirAttr.setUmapping(resourceUMapping);
+ resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
+ // -------------------------------------------
+ }
+
+ @Test
+ public void issueSYNCOPE501() {
+ // PHASE 1: update only user virtual attributes
+
+ // 1. create user and propagate him on resource-db-virattr
+ UserTO userTO = UserITCase.getUniqueSampleTO("syncope501@apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ // virtualdata is mapped with username
+ final AttrTO virtualData = attrTO("virtualdata", "syncope501@apache.org");
+ userTO.getVirAttrs().add(virtualData);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO.getVirAttrMap().get("virtualdata"));
+ assertEquals("syncope501@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // 2. update virtual attribute
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ final StatusMod statusMod = new StatusMod();
+ statusMod.getResourceNames().addAll(Collections.<String>emptySet());
+ statusMod.setOnSyncope(false);
+
+ userMod.setPwdPropRequest(statusMod);
+ // change virtual attribute value
+ final AttrMod virtualDataMod = new AttrMod();
+ virtualDataMod.setSchema("virtualdata");
+ virtualDataMod.getValuesToBeAdded().add("syncope501_updated@apache.org");
+ virtualDataMod.getValuesToBeRemoved().add("syncope501@apache.org");
+ userMod.getVirAttrsToUpdate().add(virtualDataMod);
+ userMod.getVirAttrsToRemove().add("virtualdata");
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // 3. check that user virtual attribute has really been updated
+ assertFalse(userTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
+ assertEquals("syncope501_updated@apache.org", userTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // ----------------------------------------------------------
+ // PHASE 2: update only membership virtual attributes
+ // -------------------------------------------
+ // Update resource-db-virattr mapping adding new membership virtual schema mapping
+ // -------------------------------------------
+ ResourceTO resourceDBVirAttr = resourceService.read(RESOURCE_NAME_DBVIRATTR);
+ assertNotNull(resourceDBVirAttr);
+
+ final MappingTO resourceUMapping = resourceDBVirAttr.getUmapping();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntAttrName("mvirtualdata");
+ item.setIntMappingType(IntMappingType.MembershipVirtualSchema);
+ item.setExtAttrName("EMAIL");
+ item.setPurpose(MappingPurpose.BOTH);
+
+ resourceUMapping.addItem(item);
+
+ resourceDBVirAttr.setUmapping(resourceUMapping);
+
+ resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
+ // -------------------------------------------
+
+ // -------------------------------------------
+ // Create a role ad-hoc
+ // -------------------------------------------
+ final String roleName = "issueSYNCOPE501-Role-" + getUUIDString();
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName(roleName);
+ roleTO.setParent(2L);
+ roleTO.setInheritTemplates(true);
+ roleTO = createRole(roleTO);
+ // -------------------------------------------
+
+ // 1. add membership, with virtual attribute populated, to user
+ MembershipMod membershipMod = new MembershipMod();
+ membershipMod.setRole(roleTO.getKey());
+ membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata", "syncope501membership@test.org"));
+
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.setPwdPropRequest(statusMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertEquals("syncope501membership@test.org",
+ userTO.getMemberships().get(0).getVirAttrMap().get("mvirtualdata").getValues().get(0));
+
+ // 2. update only membership virtual attribute and propagate user
+ membershipMod = new MembershipMod();
+ membershipMod.setRole(roleTO.getKey());
+ membershipMod.getVirAttrsToUpdate().add(attrMod("mvirtualdata",
+ "syncope501membership_updated@test.org"));
+ membershipMod.getVirAttrsToRemove().add("syncope501membership@test.org");
+
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+ userMod.setPwdPropRequest(statusMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // 3. check if change has been propagated
+ assertEquals("syncope501membership_updated@test.org", userTO.getMemberships().get(0).getVirAttrMap().
+ get("mvirtualdata").getValues().get(0));
+
+ // 4. delete membership and check on resource attribute deletion
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().get(0).getKey());
+ userMod.setPwdPropRequest(statusMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertTrue(userTO.getMemberships().isEmpty());
+
+ // read attribute value directly on resource
+ final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ final String emailValue = jdbcTemplate.queryForObject(
+ "SELECT EMAIL FROM testsync WHERE ID=?", String.class, userTO.getKey());
+ assertTrue(StringUtils.isBlank(emailValue));
+ // ----------------------------------------
+
+ // -------------------------------------------
+ // Delete role ad-hoc and restore resource mapping
+ // -------------------------------------------
+ roleService.delete(roleTO.getKey());
+
+ resourceUMapping.removeItem(item);
+ resourceDBVirAttr.setUmapping(resourceUMapping);
+ resourceService.update(RESOURCE_NAME_DBVIRATTR, resourceDBVirAttr);
+ // -------------------------------------------
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirSchemaITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirSchemaITCase.java
new file mode 100644
index 0000000..884b5cb
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/VirSchemaITCase.java
@@ -0,0 +1,122 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.VirSchemaTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class VirSchemaITCase extends AbstractITCase {
+
+ @Test
+ public void list() {
+ List<VirSchemaTO> vSchemas = schemaService.list(AttributableType.USER, SchemaType.VIRTUAL);
+ assertFalse(vSchemas.isEmpty());
+ for (VirSchemaTO vSchemaTO : vSchemas) {
+ assertNotNull(vSchemaTO);
+ }
+ }
+
+ @Test
+ public void read() {
+ VirSchemaTO vSchemaTO = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL,
+ "mvirtualdata");
+ assertNotNull(vSchemaTO);
+ }
+
+ @Test
+ public void create() {
+ VirSchemaTO schema = new VirSchemaTO();
+ schema.setKey("virtual");
+
+ VirSchemaTO actual = createSchema(AttributableType.USER, SchemaType.VIRTUAL, schema);
+ assertNotNull(actual);
+
+ actual = schemaService.read(AttributableType.USER, SchemaType.VIRTUAL, actual.getKey());
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void delete() {
+ VirSchemaTO schema = schemaService.read(AttributableType.ROLE, SchemaType.VIRTUAL, "rvirtualdata");
+ assertNotNull(schema);
+
+ schemaService.delete(AttributableType.ROLE, SchemaType.VIRTUAL, schema.getKey());
+
+ try {
+ schemaService.read(AttributableType.ROLE, SchemaType.VIRTUAL, "rvirtualdata");
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE323() {
+ VirSchemaTO actual = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, "mvirtualdata");
+ assertNotNull(actual);
+
+ try {
+ createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.EntityExists, e.getType());
+ }
+
+ actual.setKey(null);
+ try {
+ createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE418() {
+ VirSchemaTO schema = new VirSchemaTO();
+ schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+
+ try {
+ createSchema(AttributableType.MEMBERSHIP, SchemaType.VIRTUAL, schema);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidVirSchema, e.getType());
+
+ assertTrue(e.getElements().iterator().next().toString().contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
new file mode 100644
index 0000000..161a23c
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/WorkflowITCase.java
@@ -0,0 +1,86 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.junit.Assume;
+import org.junit.Test;
+
+public class WorkflowITCase extends AbstractITCase {
+
+ @Test
+ public void isActivitiEnabled() {
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers(),
+ adminClient.isActivitiEnabledFor(SubjectType.USER));
+ assertEquals(ActivitiDetector.isActivitiEnabledForRoles(),
+ adminClient.isActivitiEnabledFor(SubjectType.ROLE));
+ }
+
+ private void exportDefinition(final SubjectType type) throws IOException {
+ Response response = workflowService.exportDefinition(type);
+ assertTrue(response.getMediaType().toString().
+ startsWith(clientFactory.getContentType().getMediaType().toString()));
+ assertTrue(response.getEntity() instanceof InputStream);
+ String definition = IOUtils.toString((InputStream) response.getEntity());
+ assertNotNull(definition);
+ assertFalse(definition.isEmpty());
+ }
+
+ @Test
+ public void exportUserDefinition() throws IOException {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+ exportDefinition(SubjectType.USER);
+ }
+
+ @Test
+ public void getRoleDefinition() throws IOException {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles());
+ exportDefinition(SubjectType.ROLE);
+ }
+
+ private void importDefinition(final SubjectType type) throws IOException {
+ Response response = workflowService.exportDefinition(type);
+ String definition = IOUtils.toString((InputStream) response.getEntity());
+
+ workflowService.importDefinition(type, definition);
+ }
+
+ @Test
+ public void updateUserDefinition() throws IOException {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ importDefinition(SubjectType.USER);
+ }
+
+ @Test
+ public void updateRoleDefinition() throws IOException {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForRoles());
+
+ importDefinition(SubjectType.ROLE);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/resources/favicon.jpg
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/resources/favicon.jpg b/syncope620/fit/reference/src/test/resources/favicon.jpg
new file mode 100644
index 0000000..cf212be
Binary files /dev/null and b/syncope620/fit/reference/src/test/resources/favicon.jpg differ
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/resources/test.csv
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/resources/test.csv b/syncope620/fit/reference/src/test/resources/test.csv
new file mode 100644
index 0000000..f227366
--- /dev/null
+++ b/syncope620/fit/reference/src/test/resources/test.csv
@@ -0,0 +1,10 @@
+test0,nome0,cognome0,test0@syncope.apache.org,password0,role1,membership1,true,false
+test1,nome1,cognome1,test1@syncope.apache.org,password1,role1,membership1,false,false
+test2,nome2,cognome2,test2@syncope.apache.org,notpermitted1,role1,membership1,true,false
+test3,nome3,cognome3,test3@syncope.apache.org,password3,role1,membership1,true,false
+test4,nome4,cognome4,test4@syncope.apache.org,password4,role1,membership1,true,false
+test5,nome5,cognome5,test5@syncope.apache.org,password5,role1,membership1,true,false
+test6,nome6,cognome6,test6@syncope.apache.org,password6,role1,membership1,true,false
+test7,nome7,cognome7,test7@syncope.apache.org,password7,role1,membership1,true,false
+test8,nome8,cognome8,test8@syncope.apache.org,password8,role1,membership1,true,false
+test9,nome9,cognome9,test9@syncope.apache.org,password999,role1,membership1,true,false
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/resources/testJDBCContext.xml
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/resources/testJDBCContext.xml b/syncope620/fit/reference/src/test/resources/testJDBCContext.xml
new file mode 100644
index 0000000..d89e067
--- /dev/null
+++ b/syncope620/fit/reference/src/test/resources/testJDBCContext.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
+ http://www.springframework.org/schema/beans/spring-beans.xsd">
+
+ <bean id="testDataSource"
+ class="org.springframework.jdbc.datasource.DriverManagerDataSource">
+ <property name="driverClassName" value="${testdb.driver}"/>
+ <property name="url" value="${testdb.url}"/>
+ <property name="username" value="${testdb.username}"/>
+ <property name="password" value="${testdb.password}"/>
+ </bean>
+
+</beans>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/pom.xml
----------------------------------------------------------------------
diff --git a/syncope620/pom.xml b/syncope620/pom.xml
index 4b0e328..b784741 100644
--- a/syncope620/pom.xml
+++ b/syncope620/pom.xml
@@ -315,8 +315,8 @@ under the License.
<connid.version>1.4.0.0</connid.version>
<connid.soap.version>1.3.0</connid.soap.version>
- <connid.db.table.version>2.2.0</connid.db.table.version>
- <connid.csvdir.version>0.8</connid.csvdir.version>
+ <connid.db.table.version>2.2.1</connid.db.table.version>
+ <connid.csvdir.version>0.8.1</connid.csvdir.version>
<connid.ldap.version>1.4.0</connid.ldap.version>
<connid.ad.version>1.2.1</connid.ad.version>
@@ -382,7 +382,7 @@ under the License.
<cargo.log>${log.directory}/cargo.log</cargo.log>
<cargo.output>${log.directory}/cargo-output.log</cargo.output>
- <tomcat.version>8.0.15</tomcat.version>
+ <tomcat.version>8.0.17</tomcat.version>
<anonymousUser>anonymous</anonymousUser>
<!-- static keys, only used for build: generated overlays will override during archetype:generate -->
@@ -881,6 +881,12 @@ under the License.
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.1</version>
+ </plugin>
+
+ <plugin>
<groupId>org.apache.openjpa</groupId>
<artifactId>openjpa-maven-plugin</artifactId>
<version>${openjpa.version}</version>
@@ -929,9 +935,15 @@ under the License.
</plugin>
<plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <version>1.8</version>
+ </plugin>
+
+ <plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
- <version>1.4.11</version>
+ <version>1.4.12</version>
<configuration>
<container>
<containerId>tomcat8x</containerId>
@@ -950,7 +962,7 @@ under the License.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
- <version>2.18</version>
+ <version>2.18.1</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<encoding>utf-8</encoding>
@@ -958,6 +970,24 @@ under the License.
<argLine>-Xms512m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m</argLine>
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <version>2.18.1</version>
+ <configuration>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ <encoding>utf-8</encoding>
+ <runOrder>alphabetical</runOrder>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@@ -986,6 +1016,110 @@ under the License.
</plugins>
</build>
+ <profiles>
+
+ <profile>
+ <id>apache-release</id>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <version>2.8.2</version>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-gpg-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <id>sign-artifacts</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>site</id>
+ <build>
+ <defaultGoal>clean site-deploy</defaultGoal>
+
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-site-plugin</artifactId>
+ <version>3.4</version>
+ <configuration>
+ <locales>en</locales>
+ <generateProjectInfo>false</generateProjectInfo>
+ <reportPlugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-project-info-reports-plugin</artifactId>
+ <version>2.8</version>
+ <configuration>
+ <dependencyDetailsEnabled>false</dependencyDetailsEnabled>
+ <dependencyLocationsEnabled>false</dependencyLocationsEnabled>
+ </configuration>
+ <reports>
+ <report>index</report>
+ <report>mailing-list</report>
+ <report>project-team</report>
+ <report>issue-tracking</report>
+ <report>license</report>
+ </reports>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-javadoc-plugin</artifactId>
+ <version>2.10.1</version>
+ <configuration>
+ <destDir>apidocs/2.0</destDir>
+ <detectLinks>true</detectLinks>
+ <detectJavaApiLink>true</detectJavaApiLink>
+ <links>
+ <link>http://docs.oracle.com/javaee/7/api/</link>
+ <link>http://www.slf4j.org/api/</link>
+ <link>http://connid.tirasa.net/apidocs/1.4/</link>
+ <link>http://camel.apache.org/maven/current/camel-core/apidocs/</link>
+ <link>http://camel.apache.org/maven/current/camel-spring/apidocs/</link>
+ <link>http://ci.apache.org/projects/wicket/apidocs/7.x/</link>
+ <link>http://docs.spring.io/spring/docs/4.1.x/javadoc-api/</link>
+ <link>http://docs.spring.io/spring-security/site/docs/3.2.x/apidocs/</link>
+ <link>http://activiti.org/javadocs/</link>
+ </links>
+ </configuration>
+ <reports>
+ <report>aggregate</report>
+ </reports>
+ </plugin>
+ </reportPlugins>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+
+ <profile>
+ <id>skipTests</id>
+ <properties>
+ <skipTests>true</skipTests>
+ </properties>
+ <build>
+ <defaultGoal>clean install</defaultGoal>
+ </build>
+ </profile>
+
+ </profiles>
+
<modules>
<module>common</module>
<module>server</module>
[02/15] syncope git commit: Merge branch '1_2_X'
Posted by il...@apache.org.
Merge branch '1_2_X'
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/336d8d6f
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/336d8d6f
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/336d8d6f
Branch: refs/heads/2_0_X
Commit: 336d8d6f29b96e25ea2994868d945c89c3ac3e91
Parents: 8d270a1 4efca7c
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Wed Jan 21 06:54:51 2015 +0100
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Wed Jan 21 06:54:51 2015 +0100
----------------------------------------------------------------------
.../core/rest/ConfigurationTestITCase.java | 79 +++++++++++---------
1 file changed, 42 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
[07/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/ResourceTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/ResourceTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/ResourceTest.java
index c5fbf29..dc9124b 100644
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/ResourceTest.java
+++ b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/server/persistence/jpa/relationship/ResourceTest.java
@@ -118,7 +118,7 @@ public class ResourceTest extends AbstractTest {
UMappingItem item = entityFactory.newEntity(UMappingItem.class);
item.setExtAttrName("test" + i);
item.setIntAttrName("nonexistent" + i);
- item.setIntMappingType(IntMappingType.UserSchema);
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
item.setMandatoryCondition("false");
item.setPurpose(MappingPurpose.SYNCHRONIZATION);
mapping.addItem(item);
@@ -257,13 +257,16 @@ public class ResourceTest extends AbstractTest {
List<? extends RMappingItem> items = ldap.getRmapping().getItems();
assertNotNull(items);
assertFalse(items.isEmpty());
- List<Long> itemIds = new ArrayList<Long>(items.size());
+ List<Long> itemIds = new ArrayList<>(items.size());
for (RMappingItem item : items) {
itemIds.add(item.getKey());
}
ldap.setRmapping(null);
+ // need to avoid any class not defined in this Maven module
+ ldap.getPropagationActionsClassNames().clear();
+
resourceDAO.save(ldap);
resourceDAO.flush();
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/persistence-jpa/src/test/resources/content.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/resources/content.xml b/syncope620/server/persistence-jpa/src/test/resources/content.xml
index 0fb3b79..ecbf06d 100644
--- a/syncope620/server/persistence-jpa/src/test/resources/content.xml
+++ b/syncope620/server/persistence-jpa/src/test/resources/content.xml
@@ -407,10 +407,10 @@ under the License.
<RDerAttrTemplate id="1003" owner_id="1" schema_name="rderToBePropagated"/>
<RDerAttr id="1003" owner_id="1" template_id="1003"/>
- <RVirAttrTemplate id="100" owner_id="4" schema_name="rvirtualdata"/>
- <RVirAttr id="100" owner_id="4" template_id="100"/>
+ <RVirAttrTemplate id="98" owner_id="4" schema_name="rvirtualdata"/>
+ <RVirAttr id="98" owner_id="4" template_id="98"/>
- <RVirAttrTemplate id="101" owner_id="3" schema_name="rvirtualdata"/>
+ <RVirAttrTemplate id="99" owner_id="3" schema_name="rvirtualdata"/>
<MPlainAttrTemplate id="98" owner_id="1" schema_name="mderived_sx"/>
@@ -438,7 +438,7 @@ under the License.
<MDerAttrTemplate id="100" owner_id="1" schema_name="mderToBePropagated"/>
- <MVirAttrTemplate id="100" owner_id="2" schema_name="mvirtualdata"/>
+ <MVirAttrTemplate id="99" owner_id="2" schema_name="mvirtualdata"/>
<ConnInstance id="100" displayName="ConnInstance100"
location="${connid.location}"
@@ -605,7 +605,7 @@ under the License.
creator="admin" lastModifier="admin"
creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
<ExternalResource_PropActions externalResource_name="resource-ldap"
- action="org.apache.syncope.server.provisioning.api.propagation.PropagationActions"/>
+ action="org.apache.syncope.server.provisioning.java.propagation.LDAPMembershipPropagationActions"/>
<ExternalResource name="ws-target-resource-nopropagation" connector_id="103"
randomPwdIfNotProvided="0" enforceMandatoryCondition="1" propagationMode="TWO_PHASES"
propagationPriority="0" propagationPrimary="0" createTraceLevel="ALL" deleteTraceLevel="ALL" updateTraceLevel="ALL" syncTraceLevel="ALL"
@@ -664,49 +664,49 @@ under the License.
intMappingType="UserId" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMappingItem id="100" extAttrName="email" mapping_id="15"
- intAttrName="email" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMappingItem id="101" extAttrName="surname" mapping_id="15"
- intAttrName="surname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMappingItem id="102" mapping_id="15"
extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
accountid="0" password="1" purpose="PROPAGATION"/>
<UMappingItem id="335" mapping_id="15"
- extAttrName="fullname" intAttrName="surname" intMappingType="UserSchema" mandatoryCondition="true"
+ extAttrName="fullname" intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMappingItem id="336" mapping_id="15"
- extAttrName="type" intAttrName="type" intMappingType="UserSchema" mandatoryCondition="true"
+ extAttrName="type" intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMappingItem id="337" mapping_id="15"
- extAttrName="name" intAttrName="firstname" intMappingType="UserSchema" mandatoryCondition="false"
+ extAttrName="name" intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="0" purpose="NONE"/>
<UMapping id="12" resource_name="ws-target-resource-list-mappings-1"/>
<UMappingItem id="103" mapping_id="12"
- extAttrName="email" intAttrName="email" intMappingType="UserSchema" mandatoryCondition="true"
+ extAttrName="email" intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMappingItem id="104" extAttrName="surname" mapping_id="12"
- intAttrName="surname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMapping id="13" resource_name="ws-target-resource-list-mappings-2"/>
<UMappingItem id="105" mapping_id="13"
- extAttrName="userId" intAttrName="userId" intMappingType="UserSchema" mandatoryCondition="true"
+ extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMapping id="1" resource_name="ws-target-resource-2"/>
<UMappingItem id="106" mapping_id="1" extAttrName="fullname"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="BOTH"/>
<UMappingItem id="107" mapping_id="1"
extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
accountid="0" password="1" purpose="BOTH"/>
<UMappingItem id="108" extAttrName="type" mapping_id="1"
- intAttrName="type" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="type" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="109" extAttrName="surname" mapping_id="1"
- intAttrName="surname" intMappingType="UserSchema" mandatoryCondition="type == 'F'"
+ intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="type == 'F'"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="110" extAttrName="name" mapping_id="1"
intAttrName="virtualdata" intMappingType="UserVirtualSchema" mandatoryCondition="type == 'F'"
@@ -717,33 +717,33 @@ under the License.
<UMapping id="2" resource_name="ws-target-resource-update"/>
<UMappingItem id="112" extAttrName="email" mapping_id="2"
- intAttrName="email" intMappingType="UserSchema" mandatoryCondition="false"
+ intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMappingItem id="113" extAttrName="userId" mapping_id="2"
- intAttrName="userId" intMappingType="UserSchema" mandatoryCondition="false"
+ intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMappingItem id="114" extAttrName="test3" mapping_id="2"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="false"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="0" purpose="PROPAGATION"/>
<UMapping id="3" resource_name="ws-target-resource-nopropagation"/>
<UMappingItem id="115" mapping_id="3" extAttrName="fullname"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMapping id="4" resource_name="ws-target-resource-nopropagation2"/>
<UMappingItem id="116" mapping_id="4" extAttrName="fullname"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMapping id="5" resource_name="ws-target-resource-nopropagation3"/>
<UMappingItem id="117" mapping_id="5" extAttrName="fullname"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMapping id="6" resource_name="ws-target-resource-nopropagation4"/>
<UMappingItem id="118" mapping_id="6"
- extAttrName="fullname" intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="1" password="0" purpose="PROPAGATION"/>
<UMapping id="7" resource_name="resource-testdb"/>
@@ -767,22 +767,22 @@ under the License.
intMappingType="Username" mandatoryCondition="true"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="201" extAttrName="id" mapping_id="9"
- intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="202" mapping_id="9"
extAttrName="__PASSWORD__" intMappingType="Password" mandatoryCondition="true"
accountid="0" password="1" purpose="BOTH"/>
<UMappingItem id="203" extAttrName="name" mapping_id="9"
- intAttrName="firstname" intMappingType="UserSchema" mandatoryCondition="false"
+ intAttrName="firstname" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="204" extAttrName="surname" mapping_id="9"
- intAttrName="surname" intMappingType="UserSchema" mandatoryCondition="false"
+ intAttrName="surname" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="0" purpose="BOTH"/>
<UMappingItem id="205" extAttrName="email" mapping_id="9"
- intAttrName="userId" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="SYNCHRONIZATION"/>
<UMappingItem id="206" extAttrName="email" mapping_id="9"
- intAttrName="email" intMappingType="UserSchema" mandatoryCondition="true"
+ intAttrName="email" intMappingType="UserPlainSchema" mandatoryCondition="true"
accountid="0" password="0" purpose="SYNCHRONIZATION"/>
<UMappingItem id="207" extAttrName="__NAME__" mapping_id="9"
intAttrName="csvuserid" intMappingType="UserDerivedSchema" mandatoryCondition="true"
@@ -796,10 +796,10 @@ under the License.
<UMapping id="10" resource_name="ws-target-resource-update-resetsynctoken"/>
<UMappingItem id="300" mapping_id="10"
- extAttrName="userId" intAttrName="userId" intMappingType="UserSchema" mandatoryCondition="false"
+ extAttrName="userId" intAttrName="userId" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="1" password="0" purpose="BOTH"/>
<UMappingItem id="301" mapping_id="10"
- extAttrName="__PASSWORD__" intAttrName="fullname" intMappingType="UserSchema" mandatoryCondition="false"
+ extAttrName="__PASSWORD__" intAttrName="fullname" intMappingType="UserPlainSchema" mandatoryCondition="false"
accountid="0" password="1" purpose="BOTH"/>
<UMapping id="11" resource_name="resource-ldap"
@@ -811,31 +811,31 @@ under the License.
extAttrName="__PASSWORD__" intAttrName="Password" intMappingType="Password"
mandatoryCondition="true" purpose="BOTH"/>
<UMappingItem id="313" accountid="0" password="0" mapping_id="11"
- extAttrName="sn" intAttrName="surname" intMappingType="UserSchema"
+ extAttrName="sn" intAttrName="surname" intMappingType="UserPlainSchema"
mandatoryCondition="true" purpose="BOTH"/>
<UMappingItem id="314" accountid="0" password="0" mapping_id="11"
- extAttrName="cn" intAttrName="fullname" intMappingType="UserSchema"
+ extAttrName="cn" intAttrName="fullname" intMappingType="UserPlainSchema"
mandatoryCondition="true" purpose="BOTH"/>
<UMappingItem id="315" accountid="0" password="0" mapping_id="11"
- extAttrName="mail" intAttrName="email" intMappingType="UserSchema"
+ extAttrName="mail" intAttrName="email" intMappingType="UserPlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="316" accountid="0" password="0" mapping_id="11"
- extAttrName="title" intAttrName="title" intMappingType="RoleSchema"
+ extAttrName="title" intAttrName="title" intMappingType="RolePlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="317" accountid="0" password="0" mapping_id="11"
- extAttrName="postalAddress" intAttrName="postalAddress" intMappingType="MembershipSchema"
+ extAttrName="postalAddress" intAttrName="postalAddress" intMappingType="MembershipPlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="318" accountid="0" password="0" mapping_id="11"
- extAttrName="mail" intAttrName="userId" intMappingType="UserSchema"
+ extAttrName="mail" intAttrName="userId" intMappingType="UserPlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="319" accountid="0" password="0" mapping_id="11"
extAttrName="givenname" intAttrName="virtualReadOnly" intMappingType="UserVirtualSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="320" accountid="0" password="0" mapping_id="11"
- extAttrName="registeredAddress" intAttrName="obscure" intMappingType="UserSchema"
+ extAttrName="registeredAddress" intAttrName="obscure" intMappingType="UserPlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<UMappingItem id="321" accountid="0" password="0" mapping_id="11"
- extAttrName="jpegPhoto" intAttrName="photo" intMappingType="UserSchema"
+ extAttrName="jpegPhoto" intAttrName="photo" intMappingType="UserPlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<RMapping id="1" resource_name="resource-ldap"
@@ -847,7 +847,7 @@ under the License.
extAttrName="owner" intAttrName="roleOwnerSchema" intMappingType="RoleOwnerSchema"
mandatoryCondition="false" purpose="BOTH"/>
<RMappingItem id="3" accountid="0" password="0" mapping_id="1"
- extAttrName="description" intAttrName="title" intMappingType="RoleSchema"
+ extAttrName="description" intAttrName="title" intMappingType="RolePlainSchema"
mandatoryCondition="false" purpose="BOTH"/>
<RMappingItem id="4" extAttrName="businessCategory" mapping_id="1"
intAttrName="rvirtualdata" intMappingType="RoleVirtualSchema" mandatoryCondition="false"
@@ -855,22 +855,22 @@ under the License.
<UMapping id="16" resource_name="resource-db-sync"/>
<UMappingItem id="322" accountid="0" mapping_id="16"
- extAttrName="EMAIL" intAttrName="email" intMappingType="UserSchema"
+ extAttrName="EMAIL" intAttrName="email" intMappingType="UserPlainSchema"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMappingItem id="323" accountid="0" mapping_id="16"
- extAttrName="SURNAME" intAttrName="fullname" intMappingType="UserSchema"
+ extAttrName="SURNAME" intAttrName="fullname" intMappingType="UserPlainSchema"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMappingItem id="324" accountid="1" mapping_id="16"
- extAttrName="ID" intAttrName="aLong" intMappingType="UserSchema"
+ extAttrName="ID" intAttrName="aLong" intMappingType="UserPlainSchema"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMappingItem id="325" accountid="0" mapping_id="16"
- extAttrName="SURNAME" intAttrName="surname" intMappingType="UserSchema"
+ extAttrName="SURNAME" intAttrName="surname" intMappingType="UserPlainSchema"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMappingItem id="326" accountid="0" mapping_id="16"
extAttrName="USERNAME" intAttrName="Username" intMappingType="Username"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMappingItem id="327" accountid="0" mapping_id="16"
- extAttrName="EMAIL" intAttrName="userId" intMappingType="UserSchema"
+ extAttrName="EMAIL" intAttrName="userId" intMappingType="UserPlainSchema"
mandatoryCondition="false" password="0" purpose="BOTH"/>
<UMapping id="17" resource_name="resource-db-virattr"/>
@@ -883,7 +883,7 @@ under the License.
<UMapping id="18" resource_name="ws-target-resource-timeout"/>
<UMappingItem id="333" mapping_id="18" accountid="1" password="0"
- extAttrName="fullname" intAttrName="fullname" intMappingType="UserSchema"
+ extAttrName="fullname" intAttrName="fullname" intMappingType="UserPlainSchema"
mandatoryCondition="true" purpose="PROPAGATION"/>
<UMapping id="19" resource_name="ws-target-resource-delete"/>
@@ -904,7 +904,7 @@ under the License.
<Task DTYPE="SyncTask" type="SYNCHRONIZATION" id="4" name="CSV (update matching; assign unmatching)" resource_name="resource-csv"
performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
jobClassName="org.apache.syncope.server.provisioning.api.job.SyncJob" unmatchingRule="ASSIGN" matchingRule="UPDATE"
- userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[{"schema":"type","readonly":false,"values":["email == 'test8@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}],"derivedAttributes":[{"schema":"cn","readonly":false,"values":[null]}],"virtualAttributes":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"id":0,"roleId":8,"roleName":null,"attributes":[{"schema":"subscriptionDate","readonly":false,"values":["'2009-08-18T16:33:12.203+0200'"]}],"derivedAttributes":[],"virtualAttributes":[]}]}'
+ userTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"password":null,"status":null,"token":null,"tokenExpireTime":null,"username":null,"lastLoginDate":null,"changePwdDate":null,"failedLogins":null,"attributes":[{"schema":"type","readonly":false,"values":["email == 'test8@syncope.apache.org'? 'TYPE_8': 'TYPE_OTHER'"]}],"derivedAttributes":[{"schema":"cn","readonly":false,"values":[null]}],"virtualAttributes":[],"resources":["resource-testdb"],"propagationStatuses":[],"memberships":[{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"roleId":8,"roleName":null,"attributes":[{"schema":"subscriptionDate","readonly":false,"values":["'2009-08-18T16:33:12.203+0200'"]}],"derivedAttributes":[],"virtualAttributes":[]}]}'
roleTemplate='{"creator":null,"creationDate":null,"lastModifier":null,"lastChangeDate":null,"key":0,"name":null,"parent":0,"userOwner":null,"roleOwner":null,"inheritOwner":false,"inheritTemplates":false,"inheritPlainAttrs":false,"inheritDerAttrs":false,"inheritVirAttrs":false,"inheritPasswordPolicy":false,"inheritAccountPolicy":false,"passwordPolicy":null,"accountPolicy":null,"attributes":[],"derivedAttributes":[],"virtualAttributes":[],"resources":[],"propagationStatuses":[],"entitlements":[],"rAttrTemplates":[],"rDerAttrTemplates":[],"rVirAttrTemplates":[],"mAttrTemplates":[],"mDerAttrTemplates":[],"mVirAttrTemplates":[]}'/>
<Task DTYPE="SchedTask" type="SCHEDULED" id="5" name="SampleJob Task" jobClassName="org.apache.syncope.server.provisioning.java.job.SampleJob" cronExpression="0 0 0 1 * ?"/>
<Task DTYPE="PropagationTask" type="PROPAGATION" id="6" propagationMode="TWO_PHASES" propagationOperation="UPDATE"
@@ -989,12 +989,12 @@ under the License.
performCreate="1" performUpdate="1" performDelete="1" syncStatus="1" fullReconciliation="0"
jobClassName="org.apache.syncope.server.provisioning.api.job.SyncJob" unmatchingRule="ASSIGN" matchingRule="IGNORE"/>
- <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1"
+ <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" 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"
+ <Notification id="2" active="1" recipientAttrName="email" recipientAttrType="UserPlainSchema" 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]"/>
@@ -1003,7 +1003,7 @@ under the License.
traceLevel="FAILURES"
userAbout="fullname==*o*;fullname==*i*"
recipients="$roles==7"
- recipientAttrType="UserSchema" recipientAttrName="email" active="1"/>
+ recipientAttrType="UserPlainSchema" recipientAttrName="email" active="1"/>
<Notification_events Notification_id="10" events="[CUSTOM]:[]:[]:[unexisting1]:[FAILURE]"/>
<Notification_events Notification_id="10" events="[CUSTOM]:[]:[]:[unexisting2]:[SUCCESS]"/>
@@ -1011,7 +1011,7 @@ under the License.
<Report id="1" name="test"/>
<ReportletConfInstance id="1" Report_id="1"
- serializedInstance='{"@class":"org.apache.syncope.common.lib.report.UserReportletConf","name":"testUserReportlet","matchingCond":null,"attributes":["fullname","gender"],"derivedAttributes":["cn"],"virtualAttributes":["virtualdata"],"features":["key","username","workflowId","status","creationDate","lastLoginDate","changePwdDate","passwordHistorySize","failedLoginCount","memberships","resources"]}'/>
+ serializedInstance='{"@class":"org.apache.syncope.common.lib.report.UserReportletConf","name":"testUserReportlet","matchingCond":null,"plainAttributes":["fullname","gender"],"derivedAttributes":["cn"],"virtualAttributes":["virtualdata"],"features":["key","username","workflowId","status","creationDate","lastLoginDate","changePwdDate","passwordHistorySize","failedLoginCount","memberships","resources"]}'/>
<ReportExec Report_id="1" id="1" status="SUCCESS" startDate="2012-02-26 15:40:04" endDate="2012-02-26 15:41:04"/>
<SyncopeLogger logName="syncope.audit.[REST]:[EntitlementController]:[]:[getOwn]:[SUCCESS]" logLevel="DEBUG" logType="AUDIT"/>
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/UserSuspender.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/UserSuspender.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/UserSuspender.java
new file mode 100644
index 0000000..218f826
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/UserSuspender.java
@@ -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.
+ */
+package org.apache.syncope.server.provisioning.api;
+
+import org.apache.syncope.server.persistence.api.entity.user.User;
+
+public interface UserSuspender {
+
+ void suspend(User user, boolean propagateSuspension);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/job/JobInstanceLoader.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/job/JobInstanceLoader.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/job/JobInstanceLoader.java
new file mode 100644
index 0000000..e77aaca
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/job/JobInstanceLoader.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.provisioning.api.job;
+
+import java.text.ParseException;
+import org.apache.syncope.server.persistence.api.entity.Report;
+import org.apache.syncope.server.persistence.api.entity.task.Task;
+import org.quartz.SchedulerException;
+
+public interface JobInstanceLoader {
+
+ void registerJob(Task task, String jobClassName, String cronExpression)
+ throws ClassNotFoundException, SchedulerException, ParseException;
+
+ void registerJob(Report report) throws SchedulerException, ParseException;
+
+ void registerReportJob(Long reportKey) throws SchedulerException, ParseException;
+
+ void registerTaskJob(Long taskKey) throws ClassNotFoundException, SchedulerException, ParseException;
+
+ void unregisterJob(Task task);
+
+ void unregisterJob(Report report);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/ProvisioningActions.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/ProvisioningActions.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/ProvisioningActions.java
index f7b1663..7277708 100644
--- a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/ProvisioningActions.java
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/ProvisioningActions.java
@@ -18,7 +18,6 @@
*/
package org.apache.syncope.server.provisioning.api.sync;
-import java.util.List;
import org.quartz.JobExecutionException;
public interface ProvisioningActions {
@@ -35,9 +34,7 @@ public interface ProvisioningActions {
* Action to be executed after the synchronization task completion.
*
* @param profile sync profile
- * @param results synchronization result
* @throws JobExecutionException in case of generic failure
*/
- void afterAll(final ProvisioningProfile<?, ?> profile, final List<ProvisioningResult> results)
- throws JobExecutionException;
+ void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RolePushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RolePushResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RolePushResultHandler.java
new file mode 100644
index 0000000..0c765b5
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RolePushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.server.provisioning.api.sync;
+
+public interface RolePushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RoleSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RoleSyncResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RoleSyncResultHandler.java
new file mode 100644
index 0000000..1f77591
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/RoleSyncResultHandler.java
@@ -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.
+ */
+package org.apache.syncope.server.provisioning.api.sync;
+
+import java.util.Map;
+
+public interface RoleSyncResultHandler extends SyncopeSyncResultHandler {
+
+ Map<Long, String> getRoleOwnerMap();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopePushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopePushResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopePushResultHandler.java
new file mode 100644
index 0000000..bf6f680
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopePushResultHandler.java
@@ -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.
+ */
+package org.apache.syncope.server.provisioning.api.sync;
+
+import org.apache.syncope.server.persistence.api.entity.task.PushTask;
+
+public interface SyncopePushResultHandler extends SyncopeResultHandler<PushTask, PushActions> {
+
+ boolean handle(long subjectId);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopeSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopeSyncResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopeSyncResultHandler.java
new file mode 100644
index 0000000..111af19
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/SyncopeSyncResultHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.server.provisioning.api.sync;
+
+import org.apache.syncope.server.persistence.api.entity.task.SyncTask;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.identityconnectors.framework.common.objects.SyncResultsHandler;
+
+public interface SyncopeSyncResultHandler extends SyncopeResultHandler<SyncTask, SyncActions>, SyncResultsHandler {
+
+ @Override
+ boolean handle(SyncDelta delta);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserPushResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserPushResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserPushResultHandler.java
new file mode 100644
index 0000000..6d93a87
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserPushResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.server.provisioning.api.sync;
+
+public interface UserPushResultHandler extends SyncopePushResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserSyncResultHandler.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserSyncResultHandler.java b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserSyncResultHandler.java
new file mode 100644
index 0000000..00b972c
--- /dev/null
+++ b/syncope620/server/provisioning-api/src/main/java/org/apache/syncope/server/provisioning/api/sync/UserSyncResultHandler.java
@@ -0,0 +1,23 @@
+/*
+ * 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.server.provisioning.api.sync;
+
+public interface UserSyncResultHandler extends SyncopeSyncResultHandler {
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/AsyncConnectorFacade.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/AsyncConnectorFacade.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/AsyncConnectorFacade.java
index a22145a..b7e2197 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/AsyncConnectorFacade.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/AsyncConnectorFacade.java
@@ -58,7 +58,7 @@ public class AsyncConnectorFacade {
final GuardedString password,
final OperationOptions options) {
- return new AsyncResult<Uid>(connector.authenticate(ObjectClass.ACCOUNT, username, password, options));
+ return new AsyncResult<>(connector.authenticate(ObjectClass.ACCOUNT, username, password, options));
}
@Async
@@ -68,7 +68,7 @@ public class AsyncConnectorFacade {
final Set<Attribute> attrs,
final OperationOptions options) {
- return new AsyncResult<Uid>(connector.create(objectClass, attrs, options));
+ return new AsyncResult<>(connector.create(objectClass, attrs, options));
}
@Async
@@ -79,7 +79,7 @@ public class AsyncConnectorFacade {
final Set<Attribute> attrs,
final OperationOptions options) {
- return new AsyncResult<Uid>(connector.update(objectClass, uid, attrs, options));
+ return new AsyncResult<>(connector.update(objectClass, uid, attrs, options));
}
@Async
@@ -90,14 +90,14 @@ public class AsyncConnectorFacade {
final OperationOptions options) {
connector.delete(objectClass, uid, options);
- return new AsyncResult<Uid>(uid);
+ return new AsyncResult<>(uid);
}
@Async
public Future<SyncToken> getLatestSyncToken(
final ConnectorFacade connector, final ObjectClass objectClass) {
- return new AsyncResult<SyncToken>(connector.getLatestSyncToken(objectClass));
+ return new AsyncResult<>(connector.getLatestSyncToken(objectClass));
}
@Async
@@ -107,7 +107,7 @@ public class AsyncConnectorFacade {
final Uid uid,
final OperationOptions options) {
- return new AsyncResult<ConnectorObject>(connector.getObject(objectClass, uid, options));
+ return new AsyncResult<>(connector.getObject(objectClass, uid, options));
}
@Async
@@ -127,7 +127,7 @@ public class AsyncConnectorFacade {
attribute = object.getAttributeByName(attributeName);
}
- return new AsyncResult<Attribute>(attribute);
+ return new AsyncResult<>(attribute);
}
@Async
@@ -137,7 +137,7 @@ public class AsyncConnectorFacade {
final Uid uid,
final OperationOptions options) {
- final Set<Attribute> attributes = new HashSet<Attribute>();
+ final Set<Attribute> attributes = new HashSet<>();
final ConnectorObject object = connector.getObject(objectClass, uid, options);
@@ -149,7 +149,7 @@ public class AsyncConnectorFacade {
}
}
- return new AsyncResult<Set<Attribute>>(attributes);
+ return new AsyncResult<>(attributes);
}
@Async
@@ -170,7 +170,7 @@ public class AsyncConnectorFacade {
LOG.debug("While reading schema on connector {}", connector, e);
}
- return new AsyncResult<Set<String>>(schemaNames);
+ return new AsyncResult<>(schemaNames);
}
@Async
@@ -187,18 +187,18 @@ public class AsyncConnectorFacade {
LOG.debug("While reading schema on connector {}", connector, e);
}
- return new AsyncResult<Set<ObjectClass>>(objectClasses);
+ return new AsyncResult<>(objectClasses);
}
@Async
public Future<String> validate(final ConnectorFacade connector) {
connector.validate();
- return new AsyncResult<String>("OK");
+ return new AsyncResult<>("OK");
}
@Async
public Future<String> test(final ConnectorFacade connector) {
connector.test();
- return new AsyncResult<String>("OK");
+ return new AsyncResult<>("OK");
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnectorFacadeProxy.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnectorFacadeProxy.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnectorFacadeProxy.java
index 3e5f03a..6557979 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnectorFacadeProxy.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/ConnectorFacadeProxy.java
@@ -388,13 +388,12 @@ public class ConnectorFacadeProxy implements Connector {
@Override
public boolean handle(final ConnectorObject obj) {
- final SyncDeltaBuilder bld = new SyncDeltaBuilder();
- bld.setObject(obj);
- bld.setUid(obj.getUid());
- bld.setDeltaType(SyncDeltaType.CREATE_OR_UPDATE);
- bld.setToken(new SyncToken(""));
-
- return handler.handle(bld.build());
+ return handler.handle(new SyncDeltaBuilder().
+ setObject(obj).
+ setUid(obj.getUid()).
+ setDeltaType(SyncDeltaType.CREATE_OR_UPDATE).
+ setToken(new SyncToken("")).
+ build());
}
}, options);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultRoleProvisioningManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultRoleProvisioningManager.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultRoleProvisioningManager.java
index 666d535..06f205b 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultRoleProvisioningManager.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultRoleProvisioningManager.java
@@ -99,7 +99,7 @@ public class DefaultRoleProvisioningManager implements RoleProvisioningManager {
final RoleTO roleTO, final Map<Long, String> roleOwnerMap, final Set<String> excludedResources) {
WorkflowResult<Long> created = rwfAdapter.create((RoleTO) roleTO);
- AttrTO roleOwner = roleTO.getAttrMap().get(StringUtils.EMPTY);
+ AttrTO roleOwner = roleTO.getPlainAttrMap().get(StringUtils.EMPTY);
if (roleOwner != null) {
roleOwnerMap.put(created.getResult(), roleOwner.getValues().iterator().next());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultUserProvisioningManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultUserProvisioningManager.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultUserProvisioningManager.java
index 2c00a02..3c4225e 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultUserProvisioningManager.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/DefaultUserProvisioningManager.java
@@ -73,6 +73,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
return create(userTO, true, false, null, Collections.<String>emptySet());
}
+ @Override
public Map.Entry<Long, List<PropagationStatus>> create(final UserTO userTO, final boolean storePassword) {
return create(userTO, storePassword, false, null, Collections.<String>emptySet());
}
@@ -99,7 +100,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
propagationReporter.onPrimaryResourceFailure(tasks);
}
- Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<>(
created.getResult().getKey(), propagationReporter.getStatuses());
return result;
}
@@ -149,7 +150,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
}
}
- Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(
+ Map.Entry<Long, List<PropagationStatus>> result = new AbstractMap.SimpleEntry<>(
updated.getResult().getKey().getKey(), propagationReporter.getStatuses());
return result;
}
@@ -198,11 +199,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
if (statusMod.isOnSyncope()) {
updated = uwfAdapter.activate(user.getKey(), statusMod.getToken());
} else {
- updated = new WorkflowResult<Long>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+ updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
}
List<PropagationStatus> statuses = propagateStatus(user, statusMod);
- return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
}
@Override
@@ -211,11 +212,11 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
if (statusMod.isOnSyncope()) {
updated = uwfAdapter.reactivate(user.getKey());
} else {
- updated = new WorkflowResult<Long>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+ updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
}
List<PropagationStatus> statuses = propagateStatus(user, statusMod);
- return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
}
@Override
@@ -224,15 +225,15 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
if (statusMod.isOnSyncope()) {
updated = uwfAdapter.suspend(user.getKey());
} else {
- updated = new WorkflowResult<Long>(user.getKey(), null, statusMod.getType().name().toLowerCase());
+ updated = new WorkflowResult<>(user.getKey(), null, statusMod.getType().name().toLowerCase());
}
List<PropagationStatus> statuses = propagateStatus(user, statusMod);
- return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult(), statuses);
+ return new AbstractMap.SimpleEntry<>(updated.getResult(), statuses);
}
protected List<PropagationStatus> propagateStatus(final User user, final StatusMod statusMod) {
- Set<String> resourcesToBeExcluded = new HashSet<String>(user.getResourceNames());
+ Set<String> resourcesToBeExcluded = new HashSet<>(user.getResourceNames());
resourcesToBeExcluded.removeAll(statusMod.getResourceNames());
List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
@@ -261,7 +262,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
final List<PropagationTask> tasks = propagationManager.getUserUpdateTaskIds(
new WorkflowResult<Map.Entry<UserMod, Boolean>>(
- new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, Boolean.FALSE),
+ new AbstractMap.SimpleEntry<>(userMod, Boolean.FALSE),
updated.getPropByRes(), updated.getPerformedTasks()));
taskExecutor.execute(tasks);
@@ -276,7 +277,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
noPropResourceName.removeAll(resources);
final List<PropagationTask> tasks =
- propagationManager.getUserDeleteTaskIds(userKey, new HashSet<String>(resources), noPropResourceName);
+ propagationManager.getUserDeleteTaskIds(userKey, new HashSet<>(resources), noPropResourceName);
final PropagationReporter propagationReporter =
ApplicationContextProvider.getApplicationContext().getBean(PropagationReporter.class);
try {
@@ -303,7 +304,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
result.setMessage("Update failed, trying to sync status anyway (if configured)\n" + e.getMessage());
updated = new WorkflowResult<Map.Entry<UserMod, Boolean>>(
- new AbstractMap.SimpleEntry<UserMod, Boolean>(userMod, false), new PropagationByResource(),
+ new AbstractMap.SimpleEntry<>(userMod, false), new PropagationByResource(),
new HashSet<String>());
}
@@ -341,7 +342,7 @@ public class DefaultUserProvisioningManager implements UserProvisioningManager {
propagationReporter.onPrimaryResourceFailure(tasks);
}
- return new AbstractMap.SimpleEntry<Long, List<PropagationStatus>>(updated.getResult().getKey().getKey(),
+ return new AbstractMap.SimpleEntry<>(updated.getResult().getKey().getKey(),
propagationReporter.getStatuses());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/UserSuspenderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/UserSuspenderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/UserSuspenderImpl.java
new file mode 100644
index 0000000..357c15f
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/UserSuspenderImpl.java
@@ -0,0 +1,51 @@
+/*
+ * 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.server.provisioning.java;
+
+import org.apache.syncope.server.provisioning.api.UserSuspender;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.provisioning.api.UserProvisioningManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Component
+public class UserSuspenderImpl implements UserSuspender {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UserSuspenderImpl.class);
+
+ @Autowired
+ private UserProvisioningManager provisioningManager;
+
+ @Override
+ public void suspend(final User user, final boolean suspend) {
+ try {
+ LOG.debug("User {}:{} is over to max failed logins", user.getKey(), user.getUsername());
+
+ // reduce failed logins number to avoid multiple request
+ user.setFailedLogins(user.getFailedLogins() - 1);
+
+ // disable user and propagate suspension if and only if it is required by policy
+ provisioningManager.innerSuspend(user, suspend);
+ } catch (Exception e) {
+ LOG.error("Error during user suspension", e);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java
index c38edfc..f7e75c0 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/AbstractAttributableDataBinder.java
@@ -215,7 +215,7 @@ abstract class AbstractAttributableDataBinder {
}
private boolean evaluateMandatoryCondition(final AttributableUtil attrUtil, final ExternalResource resource,
- final Attributable attributable, final String intAttrName, final IntMappingType intMappingType) {
+ final Attributable<?,?,?> attributable, final String intAttrName, final IntMappingType intMappingType) {
boolean result = false;
@@ -409,7 +409,7 @@ abstract class AbstractAttributableDataBinder {
}
// 3. attributes to be removed
- for (String attributeToBeRemoved : attributableMod.getAttrsToRemove()) {
+ for (String attributeToBeRemoved : attributableMod.getPlainAttrsToRemove()) {
PlainSchema schema = getPlainSchema(attributeToBeRemoved, attrUtil.plainSchemaClass());
if (schema != null) {
PlainAttr attr = attributable.getPlainAttr(schema.getKey());
@@ -417,7 +417,7 @@ abstract class AbstractAttributableDataBinder {
LOG.debug("No attribute found for schema {}", schema);
} else {
String newValue = null;
- for (AttrMod mod : attributableMod.getAttrsToUpdate()) {
+ for (AttrMod mod : attributableMod.getPlainAttrsToUpdate()) {
if (schema.getKey().equals(mod.getSchema())) {
newValue = mod.getValuesToBeAdded().get(0);
}
@@ -456,7 +456,7 @@ abstract class AbstractAttributableDataBinder {
LOG.debug("Attributes to be removed:\n{}", propByRes);
// 4. attributes to be updated
- for (AttrMod attributeMod : attributableMod.getAttrsToUpdate()) {
+ for (AttrMod attributeMod : attributableMod.getPlainAttrsToUpdate()) {
PlainSchema schema = getPlainSchema(attributeMod.getSchema(), attrUtil.plainSchemaClass());
PlainAttr attr = null;
if (schema != null) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/ReportDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/ReportDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/ReportDataBinderImpl.java
index 12c0254..6ffe2fc 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/ReportDataBinderImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/ReportDataBinderImpl.java
@@ -18,6 +18,8 @@
*/
package org.apache.syncope.server.provisioning.java.data;
+import java.util.HashSet;
+import java.util.Set;
import org.apache.syncope.server.provisioning.api.data.ReportDataBinder;
import org.apache.syncope.common.lib.report.AbstractReportletConf;
import org.apache.syncope.common.lib.report.ReportletConf;
@@ -59,7 +61,17 @@ public class ReportDataBinderImpl implements ReportDataBinder {
@Override
public void getReport(final Report report, final ReportTO reportTO) {
BeanUtils.copyProperties(reportTO, report, IGNORE_REPORT_PROPERTIES);
- report.getReportletConfs().clear();
+
+ // 1. remove all reportlet confs
+ Set<ReportletConf> toRemove = new HashSet<>();
+ for (ReportletConf conf : report.getReportletConfs()) {
+ toRemove.add(conf);
+ }
+ for (ReportletConf conf : toRemove) {
+ report.removeReportletConf(conf);
+ }
+
+ // 2. take all reportlet confs from reportTO
for (ReportletConf conf : reportTO.getReportletConfs()) {
report.addReportletConf(conf);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java
index be16ee7..851799c 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/RoleDataBinderImpl.java
@@ -29,7 +29,6 @@ import org.apache.syncope.common.lib.types.AttributableType;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ResourceOperation;
import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
-import org.apache.syncope.server.persistence.api.dao.RoleDAO;
import org.apache.syncope.server.persistence.api.entity.AccountPolicy;
import org.apache.syncope.server.persistence.api.entity.AttrTemplate;
import org.apache.syncope.server.persistence.api.entity.Entitlement;
@@ -64,9 +63,6 @@ import org.springframework.transaction.annotation.Transactional;
public class RoleDataBinderImpl extends AbstractAttributableDataBinder implements RoleDataBinder {
@Autowired
- private RoleDAO roleDAO;
-
- @Autowired
private ConnObjectUtil connObjectUtil;
@Autowired
@@ -76,7 +72,7 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement
final Role role, final List<String> schemaNames,
final Class<T> templateClass, final Class<S> schemaClass) {
- List<T> toRemove = new ArrayList<T>();
+ List<T> toRemove = new ArrayList<>();
for (T template : role.getAttrTemplates(templateClass)) {
if (!schemaNames.contains(template.getSchema().getKey())) {
toRemove.add(template);
@@ -89,7 +85,7 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement
S schema = getSchema(schemaName, schemaClass);
if (schema != null) {
try {
- T template = templateClass.newInstance();
+ T template = entityFactory.newEntity(templateClass);
template.setSchema(schema);
template.setOwner(role);
role.getAttrTemplates(templateClass).add(template);
@@ -105,7 +101,7 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement
public Role create(final Role role, final RoleTO roleTO) {
role.setInheritOwner(roleTO.isInheritOwner());
- role.setInheritPlainAttrs(roleTO.isInheritAttrs());
+ role.setInheritPlainAttrs(roleTO.isInheritPlainAttrs());
role.setInheritDerAttrs(roleTO.isInheritDerAttrs());
role.setInheritVirAttrs(roleTO.isInheritVirAttrs());
@@ -335,7 +331,7 @@ public class RoleDataBinderImpl extends AbstractAttributableDataBinder implement
roleTO.setInheritTemplates(role.isInheritTemplates());
- roleTO.setInheritAttrs(role.isInheritPlainAttrs());
+ roleTO.setInheritPlainAttrs(role.isInheritPlainAttrs());
roleTO.setInheritDerAttrs(role.isInheritDerAttrs());
roleTO.setInheritVirAttrs(role.isInheritVirAttrs());
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/SchemaDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/SchemaDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/SchemaDataBinderImpl.java
index 94b0ccf..31141c0 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/SchemaDataBinderImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/SchemaDataBinderImpl.java
@@ -69,15 +69,13 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
List<PlainAttr> attrs = schemaDAO.findAttrs(schema, attributableUtil.plainAttrClass());
if (!attrs.isEmpty()) {
if (schema.getType() != schemaTO.getType()) {
- SyncopeClientException e = SyncopeClientException.build(
- ClientExceptionType.valueOf("Invalid" + schema.getClass().getSimpleName()));
+ SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidPlainSchema);
e.getElements().add("Cannot change type since " + schema.getKey() + " has attributes");
scce.addException(e);
}
if (schema.isUniqueConstraint() != schemaTO.isUniqueConstraint()) {
- SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.valueOf("Invalid"
- + schema.getClass().getSimpleName()));
+ SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidPlainSchema);
e.getElements().add("Cannot alter unique contraint since " + schema.getKey() + " has attributes");
scce.addException(e);
@@ -112,11 +110,10 @@ public class SchemaDataBinderImpl implements SchemaDataBinder {
scce.addException(requiredValuesMissing);
} else if (!JexlUtil.isExpressionValid(derSchemaTO.getExpression())) {
- SyncopeClientException invalidMandatoryCondition = SyncopeClientException.build(
- ClientExceptionType.InvalidValues);
- invalidMandatoryCondition.getElements().add(derSchemaTO.getExpression());
+ SyncopeClientException e = SyncopeClientException.build(ClientExceptionType.InvalidValues);
+ e.getElements().add(derSchemaTO.getExpression());
- scce.addException(invalidMandatoryCondition);
+ scce.addException(e);
}
if (scce.hasExceptions()) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/TaskDataBinderImpl.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/TaskDataBinderImpl.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/TaskDataBinderImpl.java
index 9ebfbce..920d294 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/TaskDataBinderImpl.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/data/TaskDataBinderImpl.java
@@ -180,7 +180,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
final Class<? extends AbstractTaskTO> taskTOClass = taskUtil.taskTOClass();
if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
- throw new ClassCastException(
+ throw new IllegalArgumentException(
String.format("taskUtil is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
}
@@ -211,13 +211,13 @@ public class TaskDataBinderImpl implements TaskDataBinder {
Class<? extends Task> taskClass = taskUtil.taskClass();
Class<? extends AbstractTaskTO> taskTOClass = taskUtil.taskTOClass();
- if (taskClass == null || !taskClass.equals(task.getClass())) {
- throw new ClassCastException(
+ if (taskClass == null || !taskClass.isAssignableFrom(task.getClass())) {
+ throw new IllegalArgumentException(
String.format("taskUtil is type %s but task is not: %s", taskClass, task.getClass()));
}
if (taskTOClass == null || !taskTOClass.equals(taskTO.getClass())) {
- throw new ClassCastException(
+ throw new IllegalArgumentException(
String.format("taskUtil is type %s but task is not: %s", taskTOClass, taskTO.getClass()));
}
@@ -283,7 +283,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
switch (taskUtil.getType()) {
case PROPAGATION:
if (!(task instanceof PropagationTask)) {
- throw new ClassCastException("taskUtil is type Propagation but task is not PropagationTask: "
+ throw new IllegalArgumentException("taskUtil is type Propagation but task is not PropagationTask: "
+ task.getClass().getName());
}
((PropagationTaskTO) taskTO).setResource(((PropagationTask) task).getResource().getKey());
@@ -291,7 +291,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
case SCHEDULED:
if (!(task instanceof SchedTask)) {
- throw new ClassCastException("taskUtil is type Sched but task is not SchedTask: "
+ throw new IllegalArgumentException("taskUtil is type Sched but task is not SchedTask: "
+ task.getClass().getName());
}
setExecTime((SchedTaskTO) taskTO, task);
@@ -301,7 +301,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
case SYNCHRONIZATION:
if (!(task instanceof SyncTask)) {
- throw new ClassCastException("taskUtil is type Sync but task is not SyncTask: "
+ throw new IllegalArgumentException("taskUtil is type Sync but task is not SyncTask: "
+ task.getClass().getName());
}
setExecTime((SchedTaskTO) taskTO, task);
@@ -316,7 +316,7 @@ public class TaskDataBinderImpl implements TaskDataBinder {
case PUSH:
if (!(task instanceof PushTask)) {
- throw new ClassCastException("taskUtil is type Push but task is not PushTask: "
+ throw new IllegalArgumentException("taskUtil is type Push but task is not PushTask: "
+ task.getClass().getName());
}
setExecTime((SchedTaskTO) taskTO, task);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/SpringBeanJobFactory.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/SpringBeanJobFactory.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/SpringBeanJobFactory.java
new file mode 100644
index 0000000..b56e920
--- /dev/null
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/job/SpringBeanJobFactory.java
@@ -0,0 +1,97 @@
+/*
+ * 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.server.provisioning.java.job;
+
+import org.apache.syncope.server.provisioning.api.job.JobNamer;
+import org.apache.syncope.server.provisioning.api.job.JobInstanceLoader;
+import org.quartz.SchedulerContext;
+import org.quartz.spi.TriggerFiredBundle;
+import org.springframework.beans.BeanWrapper;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.PropertyAccessorFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
+
+public class SpringBeanJobFactory extends org.springframework.scheduling.quartz.SpringBeanJobFactory {
+
+ private String[] ignoredUnknownProperties;
+
+ private SchedulerContext schedulerContext;
+
+ @Override
+ public void setIgnoredUnknownProperties(final String[] ignoredUnknownProperties) {
+ String[] defensiveCopy = ignoredUnknownProperties.clone();
+ super.setIgnoredUnknownProperties(defensiveCopy);
+ this.ignoredUnknownProperties = defensiveCopy;
+ }
+
+ @Override
+ public void setSchedulerContext(final SchedulerContext schedulerContext) {
+ super.setSchedulerContext(schedulerContext);
+ this.schedulerContext = schedulerContext;
+ }
+
+ /**
+ * An implementation of SpringBeanJobFactory that retrieves the bean from the Spring context so that autowiring and
+ * transactions work.
+ *
+ * {@inheritDoc}
+ */
+ @Override
+ protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
+ final ApplicationContext ctx = ((ConfigurableApplicationContext) schedulerContext.get("applicationContext"));
+
+ // Try to re-create job bean from underlying task (useful for managing failover scenarios)
+ if (!ctx.containsBean(bundle.getJobDetail().getKey().getName())) {
+ Long taskId = JobNamer.getTaskIdFromJobName(bundle.getJobDetail().getKey().getName());
+ if (taskId != null) {
+ JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
+ jobInstanceLoader.registerTaskJob(taskId);
+ }
+
+ Long reportId = JobNamer.getReportIdFromJobName(bundle.getJobDetail().getKey().getName());
+ if (reportId != null) {
+ JobInstanceLoader jobInstanceLoader = ctx.getBean(JobInstanceLoader.class);
+ jobInstanceLoader.registerReportJob(reportId);
+ }
+ }
+
+ final Object job = ctx.getBean(bundle.getJobDetail().getKey().getName());
+ final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(job);
+ if (isEligibleForPropertyPopulation(wrapper.getWrappedInstance())) {
+ final MutablePropertyValues pvs = new MutablePropertyValues();
+ if (this.schedulerContext != null) {
+ pvs.addPropertyValues(this.schedulerContext);
+ }
+ pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
+ pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());
+ if (this.ignoredUnknownProperties == null) {
+ wrapper.setPropertyValues(pvs, true);
+ } else {
+ for (String propName : this.ignoredUnknownProperties) {
+ if (pvs.contains(propName) && !wrapper.isWritableProperty(propName)) {
+ pvs.removePropertyValue(propName);
+ }
+ }
+ wrapper.setPropertyValues(pvs);
+ }
+ }
+ return job;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
index 59379b9..436f32c 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/notification/NotificationManager.java
@@ -350,7 +350,7 @@ public class NotificationManager {
email = user.getUsername();
break;
- case UserSchema:
+ case UserPlainSchema:
UPlainAttr attr = user.getPlainAttr(recipientAttrName);
if (attr != null && !attr.getValuesAsStrings().isEmpty()) {
email = attr.getValuesAsStrings().get(0);
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/PriorityPropagationTaskExecutor.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
index 7016a0b..6d7bf38 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/propagation/PriorityPropagationTaskExecutor.java
@@ -76,7 +76,7 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
null,
null,
result,
- reporter.getStatuses(),
+ reporter == null ? null : reporter.getStatuses(),
tasks);
auditManager.audit(
@@ -85,7 +85,7 @@ public class PriorityPropagationTaskExecutor extends AbstractPropagationTaskExec
null,
null,
result,
- reporter.getStatuses(),
+ reporter == null ? null : reporter.getStatuses(),
tasks);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractProvisioningJob.java
----------------------------------------------------------------------
diff --git a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractProvisioningJob.java b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractProvisioningJob.java
index f99e179..311c607 100644
--- a/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractProvisioningJob.java
+++ b/syncope620/server/provisioning-java/src/main/java/org/apache/syncope/server/provisioning/java/sync/AbstractProvisioningJob.java
@@ -20,6 +20,7 @@ package org.apache.syncope.server.provisioning.java.sync;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import org.apache.syncope.common.lib.types.TraceLevel;
import org.apache.syncope.server.persistence.api.dao.EntitlementDAO;
@@ -97,7 +98,7 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
* @param dryRun dry run?
* @return report as string
*/
- protected String createReport(final List<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
+ protected String createReport(final Collection<ProvisioningResult> provResults, final TraceLevel syncTraceLevel,
final boolean dryRun) {
if (syncTraceLevel == TraceLevel.NONE) {
@@ -341,7 +342,9 @@ public abstract class AbstractProvisioningJob<T extends ProvisioningTask, A exte
uMapping,
rMapping,
dryRun);
-
+ } catch (Throwable t) {
+ LOG.error("While executing provisioning job {}", getClass().getName(), t);
+ throw t;
} finally {
// POST: clean up the SecurityContextHolder
SecurityContextHolder.clearContext();
[10/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
new file mode 100644
index 0000000..96ca3de
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/UserITCase.java
@@ -0,0 +1,2442 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlException;
+import java.text.SimpleDateFormat;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import javax.naming.NamingException;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.AttributableOperations;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.ResourceAssociationMod;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.BulkActionResult.Status;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.PropagationStatus;
+import org.apache.syncope.common.lib.to.PropagationTaskTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.PolicyService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.server.misc.security.Encryptor;
+import org.apache.syncope.server.provisioning.java.propagation.DBPasswordPropagationActions;
+import org.apache.syncope.server.provisioning.java.propagation.LDAPPasswordPropagationActions;
+import org.identityconnectors.framework.common.objects.Name;
+import org.identityconnectors.framework.common.objects.OperationalAttributes;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class UserITCase extends AbstractITCase {
+
+ private String getStringAttribute(final ConnObjectTO connObjectTO, final String attrName) {
+ return connObjectTO.getPlainAttrMap().get(attrName).getValues().get(0);
+ }
+
+ private boolean getBooleanAttribute(final ConnObjectTO connObjectTO, final String attrName) {
+ return Boolean.parseBoolean(getStringAttribute(connObjectTO, attrName));
+ }
+
+ public static UserTO getUniqueSampleTO(final String email) {
+ return getSampleTO(getUUIDString() + email);
+ }
+
+ public static UserTO getSampleTO(final String email) {
+ String uid = email;
+ UserTO userTO = new UserTO();
+ userTO.setPassword("password123");
+ userTO.setUsername(uid);
+
+ userTO.getPlainAttrs().add(attrTO("fullname", uid));
+ userTO.getPlainAttrs().add(attrTO("firstname", uid));
+ userTO.getPlainAttrs().add(attrTO("surname", "surname"));
+ userTO.getPlainAttrs().add(attrTO("type", "a type"));
+ userTO.getPlainAttrs().add(attrTO("userId", uid));
+ userTO.getPlainAttrs().add(attrTO("email", uid));
+ userTO.getPlainAttrs().add(attrTO("loginDate", new SimpleDateFormat("yyyy-MM-dd").format(new Date())));
+ userTO.getDerAttrs().add(attrTO("cn", null));
+ userTO.getVirAttrs().add(attrTO("virtualdata", "virtualvalue"));
+ return userTO;
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void createUserWithNoPropagation() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+
+ // create a new user
+ UserTO userTO = getUniqueSampleTO("xxx@xxx.xxx");
+
+ userTO.setPassword("password123");
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+
+ createUser(userTO);
+
+ // get the new task list
+ tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxId = tasks.getResult().iterator().next().getKey();
+
+ assertTrue(newMaxId > maxKey);
+
+ // get last task
+ PropagationTaskTO taskTO = taskService.read(newMaxId);
+
+ assertNotNull(taskTO);
+ assertTrue(taskTO.getExecutions().isEmpty());
+ }
+
+ @Test
+ public void issue172() {
+ List<PasswordPolicyTO> policies = policyService.list(PolicyType.GLOBAL_PASSWORD);
+ for (PasswordPolicyTO policyTO : policies) {
+ policyService.delete(policyTO.getKey());
+ }
+
+ try {
+ UserTO userTO = getUniqueSampleTO("issue172@syncope.apache.org");
+ createUser(userTO);
+ } finally {
+ for (PasswordPolicyTO policyTO : policies) {
+ Response response = policyService.create(policyTO);
+ PasswordPolicyTO cPolicyTO = getObject(
+ response.getLocation(), PolicyService.class, PasswordPolicyTO.class);
+ assertNotNull(cPolicyTO);
+ }
+ }
+ }
+
+ @Test
+ public void issue186() {
+ // 1. create an user with strict mandatory attributes only
+ UserTO userTO = new UserTO();
+ String userId = getUUIDString() + "issue186@syncope.apache.org";
+ userTO.setUsername(userId);
+ userTO.setPassword("password");
+
+ userTO.getPlainAttrs().add(attrTO("userId", userId));
+ userTO.getPlainAttrs().add(attrTO("fullname", userId));
+ userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().isEmpty());
+
+ // 2. update assigning a resource forcing mandatory constraints: must fail with RequiredValuesMissing
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS2);
+
+ try {
+ userTO = updateUser(userMod);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ // 3. update assigning a resource NOT forcing mandatory constraints
+ // AND primary: must fail with PropagationException
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+
+ // 4. update assigning a resource NOT forcing mandatory constraints
+ // BUT not primary: must succeed
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123456");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_CSV);
+ updateUser(userMod);
+ }
+
+ @Test
+ public void enforceMandatoryCondition() {
+ UserTO userTO = getUniqueSampleTO("enforce@apache.org");
+ userTO.getResources().add(RESOURCE_NAME_WS2);
+ userTO.setPassword("newPassword");
+
+ AttrTO type = null;
+ for (AttrTO attr : userTO.getPlainAttrs()) {
+ if ("type".equals(attr.getSchema())) {
+ type = attr;
+ }
+ }
+ assertNotNull(type);
+ userTO.getPlainAttrs().remove(type);
+
+ try {
+ userTO = createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getPlainAttrs().add(type);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void enforceMandatoryConditionOnDerived() {
+ ResourceTO resourceTO = resourceService.read(RESOURCE_NAME_CSV);
+ assertNotNull(resourceTO);
+ resourceTO.setKey("resource-csv-enforcing");
+ resourceTO.setEnforceMandatoryCondition(true);
+
+ Response response = resourceService.create(resourceTO);
+ resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(resourceTO);
+
+ UserTO userTO = getUniqueSampleTO("syncope222@apache.org");
+ userTO.getResources().add(resourceTO.getKey());
+ userTO.setPassword("newPassword");
+
+ try {
+ userTO = createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(Collections.singleton("resource-csv-enforcing"), userTO.getResources());
+ }
+
+ @Test
+ public void createUserWithDbPropagation() {
+ UserTO userTO = getUniqueSampleTO("yyy@yyy.yyy");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPassword() {
+ UserTO userTO = getSampleTO("invalidpasswd@syncope.apache.org");
+ userTO.setPassword("pass");
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidUsername() {
+ UserTO userTO = getSampleTO("invalidusername@syncope.apache.org");
+ userTO.setUsername("us");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+
+ userTO.getMemberships().add(membershipTO);
+
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPasswordByRes() {
+ UserTO userTO = getSampleTO("invalidPwdByRes@passwd.com");
+
+ // configured to be minLength=16
+ userTO.setPassword("password1");
+ userTO.getResources().add(RESOURCE_NAME_NOPROPAGATION);
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithInvalidPasswordByRole() {
+ UserTO userTO = getSampleTO("invalidPwdByRole@passwd.com");
+
+ // configured to be minLength=16
+ userTO.setPassword("password1");
+
+ final MembershipTO membership = new MembershipTO();
+ membership.setRoleId(8L);
+
+ userTO.getMemberships().add(membership);
+
+ createUser(userTO);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithException() {
+ UserTO newUserTO = new UserTO();
+ newUserTO.getPlainAttrs().add(attrTO("userId", "userId@nowhere.org"));
+ createUser(newUserTO);
+ }
+
+ @Test
+ public void create() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+ PropagationTaskTO taskTO = taskService.read(maxKey);
+
+ assertNotNull(taskTO);
+ int maxTaskExecutions = taskTO.getExecutions().size();
+
+ UserTO userTO = getUniqueSampleTO("a.b@c.com");
+
+ // add a membership
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // add an attribute with no values: must be ignored
+ membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", null));
+
+ // add an attribute with a non-existing schema: must be ignored
+ AttrTO attrWithInvalidSchemaTO = attrTO("invalid schema", "a value");
+ userTO.getPlainAttrs().add(attrWithInvalidSchemaTO);
+
+ // add an attribute with null value: must be ignored
+ userTO.getPlainAttrs().add(attrTO("activationDate", null));
+
+ // 1. create user
+ UserTO newUserTO = createUser(userTO);
+
+ assertNotNull(newUserTO);
+
+ // issue SYNCOPE-15
+ assertNotNull(newUserTO.getCreationDate());
+ assertNotNull(newUserTO.getCreator());
+ assertNotNull(newUserTO.getLastChangeDate());
+ assertNotNull(newUserTO.getLastModifier());
+ assertEquals(newUserTO.getCreationDate(), newUserTO.getLastChangeDate());
+
+ assertFalse(newUserTO.getPlainAttrs().contains(attrWithInvalidSchemaTO));
+
+ // check for changePwdDate
+ assertNotNull(newUserTO.getCreationDate());
+
+ // 2. check for virtual attribute value
+ newUserTO = userService.read(newUserTO.getKey());
+ assertNotNull(newUserTO);
+
+ assertNotNull(newUserTO.getVirAttrMap());
+ assertNotNull(newUserTO.getVirAttrMap().get("virtualdata").getValues());
+ assertFalse(newUserTO.getVirAttrMap().get("virtualdata").getValues().isEmpty());
+ assertEquals("virtualvalue", newUserTO.getVirAttrMap().get("virtualdata").getValues().get(0));
+
+ // get the new task list
+ tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // only failed executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+
+ // get last task
+ taskTO = taskService.read(newMaxKey);
+
+ assertNotNull(taskTO);
+ assertEquals(maxTaskExecutions, taskTO.getExecutions().size());
+
+ // 3. verify password
+ UserSelfService userSelfService1 = clientFactory.create(
+ newUserTO.getUsername(), "password123").getService(UserSelfService.class);
+ try {
+ UserTO user = userSelfService1.read();
+ assertNotNull(user);
+ } catch (AccessControlException e) {
+ fail("Credentials should be valid and not cause AccessControlException");
+ }
+
+ UserSelfService userSelfService2 = clientFactory.create(
+ newUserTO.getUsername(), "passwordXX").getService(UserSelfService.class);
+ try {
+ userSelfService2.read();
+ fail("Credentials are invalid, thus request should raise AccessControlException");
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ // 4. try (and fail) to create another user with same (unique) values
+ userTO = getSampleTO(userTO.getUsername());
+ AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+ userIdAttr.getValues().clear();
+ userIdAttr.getValues().add("a.b@c.com");
+
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.DataIntegrityViolation, e.getType());
+ }
+ }
+
+ @Test
+ public void createWithRequiredValueMissing() {
+ UserTO userTO = getSampleTO("a.b@c.it");
+
+ AttrTO type = userTO.getPlainAttrMap().get("type");
+ userTO.getPlainAttrs().remove(type);
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user without type (mandatory by UserSchema)
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ userTO.getPlainAttrs().add(attrTO("type", "F"));
+
+ AttrTO surname = userTO.getPlainAttrMap().get("surname");
+ userTO.getPlainAttrs().remove(surname);
+
+ // 2. create user without surname (mandatory when type == 'F')
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void delete() {
+ try {
+ userService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+
+ UserTO userTO = getSampleTO("qqgf.z@nn.com");
+
+ // specify a propagation
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+
+ long id = userTO.getKey();
+
+ userTO = deleteUser(id);
+
+ assertNotNull(userTO);
+ assertEquals(id, userTO.getKey());
+ assertTrue(userTO.getPlainAttrs().isEmpty());
+
+ // check for propagation result
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ try {
+ userService.delete(userTO.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void deleteByUsername() {
+ UserTO userTO = getSampleTO("delete.by.username@apache.org");
+
+ // specify a propagation
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+
+ long id = userTO.getKey();
+ userTO = userService.read(id);
+ userTO = deleteUser(userTO.getKey());
+
+ assertNotNull(userTO);
+ assertEquals(id, userTO.getKey());
+ assertTrue(userTO.getPlainAttrs().isEmpty());
+
+ // check for propagation result
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+
+ try {
+ userService.read(userTO.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void list() {
+ PagedResult<UserTO> users = userService.list();
+ assertNotNull(users);
+ assertFalse(users.getResult().isEmpty());
+
+ for (UserTO user : users.getResult()) {
+ assertNotNull(user);
+ }
+ }
+
+ @Test
+ public void paginatedList() {
+ PagedResult<UserTO> users = userService.list(1, 2);
+ assertNotNull(users);
+ assertFalse(users.getResult().isEmpty());
+ assertEquals(2, users.getResult().size());
+
+ for (UserTO user : users.getResult()) {
+ assertNotNull(user);
+ }
+
+ users = userService.list(2, 2);
+ assertNotNull(users);
+ assertFalse(users.getResult().isEmpty());
+ assertEquals(2, users.getResult().size());
+
+ users = userService.list(100, 2);
+ assertNotNull(users);
+ assertTrue(users.getResult().isEmpty());
+ }
+
+ @Test
+ public void read() {
+ UserTO userTO = userService.read(1L);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getPlainAttrs());
+ assertFalse(userTO.getPlainAttrs().isEmpty());
+ }
+
+ @Test
+ public void readWithMailAddressAsUserName() {
+ UserTO userTO = createUser(getUniqueSampleTO("mail@domain.org"));
+ userTO = userService.read(userTO.getKey());
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void updateWithouPassword() {
+ UserTO userTO = getUniqueSampleTO("updatewithout@password.com");
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getDerAttrsToRemove().add("cn");
+
+ userTO = updateUser(userMod);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getDerAttrMap());
+ assertFalse(userTO.getDerAttrMap().containsKey("cn"));
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void updateInvalidPassword() {
+ UserTO userTO = getSampleTO("updateinvalid@password.com");
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("pass");
+
+ userService.update(userMod.getKey(), userMod);
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void updateSamePassword() {
+ UserTO userTO = getSampleTO("updatesame@password.com");
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("password123");
+
+ userService.update(userMod.getKey(), userMod);
+ }
+
+ @Test
+ public void update() {
+ UserTO userTO = getUniqueSampleTO("g.h@t.com");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", "2009-08-18T16:33:12.203+0200"));
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertFalse(userTO.getDerAttrs().isEmpty());
+ assertEquals(1, userTO.getMemberships().size());
+
+ MembershipMod membershipMod = new MembershipMod();
+ membershipMod.setRole(8L);
+ membershipMod.getPlainAttrsToUpdate().add(attrMod("subscriptionDate", "2010-08-18T16:33:12.203+0200"));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("new2Password");
+
+ userMod.getPlainAttrsToRemove().add("userId");
+ String newUserId = getUUIDString() + "t.w@spre.net";
+ userMod.getPlainAttrsToUpdate().add(attrMod("userId", newUserId));
+
+ userMod.getPlainAttrsToRemove().add("fullname");
+ String newFullName = getUUIDString() + "g.h@t.com";
+ userMod.getPlainAttrsToUpdate().add(attrMod("fullname", newFullName));
+
+ userMod.getDerAttrsToAdd().add("cn");
+ userMod.getMembershipsToAdd().add(membershipMod);
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // issue SYNCOPE-15
+ assertNotNull(userTO.getCreationDate());
+ assertNotNull(userTO.getCreator());
+ assertNotNull(userTO.getLastChangeDate());
+ assertNotNull(userTO.getLastModifier());
+ assertTrue(userTO.getCreationDate().before(userTO.getLastChangeDate()));
+
+ assertEquals(1, userTO.getMemberships().size());
+ assertEquals(1, userTO.getMemberships().iterator().next().getPlainAttrs().size());
+ assertFalse(userTO.getDerAttrs().isEmpty());
+
+ AttrTO userIdAttr = userTO.getPlainAttrMap().get("userId");
+ assertEquals(Collections.singletonList(newUserId), userIdAttr.getValues());
+
+ AttrTO fullNameAttr = userTO.getPlainAttrMap().get("fullname");
+ assertEquals(Collections.singletonList(newFullName), fullNameAttr.getValues());
+ }
+
+ @Test
+ public void updatePasswordOnly() {
+ int beforeTasks = taskService.list(TaskType.PROPAGATION, 1, 1).getTotalCount();
+ assertFalse(beforeTasks <= 0);
+
+ UserTO userTO = getUniqueSampleTO("pwdonly@t.com");
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ membershipTO.getPlainAttrs().add(attrTO("subscriptionDate", "2009-08-18T16:33:12.203+0200"));
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword123");
+
+ userTO = updateUser(userMod);
+
+ // check for changePwdDate
+ assertNotNull(userTO.getChangePwdDate());
+
+ int afterTasks = taskService.list(TaskType.PROPAGATION, 1, 1).getTotalCount();
+ assertFalse(beforeTasks <= 0);
+
+ assertTrue(beforeTasks < afterTasks);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Test
+ public void verifyTaskRegistration() {
+ // get task list
+ PagedResult<PropagationTaskTO> tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long maxKey = tasks.getResult().iterator().next().getKey();
+
+ // --------------------------------------
+ // Create operation
+ // --------------------------------------
+ UserTO userTO = getUniqueSampleTO("t@p.mode");
+
+ // add a membership
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(8L);
+ userTO.getMemberships().add(membershipTO);
+
+ // 1. create user
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // get the new task list
+ tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+ assertNotNull(tasks);
+ assertFalse(tasks.getResult().isEmpty());
+
+ long newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // only failed executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+
+ // --------------------------------------
+ // Update operation
+ // --------------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ userMod.getPlainAttrsToUpdate().add(attrMod("surname", "surname"));
+
+ userTO = updateUser(userMod);
+
+ assertNotNull(userTO);
+
+ // get the new task list
+ tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+
+ maxKey = newMaxKey;
+ newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2:
+ // all update executions have to be registered
+ assertTrue(newMaxKey > maxKey);
+
+ final PropagationTaskTO taskTO = taskService.read(newMaxKey);
+
+ assertNotNull(taskTO);
+ assertEquals(1, taskTO.getExecutions().size());
+
+ // --------------------------------------
+ // Delete operation
+ // --------------------------------------
+ userService.delete(userTO.getKey());
+
+ // get the new task list
+ tasks = taskService.list(TaskType.PROPAGATION, 1, 1);
+
+ maxKey = newMaxKey;
+ newMaxKey = tasks.getResult().iterator().next().getKey();
+
+ // default configuration for ws-target-resource2: no delete executions have to be registered
+ // --> no more tasks/executions should be added
+ assertEquals(newMaxKey, maxKey);
+ }
+
+ @Test
+ public void createActivate() {
+ Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers());
+
+ UserTO userTO = getUniqueSampleTO("createActivate@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(11L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+ assertNotNull(userTO.getToken());
+ assertNotNull(userTO.getTokenExpireTime());
+
+ assertEquals("created", userTO.getStatus());
+
+ StatusMod statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.ACTIVATE);
+ statusMod.setToken(userTO.getToken());
+ userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+
+ assertNotNull(userTO);
+ assertNull(userTO.getToken());
+ assertNull(userTO.getTokenExpireTime());
+ assertEquals("active", userTO.getStatus());
+ }
+
+ @Test
+ public void suspendReactivate() {
+ UserTO userTO = getUniqueSampleTO("suspendReactivate@syncope.apache.org");
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(7L);
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+
+ assertNotNull(userTO);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers()
+ ? "active"
+ : "created", userTO.getStatus());
+
+ StatusMod statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(userTO.getKey(), statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+ }
+
+ @Test
+ public void suspendReactivateOnResource() {
+ // Assert resources are present
+ ResourceTO dbTable = resourceService.read(RESOURCE_NAME_TESTDB);
+ assertNotNull(dbTable);
+ ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ assertNotNull(ldap);
+
+ // Create user with reference to resources
+ UserTO userTO = getUniqueSampleTO("suspreactonresource@syncope.apache.org");
+ userTO.getMemberships().clear();
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(ActivitiDetector.isActivitiEnabledForUsers()
+ ? "active"
+ : "created", userTO.getStatus());
+ long userId = userTO.getKey();
+
+ // Suspend with effect on syncope, ldap and db => user should be suspended in syncope and all resources
+ StatusMod statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ statusMod.setOnSyncope(true);
+ statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
+ statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
+ userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ ConnObjectTO connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+ assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userId);
+ assertNotNull(connObjectTO);
+
+ // Suspend and reactivate only on ldap => db and syncope should still show suspended
+ statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.SUSPEND);
+ statusMod.setOnSyncope(false);
+ statusMod.getResourceNames().add(RESOURCE_NAME_LDAP);
+ userService.status(userId, statusMod);
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("suspended", userTO.getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+ assertFalse(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+
+ // Reactivate on syncope and db => syncope and db should show the user as active
+ statusMod = new StatusMod();
+ statusMod.setType(StatusMod.ModType.REACTIVATE);
+ statusMod.setOnSyncope(true);
+ statusMod.getResourceNames().add(RESOURCE_NAME_TESTDB);
+
+ userTO = userService.status(userId, statusMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertEquals("active", userTO.getStatus());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userId);
+ assertTrue(getBooleanAttribute(connObjectTO, OperationalAttributes.ENABLE_NAME));
+ }
+
+ public void updateMultivalueAttribute() {
+ UserTO userTO = getSampleTO("multivalue@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ AttrTO loginDate = userTO.getPlainAttrMap().get("loginDate");
+ assertNotNull(loginDate);
+ assertEquals(1, loginDate.getValues().size());
+
+ UserMod userMod = new UserMod();
+
+ AttrMod loginDateMod = new AttrMod();
+ loginDateMod.getValuesToBeAdded().add("2000-01-01");
+
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToUpdate().add(loginDateMod);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ loginDate = userTO.getPlainAttrMap().get("loginDate");
+ assertNotNull(loginDate);
+ assertEquals(2, loginDate.getValues().size());
+ }
+
+ @Test(expected = EmptyResultDataAccessException.class)
+ public void issue213() {
+ UserTO userTO = getUniqueSampleTO("issue213@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getResources().size());
+
+ JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+
+ String username = jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class,
+ userTO.getUsername());
+
+ assertEquals(userTO.getUsername(), username);
+
+ UserMod userMod = new UserMod();
+
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToRemove().add(RESOURCE_NAME_TESTDB);
+
+ userTO = updateUser(userMod);
+ assertTrue(userTO.getResources().isEmpty());
+
+ jdbcTemplate.queryForObject("SELECT id FROM test WHERE id=?", String.class, userTO.getUsername());
+ }
+
+ @Test
+ public void issue234() {
+ UserTO inUserTO = getUniqueSampleTO("issue234@syncope.apache.org");
+ inUserTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ UserTO userTO = createUser(inUserTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+
+ userMod.setKey(userTO.getKey());
+ userMod.setUsername("1" + userTO.getUsername());
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ assertEquals("1" + inUserTO.getUsername(), userTO.getUsername());
+ }
+
+ @Test
+ public void issue270() {
+ // 1. create a new user without virtual attributes
+ UserTO original = getUniqueSampleTO("issue270@syncope.apache.org");
+ // be sure to remove all virtual attributes
+ original.getVirAttrs().clear();
+
+ original = createUser(original);
+
+ assertNotNull(original);
+
+ assertTrue(original.getVirAttrs().isEmpty());
+
+ UserTO toBeUpdated = userService.read(original.getKey());
+
+ AttrTO virtual = attrTO("virtualdata", "virtualvalue");
+ toBeUpdated.getVirAttrs().add(virtual);
+
+ // 2. try to update by adding a resource, but no password: must fail
+ UserMod userMod = AttributableOperations.diff(toBeUpdated, original);
+ assertNotNull(userMod);
+
+ toBeUpdated = updateUser(userMod);
+ assertNotNull(toBeUpdated);
+
+ assertFalse(toBeUpdated.getVirAttrs().isEmpty());
+ assertNotNull(toBeUpdated.getVirAttrs().get(0));
+
+ assertEquals(virtual.getSchema(), toBeUpdated.getVirAttrs().get(0).getSchema());
+ }
+
+ @Test
+ public final void issue280() {
+ UserTO userTO = getUniqueSampleTO("issue280@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("123password");
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ final List<PropagationStatus> propagations = userTO.getPropagationStatusTOs();
+
+ assertNotNull(propagations);
+ assertEquals(1, propagations.size());
+
+ final PropagationTaskExecStatus status = propagations.get(0).getStatus();
+ final String resource = propagations.get(0).getResource();
+
+ assertNotNull(status);
+ assertEquals(RESOURCE_NAME_TESTDB, resource);
+ assertTrue(status.isSuccessful());
+ }
+
+ @Test
+ public void issue281() {
+ UserTO userTO = getUniqueSampleTO("issue281@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ final List<PropagationStatus> propagations = userTO.getPropagationStatusTOs();
+
+ assertNotNull(propagations);
+ assertEquals(1, propagations.size());
+
+ final PropagationTaskExecStatus status = propagations.get(0).getStatus();
+ final String resource = propagations.get(0).getResource();
+
+ assertNotNull(status);
+ assertEquals(RESOURCE_NAME_CSV, resource);
+ assertFalse(status.isSuccessful());
+ }
+
+ @Test
+ public void issue288() {
+ UserTO userTO = getSampleTO("issue288@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("aLong", "STRING"));
+
+ try {
+ createUser(userTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidValues, e.getType());
+ }
+ }
+
+ @Test
+ public void roleAttrPropagation() {
+ UserTO userTO = getUniqueSampleTO("checkRoleAttrPropagation@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(1L);
+
+ userTO.getMemberships().add(membershipTO);
+
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(actual.getDerAttrMap().get("csvuserid"));
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("ROLE").getValues().get(0));
+ }
+
+ @Test
+ public void membershipAttrPropagation() {
+ UserTO userTO = getUniqueSampleTO("checkMembAttrPropagation@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(1L);
+ membershipTO.getPlainAttrs().add(attrTO("mderived_sx", "sx"));
+ membershipTO.getPlainAttrs().add(attrTO("mderived_dx", "dx"));
+ membershipTO.getDerAttrs().add(attrTO("mderToBePropagated", null));
+ userTO.getMemberships().add(membershipTO);
+
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(actual.getDerAttrMap().get("csvuserid"));
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("sx-dx", connObjectTO.getPlainAttrMap().get("MEMBERSHIP").getValues().get(0));
+ }
+
+ @Test
+ public void noContent() throws IOException {
+ SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+ UserService noContentService = noContentclient.prefer(UserService.class, Preference.RETURN_NO_CONTENT);
+
+ UserTO user = getUniqueSampleTO("nocontent@syncope.apache.org");
+
+ Response response = noContentService.create(user, true);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ user = getObject(response.getLocation(), UserService.class, UserTO.class);
+ assertNotNull(user);
+
+ UserMod userMod = new UserMod();
+ userMod.setPassword("password321");
+
+ response = noContentService.update(user.getKey(), userMod);
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ response = noContentService.delete(user.getKey());
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+ }
+
+ @Test
+ public void issueSYNCOPE108() {
+ UserTO userTO = getUniqueSampleTO("syncope108@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO memb12 = new MembershipTO();
+ memb12.setRoleId(12L);
+
+ userTO.getMemberships().add(memb12);
+
+ MembershipTO memb13 = new MembershipTO();
+ memb13.setRoleId(13L);
+
+ userTO.getMemberships().add(memb13);
+
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertEquals(2, actual.getMemberships().size());
+ assertEquals(1, actual.getResources().size());
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+
+ // -----------------------------------
+ // Remove the first membership: de-provisioning shouldn't happen
+ // -----------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getKey());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertEquals(1, actual.getMemberships().size());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+ // -----------------------------------
+
+ // -----------------------------------
+ // Remove the resource assigned directly: de-provisioning shouldn't happen
+ // -----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getResourcesToRemove().add(actual.getResources().iterator().next());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertEquals(1, actual.getMemberships().size());
+ assertFalse(actual.getResources().isEmpty());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+ // -----------------------------------
+
+ // -----------------------------------
+ // Remove the first membership: de-provisioning should happen
+ // -----------------------------------
+ userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ userMod.getMembershipsToRemove().add(actual.getMemberships().get(0).getKey());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertTrue(actual.getMemberships().isEmpty());
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail("Read should not succeeed");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE111() {
+ UserTO userTO = getUniqueSampleTO("syncope111@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ MembershipTO memb12 = new MembershipTO();
+ memb12.setRoleId(12L);
+ memb12.getPlainAttrs().add(attrTO("postalAddress", "postalAddress"));
+ userTO.getMemberships().add(memb12);
+
+ MembershipTO memb13 = new MembershipTO();
+ memb13.setRoleId(13L);
+ userTO.getMemberships().add(memb13);
+
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertEquals(2, actual.getMemberships().size());
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+
+ AttrTO postalAddress = connObjectTO.getPlainAttrMap().get("postalAddress");
+ assertNotNull(postalAddress);
+ assertEquals(1, postalAddress.getValues().size());
+ assertEquals("postalAddress", postalAddress.getValues().get(0));
+
+ AttrTO title = connObjectTO.getPlainAttrMap().get("title");
+ assertNotNull(title);
+ assertEquals(2, title.getValues().size());
+ assertTrue(title.getValues().contains("r12") && title.getValues().contains("r13"));
+
+ // -----------------------------------
+ // Remove the first membership and check for membership attr propagation and role attr propagation
+ // -----------------------------------
+ UserMod userMod = new UserMod();
+ userMod.setKey(actual.getKey());
+
+ MembershipTO membershipTO = actual.getMemberships().get(0).getRoleId() == 12L
+ ? actual.getMemberships().get(0)
+ : actual.getMemberships().get(1);
+
+ userMod.getMembershipsToRemove().add(membershipTO.getKey());
+
+ actual = updateUser(userMod);
+ assertNotNull(actual);
+ assertEquals(1, actual.getMemberships().size());
+
+ connObjectTO = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, actual.getKey());
+ assertNotNull(connObjectTO);
+
+ postalAddress = connObjectTO.getPlainAttrMap().get("postalAddress");
+ assertTrue(postalAddress == null || postalAddress.getValues().isEmpty()
+ || StringUtils.isNotBlank(postalAddress.getValues().get(0)));
+
+ title = connObjectTO.getPlainAttrMap().get("title");
+ assertNotNull(title);
+ assertEquals(1, title.getValues().size());
+ assertTrue(title.getValues().contains("r13"));
+ // -----------------------------------
+ }
+
+ @Test
+ public void issueSYNCOPE185() {
+ // 1. create user with LDAP resource, succesfully propagated
+ UserTO userTO = getSampleTO("syncope185@syncope.apache.org");
+ userTO.getVirAttrs().clear();
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_LDAP, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUCCESS, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ // 2. delete this user
+ userService.delete(userTO.getKey());
+
+ // 3. try (and fail) to find this user on the external LDAP resource
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+ fail("This entry should not be present on this resource");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test()
+ public void issueSYNCOPE51() {
+ AttrTO defaultCA = configurationService.read("password.cipher.algorithm");
+ final String originalCAValue = defaultCA.getValues().get(0);
+ defaultCA.getValues().set(0, "MD5");
+ configurationService.set(defaultCA.getSchema(), defaultCA);
+
+ AttrTO newCA = configurationService.read(defaultCA.getSchema());
+ assertEquals(defaultCA, newCA);
+
+ UserTO userTO = getSampleTO("syncope51@syncope.apache.org");
+ userTO.setPassword("password");
+
+ try {
+ createUser(userTO);
+ fail("Create user should not succeed");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ assertTrue(e.getElements().iterator().next().contains("MD5"));
+ }
+
+ defaultCA.getValues().set(0, originalCAValue);
+ configurationService.set(defaultCA.getSchema(), defaultCA);
+
+ AttrTO oldCA = configurationService.read(defaultCA.getSchema());
+ assertEquals(defaultCA, oldCA);
+ }
+
+ @Test
+ public void issueSYNCOPE267() {
+ // ----------------------------------
+ // create user and check virtual attribute value propagation
+ // ----------------------------------
+ UserTO userTO = getUniqueSampleTO("syncope267@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_DBVIRATTR);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertFalse(userTO.getPropagationStatusTOs().isEmpty());
+ assertEquals(RESOURCE_NAME_DBVIRATTR, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_DBVIRATTR, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObjectTO);
+ assertEquals("virtualvalue", connObjectTO.getPlainAttrMap().get("USERNAME").getValues().get(0));
+ // ----------------------------------
+
+ userTO = userService.read(userTO.getKey());
+
+ assertNotNull(userTO);
+ assertEquals(1, userTO.getVirAttrs().size());
+ assertEquals("virtualvalue", userTO.getVirAttrs().get(0).getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE266() {
+ UserTO userTO = getUniqueSampleTO("syncope266@apache.org");
+ userTO.getResources().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+
+ // this resource has not a mapping for Password
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_UPDATE);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE279() {
+ UserTO userTO = getUniqueSampleTO("syncope279@apache.org");
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_TIMEOUT);
+ userTO = createUser(userTO);
+ assertEquals(RESOURCE_NAME_TIMEOUT, userTO.getPropagationStatusTOs().get(0).getResource());
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+ assertEquals(PropagationTaskExecStatus.UNSUBMITTED, userTO.getPropagationStatusTOs().get(0).getStatus());
+ }
+
+ @Test
+ public void issueSYNCOPE122() {
+ // 1. create user on testdb and testdb2
+ UserTO userTO = getUniqueSampleTO("syncope122@apache.org");
+ userTO.getResources().clear();
+
+ userTO.getResources().add(RESOURCE_NAME_TESTDB);
+ userTO.getResources().add(RESOURCE_NAME_TESTDB2);
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB));
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_TESTDB2));
+
+ final String pwdOnSyncope = userTO.getPassword();
+
+ ConnObjectTO userOnDb = resourceService.getConnectorObject(
+ RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+ final AttrTO pwdOnTestDbAttr = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDbAttr);
+ assertNotNull(pwdOnTestDbAttr.getValues());
+ assertFalse(pwdOnTestDbAttr.getValues().isEmpty());
+ final String pwdOnTestDb = pwdOnTestDbAttr.getValues().iterator().next();
+
+ ConnObjectTO userOnDb2 = resourceService.getConnectorObject(
+ RESOURCE_NAME_TESTDB2, SubjectType.USER, userTO.getKey());
+ final AttrTO pwdOnTestDb2Attr = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDb2Attr);
+ assertNotNull(pwdOnTestDb2Attr.getValues());
+ assertFalse(pwdOnTestDb2Attr.getValues().isEmpty());
+ final String pwdOnTestDb2 = pwdOnTestDb2Attr.getValues().iterator().next();
+
+ // 2. request to change password only on testdb (no Syncope, no testdb2)
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword(getUUIDString());
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.setOnSyncope(false);
+ pwdPropRequest.getResourceNames().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(pwdPropRequest);
+
+ userTO = updateUser(userMod);
+
+ // 3a. Chech that only a single propagation took place
+ assertNotNull(userTO.getPropagationStatusTOs());
+ assertEquals(1, userTO.getPropagationStatusTOs().size());
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getPropagationStatusTOs().iterator().next().getResource());
+
+ // 3b. verify that password hasn't changed on Syncope
+ assertEquals(pwdOnSyncope, userTO.getPassword());
+
+ // 3c. verify that password *has* changed on testdb
+ userOnDb = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB, SubjectType.USER, userTO.getKey());
+ final AttrTO pwdOnTestDbAttrAfter = userOnDb.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDbAttrAfter);
+ assertNotNull(pwdOnTestDbAttrAfter.getValues());
+ assertFalse(pwdOnTestDbAttrAfter.getValues().isEmpty());
+ assertNotEquals(pwdOnTestDb, pwdOnTestDbAttrAfter.getValues().iterator().next());
+
+ // 3d. verify that password hasn't changed on testdb2
+ userOnDb2 = resourceService.getConnectorObject(RESOURCE_NAME_TESTDB2, SubjectType.USER, userTO.getKey());
+ final AttrTO pwdOnTestDb2AttrAfter = userOnDb2.getPlainAttrMap().get(OperationalAttributes.PASSWORD_NAME);
+ assertNotNull(pwdOnTestDb2AttrAfter);
+ assertNotNull(pwdOnTestDb2AttrAfter.getValues());
+ assertFalse(pwdOnTestDb2AttrAfter.getValues().isEmpty());
+ assertEquals(pwdOnTestDb2, pwdOnTestDb2AttrAfter.getValues().iterator().next());
+ }
+
+ @Test
+ public void isseSYNCOPE136AES() {
+ // 1. read configured cipher algorithm in order to be able to restore it at the end of test
+ AttrTO pwdCipherAlgo = configurationService.read("password.cipher.algorithm");
+ final String origpwdCipherAlgo = pwdCipherAlgo.getValues().get(0);
+
+ // 2. set AES password cipher algorithm
+ pwdCipherAlgo.getValues().set(0, "AES");
+ configurationService.set(pwdCipherAlgo.getSchema(), pwdCipherAlgo);
+
+ // 3. create user with no resources
+ UserTO userTO = getUniqueSampleTO("syncope136_AES@apache.org");
+ userTO.getResources().clear();
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 4. update user, assign a propagation primary resource but don't provide any password
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // 5. verify that propagation was successful
+ List<PropagationStatus> props = userTO.getPropagationStatusTOs();
+ assertNotNull(props);
+ assertEquals(1, props.size());
+ PropagationStatus prop = props.iterator().next();
+ assertNotNull(prop);
+ assertEquals(RESOURCE_NAME_WS1, prop.getResource());
+ assertEquals(PropagationTaskExecStatus.SUBMITTED, prop.getStatus());
+
+ // 6. restore initial cipher algorithm
+ pwdCipherAlgo.getValues().set(0, origpwdCipherAlgo);
+ configurationService.set(pwdCipherAlgo.getSchema(), pwdCipherAlgo);
+ }
+
+ @Test
+ public void isseSYNCOPE136Random() {
+ // 1. create user with no resources
+ UserTO userTO = getUniqueSampleTO("syncope136_Random@apache.org");
+ userTO.getResources().clear();
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 2. update user, assign a propagation primary resource but don't provide any password
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_LDAP);
+ userTO = updateUser(userMod);
+ assertNotNull(userTO);
+
+ // 3. verify that propagation was successful
+ List<PropagationStatus> props = userTO.getPropagationStatusTOs();
+ assertNotNull(props);
+ assertEquals(1, props.size());
+ PropagationStatus prop = props.iterator().next();
+ assertNotNull(prop);
+ assertEquals(RESOURCE_NAME_LDAP, prop.getResource());
+ assertEquals(PropagationTaskExecStatus.SUCCESS, prop.getStatus());
+ }
+
+ @Test
+ public void mappingPurpose() {
+ UserTO userTO = getUniqueSampleTO("mpurpose@apache.org");
+
+ AttrTO csvuserid = new AttrTO();
+ csvuserid.setSchema("csvuserid");
+ userTO.getDerAttrs().add(csvuserid);
+
+ userTO.getResources().clear();
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ assertNull(connObjectTO.getPlainAttrMap().get("email"));
+ }
+
+ @Test
+ public void issueSYNCOPE265() {
+ for (long i = 1; i <= 5; i++) {
+ UserMod userMod = new UserMod();
+ userMod.setKey(i);
+
+ AttrMod attributeMod = new AttrMod();
+ attributeMod.setSchema("type");
+ attributeMod.getValuesToBeAdded().add("a type");
+
+ userMod.getPlainAttrsToRemove().add("type");
+ userMod.getPlainAttrsToUpdate().add(attributeMod);
+
+ UserTO userTO = updateUser(userMod);
+ assertEquals("a type", userTO.getPlainAttrMap().get("type").getValues().get(0));
+ }
+ }
+
+ @Test
+ public void bulkActions() {
+ final BulkAction bulkAction = new BulkAction();
+
+ for (int i = 0; i < 10; i++) {
+ UserTO userTO = getUniqueSampleTO("bulk_" + i + "@apache.org");
+ bulkAction.getTargets().add(String.valueOf(createUser(userTO).getKey()));
+ }
+
+ // check for a fail
+ bulkAction.getTargets().add(String.valueOf(Long.MAX_VALUE));
+
+ assertEquals(11, bulkAction.getTargets().size());
+
+ bulkAction.setOperation(BulkAction.Type.SUSPEND);
+ BulkActionResult res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ assertEquals("suspended", userService.read(
+ Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3).toString())).getStatus());
+
+ bulkAction.setOperation(BulkAction.Type.REACTIVATE);
+ res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ assertEquals("active", userService.read(
+ Long.parseLong(res.getResultByStatus(Status.SUCCESS).get(3).toString())).getStatus());
+
+ bulkAction.setOperation(BulkAction.Type.DELETE);
+ res = userService.bulk(bulkAction);
+ assertEquals(10, res.getResultByStatus(Status.SUCCESS).size());
+ assertEquals(1, res.getResultByStatus(Status.FAILURE).size());
+ }
+
+ @Test
+ public void issueSYNCOPE354() {
+ // change resource-ldap role mapping for including uniqueMember (need for assertions below)
+ ResourceTO ldap = resourceService.read(RESOURCE_NAME_LDAP);
+ for (MappingItemTO item : ldap.getRmapping().getItems()) {
+ if ("description".equals(item.getExtAttrName())) {
+ item.setExtAttrName("uniqueMember");
+ }
+ }
+ resourceService.update(ldap.getKey(), ldap);
+
+ // 1. create role with LDAP resource
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("SYNCOPE354-" + getUUIDString());
+ roleTO.setParent(8L);
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ // 2. create user with LDAP resource and membership of the above role
+ UserTO userTO = getUniqueSampleTO("syncope354@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(roleTO.getKey());
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+ // 3. read role on resource, check that user DN is included in uniqueMember
+ ConnObjectTO connObj = resourceService.getConnectorObject(
+ RESOURCE_NAME_LDAP, SubjectType.ROLE, roleTO.getKey());
+ assertNotNull(connObj);
+ assertTrue(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+ contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+ // 4. remove membership
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getMembershipsToRemove().add(userTO.getMemberships().iterator().next().getKey());
+
+ userTO = updateUser(userMod);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+ // 5. read role on resource, check that user DN was removed from uniqueMember
+ connObj = resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, roleTO.getKey());
+ assertNotNull(connObj);
+ assertFalse(connObj.getPlainAttrMap().get("uniqueMember").getValues().
+ contains("uid=" + userTO.getUsername() + ",ou=people,o=isp"));
+
+ // 6. restore original resource-ldap role mapping
+ for (MappingItemTO item : ldap.getRmapping().getItems()) {
+ if ("uniqueMember".equals(item.getExtAttrName())) {
+ item.setExtAttrName("description");
+ }
+ }
+ resourceService.update(ldap.getKey(), ldap);
+ }
+
+ @Test
+ public void issueSYNCOPE357() throws IOException {
+ // 1. create role with LDAP resource
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("SYNCOPE357-" + getUUIDString());
+ roleTO.setParent(8L);
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ // 2. create user with membership of the above role
+ UserTO userTO = getUniqueSampleTO("syncope357@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("obscure", "valueToBeObscured"));
+ userTO.getPlainAttrs().add(attrTO("photo",
+ Base64Utility.encode(IOUtils.readBytesFromStream(getClass().getResourceAsStream("/favicon.jpg")))));
+ MembershipTO membershipTO = new MembershipTO();
+ membershipTO.setRoleId(roleTO.getKey());
+ userTO.getMemberships().add(membershipTO);
+
+ userTO = createUser(userTO);
+ assertTrue(userTO.getResources().contains(RESOURCE_NAME_LDAP));
+ assertNotNull(userTO.getPlainAttrMap().get("obscure"));
+ assertNotNull(userTO.getPlainAttrMap().get("photo"));
+
+ // 3. read user on resource
+ ConnObjectTO connObj = resourceService.getConnectorObject(
+ RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+ assertNotNull(connObj);
+ AttrTO registeredAddress = connObj.getPlainAttrMap().get("registeredAddress");
+ assertNotNull(registeredAddress);
+ assertEquals(userTO.getPlainAttrMap().get("obscure").getValues(), registeredAddress.getValues());
+ AttrTO jpegPhoto = connObj.getPlainAttrMap().get("jpegPhoto");
+ assertNotNull(jpegPhoto);
+ assertEquals(userTO.getPlainAttrMap().get("photo").getValues(), jpegPhoto.getValues());
+
+ // 4. remove role
+ roleService.delete(roleTO.getKey());
+
+ // 5. try to read user on resource: fail
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.NotFound, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE383() {
+ // 1. create user without resources
+ UserTO userTO = getUniqueSampleTO("syncope383@apache.org");
+ userTO.getResources().clear();
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 2. assign resource without specifying a new pwd and check propagation failure
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+ userTO = updateUser(userMod);
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+ assertFalse(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ assertNotNull(userTO.getPropagationStatusTOs().get(0).getFailureReason());
+
+ // 3. request to change password only on testdb
+ userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword(getUUIDString());
+ StatusMod pwdPropRequest = new StatusMod();
+ pwdPropRequest.getResourceNames().add(RESOURCE_NAME_TESTDB);
+ userMod.setPwdPropRequest(pwdPropRequest);
+
+ userTO = updateUser(userMod);
+ assertEquals(RESOURCE_NAME_TESTDB, userTO.getResources().iterator().next());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ }
+
+ @Test
+ public void issueSYNCOPE402() {
+ // 1. create an user with strict mandatory attributes only
+ UserTO userTO = new UserTO();
+ String userId = getUUIDString() + "syncope402@syncope.apache.org";
+ userTO.setUsername(userId);
+ userTO.setPassword("password");
+
+ userTO.getPlainAttrs().add(attrTO("userId", userId));
+ userTO.getPlainAttrs().add(attrTO("fullname", userId));
+ userTO.getPlainAttrs().add(attrTO("surname", userId));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+ assertTrue(userTO.getResources().isEmpty());
+
+ //2. update assigning a resource NOT forcing mandatory constraints
+ // AND primary: must fail with PropagationException
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPassword("newPassword");
+
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_TESTDB);
+ userTO = updateUser(userMod);
+
+ List<PropagationStatus> propagationStatuses = userTO.getPropagationStatusTOs();
+ PropagationStatus ws1PropagationStatus = null;
+ if (propagationStatuses != null) {
+ for (PropagationStatus propStatus : propagationStatuses) {
+ if (RESOURCE_NAME_WS1.equals(propStatus.getResource())) {
+ ws1PropagationStatus = propStatus;
+ break;
+ }
+ }
+ }
+ assertNotNull(ws1PropagationStatus);
+ assertEquals(RESOURCE_NAME_WS1, ws1PropagationStatus.getResource());
+ assertNotNull(ws1PropagationStatus.getFailureReason());
+ assertEquals(PropagationTaskExecStatus.UNSUBMITTED, ws1PropagationStatus.getStatus());
+ }
+
+ @Test
+ public void unlink() {
+ UserTO userTO = getUniqueSampleTO("unlink@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+
+ assertNotNull(userService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+ }
+
+ @Test
+ public void link() {
+ UserTO userTO = getUniqueSampleTO("link@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+
+ assertNotNull(userService.bulkAssociation(
+ actual.getKey(), ResourceAssociationActionType.LINK, associationMod).readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void unassign() {
+ UserTO userTO = getUniqueSampleTO("unassign@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+
+ assertNotNull(userService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void assign() {
+ UserTO userTO = getUniqueSampleTO("assign@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.ASSIGN, associationMod)
+ .readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+ }
+
+ @Test
+ public void deprovision() {
+ UserTO userTO = getUniqueSampleTO("deprovision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+ userTO.getResources().add(RESOURCE_NAME_CSV);
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+
+ assertNotNull(userService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void provision() {
+ UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
+ associationMod)
+ .readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+ }
+
+ @Test
+ public void deprovisionUnlinked() {
+ UserTO userTO = getUniqueSampleTO("provision@syncope.apache.org");
+ userTO.getResources().clear();
+ userTO.getMemberships().clear();
+ userTO.getDerAttrs().clear();
+ userTO.getVirAttrs().clear();
+ userTO.getDerAttrs().add(attrTO("csvuserid", null));
+
+ UserTO actual = createUser(userTO);
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ final ResourceAssociationMod associationMod = new ResourceAssociationMod();
+ associationMod.getTargetResources().addAll(CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class));
+ associationMod.setChangePwd(true);
+ associationMod.setPassword("password");
+
+ assertNotNull(userService.bulkAssociation(actual.getKey(), ResourceAssociationActionType.PROVISION,
+ associationMod)
+ .readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey()));
+
+ assertNotNull(userService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_CSV, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = userService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_CSV, SubjectType.USER, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE420() {
+ UserTO userTO = getUniqueSampleTO("syncope420@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO("makeItDouble", "3"));
+
+ userTO = createUser(userTO);
+ assertEquals("6", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.getPlainAttrsToRemove().add("makeItDouble");
+ userMod.getPlainAttrsToUpdate().add(attrMod("makeItDouble", "7"));
+
+ userTO = updateUser(userMod);
+ assertEquals("14", userTO.getPlainAttrMap().get("makeItDouble").getValues().get(0));
+ }
+
+ @Test
+ public void issueSYNCOPE426() {
+ UserTO userTO = getUniqueSampleTO("syncope426@syncope.apache.org");
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserMod userMod = new UserMod();
+ userMod.setPassword("anotherPassword123");
+ userTO = userService.update(userTO.getKey(), userMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issueSYNCOPE435() {
+ // 1. create user without password
+ UserTO userTO = getUniqueSampleTO("syncope435@syncope.apache.org");
+ userTO.setPassword(null);
+ userTO = createUser(userTO, false);
+ assertNotNull(userTO);
+
+ // 2. try to update user by subscribing a resource - works but propagation is not even attempted
+ UserMod userMod = new UserMod();
+ userMod.getResourcesToAdd().add(RESOURCE_NAME_WS1);
+
+ userTO = userService.update(userTO.getKey(), userMod).readEntity(UserTO.class);
+ assertEquals(Collections.singleton(RESOURCE_NAME_WS1), userTO.getResources());
+ assertFalse(userTO.getPropagationStatusTOs().get(0).getStatus().isSuccessful());
+ assertTrue(userTO.getPropagationStatusTOs().get(0).getFailureReason().
+ startsWith("Not attempted because there are mandatory attributes without value(s): [__PASSWORD__]"));
+ }
+
+ @Test
+ public void ifMatch() {
+ UserTO userTO = userService.create(getUniqueSampleTO("ifmatch@syncope.apache.org"), true).
+ readEntity(UserTO.class);
+ assertNotNull(userTO);
+ assertNotNull(userTO.getKey());
+
+ EntityTag etag = adminClient.getLatestEntityTag(userService);
+ assertNotNull(etag);
+ assertTrue(StringUtils.isNotBlank(etag.getValue()));
+
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setUsername(userTO.getUsername() + "XX");
+ userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+ assertTrue(userTO.getUsername().endsWith("XX"));
+ EntityTag etag1 = adminClient.getLatestEntityTag(userService);
+ assertFalse(etag.getValue().equals(etag1.getValue()));
+
+ UserService ifMatchService = adminClient.ifMatch(UserService.class, etag);
+ userMod.setUsername(userTO.getUsername() + "YY");
+ try {
+ ifMatchService.update(userMod.getKey(), userMod);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.ConcurrentModification, e.getType());
+ }
+
+ userTO = userService.read(userTO.getKey());
+ assertTrue(userTO.getUsername().endsWith("XX"));
+ }
+
+ @Test
+ public void issueSYNCOPE454() throws NamingException {
+ // 1. create user with LDAP resource (with 'Generate password if missing' enabled)
+ UserTO userTO = getUniqueSampleTO("syncope454@syncope.apache.org");
+ userTO.getResources().add(RESOURCE_NAME_LDAP);
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ // 2. read resource configuration for LDAP binding
+ ConnObjectTO connObject =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.USER, userTO.getKey());
+
+ // 3. try (and succeed) to perform simple LDAP binding with provided password ('password123')
+ assertNotNull(getLdapRemoteObject(
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+ "password123",
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+ // 4. update user without any password change request
+ UserMod userMod = new UserMod();
+ userMod.setKey(userTO.getKey());
+ userMod.setPwdPropRequest(new StatusMod());
+ userMod.getPlainAttrsToUpdate().add(attrMod("surname", "surname2"));
+
+ userService.update(userTO.getKey(), userMod);
+
+ // 5. try (and succeed again) to perform simple LDAP binding: password has not changed
+ assertNotNull(getLdapRemoteObject(
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0),
+ "password123",
+ connObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+ }
+
+ @Test
+ public void issueSYNCOPE493() {
+ // 1. create user and check that firstname is not propagated on resource with mapping for firstname set to NONE
+ UserTO userTO = getUniqueSampleTO("issueSYNCOPE493@test.org");
+ userTO.getResources().add(RESOURCE_NAME_WS1);
+ us
<TRUNCATED>
[12/15] syncope git commit: FIT server integration tests
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
new file mode 100644
index 0000000..448d1fa
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PlainSchemaITCase.java
@@ -0,0 +1,317 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.security.AccessControlException;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.syncope.common.lib.AttributableOperations;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PlainSchemaITCase extends AbstractITCase {
+
+ private PlainSchemaTO buildPlainSchemaTO(final String name, final AttrSchemaType type) {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey(name + getUUIDString());
+ schemaTO.setType(type);
+ return schemaTO;
+ }
+
+ @Test
+ public void create() {
+ PlainSchemaTO schemaTO = buildPlainSchemaTO("testAttribute", AttrSchemaType.String);
+ schemaTO.setMandatoryCondition("false");
+
+ PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ assertEquals(schemaTO, newPlainSchemaTO);
+
+ newPlainSchemaTO = createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+ assertEquals(schemaTO, newPlainSchemaTO);
+ }
+
+ @Test
+ public void createWithNotPermittedName() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("failedLogins");
+ schemaTO.setType(AttrSchemaType.String);
+
+ try {
+ createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+ assertTrue(e.getElements().iterator().next().toString().
+ contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+
+ @Test
+ public void createREnumWithoutEnumeration() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("enumcheck");
+ schemaTO.setType(AttrSchemaType.Enum);
+
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+ assertTrue(e.getElements().iterator().next().toString().
+ contains(EntityViolationType.InvalidSchemaEnum.name()));
+ }
+ }
+
+ @Test
+ public void createUEnumWithoutEnumeration() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("enumcheck");
+ schemaTO.setType(AttrSchemaType.Enum);
+
+ try {
+ createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+ assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidSchemaEnum.name()));
+ }
+ }
+
+ @Test
+ public void createEncrypted() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("encrypted");
+ schemaTO.setType(AttrSchemaType.Encrypted);
+ schemaTO.setCipherAlgorithm(CipherAlgorithm.AES);
+ schemaTO.setSecretKey("huhadfhsjfsfsdkj!####");
+
+ createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, schemaTO);
+ }
+
+ @Test
+ public void createBinary() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("x509certificate");
+ schemaTO.setType(AttrSchemaType.Binary);
+ schemaTO.setMimeType("application/x-x509-ca-cert");
+
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, schemaTO);
+ }
+
+ @Test
+ public void delete() {
+ PlainSchemaTO schemaTO = buildPlainSchemaTO("todelete", AttrSchemaType.String);
+ schemaTO.setMandatoryCondition("false");
+ createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+
+ schemaService.delete(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+ PlainSchemaTO firstname = null;
+ try {
+ firstname = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ assertNull(firstname);
+ }
+
+ @Test
+ public void list() {
+ List<PlainSchemaTO> userSchemas = schemaService.list(AttributableType.USER, SchemaType.PLAIN);
+ assertFalse(userSchemas.isEmpty());
+ for (PlainSchemaTO schemaTO : userSchemas) {
+ assertNotNull(schemaTO);
+ }
+
+ List<PlainSchemaTO> roleSchemas = schemaService.list(AttributableType.ROLE, SchemaType.PLAIN);
+ assertFalse(roleSchemas.isEmpty());
+ for (PlainSchemaTO schemaTO : roleSchemas) {
+ assertNotNull(schemaTO);
+ }
+
+ List<PlainSchemaTO> membershipSchemas = schemaService.list(AttributableType.MEMBERSHIP, SchemaType.PLAIN);
+ assertFalse(membershipSchemas.isEmpty());
+ for (PlainSchemaTO schemaTO : membershipSchemas) {
+ assertNotNull(schemaTO);
+ }
+ }
+
+ @Test
+ public void update() {
+ PlainSchemaTO schemaTO = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+ assertNotNull(schemaTO);
+
+ schemaService.update(AttributableType.ROLE, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+ PlainSchemaTO updatedTO = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+ assertEquals(schemaTO, updatedTO);
+
+ updatedTO.setType(AttrSchemaType.Date);
+ try {
+ schemaService.update(AttributableType.ROLE, SchemaType.PLAIN, schemaTO.getKey(), updatedTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+ }
+ }
+
+ @Test
+ public void issue258() {
+ PlainSchemaTO schemaTO = new PlainSchemaTO();
+ schemaTO.setKey("schema_issue258");
+ schemaTO.setType(AttrSchemaType.Double);
+
+ schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ assertNotNull(schemaTO);
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("issue258@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ schemaTO.setType(AttrSchemaType.Long);
+ try {
+ schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+ }
+ }
+
+ @Test
+ public void issue259() {
+ PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue259", AttrSchemaType.Double);
+ schemaTO.setUniqueConstraint(true);
+
+ schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ assertNotNull(schemaTO);
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("issue259@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1"));
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ UserTO newUserTO = SerializationUtils.clone(userTO);
+ MembershipTO membership = new MembershipTO();
+ membership.setRoleId(2L);
+ newUserTO.getMemberships().add(membership);
+
+ UserMod userMod = AttributableOperations.diff(newUserTO, userTO);
+
+ userTO = userService.update(userMod.getKey(), userMod).readEntity(UserTO.class);
+ assertNotNull(userTO);
+ }
+
+ @Test
+ public void issue260() {
+ PlainSchemaTO schemaTO = buildPlainSchemaTO("schema_issue260", AttrSchemaType.Double);
+ schemaTO.setUniqueConstraint(true);
+
+ schemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+ assertNotNull(schemaTO);
+
+ UserTO userTO = UserITCase.getUniqueSampleTO("issue260@syncope.apache.org");
+ userTO.getPlainAttrs().add(attrTO(schemaTO.getKey(), "1.2"));
+ userTO = createUser(userTO);
+ assertNotNull(userTO);
+
+ schemaTO.setUniqueConstraint(false);
+ try {
+ schemaService.update(AttributableType.USER, SchemaType.PLAIN, schemaTO.getKey(), schemaTO);
+ fail("This should not be reacheable");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE323() {
+ PlainSchemaTO actual = schemaService.read(AttributableType.ROLE, SchemaType.PLAIN, "icon");
+ assertNotNull(actual);
+
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.EntityExists, e.getType());
+ }
+
+ actual.setKey(null);
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE418() {
+ PlainSchemaTO schema = buildPlainSchemaTO("http://schemas.examples.org/security/authorization/organizationUnit",
+ AttrSchemaType.Double);
+
+ try {
+ createSchema(AttributableType.ROLE, SchemaType.PLAIN, schema);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+ assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+
+ @Test
+ public void anonymous() {
+ SchemaService unauthenticated = clientFactory.createAnonymous().getService(SchemaService.class);
+ try {
+ unauthenticated.list(AttributableType.USER, SchemaType.VIRTUAL);
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ SchemaService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(SchemaService.class);
+ assertFalse(anonymous.list(AttributableType.USER, SchemaType.VIRTUAL).isEmpty());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
new file mode 100644
index 0000000..075cdd9
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/PolicyITCase.java
@@ -0,0 +1,238 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Arrays;
+import java.util.List;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.AccountPolicyTO;
+import org.apache.syncope.common.lib.to.PasswordPolicyTO;
+import org.apache.syncope.common.lib.to.SyncPolicyTO;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.common.lib.types.PolicyType;
+import org.apache.syncope.common.lib.types.SyncPolicySpec;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class PolicyITCase extends AbstractITCase {
+
+ private SyncPolicyTO buildSyncPolicyTO() {
+ SyncPolicyTO policy = new SyncPolicyTO();
+
+ SyncPolicySpec spec = new SyncPolicySpec();
+ spec.setUserJavaRule(TestSyncRule.class.getName());
+
+ policy.setSpecification(spec);
+ policy.setDescription("Sync policy");
+
+ return policy;
+ }
+
+ @Test
+ public void listByType() {
+ List<SyncPolicyTO> policyTOs = policyService.list(PolicyType.SYNC);
+
+ assertNotNull(policyTOs);
+ assertFalse(policyTOs.isEmpty());
+ }
+
+ @Test
+ public void getAccountPolicy() {
+ AccountPolicyTO policyTO = policyService.read(6L);
+
+ assertNotNull(policyTO);
+ assertTrue(policyTO.getUsedByResources().isEmpty());
+ assertEquals(Arrays.asList(6L, 7L, 10L, 14L), policyTO.getUsedByRoles());
+ }
+
+ @Test
+ public void getPasswordPolicy() {
+ PasswordPolicyTO policyTO = policyService.read(4L);
+
+ assertNotNull(policyTO);
+ assertTrue(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
+ assertEquals(Arrays.asList(6L, 7L, 10L, 8L), policyTO.getUsedByRoles());
+ }
+
+ @Test
+ public void getSyncPolicy() {
+ SyncPolicyTO policyTO = policyService.read(1L);
+
+ assertNotNull(policyTO);
+ assertTrue(policyTO.getUsedByRoles().isEmpty());
+ }
+
+ @Test
+ public void getGlobalAccountPolicy() {
+ AccountPolicyTO policyTO = policyService.readGlobal(PolicyType.ACCOUNT);
+
+ assertNotNull(policyTO);
+ assertEquals(PolicyType.GLOBAL_ACCOUNT, policyTO.getType());
+ }
+
+ @Test
+ public void getGlobalPasswordPolicy() {
+ PasswordPolicyTO policyTO = policyService.readGlobal(PolicyType.PASSWORD);
+
+ assertNotNull(policyTO);
+ assertEquals(PolicyType.GLOBAL_PASSWORD, policyTO.getType());
+ assertEquals(8, policyTO.getSpecification().getMinLength());
+ assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_NOPROPAGATION));
+ }
+
+ @Test
+ public void getGlobalSyncPolicy() {
+ SyncPolicyTO policyTO = policyService.readGlobal(PolicyType.SYNC);
+
+ assertNotNull(policyTO);
+ assertEquals(PolicyType.GLOBAL_SYNC, policyTO.getType());
+ assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_CSV));
+ assertFalse(policyTO.getUsedByResources().contains(RESOURCE_NAME_WS2));
+ assertTrue(policyTO.getUsedByRoles().isEmpty());
+ }
+
+ @Test
+ public void createWithException() {
+ PasswordPolicyTO policy = new PasswordPolicyTO(true);
+ policy.setSpecification(new PasswordPolicySpec());
+ policy.setDescription("global password policy");
+
+ try {
+ createPolicy(policy);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+ }
+ }
+
+ @Test
+ public void createMissingDescription() {
+ SyncPolicyTO policy = new SyncPolicyTO();
+ policy.setSpecification(new SyncPolicySpec());
+
+ try {
+ createPolicy(policy);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+ }
+ }
+
+ @Test
+ public void create() {
+ SyncPolicyTO policy = buildSyncPolicyTO();
+
+ SyncPolicyTO policyTO = createPolicy(policy);
+
+ assertNotNull(policyTO);
+ assertEquals(PolicyType.SYNC, policyTO.getType());
+ assertEquals(TestSyncRule.class.getName(), policyTO.getSpecification().getUserJavaRule());
+ }
+
+ @Test
+ public void update() {
+ // get global password
+ PasswordPolicyTO globalPolicy = policyService.read(2L);
+
+ PasswordPolicyTO policy = new PasswordPolicyTO();
+ policy.setDescription("A simple password policy");
+ policy.setSpecification(globalPolicy.getSpecification());
+
+ // create a new password policy using global password as a template
+ policy = createPolicy(policy);
+
+ // read new password policy
+ policy = policyService.read(policy.getKey());
+
+ assertNotNull("find to update did not work", policy);
+
+ PasswordPolicySpec policySpec = policy.getSpecification();
+ policySpec.setMaxLength(22);
+ policy.setSpecification(policySpec);
+
+ // update new password policy
+ policyService.update(policy.getKey(), policy);
+ policy = policyService.read(policy.getKey());
+
+ assertNotNull(policy);
+ assertEquals(PolicyType.PASSWORD, policy.getType());
+ assertEquals(22, policy.getSpecification().getMaxLength());
+ assertEquals(8, policy.getSpecification().getMinLength());
+ }
+
+ @Test
+ public void delete() {
+ SyncPolicyTO policy = buildSyncPolicyTO();
+
+ SyncPolicyTO policyTO = createPolicy(policy);
+ assertNotNull(policyTO);
+
+ policyService.delete(policyTO.getKey());
+
+ try {
+ policyService.read(policyTO.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void getCorrelationRules() {
+ assertEquals(1, policyService.getSyncCorrelationRuleClasses().size());
+ }
+
+ @Test
+ public void issueSYNCOPE466() {
+ PasswordPolicyTO policy = policyService.read(4L);
+ assertEquals(PolicyType.PASSWORD, policy.getType());
+
+ policy.setType(PolicyType.GLOBAL_PASSWORD);
+ try {
+ policyService.update(policy.getKey(), policy);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidPolicy, e.getType());
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE553() {
+ AccountPolicyTO policy = new AccountPolicyTO(false);
+ policy.setDescription("SYNCOPE553");
+
+ final AccountPolicySpec accountPolicySpec = new AccountPolicySpec();
+ accountPolicySpec.setMinLength(3);
+ accountPolicySpec.setMaxLength(8);
+ policy.setSpecification(accountPolicySpec);
+
+ policy = createPolicy(policy);
+ assertNotNull(policy);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
new file mode 100644
index 0000000..8102fe0
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ReportITCase.java
@@ -0,0 +1,252 @@
+/*
+ * 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.fit.server.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.report.UserReportletConf;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.ReportExecTO;
+import org.apache.syncope.common.lib.to.ReportTO;
+import org.apache.syncope.common.lib.types.ReportExecExportFormat;
+import org.apache.syncope.common.lib.types.ReportExecStatus;
+import org.apache.syncope.common.lib.wrap.ReportletConfClass;
+import org.apache.syncope.common.rest.api.service.ReportService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ReportITCase extends AbstractITCase {
+
+ private ReportTO createReport(final ReportTO report) {
+ Response response = reportService.create(report);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatusInfo().getStatusCode());
+ return getObject(response.getLocation(), ReportService.class, ReportTO.class);
+ }
+
+ @Test
+ public void getReportletClasses() {
+ List<ReportletConfClass> reportletClasses = reportService.getReportletConfClasses();
+ assertNotNull(reportletClasses);
+ assertFalse(reportletClasses.isEmpty());
+ }
+
+ @Test
+ public void list() {
+ PagedResult<ReportTO> reports = reportService.list();
+ assertNotNull(reports);
+ assertFalse(reports.getResult().isEmpty());
+ for (ReportTO report : reports.getResult()) {
+ assertNotNull(report);
+ }
+ }
+
+ @Test
+ public void read() {
+ ReportTO reportTO = reportService.read(1L);
+
+ assertNotNull(reportTO);
+ assertNotNull(reportTO.getExecutions());
+ assertFalse(reportTO.getExecutions().isEmpty());
+ }
+
+ @Test
+ public void readExecution() {
+ ReportExecTO reportExecTO = reportService.readExecution(1L);
+ assertNotNull(reportExecTO);
+ }
+
+ @Test
+ public void create() {
+ ReportTO report = new ReportTO();
+ report.setName("testReportForCreate" + getUUIDString());
+ report.getReportletConfs().add(new UserReportletConf("first"));
+ report.getReportletConfs().add(new UserReportletConf("second"));
+
+ report = createReport(report);
+ assertNotNull(report);
+
+ ReportTO actual = reportService.read(report.getKey());
+ assertNotNull(actual);
+
+ assertEquals(actual, report);
+ }
+
+ @Test
+ public void update() {
+ ReportTO report = new ReportTO();
+ report.setName("testReportForUpdate" + getUUIDString());
+
+ report.getReportletConfs().add(new UserReportletConf("first"));
+ report.getReportletConfs().add(new UserReportletConf("second"));
+
+ report = createReport(report);
+ assertNotNull(report);
+ assertEquals(2, report.getReportletConfs().size());
+
+ report.getReportletConfs().add(new UserReportletConf("last"));
+
+ reportService.update(report.getKey(), report);
+ ReportTO updated = reportService.read(report.getKey());
+ assertNotNull(updated);
+ assertEquals(3, updated.getReportletConfs().size());
+ }
+
+ @Test
+ public void delete() {
+ ReportTO report = new ReportTO();
+ report.setName("testReportForDelete" + getUUIDString());
+ report.getReportletConfs().add(new UserReportletConf("first"));
+ report.getReportletConfs().add(new UserReportletConf("second"));
+
+ report = createReport(report);
+ assertNotNull(report);
+
+ reportService.delete(report.getKey());
+
+ try {
+ reportService.read(report.getKey());
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ private void checkExport(final Long execId, final ReportExecExportFormat fmt) throws IOException {
+ final Response response = reportService.exportExecutionResult(execId, fmt);
+ assertNotNull(response);
+ assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+ assertNotNull(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION));
+ assertTrue(response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION).
+ endsWith("." + fmt.name().toLowerCase()));
+
+ Object entity = response.getEntity();
+ assertTrue(entity instanceof InputStream);
+ assertFalse(IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING).isEmpty());
+ }
+
+ @Test
+ public void executeAndExport() throws IOException {
+ ReportTO reportTO = reportService.read(1L);
+ reportTO.setKey(0);
+ reportTO.setName("executeAndExport" + getUUIDString());
+ reportTO.getExecutions().clear();
+ reportTO = createReport(reportTO);
+ assertNotNull(reportTO);
+
+ ReportExecTO execution = reportService.execute(reportTO.getKey());
+ assertNotNull(execution);
+
+ int i = 0;
+ int maxit = 50;
+
+ // wait for report execution completion (executions incremented)
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ reportTO = reportService.read(reportTO.getKey());
+
+ assertNotNull(reportTO);
+ assertNotNull(reportTO.getExecutions());
+
+ i++;
+ } while (reportTO.getExecutions().isEmpty()
+ || (!ReportExecStatus.SUCCESS.name().equals(reportTO.getExecutions().get(0).getStatus()) && i < maxit));
+ assertEquals(ReportExecStatus.SUCCESS.name(), reportTO.getExecutions().get(0).getStatus());
+
+ long execId = reportTO.getExecutions().get(0).getKey();
+
+ checkExport(execId, ReportExecExportFormat.XML);
+ checkExport(execId, ReportExecExportFormat.HTML);
+ checkExport(execId, ReportExecExportFormat.PDF);
+ checkExport(execId, ReportExecExportFormat.RTF);
+ checkExport(execId, ReportExecExportFormat.CSV);
+ }
+
+ @Test
+ public void issueSYNCOPE43() {
+ ReportTO reportTO = new ReportTO();
+ reportTO.setName("issueSYNCOPE43" + getUUIDString());
+ reportTO = createReport(reportTO);
+ assertNotNull(reportTO);
+
+ ReportExecTO execution = reportService.execute(reportTO.getKey());
+ assertNotNull(execution);
+
+ int maxit = 50;
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ reportTO = reportService.read(reportTO.getKey());
+
+ maxit--;
+ } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+
+ assertEquals(1, reportTO.getExecutions().size());
+ }
+
+ @Test
+ public void issueSYNCOPE102() throws IOException {
+ // Create
+ ReportTO reportTO = reportService.read(1L);
+ reportTO.setKey(0);
+ reportTO.setName("issueSYNCOPE102" + getUUIDString());
+ reportTO = createReport(reportTO);
+ assertNotNull(reportTO);
+
+ // Execute (multiple requests)
+ for (int i = 0; i < 10; i++) {
+ ReportExecTO execution = reportService.execute(reportTO.getKey());
+ assertNotNull(execution);
+ }
+
+ // Wait for one execution
+ int maxit = 50;
+ do {
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+ reportTO = reportService.read(reportTO.getKey());
+
+ maxit--;
+ } while (reportTO.getExecutions().isEmpty() && maxit > 0);
+ assertFalse(reportTO.getExecutions().isEmpty());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
new file mode 100644
index 0000000..6cb624a
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/ResourceITCase.java
@@ -0,0 +1,590 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.security.AccessControlException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.lib.types.MappingPurpose;
+import org.apache.syncope.common.lib.wrap.PropagationActionClass;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ResourceITCase extends AbstractITCase {
+
+ private ResourceTO buildResourceTO(final String resourceName) {
+ ResourceTO resourceTO = new ResourceTO();
+
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setExtAttrName("userId");
+ item.setIntAttrName("userId");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("username");
+ item.setIntAttrName("fullname");
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("fullname");
+ item.setIntAttrName("cn");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setAccountid(false);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ resourceTO.setUmapping(mapping);
+ return resourceTO;
+ }
+
+ @Test
+ public void getPropagationActionsClasses() {
+ List<PropagationActionClass> actions = resourceService.getPropagationActionsClasses();
+ assertNotNull(actions);
+ assertFalse(actions.isEmpty());
+ }
+
+ @Test
+ public void create() {
+ String resourceName = RESOURCE_NAME_CREATE;
+ ResourceTO resourceTO = buildResourceTO(resourceName);
+
+ Response response = resourceService.create(resourceTO);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(actual);
+
+ // check for existence
+ actual = resourceService.read(resourceName);
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void createOverridingProps() {
+ String resourceName = "overriding-conn-conf-target-resource-create";
+ ResourceTO resourceTO = new ResourceTO();
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setExtAttrName("uid");
+ item.setIntAttrName("userId");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("username");
+ item.setIntAttrName("fullname");
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setExtAttrName("fullname");
+ item.setIntAttrName("cn");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setAccountid(false);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ resourceTO.setUmapping(mapping);
+
+ ConnConfProperty p = new ConnConfProperty();
+ ConnConfPropSchema schema = new ConnConfPropSchema();
+ schema.setType("java.lang.String");
+ schema.setName("endpoint");
+ schema.setRequired(true);
+ p.setSchema(schema);
+ p.getValues().add("http://invalidurl/");
+
+ Set<ConnConfProperty> connectorConfigurationProperties = new HashSet<ConnConfProperty>(Arrays.asList(p));
+ resourceTO.getConnConfProperties().addAll(connectorConfigurationProperties);
+
+ Response response = resourceService.create(resourceTO);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(actual);
+
+ // check the existence
+ actual = resourceService.read(resourceName);
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void createWithSingleMappingItem() {
+ String resourceName = RESOURCE_NAME_CREATE_SINGLE;
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ MappingTO umapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setExtAttrName("userId");
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ umapping.setAccountIdItem(item);
+
+ resourceTO.setUmapping(umapping);
+
+ MappingTO rmapping = new MappingTO();
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.RoleId);
+ item.setExtAttrName("roleId");
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.SYNCHRONIZATION);
+ rmapping.setAccountIdItem(item);
+
+ resourceTO.setRmapping(rmapping);
+
+ Response response = resourceService.create(resourceTO);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(actual);
+ assertNotNull(actual.getUmapping());
+ assertNotNull(actual.getUmapping().getItems());
+ assertNotNull(actual.getRmapping());
+ assertNotNull(actual.getRmapping().getItems());
+ assertEquals(MappingPurpose.SYNCHRONIZATION, actual.getRmapping().getAccountIdItem().getPurpose());
+ assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
+ }
+
+ @Test
+ public void createWithInvalidMapping() {
+ String resourceName = RESOURCE_NAME_CREATE_WRONG;
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setExtAttrName("userId");
+ item.setAccountid(true);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setExtAttrName("email");
+ // missing intAttrName ...
+ mapping.addItem(item);
+
+ resourceTO.setUmapping(mapping);
+
+ try {
+ createResource(resourceTO);
+ fail("Create should not have worked");
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ assertEquals("intAttrName", e.getElements().iterator().next());
+ }
+ }
+
+ @Test(expected = SyncopeClientException.class)
+ public void createWithoutExtAttr() {
+ String resourceName = RESOURCE_NAME_CREATE_WRONG;
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setExtAttrName("userId");
+ item.setAccountid(true);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setIntAttrName("usernane");
+ // missing extAttrName ...
+ mapping.addItem(item);
+
+ resourceTO.setUmapping(mapping);
+
+ createResource(resourceTO);
+ }
+
+ @Test
+ public void createWithPasswordPolicy() {
+ String resourceName = "res-with-password-policy";
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+ resourceTO.setPasswordPolicy(4L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setExtAttrName("userId");
+ item.setIntAttrName("userId");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.setAccountIdItem(item);
+
+ resourceTO.setUmapping(mapping);
+
+ Response response = resourceService.create(resourceTO);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(actual);
+
+ // check the existence
+ actual = resourceService.read(resourceName);
+ assertNotNull(actual);
+ assertNotNull(actual.getPasswordPolicy());
+ assertEquals(4L, (long) actual.getPasswordPolicy());
+ }
+
+ @Test
+ public void updateWithException() {
+ try {
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey("resourcenotfound");
+
+ resourceService.update(resourceTO.getKey(), resourceTO);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void update() {
+ String resourceName = RESOURCE_NAME_UPDATE;
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(101L);
+
+ MappingTO mapping = new MappingTO();
+
+ // Update with an existing and already assigned mapping
+ MappingItemTO item = new MappingItemTO();
+ item.setKey(112L);
+ item.setExtAttrName("test3");
+ item.setIntAttrName("fullname");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ // Update defining new mappings
+ for (int i = 4; i < 6; i++) {
+ item = new MappingItemTO();
+ item.setExtAttrName("test" + i);
+ item.setIntAttrName("fullname");
+ item.setIntMappingType(IntMappingType.UserPlainSchema);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+ }
+ item = new MappingItemTO();
+ item.setExtAttrName("username");
+ item.setIntAttrName("fullname");
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.setAccountIdItem(item);
+
+ resourceTO.setUmapping(mapping);
+
+ resourceService.update(resourceTO.getKey(), resourceTO);
+ ResourceTO actual = resourceService.read(resourceTO.getKey());
+ assertNotNull(actual);
+
+ // check for existence
+ Collection<MappingItemTO> mapItems = actual.getUmapping().getItems();
+ assertNotNull(mapItems);
+ assertEquals(4, mapItems.size());
+ }
+
+ @Test
+ public void deleteWithException() {
+ try {
+ resourceService.delete("resourcenotfound");
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void updateResetSyncToken() {
+ // create resource with sync token
+ String resourceName = RESOURCE_NAME_RESETSYNCTOKEN + getUUIDString();
+ ResourceTO pre = buildResourceTO(resourceName);
+ pre.setUsyncToken("test");
+ resourceService.create(pre);
+
+ pre.setUsyncToken(null);
+ resourceService.update(pre.getKey(), pre);
+ ResourceTO actual = resourceService.read(pre.getKey());
+ // check that the synctoken has been reset
+ assertNull(actual.getUsyncToken());
+ }
+
+ @Test
+ public void delete() {
+ String resourceName = "tobedeleted";
+
+ ResourceTO resource = buildResourceTO(resourceName);
+ Response response = resourceService.create(resource);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+ assertNotNull(actual);
+
+ resourceService.delete(resourceName);
+
+ try {
+ resourceService.read(resourceName);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void list() {
+ List<ResourceTO> actuals = resourceService.list();
+ assertNotNull(actuals);
+ assertFalse(actuals.isEmpty());
+ for (ResourceTO resourceTO : actuals) {
+ assertNotNull(resourceTO);
+ }
+ }
+
+ @Test
+ public void listByType() {
+ List<ResourceTO> actuals = resourceService.list(105L);
+ assertNotNull(actuals);
+
+ for (ResourceTO resourceTO : actuals) {
+ assertNotNull(resourceTO);
+ assertEquals(105L, resourceTO.getConnectorId().longValue());
+ }
+ }
+
+ @Test
+ public void read() {
+ ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+ assertNotNull(actual);
+ }
+
+ @Test
+ public void issueSYNCOPE323() {
+ ResourceTO actual = resourceService.read(RESOURCE_NAME_TESTDB);
+ assertNotNull(actual);
+
+ try {
+ createResource(actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.EntityExists, e.getType());
+ }
+
+ actual.setKey(null);
+ try {
+ createResource(actual);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+ }
+
+ @Test
+ public void bulkAction() {
+ resourceService.create(buildResourceTO("forBulk1"));
+ resourceService.create(buildResourceTO("forBulk2"));
+
+ assertNotNull(resourceService.read("forBulk1"));
+ assertNotNull(resourceService.read("forBulk2"));
+
+ final BulkAction bulkAction = new BulkAction();
+ bulkAction.setOperation(BulkAction.Type.DELETE);
+
+ bulkAction.getTargets().add(String.valueOf("forBulk1"));
+ bulkAction.getTargets().add(String.valueOf("forBulk2"));
+
+ resourceService.bulk(bulkAction);
+
+ try {
+ resourceService.read("forBulk1");
+ fail();
+ } catch (SyncopeClientException e) {
+ }
+
+ try {
+ resourceService.read("forBulk2");
+ fail();
+ } catch (SyncopeClientException e) {
+ }
+ }
+
+ @Test
+ public void issueSYNCOPE360() {
+ final String name = "SYNCOPE360-" + getUUIDString();
+ resourceService.create(buildResourceTO(name));
+
+ ResourceTO resource = resourceService.read(name);
+ assertNotNull(resource);
+ assertNotNull(resource.getUmapping());
+
+ resource.setUmapping(new MappingTO());
+ resourceService.update(name, resource);
+
+ resource = resourceService.read(name);
+ assertNotNull(resource);
+ assertNull(resource.getUmapping());
+ }
+
+ @Test
+ public void issueSYNCOPE368() {
+ final String name = "SYNCOPE368-" + getUUIDString();
+
+ ResourceTO resourceTO = new ResourceTO();
+
+ resourceTO.setKey(name);
+ resourceTO.setConnectorId(105L);
+
+ MappingTO mapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.RoleName);
+ item.setExtAttrName("cn");
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.setAccountIdItem(item);
+
+ item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.RoleOwnerSchema);
+ item.setExtAttrName("owner");
+ item.setPurpose(MappingPurpose.BOTH);
+ mapping.addItem(item);
+
+ resourceTO.setRmapping(mapping);
+
+ resourceTO = createResource(resourceTO);
+ assertNotNull(resourceTO);
+ assertEquals(2, resourceTO.getRmapping().getItems().size());
+ }
+
+ @Test
+ public void issueSYNCOPE418() {
+ try {
+ resourceService.create(
+ buildResourceTO("http://schemas.examples.org/security/authorization/organizationUnit"));
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidExternalResource, e.getType());
+
+ assertTrue(e.getElements().iterator().next().toString().contains(EntityViolationType.InvalidName.name()));
+ }
+ }
+
+ @Test
+ public void anonymous() {
+ ResourceService unauthenticated = clientFactory.createAnonymous().getService(ResourceService.class);
+ try {
+ unauthenticated.list();
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ ResourceService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).
+ getService(ResourceService.class);
+ assertFalse(anonymous.list().isEmpty());
+ }
+
+ @Test
+ public void issueSYNCOPE493() {
+ // create resource with attribute mapping set to NONE and check its propagation
+ String resourceName = RESOURCE_NAME_CREATE_NONE;
+ ResourceTO resourceTO = new ResourceTO();
+ resourceTO.setKey(resourceName);
+ resourceTO.setConnectorId(102L);
+
+ MappingTO umapping = new MappingTO();
+
+ MappingItemTO item = new MappingItemTO();
+ item.setIntMappingType(IntMappingType.UserId);
+ item.setExtAttrName("userId");
+ item.setAccountid(true);
+ item.setPurpose(MappingPurpose.PROPAGATION);
+ umapping.setAccountIdItem(item);
+
+ MappingItemTO item2 = new MappingItemTO();
+ item2.setIntMappingType(IntMappingType.UserPlainSchema);
+ item2.setAccountid(false);
+ item2.setIntAttrName("gender");
+ item2.setExtAttrName("gender");
+ item2.setPurpose(MappingPurpose.NONE);
+ umapping.addItem(item2);
+
+ resourceTO.setUmapping(umapping);
+
+ Response response = resourceService.create(resourceTO);
+ ResourceTO actual = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+ assertNotNull(actual);
+ assertNotNull(actual.getUmapping());
+ assertNotNull(actual.getUmapping().getItems());
+ assertEquals(MappingPurpose.PROPAGATION, actual.getUmapping().getAccountIdItem().getPurpose());
+ for (MappingItemTO itemTO : actual.getUmapping().getItems()) {
+ if ("gender".equals(itemTO.getIntAttrName())) {
+ assertEquals(MappingPurpose.NONE, itemTO.getPurpose());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/80589a1b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
new file mode 100644
index 0000000..dbd9532
--- /dev/null
+++ b/syncope620/fit/reference/src/test/java/org/apache/syncope/fit/server/reference/RoleITCase.java
@@ -0,0 +1,797 @@
+/*
+ * 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.fit.server.reference;
+
+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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlException;
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.ReferenceMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.ConnObjectTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ResourceAssociationActionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.Preference;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.RoleService;
+import org.identityconnectors.framework.common.objects.Name;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class RoleITCase extends AbstractITCase {
+
+ private RoleTO buildBasicRoleTO(final String name) {
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName(name + getUUIDString());
+ roleTO.setParent(8L);
+ return roleTO;
+ }
+
+ private RoleTO buildRoleTO(final String name) {
+ RoleTO roleTO = buildBasicRoleTO(name);
+
+ // verify inheritance password and account policies
+ roleTO.setInheritAccountPolicy(false);
+ // not inherited so setter execution shouldn't be ignored
+ roleTO.setAccountPolicy(6L);
+
+ roleTO.setInheritPasswordPolicy(true);
+ // inherited so setter execution should be ignored
+ roleTO.setPasswordPolicy(2L);
+
+ roleTO.getRAttrTemplates().add("icon");
+ roleTO.getPlainAttrs().add(attrTO("icon", "anIcon"));
+
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
+ return roleTO;
+ }
+
+ @Test
+ public void createWithException() {
+ RoleTO newRoleTO = new RoleTO();
+ newRoleTO.getPlainAttrs().add(attrTO("attr1", "value1"));
+
+ try {
+ createRole(newRoleTO);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.InvalidRole, e.getType());
+ }
+ }
+
+ @Test
+ @Ignore
+ public void create() {
+ RoleTO roleTO = buildRoleTO("lastRole");
+ roleTO.getRVirAttrTemplates().add("rvirtualdata");
+ roleTO.getVirAttrs().add(attrTO("rvirtualdata", "rvirtualvalue"));
+ roleTO.setRoleOwner(8L);
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ assertNotNull(roleTO.getVirAttrMap());
+ assertNotNull(roleTO.getVirAttrMap().get("rvirtualdata").getValues());
+ assertFalse(roleTO.getVirAttrMap().get("rvirtualdata").getValues().isEmpty());
+ assertEquals("rvirtualvalue", roleTO.getVirAttrMap().get("rvirtualdata").getValues().get(0));
+
+ assertNotNull(roleTO.getAccountPolicy());
+ assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+ assertNotNull(roleTO.getPasswordPolicy());
+ assertEquals(4L, (long) roleTO.getPasswordPolicy());
+
+ assertTrue(roleTO.getResources().contains(RESOURCE_NAME_LDAP));
+
+ ConnObjectTO connObjectTO =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, roleTO.getKey());
+ assertNotNull(connObjectTO);
+ assertNotNull(connObjectTO.getPlainAttrMap().get("owner"));
+
+ // SYNCOPE-515: remove ownership
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.setRoleOwner(new ReferenceMod());
+
+ assertNull(updateRole(roleMod).getRoleOwner());
+ }
+
+ @Test
+ public void createWithPasswordPolicy() {
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("roleWithPassword" + getUUIDString());
+ roleTO.setParent(8L);
+ roleTO.setPasswordPolicy(4L);
+
+ RoleTO actual = createRole(roleTO);
+ assertNotNull(actual);
+
+ actual = roleService.read(actual.getKey());
+ assertNotNull(actual);
+ assertNotNull(actual.getPasswordPolicy());
+ assertEquals(4L, (long) actual.getPasswordPolicy());
+ }
+
+ @Test
+ public void delete() {
+ try {
+ roleService.delete(0L);
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+
+ RoleTO roleTO = new RoleTO();
+ roleTO.setName("toBeDeleted" + getUUIDString());
+ roleTO.setParent(8L);
+
+ roleTO.getResources().add(RESOURCE_NAME_LDAP);
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+
+ RoleTO deletedRole = deleteRole(roleTO.getKey());
+ assertNotNull(deletedRole);
+
+ try {
+ roleService.read(deletedRole.getKey());
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+ }
+ }
+
+ @Test
+ public void list() {
+ PagedResult<RoleTO> roleTOs = roleService.list();
+ assertNotNull(roleTOs);
+ assertTrue(roleTOs.getResult().size() >= 8);
+ for (RoleTO roleTO : roleTOs.getResult()) {
+ assertNotNull(roleTO);
+ }
+ }
+
+ @Test
+ public void parent() {
+ RoleTO roleTO = roleService.parent(7L);
+
+ assertNotNull(roleTO);
+ assertEquals(roleTO.getKey(), 6L);
+ }
+
+ @Test
+ public void read() {
+ RoleTO roleTO = roleService.read(1L);
+
+ assertNotNull(roleTO);
+ assertNotNull(roleTO.getPlainAttrs());
+ assertFalse(roleTO.getPlainAttrs().isEmpty());
+ }
+
+ @Test
+ public void selfRead() {
+ UserTO userTO = userService.read(1L);
+ assertNotNull(userTO);
+
+ assertTrue(userTO.getMembershipMap().containsKey(1L));
+ assertFalse(userTO.getMembershipMap().containsKey(3L));
+
+ RoleService roleService2 = clientFactory.create("rossini", ADMIN_PWD).getService(RoleService.class);
+
+ try {
+ roleService2.readSelf(3L);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.UnauthorizedRole, e.getType());
+ }
+
+ RoleTO roleTO = roleService2.readSelf(1L);
+ assertNotNull(roleTO);
+ assertNotNull(roleTO.getPlainAttrs());
+ assertFalse(roleTO.getPlainAttrs().isEmpty());
+ }
+
+ @Test
+ public void update() {
+ RoleTO roleTO = buildRoleTO("latestRole" + getUUIDString());
+ roleTO.getRAttrTemplates().add("show");
+ roleTO = createRole(roleTO);
+
+ assertEquals(1, roleTO.getPlainAttrs().size());
+
+ assertNotNull(roleTO.getAccountPolicy());
+ assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+ assertNotNull(roleTO.getPasswordPolicy());
+ assertEquals(4L, (long) roleTO.getPasswordPolicy());
+
+ RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ String modName = "finalRole" + getUUIDString();
+ roleMod.setName(modName);
+ roleMod.getPlainAttrsToUpdate().add(attrMod("show", "FALSE"));
+
+ // change password policy inheritance
+ roleMod.setInheritPasswordPolicy(Boolean.FALSE);
+
+ roleTO = updateRole(roleMod);
+
+ assertEquals(modName, roleTO.getName());
+ assertEquals(2, roleTO.getPlainAttrs().size());
+
+ // changes ignored because not requested (null ReferenceMod)
+ assertNotNull(roleTO.getAccountPolicy());
+ assertEquals(6L, (long) roleTO.getAccountPolicy());
+
+ // password policy null because not inherited
+ assertNull(roleTO.getPasswordPolicy());
+ }
+
+ @Test
+ public void updateRemovingVirAttribute() {
+ RoleTO roleTO = buildBasicRoleTO("withvirtual" + getUUIDString());
+ roleTO.getRVirAttrTemplates().add("rvirtualdata");
+ roleTO.getVirAttrs().add(attrTO("rvirtualdata", null));
+
+ roleTO = createRole(roleTO);
+
+ assertNotNull(roleTO);
+ assertEquals(1, roleTO.getVirAttrs().size());
+
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.getVirAttrsToRemove().add("rvirtualdata");
+
+ roleTO = updateRole(roleMod);
+ assertNotNull(roleTO);
+ assertTrue(roleTO.getVirAttrs().isEmpty());
+ }
+
+ @Test
+ public void updateRemovingDerAttribute() {
+ RoleTO roleTO = buildBasicRoleTO("withderived" + getUUIDString());
+ roleTO.getRDerAttrTemplates().add("rderivedschema");
+ roleTO.getDerAttrs().add(attrTO("rderivedschema", null));
+
+ roleTO = createRole(roleTO);
+
+ assertNotNull(roleTO);
+ assertEquals(1, roleTO.getDerAttrs().size());
+
+ final RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.getDerAttrsToRemove().add("rderivedschema");
+
+ roleTO = updateRole(roleMod);
+ assertNotNull(roleTO);
+ assertTrue(roleTO.getDerAttrs().isEmpty());
+ }
+
+ @Test
+ public void updateAsRoleOwner() {
+ // 1. read role as admin
+ RoleTO roleTO = roleService.read(7L);
+
+ // issue SYNCOPE-15
+ assertNotNull(roleTO.getCreationDate());
+ assertNotNull(roleTO.getLastChangeDate());
+ assertEquals("admin", roleTO.getCreator());
+ assertEquals("admin", roleTO.getLastModifier());
+
+ // 2. prepare update
+ RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.setName("Managing Director");
+
+ // 3. try to update as verdi, not owner of role 7 - fail
+ RoleService roleService2 = clientFactory.create("verdi", ADMIN_PWD).getService(RoleService.class);
+
+ try {
+ roleService2.update(roleMod.getKey(), roleMod);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ // 4. update as puccini, owner of role 7 because owner of role 6 with inheritance - success
+ RoleService roleService3 = clientFactory.create("puccini", ADMIN_PWD).getService(RoleService.class);
+
+ roleTO = roleService3.update(roleMod.getKey(), roleMod).readEntity(RoleTO.class);
+ assertEquals("Managing Director", roleTO.getName());
+
+ // issue SYNCOPE-15
+ assertNotNull(roleTO.getCreationDate());
+ assertNotNull(roleTO.getLastChangeDate());
+ assertEquals("admin", roleTO.getCreator());
+ assertEquals("puccini", roleTO.getLastModifier());
+ assertTrue(roleTO.getCreationDate().before(roleTO.getLastChangeDate()));
+ }
+
+ /**
+ * Role rename used to fail in case of parent null.
+ *
+ * http://code.google.com/p/syncope/issues/detail?id=178
+ */
+ @Test
+ public void issue178() {
+ RoleTO roleTO = new RoleTO();
+ String roleName = "torename" + getUUIDString();
+ roleTO.setName(roleName);
+
+ RoleTO actual = createRole(roleTO);
+
+ assertNotNull(actual);
+ assertEquals(roleName, actual.getName());
+ assertEquals(0L, actual.getParent());
+
+ RoleMod roleMod = new RoleMod();
+ roleMod.setKey(actual.getKey());
+ String renamedRole = "renamed" + getUUIDString();
+ roleMod.setName(renamedRole);
+
+ actual = updateRole(roleMod);
+ assertNotNull(actual);
+ assertEquals(renamedRole, actual.getName());
+ assertEquals(0L, actual.getParent());
+ }
+
+ @Test
+ public void issueSYNCOPE228() {
+ RoleTO roleTO = buildRoleTO("issueSYNCOPE228");
+ roleTO.getEntitlements().add("USER_READ");
+ roleTO.getEntitlements().add("SCHEMA_READ");
+
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+ assertNotNull(roleTO.getEntitlements());
+ assertFalse(roleTO.getEntitlements().isEmpty());
+
+ List<String> entitlements = roleTO.getEntitlements();
+
+ RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.setInheritDerAttrs(Boolean.TRUE);
+
+ roleTO = updateRole(roleMod);
+ assertNotNull(roleTO);
+ assertEquals(entitlements, roleTO.getEntitlements());
+
+ roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.setModEntitlements(true);
+ roleMod.getEntitlements().clear();
+
+ roleTO = updateRole(roleMod);
+ assertNotNull(roleTO);
+ assertTrue(roleTO.getEntitlements().isEmpty());
+ }
+
+ @Test
+ public void unlink() {
+ RoleTO actual = createRole(buildRoleTO("unlink"));
+ assertNotNull(actual);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+ assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.UNLINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+ }
+
+ @Test
+ public void link() {
+ RoleTO roleTO = buildRoleTO("link");
+ roleTO.getResources().clear();
+
+ RoleTO actual = createRole(roleTO);
+ assertNotNull(actual);
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ assertNotNull(roleService.bulkAssociation(actual.getKey(),
+ ResourceAssociationActionType.LINK,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void unassign() {
+ RoleTO actual = createRole(buildRoleTO("unassign"));
+ assertNotNull(actual);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+ assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.UNASSIGN,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void assign() {
+ RoleTO roleTO = buildRoleTO("assign");
+ roleTO.getResources().clear();
+
+ RoleTO actual = createRole(roleTO);
+ assertNotNull(actual);
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ assertNotNull(roleService.bulkAssociation(actual.getKey(),
+ ResourceAssociationActionType.ASSIGN,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertFalse(actual.getResources().isEmpty());
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+ }
+
+ @Test
+ public void deprovision() {
+ RoleTO actual = createRole(buildRoleTO("deprovision"));
+ assertNotNull(actual);
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+ assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertNotNull(actual);
+ assertFalse(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void provision() {
+ RoleTO roleTO = buildRoleTO("assign");
+ roleTO.getResources().clear();
+
+ RoleTO actual = createRole(roleTO);
+ assertNotNull(actual);
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ assertNotNull(roleService.bulkAssociation(actual.getKey(),
+ ResourceAssociationActionType.PROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertTrue(actual.getResources().isEmpty());
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+ }
+
+ @Test
+ public void deprovisionUnlinked() {
+ RoleTO roleTO = buildRoleTO("assign");
+ roleTO.getResources().clear();
+
+ RoleTO actual = createRole(roleTO);
+ assertNotNull(actual);
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+
+ assertNotNull(roleService.bulkAssociation(actual.getKey(),
+ ResourceAssociationActionType.PROVISION,
+ CollectionWrapper.wrap("resource-ldap", ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertTrue(actual.getResources().isEmpty());
+
+ assertNotNull(resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey()));
+
+ assertNotNull(roleService.bulkDeassociation(actual.getKey(),
+ ResourceDeassociationActionType.DEPROVISION,
+ CollectionWrapper.wrap(RESOURCE_NAME_LDAP, ResourceName.class)).
+ readEntity(BulkActionResult.class));
+
+ actual = roleService.read(actual.getKey());
+ assertNotNull(actual);
+ assertTrue(actual.getResources().isEmpty());
+
+ try {
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, actual.getKey());
+ fail();
+ } catch (Exception e) {
+ assertNotNull(e);
+ }
+ }
+
+ @Test
+ public void createWithMandatorySchemaNotTemplate() {
+ // 1. create a role mandatory schema
+ PlainSchemaTO badge = new PlainSchemaTO();
+ badge.setKey("badge");
+ badge.setMandatoryCondition("true");
+ schemaService.create(AttributableType.ROLE, SchemaType.PLAIN, badge);
+
+ // 2. create a role *without* an attribute for that schema: it works
+ RoleTO roleTO = buildRoleTO("lastRole");
+ assertFalse(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+ roleTO = createRole(roleTO);
+ assertNotNull(roleTO);
+ assertFalse(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+
+ // 3. add a template for badge to the role just created -
+ // failure since no values are provided and it is mandatory
+ RoleMod roleMod = new RoleMod();
+ roleMod.setKey(roleTO.getKey());
+ roleMod.setModRAttrTemplates(true);
+ roleMod.getRPlainAttrTemplates().add("badge");
+
+ try {
+ updateRole(roleMod);
+ fail();
+ } catch (SyncopeClientException e) {
+ assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+ }
+
+ // 4. also add an actual attribute for badge - it will work
+ roleMod.getPlainAttrsToUpdate().add(attrMod(badge.getKey(), "xxxxxxxxxx"));
+
+ roleTO = updateRole(roleMod);
+ assertNotNull(roleTO);
+ assertTrue(roleTO.getPlainAttrMap().containsKey(badge.getKey()));
+ }
+
+ @Test
+ public void anonymous() {
+ RoleService unauthenticated = clientFactory.createAnonymous().getService(RoleService.class);
+ try {
+ unauthenticated.list();
+ fail();
+ } catch (AccessControlException e) {
+ assertNotNull(e);
+ }
+
+ RoleService anonymous = clientFactory.create(ANONYMOUS_UNAME, ANONYMOUS_KEY).getService(RoleService.class);
+ assertFalse(anonymous.list().getResult().isEmpty());
+ }
+
+ @Test
+ public void noContent() throws IOException {
+ SyncopeClient noContentclient = clientFactory.create(ADMIN_UNAME, ADMIN_PWD);
+ RoleService noContentService = noContentclient.prefer(RoleService.class, Preference.RETURN_NO_CONTENT);
+
+ RoleTO role = buildRoleTO("noContent");
+
+ Response response = noContentService.create(role);
+ assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ role = getObject(response.getLocation(), RoleService.class, RoleTO.class);
+ assertNotNull(role);
+
+ RoleMod roleMod = new RoleMod();
+ roleMod.getPlainAttrsToUpdate().add(attrMod("badge", "xxxxxxxxxx"));
+
+ response = noContentService.update(role.getKey(), roleMod);
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+
+ response = noContentService.delete(role.getKey());
+ assertEquals(Response.Status.NO_CONTENT.getStatusCode(), response.getStatus());
+ assertEquals(Preference.RETURN_NO_CONTENT.toString(), response.getHeaderString(RESTHeaders.PREFERENCE_APPLIED));
+ assertEquals(StringUtils.EMPTY, IOUtils.toString((InputStream) response.getEntity()));
+ }
+
+ @Test
+ public void issueSYNCOPE455() {
+ final String parentName = "issueSYNCOPE455-PRole";
+ final String childName = "issueSYNCOPE455-CRole";
+
+ // 1. create parent role
+ RoleTO parent = buildBasicRoleTO(parentName);
+ parent.getResources().add(RESOURCE_NAME_LDAP);
+
+ parent = createRole(parent);
+ assertTrue(parent.getResources().contains(RESOURCE_NAME_LDAP));
+
+ final ConnObjectTO parentRemoteObject =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, parent.getKey());
+ assertNotNull(parentRemoteObject);
+ assertNotNull(getLdapRemoteObject(parentRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+ // 2. create child role
+ RoleTO child = buildBasicRoleTO(childName);
+ child.getResources().add(RESOURCE_NAME_LDAP);
+ child.setParent(parent.getKey());
+
+ child = createRole(child);
+ assertTrue(child.getResources().contains(RESOURCE_NAME_LDAP));
+
+ final ConnObjectTO childRemoteObject =
+ resourceService.getConnectorObject(RESOURCE_NAME_LDAP, SubjectType.ROLE, child.getKey());
+ assertNotNull(childRemoteObject);
+ assertNotNull(getLdapRemoteObject(childRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+
+ // 3. remove parent role
+ roleService.delete(parent.getKey());
+
+ // 4. asserts for issue 455
+ try {
+ roleService.read(parent.getKey());
+ fail();
+ } catch (SyncopeClientException scce) {
+ assertNotNull(scce);
+ }
+
+ try {
+ roleService.read(child.getKey());
+ fail();
+ } catch (SyncopeClientException scce) {
+ assertNotNull(scce);
+ }
+
+ assertNull(getLdapRemoteObject(parentRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+ assertNull(getLdapRemoteObject(childRemoteObject.getPlainAttrMap().get(Name.NAME).getValues().get(0)));
+ }
+
+ @Test
+ public void issueSYNCOPE543() {
+ final String ancestorName = "issueSYNCOPE543-ARole";
+ final String parentName = "issueSYNCOPE543-PRole";
+ final String childName = "issueSYNCOPE543-CRole";
+
+ // 1. create ancestor role
+ RoleTO ancestor = buildBasicRoleTO(ancestorName);
+ ancestor.setParent(0L);
+ ancestor.getRAttrTemplates().add("icon");
+ ancestor.getPlainAttrs().add(attrTO("icon", "ancestorIcon"));
+ ancestor = createRole(ancestor);
+ assertEquals("ancestorIcon", ancestor.getPlainAttrMap().get("icon").getValues().get(0));
+
+ // 2. create parent role
+ RoleTO parent = buildBasicRoleTO(parentName);
+ parent.setParent(ancestor.getKey());
+ parent.getRAttrTemplates().add("icon");
+ parent.getPlainAttrs().add(attrTO("icon", "parentIcon"));
+ parent = createRole(parent);
+ assertEquals("parentIcon", parent.getPlainAttrMap().get("icon").getValues().get(0));
+
+ // 3. create child role
+ RoleTO child = buildBasicRoleTO(childName);
+ child.setParent(parent.getKey());
+ child.getRAttrTemplates().add("icon");
+ child.getPlainAttrs().add(attrTO("icon", "childIcon"));
+ child = createRole(child);
+ assertEquals("childIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+ final RoleMod roleChildMod = new RoleMod();
+ roleChildMod.setKey(child.getKey());
+ roleChildMod.setInheritPlainAttrs(Boolean.TRUE);
+ updateRole(roleChildMod);
+
+ child = roleService.read(child.getKey());
+ assertNotNull(child);
+ assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+ assertEquals("parentIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+ final RoleMod roleParentMod = new RoleMod();
+ roleParentMod.setKey(parent.getKey());
+ roleParentMod.setInheritPlainAttrs(Boolean.TRUE);
+ updateRole(roleParentMod);
+
+ child = roleService.read(child.getKey());
+ assertNotNull(child);
+ assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+ assertEquals("ancestorIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+
+ parent = roleService.read(parent.getKey());
+ assertNotNull(parent);
+ assertNotNull(parent.getPlainAttrMap().get("icon").getValues());
+ assertEquals("ancestorIcon", parent.getPlainAttrMap().get("icon").getValues().get(0));
+
+ roleParentMod.setInheritPlainAttrs(Boolean.FALSE);
+ updateRole(roleParentMod);
+
+ child = roleService.read(child.getKey());
+ assertNotNull(child);
+ assertNotNull(child.getPlainAttrMap().get("icon").getValues());
+ assertEquals("parentIcon", child.getPlainAttrMap().get("icon").getValues().get(0));
+ }
+}