http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java index 1d64ace..4e40e83 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2SPLogic.java @@ -68,7 +68,6 @@ import org.opensaml.saml.saml2.core.AuthnContext; import org.opensaml.saml.saml2.core.AuthnContextClassRef; import org.opensaml.saml.saml2.core.AuthnContextComparisonTypeEnumeration; import org.opensaml.saml.saml2.core.AuthnRequest; -import org.opensaml.saml.saml2.core.AuthnStatement; import org.opensaml.saml.saml2.core.Issuer; import org.opensaml.saml.saml2.core.LogoutRequest; import org.opensaml.saml.saml2.core.LogoutResponse; @@ -448,14 +447,14 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { if (assertion.getConditions().getNotOnOrAfter() != null) { responseTO.setNotOnOrAfter(assertion.getConditions().getNotOnOrAfter().toDate()); } - for (AuthnStatement authnStmt : assertion.getAuthnStatements()) { + assertion.getAuthnStatements().forEach(authnStmt -> { responseTO.setSessionIndex(authnStmt.getSessionIndex()); responseTO.setAuthInstant(authnStmt.getAuthnInstant().toDate()); if (authnStmt.getSessionNotOnOrAfter() != null) { responseTO.setNotOnOrAfter(authnStmt.getSessionNotOnOrAfter().toDate()); } - } + }); for (AttributeStatement attrStmt : assertion.getAttributeStatements()) { for (Attribute attr : attrStmt.getAttributes()) { @@ -469,11 +468,11 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { AttrTO attrTO = new AttrTO(); attrTO.setSchema(attrName); - for (XMLObject value : attr.getAttributeValues()) { - if (value.getDOM() != null) { - attrTO.getValues().add(value.getDOM().getTextContent()); - } - } + attr.getAttributeValues().stream(). + filter(value -> value.getDOM() != null). + forEachOrdered(value -> { + attrTO.getValues().add(value.getDOM().getTextContent()); + }); responseTO.getAttrs().add(attrTO); } } @@ -481,7 +480,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> { final List<String> matchingUsers = keyValue == null ? Collections.<String>emptyList() - : userManager.findMatchingUser(keyValue, idp.getConnObjectKeyItem()); + : userManager.findMatchingUser(keyValue, idp.getKey()); LOG.debug("Found {} matching users for {}", matchingUsers.size(), keyValue); String username;
http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java index 9b4e497..487478b 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPEntity.java @@ -31,7 +31,6 @@ import java.util.Base64; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import org.apache.syncope.common.lib.to.ItemTO; import org.apache.syncope.common.lib.to.SAML2IdPTO; import org.apache.syncope.common.lib.to.UserTO; @@ -41,9 +40,7 @@ import org.opensaml.saml.saml2.metadata.Endpoint; import org.opensaml.saml.saml2.metadata.EntityDescriptor; import org.opensaml.saml.saml2.metadata.IDPSSODescriptor; import org.opensaml.saml.saml2.metadata.KeyDescriptor; -import org.opensaml.saml.saml2.metadata.NameIDFormat; import org.opensaml.saml.saml2.metadata.SingleLogoutService; -import org.opensaml.saml.saml2.metadata.SingleSignOnService; import org.opensaml.xmlsec.signature.X509Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -75,21 +72,21 @@ public class SAML2IdPEntity { IDPSSODescriptor idpdescriptor = entityDescriptor.getIDPSSODescriptor(SAMLConstants.SAML20P_NS); - for (SingleSignOnService sso : idpdescriptor.getSingleSignOnServices()) { + idpdescriptor.getSingleSignOnServices().forEach(sso -> { LOG.debug("[{}] Add SSO binding {}({})", id, sso.getBinding(), sso.getLocation()); this.ssoBindings.put(sso.getBinding(), sso); - } + }); - for (SingleLogoutService slo : idpdescriptor.getSingleLogoutServices()) { + idpdescriptor.getSingleLogoutServices().forEach(slo -> { LOG.debug("[{}] Add SLO binding '{}'\n\tLocation: '{}'\n\tResponse Location: '{}'", id, slo.getBinding(), slo.getLocation(), slo.getResponseLocation()); this.sloBindings.put(slo.getBinding(), slo); - } + }); - for (NameIDFormat nameIDFormat : idpdescriptor.getNameIDFormats()) { + idpdescriptor.getNameIDFormats().forEach(nameIDFormat -> { LOG.debug("[{}] Add NameIDFormat '{}'", id, nameIDFormat.getFormat()); nameIDFormats.add(nameIDFormat.getFormat()); - } + }); CertificateFactory cf = CertificateFactory.getInstance("X.509"); @@ -125,6 +122,10 @@ public class SAML2IdPEntity { return id; } + public String getKey() { + return idpTO.getKey(); + } + public boolean isCreateUnmatching() { return idpTO.isCreateUnmatching(); } @@ -149,16 +150,12 @@ public class SAML2IdPEntity { return idpTO.getConnObjectKeyItem(); } - public List<ItemTO> getItems() { - return idpTO.getItems(); - } - public UserTO getUserTemplate() { return idpTO.getUserTemplate(); } - public Set<String> getActionsClassNames() { - return idpTO.getActionsClassNames(); + public List<String> getActions() { + return idpTO.getActions(); } public Endpoint getSSOLocation(final SAML2BindingType bindingType) { http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java index 2245fc7..4083a45 100644 --- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java +++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java @@ -29,17 +29,20 @@ import org.apache.syncope.common.lib.AnyOperations; import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.patch.UserPatch; import org.apache.syncope.common.lib.to.AttrTO; -import org.apache.syncope.common.lib.to.ItemTO; import org.apache.syncope.common.lib.to.PropagationStatus; import org.apache.syncope.common.lib.to.SAML2LoginResponseTO; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException; +import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO; +import org.apache.syncope.core.persistence.api.dao.SAML2IdPDAO; import org.apache.syncope.core.persistence.api.dao.UserDAO; import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.api.entity.SAML2IdP; import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; import org.apache.syncope.core.persistence.api.entity.user.User; import org.apache.syncope.core.provisioning.api.IntAttrName; @@ -65,12 +68,18 @@ public class SAML2UserManager { private static final Logger LOG = LoggerFactory.getLogger(SAML2UserManager.class); @Autowired + private SAML2IdPDAO idpDAO; + + @Autowired private UserDAO userDAO; @Autowired private PlainSchemaDAO plainSchemaDAO; @Autowired + private ImplementationDAO implementationDAO; + + @Autowired private IntAttrNameParser intAttrNameParser; @Autowired @@ -86,11 +95,17 @@ public class SAML2UserManager { private UserDataBinder binder; @Transactional(readOnly = true) - public List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) { + public List<String> findMatchingUser(final String keyValue, final String idpKey) { List<String> result = new ArrayList<>(); + SAML2IdP idp = idpDAO.find(idpKey); + if (idp == null) { + LOG.warn("Invalid IdP: {}", idpKey); + return result; + } + String transformed = keyValue; - for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) { + for (ItemTransformer transformer : MappingUtils.getItemTransformers(idp.getConnObjectKeyItem().get())) { List<Object> output = transformer.beforePull( null, null, @@ -100,7 +115,8 @@ public class SAML2UserManager { } } - IntAttrName intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER); + IntAttrName intAttrName = intAttrNameParser.parse( + idp.getConnObjectKeyItem().get().getIntAttrName(), AnyTypeKind.USER); if (intAttrName.getField() != null) { switch (intAttrName.getField()) { @@ -156,23 +172,34 @@ public class SAML2UserManager { private List<SAML2IdPActions> getActions(final SAML2IdPEntity idp) { List<SAML2IdPActions> actions = new ArrayList<>(); - idp.getActionsClassNames().forEach((className) -> { - try { - Class<?> actionsClass = Class.forName(className); - SAML2IdPActions idpActions = (SAML2IdPActions) ApplicationContextProvider.getBeanFactory(). - createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true); - - actions.add(idpActions); - } catch (Exception e) { - LOG.warn("Class '{}' not found", className, e); + idp.getActions().forEach(key -> { + Implementation impl = implementationDAO.find(key); + if (impl == null) { + LOG.warn("Invalid implementation: {}", key); + } else { + try { + Class<?> actionsClass = Class.forName(impl.getBody()); + SAML2IdPActions idpActions = (SAML2IdPActions) ApplicationContextProvider.getBeanFactory(). + createBean(actionsClass, AbstractBeanDefinition.AUTOWIRE_BY_TYPE, true); + + actions.add(idpActions); + } catch (Exception e) { + LOG.warn("Class '{}' not found", impl.getBody(), e); + } } }); return actions; } - private void fill(final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO, final UserTO userTO) { - for (ItemTO item : idp.getItems()) { + private void fill(final String idpKey, final SAML2LoginResponseTO responseTO, final UserTO userTO) { + SAML2IdP idp = idpDAO.find(idpKey); + if (idp == null) { + LOG.warn("Invalid IdP: {}", idpKey); + return; + } + + idp.getItems().forEach(item -> { IntAttrName intAttrName = intAttrNameParser.parse(item.getIntAttrName(), AnyTypeKind.USER); List<String> values = Collections.emptyList(); @@ -218,7 +245,7 @@ public class SAML2UserManager { LOG.warn("Unsupported: {} {}", intAttrName.getSchemaType(), intAttrName.getSchemaName()); } } - } + }); } @Transactional(propagation = Propagation.REQUIRES_NEW) @@ -234,7 +261,7 @@ public class SAML2UserManager { userTO = action.beforeCreate(userTO, responseTO); } - fill(idp, responseTO, userTO); + fill(idp.getKey(), responseTO, userTO); if (userTO.getRealm() == null) { userTO.setRealm(SyncopeConstants.ROOT_REALM); @@ -258,7 +285,7 @@ public class SAML2UserManager { UserTO userTO = binder.getUserTO(userDAO.findKey(username)); UserTO original = SerializationUtils.clone(userTO); - fill(idp, responseTO, userTO); + fill(idp.getKey(), responseTO, userTO); UserPatch userPatch = AnyOperations.diff(userTO, original, true); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java index 7ef1cec..b3bda7c 100644 --- a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java +++ b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2IdP.java @@ -20,7 +20,6 @@ package org.apache.syncope.core.persistence.api.entity; import java.util.List; import java.util.Optional; -import java.util.Set; import org.apache.syncope.common.lib.types.SAML2BindingType; public interface SAML2IdP extends Entity { @@ -69,6 +68,7 @@ public interface SAML2IdP extends Entity { List<? extends SAML2IdPItem> getItems(); - Set<String> getActionsClassNames(); + boolean add(Implementation action); + List<? extends Implementation> getActions(); } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java index 2de265b..13b43f1 100644 --- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java +++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdP.java @@ -19,27 +19,27 @@ package org.apache.syncope.core.persistence.jpa.entity; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; import java.util.Optional; -import java.util.Set; import javax.persistence.Basic; import javax.persistence.Cacheable; import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; import javax.persistence.Lob; +import javax.persistence.ManyToMany; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import org.apache.commons.lang3.ArrayUtils; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.common.lib.types.SAML2BindingType; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.SAML2IdP; import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem; import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate; @@ -94,12 +94,13 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "idp") private JPASAML2UserTemplate userTemplate; - @ElementCollection(fetch = FetchType.EAGER) - @Column(name = "actionClassName") - @CollectionTable(name = TABLE + "_actionsClassNames", + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = TABLE + "Action", joinColumns = - @JoinColumn(name = "saml2IdP_id", referencedColumnName = "id")) - private Set<String> actionsClassNames = new HashSet<>(); + @JoinColumn(name = "idp_id"), + inverseJoinColumns = + @JoinColumn(name = "implementation_id")) + private List<JPAImplementation> actions = new ArrayList<>(); @Override public String getEntityID() { @@ -215,7 +216,14 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP } @Override - public Set<String> getActionsClassNames() { - return actionsClassNames; + public boolean add(final Implementation action) { + checkType(action, JPAImplementation.class); + checkImplementationType(action, ImplementationType.LOGIC_ACTIONS); + return this.actions.add((JPAImplementation) action); + } + + @Override + public List<? extends Implementation> getActions() { + return actions; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java index 863d068..6e22a43 100644 --- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java +++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2IdPItem.java @@ -21,14 +21,15 @@ package org.apache.syncope.core.persistence.jpa.entity; import java.util.ArrayList; import java.util.List; import javax.persistence.Cacheable; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.SAML2IdP; import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem; import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractItem; @@ -45,15 +46,13 @@ public class JPASAML2IdPItem extends AbstractItem implements SAML2IdPItem { @ManyToOne private JPASAML2IdP idp; - /** - * (Optional) classes for Item transformation. - */ - @ElementCollection(fetch = FetchType.EAGER) - @Column(name = "transformerClassName") - @CollectionTable(name = TABLE + "_Transformer", + @ManyToMany(fetch = FetchType.EAGER) + @JoinTable(name = TABLE + "Transformer", joinColumns = - @JoinColumn(name = "saml2IdPItemItem_id", referencedColumnName = "id")) - private List<String> transformerClassNames = new ArrayList<>(); + @JoinColumn(name = "item_id"), + inverseJoinColumns = + @JoinColumn(name = "implementation_id")) + private List<JPAImplementation> transformers = new ArrayList<>(); @Override public SAML2IdP getIdP() { @@ -67,7 +66,14 @@ public class JPASAML2IdPItem extends AbstractItem implements SAML2IdPItem { } @Override - public List<String> getTransformerClassNames() { - return transformerClassNames; + public boolean add(final Implementation transformer) { + checkType(transformer, JPAImplementation.class); + checkImplementationType(transformer, ImplementationType.ITEM_TRANSFORMER); + return this.transformers.add((JPAImplementation) transformer); + } + + @Override + public List<? extends Implementation> getTransformers() { + return transformers; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java index f3b91e9..83bf348 100644 --- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java +++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/validation/entity/SAML2IdPValidator.java @@ -20,8 +20,8 @@ package org.apache.syncope.core.persistence.jpa.validation.entity; import javax.validation.ConstraintValidatorContext; import org.apache.syncope.common.lib.types.EntityViolationType; +import org.apache.syncope.common.lib.types.ImplementationEngine; import org.apache.syncope.core.persistence.api.entity.SAML2IdP; -import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem; import org.apache.syncope.core.provisioning.api.data.ItemTransformer; public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP> { @@ -36,38 +36,41 @@ public class SAML2IdPValidator extends AbstractValidator<SAML2IdPCheck, SAML2IdP return false; } - boolean isValid = true; + final boolean[] isValid = new boolean[] { true }; long passwords = value.getItems().stream().filter(item -> item.isPassword()).count(); if (passwords > 0) { context.buildConstraintViolationWithTemplate( getTemplate(EntityViolationType.InvalidMapping, "No password mapping is allowed")). addPropertyNode("password.size").addConstraintViolation(); - isValid = false; + isValid[0] = false; } - for (SAML2IdPItem item : value.getItems()) { - for (String className : item.getTransformerClassNames()) { - Class<?> actionsClass = null; - boolean isAssignable = false; - try { - actionsClass = Class.forName(className); - isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass); - } catch (Exception e) { - LOG.error("Invalid MappingItemTransformer specified: {}", className, e); - } + value.getItems().forEach(item -> { + item.getTransformers().stream(). + filter(transformer -> transformer.getEngine() == ImplementationEngine.JAVA). + forEach(transformer -> { - if (actionsClass == null || !isAssignable) { - context.buildConstraintViolationWithTemplate( - getTemplate(EntityViolationType.InvalidMapping, - "Invalid mapping item trasformer class name")). - addPropertyNode("mappingItemTransformerClassName").addConstraintViolation(); - isValid = false; - } - } - } + Class<?> actionsClass = null; + boolean isAssignable = false; + try { + actionsClass = Class.forName(transformer.getBody()); + isAssignable = ItemTransformer.class.isAssignableFrom(actionsClass); + } catch (Exception e) { + LOG.error("Invalid ItemTransformer specified: {}", transformer.getBody(), e); + } + + if (actionsClass == null || !isAssignable) { + context.buildConstraintViolationWithTemplate( + getTemplate(EntityViolationType.InvalidMapping, + "Invalid item trasformer class name")). + addPropertyNode("itemTransformers").addConstraintViolation(); + isValid[0] = false; + } + }); + }); - return isValid; + return isValid[0]; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java ---------------------------------------------------------------------- diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java index 7d003ab..4413fc3 100644 --- a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java +++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/data/SAML2IdPDataBinderImpl.java @@ -31,7 +31,9 @@ import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.MappingPurpose; import org.apache.syncope.common.lib.types.SchemaType; import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO; +import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.SAML2IdPDAO; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.api.entity.SAML2EntityFactory; import org.apache.syncope.core.persistence.api.entity.SAML2IdP; import org.apache.syncope.core.persistence.api.entity.SAML2IdPItem; @@ -60,6 +62,9 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder { private SAML2IdPDAO saml2IdPDAO; @Autowired + private ImplementationDAO implementationDAO; + + @Autowired private SAML2EntityFactory entityFactory; @Autowired @@ -196,8 +201,18 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder { }); populateItems(idpTO, idp, allowedSchemas); - idp.getActionsClassNames().clear(); - idp.getActionsClassNames().addAll(idpTO.getActionsClassNames()); + idpTO.getActions().forEach(implementationKey -> { + Implementation implementation = implementationDAO.find(implementationKey); + if (implementation == null) { + LOG.debug("Invalid " + Implementation.class.getSimpleName() + "{}, ignoring...", implementationKey); + } else { + idp.add(implementation); + } + }); + // remove all implementations not contained in the TO + idp.getActions().removeAll(idp.getActions().stream(). + filter(implementation -> !idpTO.getActions().contains(implementation.getKey())). + collect(Collectors.toList())); return saml2IdPDAO.save(idp); } @@ -237,7 +252,9 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder { populateItems(idp, idpTO); - idpTO.getActionsClassNames().addAll(idp.getActionsClassNames()); + idp.getActions().forEach(action -> { + idpTO.getActions().add(action.getKey()); + }); return idpTO; } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java index 6e8e170..e4d94d0 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/ITImplementationLookup.java @@ -18,10 +18,12 @@ */ package org.apache.syncope.fit.core.reference; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.syncope.common.lib.policy.AccountRuleConf; import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf; @@ -34,19 +36,24 @@ import org.apache.syncope.common.lib.report.ReportletConf; import org.apache.syncope.common.lib.report.StaticReportletConf; import org.apache.syncope.common.lib.report.UserReportletConf; import org.apache.syncope.common.lib.to.SchedTaskTO; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.core.logic.TaskLogic; +import org.apache.syncope.core.migration.MigrationPullActions; import org.apache.syncope.core.provisioning.java.job.report.AuditReportlet; import org.apache.syncope.core.provisioning.java.job.report.GroupReportlet; import org.apache.syncope.core.provisioning.java.job.report.ReconciliationReportlet; import org.apache.syncope.core.provisioning.java.job.report.StaticReportlet; import org.apache.syncope.core.provisioning.java.job.report.UserReportlet; -import org.apache.syncope.core.migration.MigrationPullActions; import org.apache.syncope.core.persistence.api.DomainsHolder; import org.apache.syncope.core.persistence.api.ImplementationLookup; import org.apache.syncope.core.persistence.api.dao.AccountRule; import org.apache.syncope.core.persistence.api.dao.AnySearchDAO; +import org.apache.syncope.core.persistence.api.dao.ImplementationDAO; import org.apache.syncope.core.persistence.api.dao.PasswordRule; import org.apache.syncope.core.persistence.api.dao.Reportlet; +import org.apache.syncope.core.persistence.api.entity.EntityFactory; +import org.apache.syncope.core.persistence.api.entity.Implementation; import org.apache.syncope.core.persistence.jpa.attrvalue.validation.AlwaysTrueValidator; import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator; import org.apache.syncope.core.persistence.jpa.attrvalue.validation.EmailAddressValidator; @@ -68,15 +75,59 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class ITImplementationLookup implements ImplementationLookup { - private static final Map<Type, Set<String>> CLASS_NAMES = new HashMap<Type, Set<String>>() { + private static final String ES_REINDEX = "org.apache.syncope.core.provisioning.java.job.ElasticsearchReindex"; + + private static final Set<Class<?>> JWTSSOPROVIDER_CLASSES = new HashSet<>( + Arrays.asList(SyncopeJWTSSOProvider.class, CustomJWTSSOProvider.class)); + + private static final Map<Class<? extends ReportletConf>, Class<? extends Reportlet>> REPORTLET_CLASSES = + new HashMap<Class<? extends ReportletConf>, Class<? extends Reportlet>>() { + + private static final long serialVersionUID = 3109256773218160485L; + + { + put(AuditReportletConf.class, AuditReportlet.class); + put(ReconciliationReportletConf.class, ReconciliationReportlet.class); + put(GroupReportletConf.class, GroupReportlet.class); + put(UserReportletConf.class, UserReportlet.class); + put(StaticReportletConf.class, StaticReportlet.class); + } + }; + + private static final Map<Class<? extends AccountRuleConf>, Class<? extends AccountRule>> ACCOUNT_RULE_CLASSES = + new HashMap<Class<? extends AccountRuleConf>, Class<? extends AccountRule>>() { + + private static final long serialVersionUID = 3109256773218160485L; + + { + put(TestAccountRuleConf.class, TestAccountRule.class); + put(DefaultAccountRuleConf.class, DefaultAccountRule.class); + } + }; + + private static final Map<Class<? extends PasswordRuleConf>, Class<? extends PasswordRule>> PASSWORD_RULE_CLASSES = + new HashMap<Class<? extends PasswordRuleConf>, Class<? extends PasswordRule>>() { + + private static final long serialVersionUID = -6624291041977583649L; + + { + put(TestPasswordRuleConf.class, TestPasswordRule.class); + put(DefaultPasswordRuleConf.class, DefaultPasswordRule.class); + } + }; + + private static final Set<Class<?>> AUDITAPPENDER_CLASSES = new HashSet<>( + Arrays.asList(TestFileAuditAppender.class, TestFileRewriteAuditAppender.class)); + + private static final Map<ImplementationType, Set<String>> CLASS_NAMES = + new HashMap<ImplementationType, Set<String>>() { private static final long serialVersionUID = 3109256773218160485L; { - Set<String> classNames = new HashSet<>(); - classNames.add(SyncopeJWTSSOProvider.class.getName()); - classNames.add(CustomJWTSSOProvider.class.getName()); - put(Type.JWT_SSO_PROVIDER, classNames); + Set<String> classNames = ITImplementationLookup.JWTSSOPROVIDER_CLASSES.stream(). + map(Class::getName).collect(Collectors.toSet()); + put(ImplementationType.JWT_SSO_PROVIDER, classNames); classNames = new HashSet<>(); classNames.add(ReconciliationReportletConf.class.getName()); @@ -84,39 +135,37 @@ public class ITImplementationLookup implements ImplementationLookup { classNames.add(GroupReportletConf.class.getName()); classNames.add(AuditReportletConf.class.getName()); classNames.add(StaticReportletConf.class.getName()); - put(Type.REPORTLET_CONF, classNames); + put(ImplementationType.REPORTLET, classNames); - classNames = new HashSet<>(); - classNames.add(TestAccountRuleConf.class.getName()); - classNames.add(DefaultAccountRuleConf.class.getName()); - put(Type.ACCOUNT_RULE_CONF, classNames); + classNames = ITImplementationLookup.ACCOUNT_RULE_CLASSES.values().stream(). + map(Class::getName).collect(Collectors.toSet()); + put(ImplementationType.ACCOUNT_RULE, classNames); - classNames = new HashSet<>(); - classNames.add(TestPasswordRuleConf.class.getName()); - classNames.add(DefaultPasswordRuleConf.class.getName()); - put(Type.PASSWORD_RULE_CONF, classNames); + classNames = ITImplementationLookup.PASSWORD_RULE_CLASSES.values().stream(). + map(Class::getName).collect(Collectors.toSet()); + put(ImplementationType.PASSWORD_RULE, classNames); classNames = new HashSet<>(); classNames.add(PrefixItemTransformer.class.getName()); - put(Type.ITEM_TRANSFORMER, classNames); + put(ImplementationType.ITEM_TRANSFORMER, classNames); classNames = new HashSet<>(); classNames.add(TestSampleJobDelegate.class.getName()); - put(Type.TASKJOBDELEGATE, classNames); + put(ImplementationType.TASKJOB_DELEGATE, classNames); classNames = new HashSet<>(); classNames.add(TestReconciliationFilterBuilder.class.getName()); - put(Type.RECONCILIATION_FILTER_BUILDER, classNames); + put(ImplementationType.RECON_FILTER_BUILDER, classNames); classNames = new HashSet<>(); classNames.add(DoubleValueLogicActions.class.getName()); - put(Type.LOGIC_ACTIONS, classNames); + put(ImplementationType.LOGIC_ACTIONS, classNames); classNames = new HashSet<>(); classNames.add(LDAPMembershipPropagationActions.class.getName()); classNames.add(LDAPPasswordPropagationActions.class.getName()); classNames.add(DBPasswordPropagationActions.class.getName()); - put(Type.PROPAGATION_ACTIONS, classNames); + put(ImplementationType.PROPAGATION_ACTIONS, classNames); classNames = new HashSet<>(); classNames.add(LDAPPasswordPullActions.class.getName()); @@ -124,70 +173,39 @@ public class ITImplementationLookup implements ImplementationLookup { classNames.add(MigrationPullActions.class.getName()); classNames.add(LDAPMembershipPullActions.class.getName()); classNames.add(DBPasswordPullActions.class.getName()); - put(Type.PULL_ACTIONS, classNames); + put(ImplementationType.PULL_ACTIONS, classNames); classNames = new HashSet<>(); - put(Type.PUSH_ACTIONS, classNames); + put(ImplementationType.PUSH_ACTIONS, classNames); classNames = new HashSet<>(); classNames.add(TestPullRule.class.getName()); - put(Type.PULL_CORRELATION_RULE, classNames); + put(ImplementationType.PULL_CORRELATION_RULE, classNames); classNames = new HashSet<>(); classNames.add(BasicValidator.class.getName()); classNames.add(EmailAddressValidator.class.getName()); classNames.add(AlwaysTrueValidator.class.getName()); - put(Type.VALIDATOR, classNames); + put(ImplementationType.VALIDATOR, classNames); classNames = new HashSet<>(); classNames.add(TestNotificationRecipientsProvider.class.getName()); - put(Type.NOTIFICATION_RECIPIENTS_PROVIDER, classNames); + put(ImplementationType.RECIPIENTS_PROVIDER, classNames); - classNames = new HashSet<>(); - classNames.add(TestFileRewriteAuditAppender.class.getName()); - classNames.add(TestFileAuditAppender.class.getName()); - put(Type.AUDIT_APPENDER, classNames); + classNames = ITImplementationLookup.AUDITAPPENDER_CLASSES.stream(). + map(Class::getName).collect(Collectors.toSet()); + put(ImplementationType.AUDIT_APPENDER, classNames); } }; - private static final Map<Class<? extends ReportletConf>, Class<? extends Reportlet>> REPORTLET_CLASSES = - new HashMap<Class<? extends ReportletConf>, Class<? extends Reportlet>>() { - - private static final long serialVersionUID = 3109256773218160485L; - - { - put(AuditReportletConf.class, AuditReportlet.class); - put(ReconciliationReportletConf.class, ReconciliationReportlet.class); - put(GroupReportletConf.class, GroupReportlet.class); - put(UserReportletConf.class, UserReportlet.class); - put(StaticReportletConf.class, StaticReportlet.class); - } - }; - - private static final Map<Class<? extends AccountRuleConf>, Class<? extends AccountRule>> ACCOUNT_RULE_CLASSES = - new HashMap<Class<? extends AccountRuleConf>, Class<? extends AccountRule>>() { - - private static final long serialVersionUID = 3109256773218160485L; - - { - put(TestAccountRuleConf.class, TestAccountRule.class); - put(DefaultAccountRuleConf.class, DefaultAccountRule.class); - } - }; - - private static final Map<Class<? extends PasswordRuleConf>, Class<? extends PasswordRule>> PASSWORD_RULE_CLASSES = - new HashMap<Class<? extends PasswordRuleConf>, Class<? extends PasswordRule>>() { - - private static final long serialVersionUID = -6624291041977583649L; + @Autowired + private AnySearchDAO anySearchDAO; - { - put(TestPasswordRuleConf.class, TestPasswordRule.class); - put(DefaultPasswordRuleConf.class, DefaultPasswordRule.class); - } - }; + @Autowired + private ImplementationDAO implementationDAO; @Autowired - private AnySearchDAO anySearchDAO; + private EntityFactory entityFactory; @Autowired private DomainsHolder domainsHolder; @@ -206,9 +224,21 @@ public class ITImplementationLookup implements ImplementationLookup { if (AopUtils.getTargetClass(anySearchDAO).getName().contains("Elasticsearch")) { for (Map.Entry<String, DataSource> entry : domainsHolder.getDomains().entrySet()) { AuthContextUtils.execWithAuthContext(entry.getKey(), () -> { + Implementation reindex = implementationDAO.find(ImplementationType.TASKJOB_DELEGATE). + stream(). + filter(impl -> impl.getEngine() == ImplementationEngine.JAVA + && ES_REINDEX.equals(impl.getBody())). + findAny().orElse(null); + if (reindex == null) { + reindex = entityFactory.newEntity(Implementation.class); + reindex.setEngine(ImplementationEngine.JAVA); + reindex.setType(ImplementationType.TASKJOB_DELEGATE); + reindex.setBody(ES_REINDEX); + reindex = implementationDAO.save(reindex); + } + SchedTaskTO task = new SchedTaskTO(); - task.setJobDelegateClassName( - "org.apache.syncope.core.provisioning.java.job.ElasticsearchReindex"); + task.setJobDelegate(reindex.getKey()); task.setName("Elasticsearch Reindex"); task = taskLogic.createSchedTask(task); @@ -221,16 +251,13 @@ public class ITImplementationLookup implements ImplementationLookup { } @Override - public Set<String> getClassNames(final Type type) { + public Set<String> getClassNames(final ImplementationType type) { return CLASS_NAMES.get(type); } @Override public Set<Class<?>> getJWTSSOProviderClasses() { - Set<Class<?>> classNames = new HashSet<>(); - classNames.add(SyncopeJWTSSOProvider.class); - classNames.add(CustomJWTSSOProvider.class); - return classNames; + return JWTSSOPROVIDER_CLASSES; } @Override @@ -256,9 +283,6 @@ public class ITImplementationLookup implements ImplementationLookup { @Override public Set<Class<?>> getAuditAppenderClasses() { - Set<Class<?>> classes = new HashSet<>(); - classes.add(TestFileRewriteAuditAppender.class); - classes.add(TestFileAuditAppender.class); - return classes; + return AUDITAPPENDER_CLASSES; } } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java index d3039d0..ddd48fe 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestAccountRule.java @@ -30,16 +30,19 @@ public class TestAccountRule implements AccountRule { private TestAccountRuleConf conf; - @Transactional(readOnly = true) @Override - public void enforce(final AccountRuleConf conf, final User user) { + public void setConf(final AccountRuleConf conf) { if (conf instanceof TestAccountRuleConf) { this.conf = TestAccountRuleConf.class.cast(conf); } else { throw new IllegalArgumentException( AccountRuleConf.class.getName() + " expected, got " + conf.getClass().getName()); } + } + @Transactional(readOnly = true) + @Override + public void enforce(final User user) { if (!user.getUsername().contains(this.conf.getMustContainSubstring())) { throw new AccountPolicyException("Username not containing " + this.conf.getMustContainSubstring()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestNotificationRecipientsProvider.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestNotificationRecipientsProvider.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestNotificationRecipientsProvider.java index 178e399..4d1e3f7 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestNotificationRecipientsProvider.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestNotificationRecipientsProvider.java @@ -21,10 +21,10 @@ package org.apache.syncope.fit.core.reference; import java.util.Collections; import java.util.Set; import org.apache.syncope.core.persistence.api.entity.Notification; -import org.apache.syncope.core.provisioning.api.notification.NotificationRecipientsProvider; import org.springframework.transaction.annotation.Transactional; +import org.apache.syncope.core.provisioning.api.notification.RecipientsProvider; -public class TestNotificationRecipientsProvider implements NotificationRecipientsProvider { +public class TestNotificationRecipientsProvider implements RecipientsProvider { @Transactional(readOnly = true) @Override http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java index 2ca008b..69431ef 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestPasswordRule.java @@ -30,9 +30,13 @@ public class TestPasswordRule implements PasswordRule { private TestPasswordRuleConf conf; - @Transactional(readOnly = true) @Override - public void enforce(final PasswordRuleConf conf, final User user) { + public TestPasswordRuleConf getConf() { + return conf; + } + + @Override + public void setConf(final PasswordRuleConf conf) { if (conf instanceof TestPasswordRuleConf) { this.conf = TestPasswordRuleConf.class.cast(conf); } else { @@ -40,6 +44,11 @@ public class TestPasswordRule implements PasswordRule { PasswordRuleConf.class.getName() + " expected, got " + conf.getClass().getName()); } + } + + @Transactional(readOnly = true) + @Override + public void enforce(final User user) { if (!user.getClearPassword().endsWith(this.conf.getMustEndWith())) { throw new PasswordPolicyException("Password not ending with " + this.conf.getMustEndWith()); } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java index 2c392ec..931b183 100644 --- a/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java +++ b/fit/core-reference/src/main/java/org/apache/syncope/fit/core/reference/TestReconciliationFilterBuilder.java @@ -18,12 +18,12 @@ */ package org.apache.syncope.fit.core.reference; -import org.apache.syncope.core.provisioning.api.pushpull.ReconciliationFilterBuilder; import org.identityconnectors.framework.common.objects.AttributeBuilder; import org.identityconnectors.framework.common.objects.filter.Filter; import org.identityconnectors.framework.common.objects.filter.FilterBuilder; +import org.apache.syncope.core.provisioning.api.pushpull.ReconFilterBuilder; -public class TestReconciliationFilterBuilder implements ReconciliationFilterBuilder { +public class TestReconciliationFilterBuilder implements ReconFilterBuilder { private static final Filter EQUALS = FilterBuilder.equalTo(AttributeBuilder.build("SURNAME", "Rossi")); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java index 98a80a9..97667c3 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/AbstractITCase.java @@ -81,6 +81,7 @@ 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.GroupService; +import org.apache.syncope.common.rest.api.service.ImplementationService; import org.apache.syncope.common.rest.api.service.MailTemplateService; import org.apache.syncope.common.rest.api.service.RealmService; import org.apache.syncope.common.rest.api.service.RelationshipTypeService; @@ -234,6 +235,8 @@ public abstract class AbstractITCase { protected static SecurityQuestionService securityQuestionService; + protected static ImplementationService implementationService; + protected static CamelRouteService camelRouteService; protected static SAML2SPService saml2SpService; @@ -304,6 +307,7 @@ public abstract class AbstractITCase { notificationService = adminClient.getService(NotificationService.class); schemaService = adminClient.getService(SchemaService.class); securityQuestionService = adminClient.getService(SecurityQuestionService.class); + implementationService = adminClient.getService(ImplementationService.class); camelRouteService = adminClient.getService(CamelRouteService.class); saml2SpService = adminClient.getService(SAML2SPService.class); saml2IdPService = adminClient.getService(SAML2IdPService.class); @@ -321,7 +325,7 @@ public abstract class AbstractITCase { return new AttrPatch.Builder().operation(PatchOperation.ADD_REPLACE).attrTO(attrTO(schema, value)).build(); } - public <T> T getObject(final URI location, final Class<?> serviceClass, final Class<T> resultClass) { + public static <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); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java new file mode 100644 index 0000000..fe8968e --- /dev/null +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/ImplementationITCase.java @@ -0,0 +1,73 @@ +/* + * 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.core; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.fail; + +import java.util.UUID; +import javax.ws.rs.core.Response; +import org.apache.syncope.common.lib.SyncopeClientException; +import org.apache.syncope.common.lib.to.ImplementationTO; +import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.ImplementationService; +import org.apache.syncope.fit.AbstractITCase; +import org.apache.syncope.fit.core.reference.TestPullActions; +import org.junit.jupiter.api.Test; + +public class ImplementationITCase extends AbstractITCase { + + @Test + public void create() { + ImplementationTO implementationTO = new ImplementationTO(); + implementationTO.setKey(UUID.randomUUID().toString()); + implementationTO.setEngine(ImplementationEngine.JAVA); + implementationTO.setType(ImplementationType.PUSH_ACTIONS); + implementationTO.setBody(TestPullActions.class.getName()); + + // fail because type is wrong + try { + implementationService.create(implementationTO); + fail("This should not happen"); + } catch (SyncopeClientException e) { + assertEquals(ClientExceptionType.InvalidImplementation, e.getType()); + } + implementationTO.setType(ImplementationType.PULL_ACTIONS); + + Response response = implementationService.create(implementationTO); + if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) { + Exception ex = clientFactory.getExceptionMapper().fromResponse(response); + if (ex != null) { + throw (RuntimeException) ex; + } + } + + ImplementationTO actual = + getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(actual); + + implementationTO.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY)); + assertEquals(actual, implementationTO); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java index f7fe298..943fe92 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/LoggerITCase.java @@ -237,15 +237,6 @@ public class LoggerITCase extends AbstractITCase { found = false; for (EventCategoryTO eventCategoryTO : events) { if (EventCategoryType.TASK == eventCategoryTO.getType() - && "TestSampleJobDelegate".equals(eventCategoryTO.getCategory())) { - found = true; - } - } - assertTrue(found); - - found = false; - for (EventCategoryTO eventCategoryTO : events) { - if (EventCategoryType.TASK == eventCategoryTO.getType() && "PullJobDelegate".equals(eventCategoryTO.getCategory())) { found = true; } http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java index 6790f34..38832be 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/NotificationTaskITCase.java @@ -31,13 +31,17 @@ import org.apache.syncope.common.lib.to.AttrTO; import org.apache.syncope.common.lib.to.NotificationTaskTO; import org.apache.syncope.common.lib.to.ExecTO; import org.apache.syncope.common.lib.to.GroupTO; +import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.to.NotificationTO; import org.apache.syncope.common.lib.to.PagedResult; import org.apache.syncope.common.lib.types.AnyTypeKind; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.common.lib.types.TraceLevel; import org.apache.syncope.common.rest.api.beans.ExecuteQuery; import org.apache.syncope.common.rest.api.beans.TaskQuery; +import org.apache.syncope.common.rest.api.service.ImplementationService; import org.apache.syncope.common.rest.api.service.NotificationService; import org.apache.syncope.core.provisioning.java.job.notification.NotificationJob; import org.apache.syncope.fit.core.reference.TestNotificationRecipientsProvider; @@ -219,6 +223,15 @@ public class NotificationTaskITCase extends AbstractNotificationTaskITCase { @Test public void issueSYNCOPE446() throws Exception { // 1. Create notification + ImplementationTO recipientsProvider = new ImplementationTO(); + recipientsProvider.setKey(TestNotificationRecipientsProvider.class.getSimpleName()); + recipientsProvider.setEngine(ImplementationEngine.JAVA); + recipientsProvider.setType(ImplementationType.RECIPIENTS_PROVIDER); + recipientsProvider.setBody(TestNotificationRecipientsProvider.class.getName()); + Response response = implementationService.create(recipientsProvider); + recipientsProvider = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(recipientsProvider); + NotificationTO notification = new NotificationTO(); notification.setTraceLevel(TraceLevel.ALL); notification.getEvents().add("[LOGIC]:[GroupLogic]:[]:[create]:[SUCCESS]"); @@ -232,7 +245,7 @@ public class NotificationTaskITCase extends AbstractNotificationTaskITCase { notification.setSelfAsRecipient(false); notification.setRecipientAttrName("email"); notification.getStaticRecipients().add("[email protected]"); - notification.setRecipientsProviderClassName(TestNotificationRecipientsProvider.class.getName()); + notification.setRecipientsProvider(recipientsProvider.getKey()); String sender = "syncopetest-" + getUUIDString() + "@syncope.apache.org"; notification.setSender(sender); @@ -241,10 +254,10 @@ public class NotificationTaskITCase extends AbstractNotificationTaskITCase { notification.setTemplate("optin"); notification.setActive(true); - Response response = notificationService.create(notification); + response = notificationService.create(notification); notification = getObject(response.getLocation(), NotificationService.class, NotificationTO.class); assertNotNull(notification); - assertEquals(TestNotificationRecipientsProvider.class.getName(), notification.getRecipientsProviderClassName()); + assertEquals(recipientsProvider.getKey(), notification.getRecipientsProvider()); // 2. create group GroupTO groupTO = new GroupTO(); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java index 40664f0..51b49ff 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PolicyITCase.java @@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.fail; import java.util.Arrays; import java.util.List; +import javax.ws.rs.core.Response; import org.apache.commons.lang3.SerializationUtils; import org.apache.syncope.common.lib.SyncopeClientException; import org.apache.syncope.common.lib.policy.AccountPolicyTO; @@ -38,6 +39,12 @@ import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.policy.DefaultPasswordRuleConf; import org.apache.syncope.common.lib.types.PolicyType; import org.apache.syncope.common.lib.policy.PullPolicySpec; +import org.apache.syncope.common.lib.to.ImplementationTO; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; +import org.apache.syncope.common.rest.api.RESTHeaders; +import org.apache.syncope.common.rest.api.service.ImplementationService; +import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.fit.AbstractITCase; import org.apache.syncope.fit.core.reference.TestPullRule; import org.junit.jupiter.api.Test; @@ -45,11 +52,27 @@ import org.junit.jupiter.api.Test; public class PolicyITCase extends AbstractITCase { private PullPolicyTO buildPullPolicyTO() { - PullPolicyTO policy = new PullPolicyTO(); + ImplementationTO corrRule = null; + try { + corrRule = implementationService.read(TestPullRule.class.getSimpleName()); + } catch (SyncopeClientException e) { + if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) { + corrRule = new ImplementationTO(); + corrRule.setKey(TestPullRule.class.getSimpleName()); + corrRule.setEngine(ImplementationEngine.JAVA); + corrRule.setType(ImplementationType.PULL_CORRELATION_RULE); + corrRule.setBody(TestPullRule.class.getName()); + Response response = implementationService.create(corrRule); + corrRule = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(corrRule); + } + } + assertNotNull(corrRule); PullPolicySpec spec = new PullPolicySpec(); - spec.getCorrelationRules().put(AnyTypeKind.USER.name(), TestPullRule.class.getName()); + spec.getCorrelationRules().put(AnyTypeKind.USER.name(), corrRule.getKey()); + PullPolicyTO policy = new PullPolicyTO(); policy.setSpecification(spec); policy.setDescription("Pull policy"); @@ -110,7 +133,7 @@ public class PolicyITCase extends AbstractITCase { PullPolicyTO policyTO = createPolicy(policy); assertNotNull(policyTO); - assertEquals(TestPullRule.class.getName(), + assertEquals(TestPullRule.class.getSimpleName(), policyTO.getSpecification().getCorrelationRules().get(AnyTypeKind.USER.name())); } @@ -126,15 +149,21 @@ public class PolicyITCase extends AbstractITCase { assertNotNull(policy); assertNotEquals("ce93fcda-dc3a-4369-a7b0-a6108c261c85", policy.getKey()); - ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).setMaxLength(22); + ImplementationTO rule = implementationService.read(policy.getRules().get(0)); + assertNotNull(rule); + + DefaultPasswordRuleConf ruleConf = POJOHelper.deserialize(rule.getBody(), DefaultPasswordRuleConf.class); + ruleConf.setMaxLength(22); + rule.setBody(POJOHelper.serialize(ruleConf)); // update new password policy policyService.update(policy); policy = policyService.read(policy.getKey()); - assertNotNull(policy); - assertEquals(22, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMaxLength()); - assertEquals(8, ((DefaultPasswordRuleConf) policy.getRuleConfs().get(0)).getMinLength()); + + ruleConf = POJOHelper.deserialize(rule.getBody(), DefaultPasswordRuleConf.class); + assertEquals(22, ruleConf.getMaxLength()); + assertEquals(8, ruleConf.getMinLength()); } @Test @@ -155,8 +184,9 @@ public class PolicyITCase extends AbstractITCase { } @Test - public void getCorrelationRules() { - assertEquals(1, syncopeService.platform().getPullCorrelationRules().size()); + public void getPullCorrelationRuleJavaClasses() { + assertEquals(1, syncopeService.platform(). + getJavaImplInfo(ImplementationType.PULL_CORRELATION_RULE).get().getClasses().size()); } @Test @@ -167,7 +197,16 @@ public class PolicyITCase extends AbstractITCase { DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf(); ruleConf.setMinLength(3); ruleConf.setMaxLength(8); - policy.getRuleConfs().add(ruleConf); + + ImplementationTO rule = new ImplementationTO(); + rule.setKey("DefaultAccountRuleConf" + getUUIDString()); + rule.setEngine(ImplementationEngine.JAVA); + rule.setType(ImplementationType.ACCOUNT_RULE); + rule.setBody(POJOHelper.serialize(ruleConf)); + Response response = implementationService.create(rule); + rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY)); + + policy.getRules().add(rule.getKey()); policy = createPolicy(policy); assertNotNull(policy); @@ -182,7 +221,16 @@ public class PolicyITCase extends AbstractITCase { DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf(); ruleConf.setMinLength(3); ruleConf.setMaxLength(8); - policy.getRuleConfs().add(ruleConf); + + ImplementationTO rule = new ImplementationTO(); + rule.setKey("DefaultAccountRuleConf" + getUUIDString()); + rule.setEngine(ImplementationEngine.JAVA); + rule.setType(ImplementationType.ACCOUNT_RULE); + rule.setBody(POJOHelper.serialize(ruleConf)); + Response response = implementationService.create(rule); + rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY)); + + policy.getRules().add(rule.getKey()); policy = createPolicy(policy); assertNotNull(policy); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java index c1ae0b8..a130bd5 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PropagationTaskITCase.java @@ -116,7 +116,7 @@ public class PropagationTaskITCase extends AbstractTaskITCase { Optional<ItemTO> mappingItem = provision.getMapping().getItems().stream(). filter(item -> "location".equals(item.getIntAttrName())).findFirst(); assertTrue(mappingItem.isPresent()); - assertTrue(mappingItem.get().getTransformerClassNames().isEmpty()); + assertTrue(mappingItem.get().getTransformers().isEmpty()); String suffix = getUUIDString(); mappingItem.get().setPropagationJEXLTransformer("value + '" + suffix + "'"); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java index 391289a..5d67ece 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PullTaskITCase.java @@ -62,6 +62,7 @@ import org.apache.syncope.common.lib.to.ProvisionTO; import org.apache.syncope.common.lib.to.ItemTO; import org.apache.syncope.common.lib.to.PullTaskTO; import org.apache.syncope.common.lib.to.ExecTO; +import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.syncope.common.lib.to.UserTO; import org.apache.syncope.common.lib.types.AnyTypeKind; @@ -69,6 +70,8 @@ import org.apache.syncope.common.lib.types.CipherAlgorithm; import org.apache.syncope.common.lib.types.ClientExceptionType; import org.apache.syncope.common.lib.types.ConnConfProperty; import org.apache.syncope.common.lib.types.ConnectorCapability; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; import org.apache.syncope.common.lib.types.ResourceDeassociationAction; import org.apache.syncope.common.lib.types.PullMode; @@ -76,6 +79,7 @@ import org.apache.syncope.common.lib.types.TaskType; import org.apache.syncope.common.rest.api.beans.AnyQuery; import org.apache.syncope.common.rest.api.beans.TaskQuery; import org.apache.syncope.common.rest.api.service.ConnectorService; +import org.apache.syncope.common.rest.api.service.ImplementationService; import org.apache.syncope.common.rest.api.service.TaskService; import org.apache.syncope.core.provisioning.java.pushpull.DBPasswordPullActions; import org.apache.syncope.core.provisioning.java.pushpull.LDAPPasswordPullActions; @@ -100,14 +104,32 @@ public class PullTaskITCase extends AbstractTaskITCase { @BeforeAll public static void testPullActionsSetup() { + ImplementationTO pullActions = null; + try { + pullActions = implementationService.read(TestPullActions.class.getSimpleName()); + } catch (SyncopeClientException e) { + if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) { + pullActions = new ImplementationTO(); + pullActions.setKey(TestPullActions.class.getSimpleName()); + pullActions.setEngine(ImplementationEngine.JAVA); + pullActions.setType(ImplementationType.PULL_ACTIONS); + pullActions.setBody(TestPullActions.class.getName()); + Response response = implementationService.create(pullActions); + pullActions = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(pullActions); + } + } + assertNotNull(pullActions); + PullTaskTO pullTask = taskService.read(PULL_TASK_KEY, true); - pullTask.getActionsClassNames().add(TestPullActions.class.getName()); + pullTask.getActions().add(pullActions.getKey()); taskService.update(pullTask); } @Test public void getPullActionsClasses() { - Set<String> actions = syncopeService.platform().getPullActions(); + Set<String> actions = syncopeService.platform(). + getJavaImplInfo(ImplementationType.PULL_ACTIONS).get().getClasses(); assertNotNull(actions); assertFalse(actions.isEmpty()); } @@ -147,7 +169,7 @@ public class PullTaskITCase extends AbstractTaskITCase { task = taskService.read(actual.getKey(), true); assertNotNull(task); assertEquals(actual.getKey(), task.getKey()); - assertEquals(actual.getJobDelegateClassName(), task.getJobDelegateClassName()); + assertEquals(actual.getJobDelegate(), task.getJobDelegate()); assertEquals(userTemplate, task.getTemplates().get(AnyTypeKind.USER.name())); assertEquals(groupTemplate, task.getTemplates().get(AnyTypeKind.GROUP.name())); } @@ -406,8 +428,18 @@ public class PullTaskITCase extends AbstractTaskITCase { ItemTO mappingItem = provision.getMapping().getItems().stream(). filter(object -> "location".equals(object.getIntAttrName())).findFirst().get(); assertNotNull(mappingItem); - mappingItem.getTransformerClassNames().clear(); - mappingItem.getTransformerClassNames().add(PrefixItemTransformer.class.getName()); + + ImplementationTO transformer = new ImplementationTO(); + transformer.setKey(PrefixItemTransformer.class.getSimpleName()); + transformer.setEngine(ImplementationEngine.JAVA); + transformer.setType(ImplementationType.ITEM_TRANSFORMER); + transformer.setBody(PrefixItemTransformer.class.getName()); + Response response = implementationService.create(transformer); + transformer = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(transformer); + + mappingItem.getTransformers().clear(); + mappingItem.getTransformers().add(transformer.getKey()); try { resourceService.update(resource); @@ -488,15 +520,22 @@ public class PullTaskITCase extends AbstractTaskITCase { + "'" + user2OnTestPull + "', 'user2', 'Rossi', '[email protected]', NULL)"); // 2. create new pull task for test-db, with reconciliation filter (surname 'Rossi') + ImplementationTO reconFilterBuilder = new ImplementationTO(); + reconFilterBuilder.setKey(TestReconciliationFilterBuilder.class.getSimpleName()); + reconFilterBuilder.setEngine(ImplementationEngine.JAVA); + reconFilterBuilder.setType(ImplementationType.RECON_FILTER_BUILDER); + reconFilterBuilder.setBody(TestReconciliationFilterBuilder.class.getName()); + Response response = implementationService.create(reconFilterBuilder); + reconFilterBuilder = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(reconFilterBuilder); + task = taskService.read("7c2242f4-14af-4ab5-af31-cdae23783655", true); task.setPullMode(PullMode.FILTERED_RECONCILIATION); - task.setReconciliationFilterBuilderClassName(TestReconciliationFilterBuilder.class.getName()); - Response response = taskService.create(task); + task.setReconFilterBuilder(reconFilterBuilder.getKey()); + response = taskService.create(task); task = getObject(response.getLocation(), TaskService.class, PullTaskTO.class); assertNotNull(task); - assertEquals( - TestReconciliationFilterBuilder.class.getName(), - task.getReconciliationFilterBuilderClassName()); + assertEquals(reconFilterBuilder.getKey(), task.getReconFilterBuilder()); // 3. exec task ExecTO execution = execProvisioningTask(taskService, task.getKey(), 50, false); @@ -714,8 +753,25 @@ public class PullTaskITCase extends AbstractTaskITCase { // ----------------------------- // Add a custom correlation rule // ----------------------------- + ImplementationTO corrRule = null; + try { + corrRule = implementationService.read(TestPullRule.class.getSimpleName()); + } catch (SyncopeClientException e) { + if (e.getType().getResponseStatus() == Response.Status.NOT_FOUND) { + corrRule = new ImplementationTO(); + corrRule.setKey(TestPullRule.class.getSimpleName()); + corrRule.setEngine(ImplementationEngine.JAVA); + corrRule.setType(ImplementationType.PULL_CORRELATION_RULE); + corrRule.setBody(TestPullRule.class.getName()); + Response response = implementationService.create(corrRule); + corrRule = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(corrRule); + } + } + assertNotNull(corrRule); + PullPolicyTO policyTO = policyService.read("9454b0d7-2610-400a-be82-fc23cf553dd6"); - policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), TestPullRule.class.getName()); + policyTO.getSpecification().getCorrelationRules().put(AnyTypeKind.USER.name(), corrRule.getKey()); policyService.update(policyTO); // ----------------------------- @@ -856,6 +912,15 @@ public class PullTaskITCase extends AbstractTaskITCase { jdbcTemplate.execute("UPDATE test set PASSWORD='" + newPassword + "' where ID='" + user.getUsername() + "'"); // 4. Pull the user from the resource + ImplementationTO pullActions = new ImplementationTO(); + pullActions.setKey(DBPasswordPullActions.class.getSimpleName()); + pullActions.setEngine(ImplementationEngine.JAVA); + pullActions.setType(ImplementationType.PULL_ACTIONS); + pullActions.setBody(DBPasswordPullActions.class.getName()); + Response response = implementationService.create(pullActions); + pullActions = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(pullActions); + PullTaskTO pullTask = new PullTaskTO(); pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM); pullTask.setName("DB Pull Task"); @@ -864,7 +929,7 @@ public class PullTaskITCase extends AbstractTaskITCase { pullTask.setPerformUpdate(true); pullTask.setPullMode(PullMode.FULL_RECONCILIATION); pullTask.setResource(RESOURCE_NAME_TESTDB); - pullTask.getActionsClassNames().add(DBPasswordPullActions.class.getName()); + pullTask.getActions().add(pullActions.getKey()); Response taskResponse = taskService.create(pullTask); PullTaskTO actual = getObject(taskResponse.getLocation(), TaskService.class, PullTaskTO.class); @@ -873,7 +938,7 @@ public class PullTaskITCase extends AbstractTaskITCase { pullTask = taskService.read(actual.getKey(), true); assertNotNull(pullTask); assertEquals(actual.getKey(), pullTask.getKey()); - assertEquals(actual.getJobDelegateClassName(), pullTask.getJobDelegateClassName()); + assertEquals(actual.getJobDelegate(), pullTask.getJobDelegate()); ExecTO execution = execProvisioningTask(taskService, pullTask.getKey(), 50, false); assertEquals(PropagationTaskExecStatus.SUCCESS, PropagationTaskExecStatus.valueOf(execution.getStatus())); @@ -936,6 +1001,15 @@ public class PullTaskITCase extends AbstractTaskITCase { connectorService.update(resourceConnector); // 6. Pull the user from the resource + ImplementationTO pullActions = new ImplementationTO(); + pullActions.setKey(LDAPPasswordPullActions.class.getSimpleName()); + pullActions.setEngine(ImplementationEngine.JAVA); + pullActions.setType(ImplementationType.PULL_ACTIONS); + pullActions.setBody(LDAPPasswordPullActions.class.getName()); + Response response = implementationService.create(pullActions); + pullActions = getObject(response.getLocation(), ImplementationService.class, ImplementationTO.class); + assertNotNull(pullActions); + pullTask = new PullTaskTO(); pullTask.setDestinationRealm(SyncopeConstants.ROOT_REALM); pullTask.setName("LDAP Pull Task"); @@ -944,7 +1018,7 @@ public class PullTaskITCase extends AbstractTaskITCase { pullTask.setPerformUpdate(true); pullTask.setPullMode(PullMode.FULL_RECONCILIATION); pullTask.setResource(RESOURCE_NAME_LDAP); - pullTask.getActionsClassNames().add(LDAPPasswordPullActions.class.getName()); + pullTask.getActions().add(pullActions.getKey()); Response taskResponse = taskService.create(pullTask); pullTask = getObject(taskResponse.getLocation(), TaskService.class, PullTaskTO.class); http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java index 17d9c05..c46c445 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/PushTaskITCase.java @@ -45,6 +45,7 @@ import org.apache.syncope.common.lib.to.ProvisionTO; import org.apache.syncope.common.lib.to.ResourceTO; import org.apache.syncope.common.lib.types.AnyTypeKind; import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.common.lib.types.MappingPurpose; import org.apache.syncope.common.lib.types.MatchingRule; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; @@ -70,7 +71,8 @@ public class PushTaskITCase extends AbstractTaskITCase { @Test public void getPushActionsClasses() { - Set<String> actions = syncopeService.platform().getPushActions(); + Set<String> actions = syncopeService.platform(). + getJavaImplInfo(ImplementationType.PUSH_ACTIONS).get().getClasses(); assertNotNull(actions); } @@ -110,7 +112,7 @@ public class PushTaskITCase extends AbstractTaskITCase { task = taskService.read(actual.getKey(), true); assertNotNull(task); assertEquals(task.getKey(), actual.getKey()); - assertEquals(task.getJobDelegateClassName(), actual.getJobDelegateClassName()); + assertEquals(task.getJobDelegate(), actual.getJobDelegate()); assertEquals(task.getFilters().get(AnyTypeKind.USER.name()), actual.getFilters().get(AnyTypeKind.USER.name())); assertEquals(task.getFilters().get(AnyTypeKind.GROUP.name()), http://git-wip-us.apache.org/repos/asf/syncope/blob/d5b57922/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java ---------------------------------------------------------------------- diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java index 751b9d3..23c202a 100644 --- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java +++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/RealmITCase.java @@ -27,6 +27,7 @@ import static org.junit.jupiter.api.Assertions.fail; import java.util.List; import java.util.Optional; +import java.util.UUID; import javax.ws.rs.core.GenericType; import javax.ws.rs.core.Response; import org.apache.syncope.common.lib.SyncopeClientException; @@ -34,10 +35,15 @@ import org.apache.syncope.common.lib.SyncopeConstants; import org.apache.syncope.common.lib.policy.AccountPolicyTO; import org.apache.syncope.common.lib.to.RealmTO; import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf; +import org.apache.syncope.common.lib.to.ImplementationTO; import org.apache.syncope.common.lib.to.ProvisioningResult; import org.apache.syncope.common.lib.types.ClientExceptionType; +import org.apache.syncope.common.lib.types.ImplementationEngine; +import org.apache.syncope.common.lib.types.ImplementationType; import org.apache.syncope.common.lib.types.PropagationTaskExecStatus; +import org.apache.syncope.common.rest.api.RESTHeaders; import org.apache.syncope.common.rest.api.service.RealmService; +import org.apache.syncope.core.provisioning.api.serialization.POJOHelper; import org.apache.syncope.fit.AbstractITCase; import org.junit.jupiter.api.Test; @@ -122,13 +128,21 @@ public class RealmITCase extends AbstractITCase { @Test public void deletingAccountPolicy() { // 1. create account policy - AccountPolicyTO policy = new AccountPolicyTO(); - policy.setDescription("deletingAccountPolicy"); - DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf(); ruleConf.setMinLength(3); ruleConf.setMaxLength(8); - policy.getRuleConfs().add(ruleConf); + + ImplementationTO rule = new ImplementationTO(); + rule.setKey("DefaultAccountRuleConf" + UUID.randomUUID().toString()); + rule.setEngine(ImplementationEngine.JAVA); + rule.setType(ImplementationType.ACCOUNT_RULE); + rule.setBody(POJOHelper.serialize(ruleConf)); + Response response = implementationService.create(rule); + rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY)); + + AccountPolicyTO policy = new AccountPolicyTO(); + policy.setDescription("deletingAccountPolicy"); + policy.getRules().add(rule.getKey()); policy = createPolicy(policy); assertNotNull(policy); @@ -138,7 +152,7 @@ public class RealmITCase extends AbstractITCase { realm.setName("withppolicy"); realm.setAccountPolicy(policy.getKey()); - Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm); + response = realmService.create(SyncopeConstants.ROOT_REALM, realm); RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class); assertNotNull(actuals); assertTrue(actuals.length > 0);
