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 2017/08/03 15:55:42 UTC
[1/4] syncope git commit: [SYNCOPE-1146][SYNCOPE-1147] Now it
possible to configure an IdP to create unmatching users / update matching
users;
the defined mapping, alongside with user template and SAML2IdPActions
implementations are taken into account to
Repository: syncope
Updated Branches:
refs/heads/2_0_X 48707e6b2 -> 1cf0d2a02
refs/heads/master 7eb33dcc8 -> f1c004bfc
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
index 2277c14..888e870 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
@@ -22,6 +22,7 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
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;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
import org.springframework.stereotype.Component;
@Component
@@ -36,6 +37,8 @@ public class JPASAML2EntityFactory implements SAML2EntityFactory {
result = (E) new JPASAML2IdP();
} else if (reference.equals(SAML2IdPItem.class)) {
result = (E) new JPASAML2IdPItem();
+ } else if (reference.equals(SAML2UserTemplate.class)) {
+ result = (E) new JPASAML2UserTemplate();
} else {
throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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 cf1e3a8..d6df04d 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,15 +19,21 @@
package org.apache.syncope.core.persistence.jpa.entity;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+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.Lob;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
@@ -37,6 +43,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.apache.syncope.common.lib.types.SAML2BindingType;
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;
import org.apache.syncope.core.persistence.jpa.validation.entity.SAML2IdPCheck;
@Entity
@@ -65,11 +72,31 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
@Min(0)
@Max(1)
@Column(nullable = false)
+ private Integer createUnmatching;
+
+ @Min(0)
+ @Max(1)
+ @Column(nullable = false)
+ private Integer updateMatching;
+
+ @Min(0)
+ @Max(1)
+ @Column(nullable = false)
private Integer useDeflateEncoding;
@Column(nullable = false)
private SAML2BindingType bindingType;
+ @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",
+ joinColumns =
+ @JoinColumn(name = "saml2IdP_id", referencedColumnName = "id"))
+ private Set<String> actionsClassNames = new HashSet<>();
+
@Override
public String getEntityID() {
return entityID;
@@ -101,6 +128,26 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
}
@Override
+ public boolean isCreateUnmatching() {
+ return isBooleanAsInteger(createUnmatching);
+ }
+
+ @Override
+ public void setCreateUnmatching(final boolean createUnmatching) {
+ this.createUnmatching = getBooleanAsInteger(createUnmatching);
+ }
+
+ @Override
+ public boolean isUpdateMatching() {
+ return isBooleanAsInteger(updateMatching);
+ }
+
+ @Override
+ public void setUpdateMatching(final boolean updateMatching) {
+ this.updateMatching = getBooleanAsInteger(updateMatching);
+ }
+
+ @Override
public boolean isUseDeflateEncoding() {
return isBooleanAsInteger(useDeflateEncoding);
}
@@ -121,6 +168,17 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
}
@Override
+ public SAML2UserTemplate getUserTemplate() {
+ return userTemplate;
+ }
+
+ @Override
+ public void setUserTemplate(final SAML2UserTemplate userTemplate) {
+ checkType(userTemplate, JPASAML2UserTemplate.class);
+ this.userTemplate = (JPASAML2UserTemplate) userTemplate;
+ }
+
+ @Override
public boolean add(final SAML2IdPItem item) {
checkType(item, JPASAML2IdPItem.class);
return items.contains((JPASAML2IdPItem) item) || items.add((JPASAML2IdPItem) item);
@@ -148,4 +206,8 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
this.add(item);
}
+ @Override
+ public Set<String> getActionsClassNames() {
+ return actionsClassNames;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
new file mode 100644
index 0000000..538fa94
--- /dev/null
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+
+@Entity
+@Table(name = JPASAML2UserTemplate.TABLE, uniqueConstraints =
+ @UniqueConstraint(columnNames = { "idp_id" }))
+public class JPASAML2UserTemplate extends AbstractAnyTemplate implements SAML2UserTemplate {
+
+ private static final long serialVersionUID = -4575039890434426856L;
+
+ public static final String TABLE = "SAML2UserTemplate";
+
+ @ManyToOne
+ private JPASAML2IdP idp;
+
+ @Override
+ public SAML2IdP getIdP() {
+ return idp;
+ }
+
+ @Override
+ public void setIdP(final SAML2IdP idp) {
+ checkType(idp, JPASAML2IdP.class);
+ this.idp = (JPASAML2IdP) idp;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java b/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
new file mode 100644
index 0000000..6f23804
--- /dev/null
+++ b/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+public interface SAML2IdPActions {
+
+ UserTO beforeCreate(UserTO input, SAML2LoginResponseTO loginResponse);
+
+ UserTO afterCreate(UserTO input, SAML2LoginResponseTO loginResponse);
+
+ UserPatch beforeUpdate(UserPatch input, SAML2LoginResponseTO loginResponse);
+
+ UserTO afterUpdate(UserTO input, SAML2LoginResponseTO loginResponse);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
new file mode 100644
index 0000000..ba5fc40
--- /dev/null
+++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+
+public class DefaultSAML2IdPActions implements SAML2IdPActions {
+
+ @Override
+ public UserTO beforeCreate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserTO afterCreate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserPatch beforeUpdate(final UserPatch input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserTO afterUpdate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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 b2668c5..2f2f9d0 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
@@ -24,6 +24,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
+import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -36,6 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
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;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.provisioning.api.IntAttrName;
import org.apache.syncope.core.provisioning.api.data.SAML2IdPDataBinder;
@@ -168,9 +170,24 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
idp.setEntityID(idpTO.getEntityID());
idp.setName(idpTO.getName());
idp.setMetadata(Base64.decode(idpTO.getMetadata()));
+ idp.setCreateUnmatching(idpTO.isCreateUnmatching());
+ idp.setUpdateMatching(idpTO.isUpdateMatching());
idp.setUseDeflateEncoding(idpTO.isUseDeflateEncoding());
idp.setBindingType(idpTO.getBindingType());
+ if (idpTO.getUserTemplate() == null) {
+ idp.setUserTemplate(null);
+ } else {
+ SAML2UserTemplate userTemplate = idp.getUserTemplate();
+ if (userTemplate == null) {
+ userTemplate = entityFactory.newEntity(SAML2UserTemplate.class);
+ userTemplate.setAnyType(anyTypeDAO.findUser());
+ userTemplate.setIdP(idp);
+ idp.setUserTemplate(userTemplate);
+ }
+ userTemplate.set(idpTO.getUserTemplate());
+ }
+
idp.getItems().clear();
AnyTypeClassTO allowedSchemas = new AnyTypeClassTO();
for (AnyTypeClass anyTypeClass : anyTypeDAO.findUser().getClasses()) {
@@ -186,6 +203,9 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
}
populateItems(idpTO, idp, allowedSchemas);
+ idp.getActionsClassNames().clear();
+ idp.getActionsClassNames().addAll(idpTO.getActionsClassNames());
+
return saml2IdPDAO.save(idp);
}
@@ -213,10 +233,18 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
idpTO.setName(idp.getName());
idpTO.setUseDeflateEncoding(idp.isUseDeflateEncoding());
idpTO.setBindingType(idp.getBindingType());
+ idpTO.setCreateUnmatching(idp.isCreateUnmatching());
+ idpTO.setUpdateMatching(idp.isUpdateMatching());
idpTO.setMetadata(Base64.encode(idp.getMetadata()));
+ if (idp.getUserTemplate() != null) {
+ idpTO.setUserTemplate((UserTO) idp.getUserTemplate().get());
+ }
+
populateItems(idp, idpTO);
+ idpTO.getActionsClassNames().addAll(idp.getActionsClassNames());
+
return idpTO;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java b/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
index 5761c01..0d528c3 100644
--- a/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
+++ b/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.rest.api.service;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -40,6 +41,16 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
public interface SAML2IdPService extends JAXRSService {
/**
+ * Returns the list of available SAML2IdPActions implementations.
+ *
+ * @return the list of available SAML2IdPActions implementations
+ */
+ @GET
+ @Path("actionsClasses")
+ @Produces({ MediaType.APPLICATION_JSON })
+ Set<String> getActionsClasses();
+
+ /**
* Returns a list of all defined SAML 2.0 Identity Providers.
*
* @return list of all defined SAML 2.0 Identity Providers
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java b/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
index 1f2790f..ebda30d 100644
--- a/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
+++ b/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.rest.cxf.service;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -35,6 +36,11 @@ public class SAML2IdPServiceImpl extends AbstractServiceImpl implements SAML2IdP
private SAML2IdPLogic logic;
@Override
+ public Set<String> getActionsClasses() {
+ return logic.getActionsClasses();
+ }
+
+ @Override
public List<SAML2IdPTO> list() {
return logic.list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index e3cb7e0..6967e73 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -22,6 +22,7 @@ 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;
@@ -49,6 +50,7 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
import org.apache.syncope.common.lib.to.SAML2RequestTO;
+import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.service.SAML2SPService;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.SAML2SPDetector;
@@ -173,13 +175,20 @@ public class SAML2ITCase extends AbstractITCase {
}
});
assertNotNull(ssoCircle);
+ assertFalse(ssoCircle.isCreateUnmatching());
+ assertNull(ssoCircle.getUserTemplate());
assertFalse(ssoCircle.getItems().isEmpty());
assertNotNull(ssoCircle.getConnObjectKeyItem());
assertNotEquals("email", ssoCircle.getConnObjectKeyItem().getIntAttrName());
assertNotEquals("EmailAddress", ssoCircle.getConnObjectKeyItem().getExtAttrName());
- ssoCircle.getItems().clear();
+ ssoCircle.setCreateUnmatching(true);
+
+ UserTO userTemplate = new UserTO();
+ userTemplate.setRealm("'/'");
+ ssoCircle.setUserTemplate(userTemplate);
+ ssoCircle.getItems().clear();
ItemTO keyMapping = new ItemTO();
keyMapping.setIntAttrName("email");
keyMapping.setExtAttrName("EmailAddress");
@@ -188,6 +197,8 @@ public class SAML2ITCase extends AbstractITCase {
saml2IdPService.update(ssoCircle);
ssoCircle = saml2IdPService.read(ssoCircle.getKey());
+ assertTrue(ssoCircle.isCreateUnmatching());
+ assertEquals(userTemplate, ssoCircle.getUserTemplate());
assertEquals("email", ssoCircle.getConnObjectKeyItem().getIntAttrName());
assertEquals("EmailAddress", ssoCircle.getConnObjectKeyItem().getExtAttrName());
}
[2/4] syncope git commit: [SYNCOPE-1146][SYNCOPE-1147] Now it
possible to configure an IdP to create unmatching users / update matching
users;
the defined mapping, alongside with user template and SAML2IdPActions
implementations are taken into account to
Posted by il...@apache.org.
[SYNCOPE-1146][SYNCOPE-1147] Now it possible to configure an IdP to create unmatching users / update matching users; the defined mapping, alongside with user template and SAML2IdPActions implementations are taken into account to provide the actual user data
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/1cf0d2a0
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/1cf0d2a0
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/1cf0d2a0
Branch: refs/heads/2_0_X
Commit: 1cf0d2a02873926d6a2b41f1cb11d2cc0aa5ab83
Parents: 48707e6
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 3 17:53:38 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 3 17:53:38 2017 +0200
----------------------------------------------------------------------
.../console/tasks/SchedTaskDirectoryPanel.java | 5 +-
.../markup/html/bootstrap/dialog/BaseModal.java | 4 +-
.../wizards/any/UserTemplateWizardBuilder.java | 17 ++
.../console/panels/RealmDetails_it.properties | 2 +-
.../jpa/entity/JPAAnyTemplateRealm.java | 4 +-
.../provisioning/java/utils/MappingUtils.java | 6 +-
.../provisioning/java/utils/TemplateUtils.java | 74 ++---
.../saml2lsp/agent/AbstractSAML2SPServlet.java | 1 -
.../console/panels/SAML2IdPsDirectoryPanel.java | 110 ++++++-
.../console/rest/SAML2IdPsRestClient.java | 5 +
.../console/wizards/SAML2IdPWizardBuilder.java | 36 ++-
.../panels/SAML2IdPsDirectoryPanel.properties | 4 +
.../SAML2IdPsDirectoryPanel_it.properties | 4 +
.../SAML2IdPsDirectoryPanel_pt_BR.properties | 4 +
.../SAML2IdPsDirectoryPanel_ru.properties | 4 +
.../syncope/common/lib/to/SAML2IdPTO.java | 41 +++
.../common/lib/to/SAML2LoginResponseTO.java | 14 +
.../common/lib/to/SAML2ReceivedResponseTO.java | 10 -
.../syncope/core/logic/SAML2IdPLogic.java | 16 +-
.../apache/syncope/core/logic/SAML2SPLogic.java | 140 +++------
...AML2SPClassPathScanImplementationLookup.java | 78 +++++
.../syncope/core/logic/saml2/SAML2IdPCache.java | 16 +-
.../core/logic/saml2/SAML2IdPEntity.java | 51 ++--
.../core/logic/saml2/SAML2ReaderWriter.java | 1 -
.../core/logic/saml2/SAML2UserManager.java | 292 +++++++++++++++++++
.../core/persistence/api/entity/SAML2IdP.java | 15 +
.../api/entity/SAML2UserTemplate.java | 26 ++
.../jpa/entity/JPASAML2EntityFactory.java | 3 +
.../persistence/jpa/entity/JPASAML2IdP.java | 62 ++++
.../jpa/entity/JPASAML2UserTemplate.java | 52 ++++
.../core/provisioning/api/SAML2IdPActions.java | 34 +++
.../java/DefaultSAML2IdPActions.java | 48 +++
.../java/data/SAML2IdPDataBinderImpl.java | 28 ++
.../rest/api/service/SAML2IdPService.java | 11 +
.../rest/cxf/service/SAML2IdPServiceImpl.java | 6 +
.../apache/syncope/fit/core/SAML2ITCase.java | 13 +-
36 files changed, 1026 insertions(+), 211 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index f09c0dc..7663235 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -72,8 +72,8 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
private static final long serialVersionUID = 4984337552918213290L;
- private static final String GROUP_MEMBER_PROVISION_TASKJOB
- = "org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate";
+ private static final String GROUP_MEMBER_PROVISION_TASKJOB =
+ "org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate";
protected final Class<T> reference;
@@ -116,6 +116,7 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
protected Serializable onApplyInternal(
final TemplatableTO targetObject, final String type, final AnyTO anyTO) {
+
targetObject.getTemplates().put(type, anyTO);
new TaskRestClient().update(SchedTaskTO.class.cast(targetObject));
return targetObject;
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
index a5716e6..1df1e6c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
@@ -164,8 +164,8 @@ public class BaseModal<T extends Serializable> extends Modal<T> {
private BaseModal<T> setInternalContent(final Panel component) {
if (!component.getId().equals(getContentId())) {
- throw new WicketRuntimeException(
- "Modal content id is wrong. Component ID:" + component.getId() + "; content ID: " + getContentId());
+ throw new WicketRuntimeException("Modal content id is wrong. "
+ + "Component ID: " + component.getId() + "; content ID: " + getContentId());
}
content.replaceWith(component);
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
index 8d0dc5b..3c8111c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
@@ -34,6 +34,23 @@ public class UserTemplateWizardBuilder extends UserWizardBuilder implements Temp
private final TemplatableTO templatable;
public UserTemplateWizardBuilder(
+ final UserTO template,
+ final List<String> anyTypeClasses,
+ final UserFormLayoutInfo formLayoutInfo,
+ final PageReference pageRef) {
+
+ super(anyTypeClasses, formLayoutInfo, pageRef);
+ templatable = null;
+
+ if (template == null) {
+ setItem(new UserWrapper(new UserTO()));
+ } else {
+ setItem(new UserWrapper(template));
+ }
+
+ }
+
+ public UserTemplateWizardBuilder(
final TemplatableTO templatable,
final List<String> anyTypeClasses,
final UserFormLayoutInfo formLayoutInfo,
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
index 05d20c2..80a008a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
@@ -17,5 +17,5 @@
fullPath=Percorso
accountPolicy=Account Policy
passwordPolicy=Password Policy
-actionsClassNames=Actions
+actionsClassNames=Azioni
resources=Risorse assegnate
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
index 46949ee..05ecf6b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
@@ -31,10 +31,10 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTempla
@UniqueConstraint(columnNames = { "realm_id", "anyType_id" }))
public class JPAAnyTemplateRealm extends AbstractAnyTemplate implements AnyTemplateRealm {
- public static final String TABLE = "AnyTemplateRealm";
-
private static final long serialVersionUID = 1863029633568957907L;
+ public static final String TABLE = "AnyTemplateRealm";
+
@ManyToOne
private JPARealm realm;
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index 2c71f37..ce794af 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -189,7 +189,7 @@ public final class MappingUtils {
return evaluateNAME(evalConnObjectLink, connObjectKey);
}
- private static List<ItemTransformer> getMappingItemTransformers(
+ private static List<ItemTransformer> getItemTransformers(
final String propagationJEXLTransformer,
final String pullJEXLTransformer,
final List<String> mappingItemTransformerClassNames) {
@@ -224,14 +224,14 @@ public final class MappingUtils {
}
public static List<ItemTransformer> getItemTransformers(final ItemTO item) {
- return getMappingItemTransformers(
+ return getItemTransformers(
item.getPropagationJEXLTransformer(),
item.getPullJEXLTransformer(),
item.getTransformerClassNames());
}
public static List<ItemTransformer> getItemTransformers(final Item item) {
- return getMappingItemTransformers(
+ return getItemTransformers(
item.getPropagationJEXLTransformer(),
item.getPullJEXLTransformer(),
item.getTransformerClassNames());
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
index d56f651..ef47ef1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
@@ -126,48 +126,52 @@ public class TemplateUtils {
@Transactional(readOnly = true)
public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
if (anyTemplate != null) {
- AnyTO template = anyTemplate.get();
- fill(anyTO, template);
-
- if (template instanceof AnyObjectTO) {
- fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- } else if (template instanceof UserTO) {
- if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setUsername(evaluated);
- }
+ apply(anyTO, anyTemplate.get());
+ }
+ }
+
+ @Transactional(readOnly = true)
+ public <T extends AnyTO> void apply(final T anyTO, final AnyTO template) {
+ fill(anyTO, template);
+
+ if (template instanceof AnyObjectTO) {
+ fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ } else if (template instanceof UserTO) {
+ if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setUsername(evaluated);
}
+ }
- if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setPassword(evaluated);
- }
+ if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setPassword(evaluated);
}
+ }
- fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- } else if (template instanceof GroupTO) {
- if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
- String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((GroupTO) anyTO).setName(evaluated);
- }
+ fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ } else if (template instanceof GroupTO) {
+ if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
+ String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((GroupTO) anyTO).setName(evaluated);
}
+ }
- if (((GroupTO) template).getUserOwner() != null) {
- final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
- if (userOwner != null) {
- ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
- }
+ if (((GroupTO) template).getUserOwner() != null) {
+ final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
+ if (userOwner != null) {
+ ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
}
- if (((GroupTO) template).getGroupOwner() != null) {
- final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
- if (groupOwner != null) {
- ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
- }
+ }
+ if (((GroupTO) template).getGroupOwner() != null) {
+ final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
+ if (groupOwner != null) {
+ ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
index ecc14fe..f2bbabf 100644
--- a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
+++ b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
@@ -97,7 +97,6 @@ public abstract class AbstractSAML2SPServlet extends HttpServlet {
SAML2ReceivedResponseTO receivedResponseTO = new SAML2ReceivedResponseTO();
receivedResponseTO.setSpEntityID(spEntityID);
receivedResponseTO.setUrlContext(urlContext);
- receivedResponseTO.setClientAddress(clientAddress);
receivedResponseTO.setSamlResponse(samlResponse);
receivedResponseTO.setRelayState(relayState);
return receivedResponseTO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
index 2ab6d8d..2874a84 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -30,8 +31,10 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.commons.DirectoryDataProvider;
import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.SAML2IdPsDirectoryPanel.SAML2IdPsProvider;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.SAML2IdPsRestClient;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
@@ -42,13 +45,18 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
import org.apache.syncope.client.console.wizards.AjaxWizard;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.AnyWrapper;
+import org.apache.syncope.client.console.wizards.any.UserTemplateWizardBuilder;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.SAML2SPEntitlement;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -58,6 +66,7 @@ import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.util.crypt.Base64;
public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
@@ -69,6 +78,8 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
private final BaseModal<String> metadataModal = new BaseModal<>("outer");
+ private final BaseModal<Serializable> templateModal;
+
public SAML2IdPsDirectoryPanel(final String id, final PageReference pageRef) {
super(id, new Builder<SAML2IdPTO, SAML2IdPTO, SAML2IdPsRestClient>(new SAML2IdPsRestClient(), pageRef) {
@@ -117,6 +128,29 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
setWindowClosedReloadCallback(metadataModal);
metadataModal.size(Modal.Size.Large);
+ templateModal = new BaseModal<Serializable>("outer") {
+
+ private static final long serialVersionUID = 5787433530654262016L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+ };
+ templateModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+ private static final long serialVersionUID = 8804221891699487139L;
+
+ @Override
+ public void onClose(final AjaxRequestTarget target) {
+// target.add(content);
+ templateModal.show(false);
+ }
+ });
+ templateModal.size(Modal.Size.Large);
+ addOuterObject(templateModal);
+
initResultTable();
final ImportMetadata importMetadata = new ImportMetadata("importMetadata", container, pageRef);
@@ -172,17 +206,6 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
panel.add(new ActionLink<SAML2IdPTO>() {
- private static final long serialVersionUID = -3722207913631435501L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
- SAML2IdPTO object = restClient.read(model.getObject().getKey());
- send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(object, target));
- }
- }, ActionLink.ActionType.EDIT, SAML2SPEntitlement.IDP_UPDATE);
- panel.add(new ActionLink<SAML2IdPTO>() {
-
private static final long serialVersionUID = -7978723352517770645L;
@Override
@@ -200,6 +223,49 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
}, ActionLink.ActionType.HTML, SAML2SPEntitlement.IDP_READ);
panel.add(new ActionLink<SAML2IdPTO>() {
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
+ SAML2IdPTO object = restClient.read(model.getObject().getKey());
+ send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
+ new AjaxWizard.EditItemActionEvent<>(object, target));
+ }
+ }, ActionLink.ActionType.EDIT, SAML2SPEntitlement.IDP_UPDATE);
+ panel.add(new ActionLink<SAML2IdPTO>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
+ final SAML2IdPTO object = restClient.read(model.getObject().getKey());
+
+ UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
+ object.getUserTemplate(),
+ new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(),
+ new UserFormLayoutInfo(),
+ pageRef) {
+
+ private static final long serialVersionUID = -7978723352517770634L;
+
+ @Override
+ protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
+ object.setUserTemplate(modelObject.getInnerObject());
+ restClient.update(object);
+
+ return modelObject;
+ }
+ };
+ templateModal.header(Model.of(StringUtils.capitalize(
+ new StringResourceModel("template.title", SAML2IdPsDirectoryPanel.this).getString())));
+ templateModal.setContent(builder.build(BaseModal.CONTENT_ID));
+ templateModal.show(true);
+ target.add(templateModal);
+
+ }
+ }, ActionLink.ActionType.TEMPLATE, SAML2SPEntitlement.IDP_UPDATE);
+ panel.add(new ActionLink<SAML2IdPTO>() {
+
private static final long serialVersionUID = -5467832321897812767L;
@Override
@@ -220,6 +286,28 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
return panel;
}
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ super.onEvent(event);
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
+ AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
+ WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+ final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
+ templateModal.setFormModel(model);
+ templateModal.header(newItemEvent.getResourceModel());
+ newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+ templateModal.show(true);
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ }
+ }
+ }
+
protected final class SAML2IdPsProvider extends DirectoryDataProvider<SAML2IdPTO> {
private static final long serialVersionUID = -185944053385660794L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
index ba67f57..c7e6e0c 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.rest;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
@@ -33,6 +34,10 @@ public class SAML2IdPsRestClient extends BaseRestClient {
return getService(SAML2IdPService.class).list();
}
+ public Set<String> getActionsClasses() {
+ return getService(SAML2IdPService.class).getActionsClasses();
+ }
+
public void importIdPs(final InputStream input) {
SyncopeConsoleSession.get().
getService(MediaType.APPLICATION_XML_TYPE, SAML2IdPService.class).importFromMetadata(input);
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index 8567dd2..0fc7b22 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -29,6 +29,7 @@ import org.apache.syncope.client.console.panels.SAML2IdPsDirectoryPanel;
import org.apache.syncope.client.console.rest.SAML2IdPsRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
@@ -42,9 +43,12 @@ import org.apache.wicket.extensions.wizard.WizardModel;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.model.util.ListModel;
public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
@@ -54,6 +58,16 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
private final SAML2IdPsDirectoryPanel directoryPanel;
+ private final IModel<List<String>> actionsClasses = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return new ArrayList<>(restClient.getActionsClasses());
+ }
+ };
+
public SAML2IdPWizardBuilder(
final SAML2IdPsDirectoryPanel directoryPanel, final SAML2IdPTO idpTO, final PageReference pageRef) {
@@ -68,8 +82,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
Mapping mapping = new Mapping(modelObject);
mapping.setOutputMarkupId(true);
- ItemTransformersTogglePanel mapItemTransformers =
- new ItemTransformersTogglePanel(mapping, pageRef);
+ ItemTransformersTogglePanel mapItemTransformers = new ItemTransformersTogglePanel(mapping, pageRef);
addOuterObject(mapItemTransformers);
JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
addOuterObject(jexlTransformers);
@@ -80,7 +93,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
return wizardModel;
}
- private static final class IdP extends WizardStep {
+ private final class IdP extends WizardStep {
private static final long serialVersionUID = 854012593185195024L;
@@ -94,6 +107,14 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
name.setRequired(true);
fields.add(name);
+ AjaxCheckBoxPanel createUnmatching = new AjaxCheckBoxPanel(
+ "field", "createUnmatching", new PropertyModel<Boolean>(idpTO, "createUnmatching"), false);
+ fields.add(createUnmatching);
+
+ AjaxCheckBoxPanel updateMatching = new AjaxCheckBoxPanel(
+ "field", "updateMatching", new PropertyModel<Boolean>(idpTO, "updateMatching"), false);
+ fields.add(updateMatching);
+
AjaxCheckBoxPanel useDeflateEncoding = new AjaxCheckBoxPanel(
"field", "useDeflateEncoding", new PropertyModel<Boolean>(idpTO, "useDeflateEncoding"), false);
fields.add(useDeflateEncoding);
@@ -104,6 +125,15 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
bindingType.setChoices(Arrays.asList(SAML2BindingType.values()));
fields.add(bindingType);
+ AjaxPalettePanel<String> actionsClassNames = new AjaxPalettePanel.Builder<String>().
+ setAllowMoveAll(true).setAllowOrder(true).
+ setName(new StringResourceModel("actionsClassNames", directoryPanel).getString()).
+ build("field",
+ new PropertyModel<List<String>>(idpTO, "actionsClassNames"),
+ new ListModel<>(actionsClasses.getObject()));
+ actionsClassNames.setOutputMarkupId(true);
+ fields.add(actionsClassNames);
+
add(new ListView<Component>("fields", fields) {
private static final long serialVersionUID = -9180479401817023838L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
index f9c6403..97d8690 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
@@ -21,3 +21,7 @@ any.edit=Edit ${entityID}
connObjectKeyValidation=There must be exactly one Remote Key
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Actions
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
index 312da5d..76464c0 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
@@ -21,3 +21,7 @@ any.edit=Modifica ${entityID}
connObjectKeyValidation=Deve essere definito esattamente una Chiave remota
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Azioni
+template.title=template utenti
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
index 4e053f7..d81f0a8 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
@@ -21,3 +21,7 @@ any.edit=Alterar ${entityID}
connObjectKeyValidation=Precisa ser exatamente um Remote Key
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Actions
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
index 8bedf47..8712eeb 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
@@ -21,3 +21,7 @@ any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${entityID}
connObjectKeyValidation=\u0422\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
index ffda86d..022267d 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.common.lib.to;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.PathParam;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
@@ -45,14 +47,22 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
private String metadata;
+ private boolean createUnmatching;
+
+ private boolean updateMatching;
+
private boolean useDeflateEncoding;
private SAML2BindingType bindingType;
private boolean logoutSupported;
+ private UserTO userTemplate;
+
private final List<ItemTO> items = new ArrayList<>();
+ private final Set<String> actionsClassNames = new HashSet<>();
+
@Override
public String getKey() {
return key;
@@ -88,6 +98,22 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
this.metadata = metadata;
}
+ public boolean isCreateUnmatching() {
+ return createUnmatching;
+ }
+
+ public void setCreateUnmatching(final boolean createUnmatching) {
+ this.createUnmatching = createUnmatching;
+ }
+
+ public boolean isUpdateMatching() {
+ return updateMatching;
+ }
+
+ public void setUpdateMatching(final boolean updateMatching) {
+ this.updateMatching = updateMatching;
+ }
+
public boolean isUseDeflateEncoding() {
return useDeflateEncoding;
}
@@ -112,6 +138,14 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
this.logoutSupported = logoutSupported;
}
+ public UserTO getUserTemplate() {
+ return userTemplate;
+ }
+
+ public void setUserTemplate(final UserTO userTemplate) {
+ this.userTemplate = userTemplate;
+ }
+
@Override
public ItemTO getConnObjectKeyItem() {
return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
@@ -154,4 +188,11 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
return this.items.remove(item);
}
+ @XmlElementWrapper(name = "actionsClassNames")
+ @XmlElement(name = "actionsClassName")
+ @JsonProperty("actionsClassNames")
+ public Set<String> getActionsClassNames() {
+ return actionsClassNames;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
index f905035..2b02eb4 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.common.lib.to;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
import java.util.HashSet;
@@ -26,6 +27,8 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.AbstractBaseBean;
@XmlRootElement(name = "saml2LoginResponse")
@@ -124,6 +127,17 @@ public class SAML2LoginResponseTO extends AbstractBaseBean {
this.username = username;
}
+ @JsonIgnore
+ public AttrTO getAttr(final String schema) {
+ return IterableUtils.find(attrs, new Predicate<AttrTO>() {
+
+ @Override
+ public boolean evaluate(final AttrTO object) {
+ return object.getSchema().equals(schema);
+ }
+ });
+ }
+
@XmlElementWrapper(name = "attrs")
@XmlElement(name = "attr")
@JsonProperty("attrs")
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
index 4ea2dec..556be9b 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
@@ -33,8 +33,6 @@ public class SAML2ReceivedResponseTO extends AbstractBaseBean {
private String urlContext;
- private String clientAddress;
-
private String samlResponse;
private String relayState;
@@ -55,14 +53,6 @@ public class SAML2ReceivedResponseTO extends AbstractBaseBean {
this.urlContext = urlContext;
}
- public String getClientAddress() {
- return clientAddress;
- }
-
- public void setClientAddress(final String clientAddress) {
- this.clientAddress = clientAddress;
- }
-
public String getSamlResponse() {
return samlResponse;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
index d7337b3..92dda48 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
@@ -25,6 +25,7 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
@@ -35,6 +36,7 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SAML2BindingType;
import org.apache.syncope.common.lib.types.SAML2SPEntitlement;
+import org.apache.syncope.core.logic.init.SAML2SPClassPathScanImplementationLookup;
import org.apache.syncope.core.logic.saml2.SAML2ReaderWriter;
import org.apache.syncope.core.logic.saml2.SAML2IdPCache;
import org.apache.syncope.core.logic.saml2.SAML2IdPEntity;
@@ -68,8 +70,16 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
private SAML2IdPDAO idpDAO;
@Autowired
+ private SAML2SPClassPathScanImplementationLookup implLookup;
+
+ @Autowired
private SAML2ReaderWriter saml2rw;
+ @PreAuthorize("isAuthenticated()")
+ public Set<String> getActionsClasses() {
+ return implLookup.getActionsClasses();
+ }
+
private SAML2IdPTO complete(final SAML2IdP idp, final SAML2IdPTO idpTO) {
SAML2IdPEntity idpEntity = cache.get(idpTO.getEntityID());
if (idpEntity == null) {
@@ -159,7 +169,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
connObjectKeyItem.setExtAttrName("NameID");
idpTO.setConnObjectKeyItem(connObjectKeyItem);
- SAML2IdPEntity idp = cache.put(idpEntityDescriptor, connObjectKeyItem, false, SAML2BindingType.POST);
+ SAML2IdPEntity idp = cache.put(idpEntityDescriptor, idpTO);
if (idp.getSSOLocation(SAML2BindingType.POST) != null) {
idpTO.setBindingType(SAML2BindingType.POST);
} else if (idp.getSSOLocation(SAML2BindingType.REDIRECT) != null) {
@@ -225,9 +235,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
saml2Idp = idpDAO.save(binder.update(saml2Idp, saml2IdpTO));
- idpEntity.setUseDeflateEncoding(saml2Idp.isUseDeflateEncoding());
- idpEntity.setBindingType(saml2Idp.getBindingType());
- idpEntity.setConnObjectKeyItem(binder.getIdPTO(saml2Idp).getConnObjectKeyItem());
+ idpEntity.setIdpTO(binder.getIdPTO(saml2Idp));
}
@PreAuthorize("hasRole('" + SAML2SPEntitlement.IDP_DELETE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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 a9b63ed..f6953e6 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
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.logic;
+import org.apache.syncope.core.logic.saml2.SAML2UserManager;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.RandomBasedGenerator;
import java.io.OutputStream;
@@ -25,14 +26,12 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
@@ -43,9 +42,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.SAML2RequestTO;
import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
-import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SAML2BindingType;
@@ -53,23 +50,11 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.logic.saml2.SAML2ReaderWriter;
import org.apache.syncope.core.logic.saml2.SAML2IdPCache;
import org.apache.syncope.core.logic.saml2.SAML2IdPEntity;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-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.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;
import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
-import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
-import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
import org.joda.time.DateTime;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.schema.XSString;
@@ -118,8 +103,8 @@ import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
-import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.security.AuthDataAccessor;
import org.apache.syncope.core.spring.security.Encryptor;
@@ -149,27 +134,18 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
private SAML2IdPCache cache;
@Autowired
- private UserDAO userDAO;
+ private SAML2UserManager userManager;
@Autowired
private SAML2IdPDAO saml2IdPDAO;
@Autowired
- private PlainSchemaDAO plainSchemaDAO;
-
- @Autowired
private AccessTokenDAO accessTokenDAO;
@Autowired
- private IntAttrNameParser intAttrNameParser;
-
- @Autowired
private AuthDataAccessor authDataAccessor;
@Autowired
- private EntityFactory entityFactory;
-
- @Autowired
private SAML2ReaderWriter saml2rw;
@Resource(name = "syncopeJWTSSOProviderDelegate")
@@ -352,73 +328,6 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
return requestTO;
}
- private List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
- List<String> result = new ArrayList<>();
-
- String transformed = keyValue;
- for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
- List<Object> output = transformer.beforePull(
- null,
- null,
- Collections.<Object>singletonList(transformed));
- if (output != null && !output.isEmpty()) {
- transformed = output.get(0).toString();
- }
- }
-
- IntAttrName intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER);
-
- if (intAttrName.getField() != null) {
- switch (intAttrName.getField()) {
- case "key":
- User byKey = userDAO.find(transformed);
- if (byKey != null) {
- result.add(byKey.getKey());
- }
- break;
-
- case "username":
- User byUsername = userDAO.findByUsername(transformed);
- if (byUsername != null) {
- result.add(byUsername.getKey());
- }
- break;
-
- default:
- }
- } else if (intAttrName.getSchemaType() != null) {
- switch (intAttrName.getSchemaType()) {
- case PLAIN:
- PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
-
- PlainSchema schema = plainSchemaDAO.find(intAttrName.getSchemaName());
- if (schema == null) {
- value.setStringValue(transformed);
- } else {
- try {
- value.parseValue(schema, transformed);
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided key value {}", transformed, e);
- value.setStringValue(transformed);
- }
- }
-
- CollectionUtils.collect(userDAO.findByAttrValue(intAttrName.getSchemaName(), value),
- EntityUtils.keyTransformer(), result);
- break;
-
- case DERIVED:
- CollectionUtils.collect(userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed),
- EntityUtils.keyTransformer(), result);
- break;
-
- default:
- }
- }
-
- return result;
- }
-
@PreAuthorize("hasRole('" + StandardEntitlement.ANONYMOUS + "')")
public SAML2LoginResponseTO validateLoginResponse(final SAML2ReceivedResponseTO response) {
check();
@@ -454,7 +363,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
}
// 3. validate the SAML response and, if needed, decrypt the provided assertion(s)
- SAML2IdPEntity idp = getIdP(samlResponse.getIssuer().getValue());
+ final SAML2IdPEntity idp = getIdP(samlResponse.getIssuer().getValue());
if (idp.getConnObjectKeyItem() == null) {
throw new IllegalArgumentException("No mapping provided for SAML 2.0 IdP '" + idp.getId() + "'");
}
@@ -463,7 +372,6 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
samlResponse,
idp,
getAssertionConsumerURL(response.getSpEntityID(), response.getUrlContext()),
- response.getClientAddress(),
relayState.getJwtClaims().getSubject(),
response.getSpEntityID());
} catch (Exception e) {
@@ -474,7 +382,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
}
// 4. prepare the result: find matching user (if any) and return the received attributes
- SAML2LoginResponseTO responseTO = new SAML2LoginResponseTO();
+ final SAML2LoginResponseTO responseTO = new SAML2LoginResponseTO();
responseTO.setIdp(idp.getId());
responseTO.setSloSupported(idp.getSLOLocation(idp.getBindingType()) != null);
@@ -525,19 +433,49 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
if (nameID == null) {
throw new IllegalArgumentException("NameID not found");
}
+ final String nameIDValue = nameID.getValue();
- List<String> matchingUsers = keyValue == null
+ final List<String> matchingUsers = keyValue == null
? Collections.<String>emptyList()
- : findMatchingUser(keyValue, idp.getConnObjectKeyItem());
+ : userManager.findMatchingUser(keyValue, idp.getConnObjectKeyItem());
LOG.debug("Found {} matching users for NameID {}", matchingUsers.size(), nameID.getValue());
+ String username;
if (matchingUsers.isEmpty()) {
- throw new NotFoundException("User matching the provided NameID value " + nameID.getValue());
+ if (idp.isCreateUnmatching()) {
+ LOG.debug("No user matching NameID {}, about to create", nameID.getValue());
+
+ username = AuthContextUtils.execWithAuthContext(
+ AuthContextUtils.getDomain(), new AuthContextUtils.Executable<String>() {
+
+ @Override
+ public String exec() {
+ return userManager.create(idp, responseTO, nameIDValue);
+ }
+ });
+ } else {
+ throw new NotFoundException("User matching the provided NameID value " + nameID.getValue());
+ }
} else if (matchingUsers.size() > 1) {
throw new IllegalArgumentException("Several users match the provided NameID value " + nameID.getValue());
+ } else {
+ if (idp.isUpdateMatching()) {
+ LOG.debug("About to update {} for NameID {}", matchingUsers.get(0), nameID.getValue());
+
+ username = AuthContextUtils.execWithAuthContext(
+ AuthContextUtils.getDomain(), new AuthContextUtils.Executable<String>() {
+
+ @Override
+ public String exec() {
+ return userManager.update(matchingUsers.get(0), idp, responseTO);
+ }
+ });
+ } else {
+ username = matchingUsers.get(0);
+ }
}
- responseTO.setUsername(userDAO.find(matchingUsers.get(0)).getUsername());
+ responseTO.setUsername(username);
responseTO.setNameID(nameID.getValue());
// 5. generate JWT for further access
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
new file mode 100644
index 0000000..13b3cab
--- /dev/null
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.init;
+
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+
+@Component
+public class SAML2SPClassPathScanImplementationLookup implements SyncopeLoader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ImplementationLookup.class);
+
+ private static final String DEFAULT_BASE_PACKAGE = "org.apache.syncope.core";
+
+ private Set<String> actionsClasses;
+
+ @Override
+ public Integer getPriority() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public void load() {
+ actionsClasses = new HashSet<>();
+
+ ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+ scanner.addIncludeFilter(new AssignableTypeFilter(SAML2IdPActions.class));
+
+ for (BeanDefinition bd : scanner.findCandidateComponents(DEFAULT_BASE_PACKAGE)) {
+ try {
+ Class<?> clazz = ClassUtils.resolveClassName(
+ bd.getBeanClassName(), ClassUtils.getDefaultClassLoader());
+ boolean isAbstractClazz = Modifier.isAbstract(clazz.getModifiers());
+
+ if (SAML2IdPActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+ actionsClasses.add(clazz.getName());
+ }
+ } catch (Throwable t) {
+ LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
+ }
+ }
+
+ actionsClasses = Collections.unmodifiableSet(actionsClasses);
+ }
+
+ public Set<String> getActionsClasses() {
+ return actionsClasses;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
index ed244d0..e56b4f8 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
@@ -28,8 +28,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.types.SAML2BindingType;
+import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.core.logic.init.SAML2SPLoader;
import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
import org.apache.syncope.core.provisioning.api.data.SAML2IdPDataBinder;
@@ -66,13 +65,10 @@ public class SAML2IdPCache {
public SAML2IdPEntity put(
final EntityDescriptor entityDescriptor,
- final ItemTO connObjectKeyItem,
- final boolean useDeflateEncoding,
- final SAML2BindingType bindingType)
+ final SAML2IdPTO idpTO)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
- SAML2IdPEntity idp = new SAML2IdPEntity(
- entityDescriptor, connObjectKeyItem, useDeflateEncoding, bindingType, loader.getKeyPass());
+ SAML2IdPEntity idp = new SAML2IdPEntity(entityDescriptor, idpTO, loader.getKeyPass());
cache.put(entityDescriptor.getEntityID(), idp);
return idp;
}
@@ -85,11 +81,7 @@ public class SAML2IdPCache {
Element element = OpenSAMLUtil.getParserPool().parse(
new InputStreamReader(new ByteArrayInputStream(idp.getMetadata()))).getDocumentElement();
EntityDescriptor entityDescriptor = (EntityDescriptor) OpenSAMLUtil.fromDom(element);
- return put(
- entityDescriptor,
- binder.getIdPTO(idp).getConnObjectKeyItem(),
- idp.isUseDeflateEncoding(),
- idp.getBindingType());
+ return put(entityDescriptor, binder.getIdPTO(idp));
}
public SAML2IdPEntity remove(final String entityID) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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 b747c32..b937e17 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
@@ -30,8 +30,11 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.commons.codec.binary.Base64;
import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.SAML2IdPTO;
+import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.SAML2BindingType;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.saml2.metadata.Endpoint;
@@ -51,11 +54,7 @@ public class SAML2IdPEntity {
private final String id;
- private boolean useDeflateEncoding;
-
- private SAML2BindingType bindingType;
-
- private ItemTO connObjectKeyItem;
+ private SAML2IdPTO idpTO;
private final Map<String, Endpoint> ssoBindings = new HashMap<>();
@@ -67,16 +66,12 @@ public class SAML2IdPEntity {
public SAML2IdPEntity(
final EntityDescriptor entityDescriptor,
- final ItemTO connObjectKeyItem,
- final boolean useDeflateEncoding,
- final SAML2BindingType bindingType,
+ final SAML2IdPTO idpTO,
final String keyPass)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
this.id = entityDescriptor.getEntityID();
- this.connObjectKeyItem = connObjectKeyItem;
- this.useDeflateEncoding = useDeflateEncoding;
- this.bindingType = bindingType;
+ this.idpTO = idpTO;
IDPSSODescriptor idpdescriptor = entityDescriptor.getIDPSSODescriptor(SAMLConstants.SAML20P_NS);
@@ -121,32 +116,44 @@ public class SAML2IdPEntity {
}
}
+ public void setIdpTO(final SAML2IdPTO idpTO) {
+ this.idpTO = idpTO;
+ }
+
public String getId() {
return id;
}
- public boolean isUseDeflateEncoding() {
- return useDeflateEncoding;
+ public boolean isCreateUnmatching() {
+ return idpTO.isCreateUnmatching();
}
- public void setUseDeflateEncoding(final boolean useDeflateEncoding) {
- this.useDeflateEncoding = useDeflateEncoding;
+ public boolean isUpdateMatching() {
+ return idpTO.isUpdateMatching();
}
- public SAML2BindingType getBindingType() {
- return bindingType;
+ public boolean isUseDeflateEncoding() {
+ return idpTO.isUseDeflateEncoding();
}
- public void setBindingType(final SAML2BindingType bindingType) {
- this.bindingType = bindingType;
+ public SAML2BindingType getBindingType() {
+ return idpTO.getBindingType();
}
public ItemTO getConnObjectKeyItem() {
- return connObjectKeyItem;
+ return idpTO.getConnObjectKeyItem();
+ }
+
+ public List<ItemTO> getItems() {
+ return idpTO.getItems();
+ }
+
+ public UserTO getUserTemplate() {
+ return idpTO.getUserTemplate();
}
- public void setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
- this.connObjectKeyItem = connObjectKeyItem;
+ public Set<String> getActionsClassNames() {
+ return idpTO.getActionsClassNames();
}
public Endpoint getSSOLocation(final SAML2BindingType bindingType) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index 17386ea..8e47911 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -214,7 +214,6 @@ public class SAML2ReaderWriter {
final Response samlResponse,
final SAML2IdPEntity idp,
final String assertionConsumerURL,
- final String clientAddress,
final String requestId,
final String spEntityID)
throws WSSecurityException {
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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
new file mode 100644
index 0000000..a7af5e2
--- /dev/null
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.saml2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+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.PlainSchemaDAO;
+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.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+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;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
+import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class SAML2UserManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SAML2UserManager.class);
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ private IntAttrNameParser intAttrNameParser;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private TemplateUtils templateUtils;
+
+ @Autowired
+ private UserProvisioningManager provisioningManager;
+
+ @Autowired
+ private UserDataBinder binder;
+
+ @Transactional(readOnly = true)
+ public List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
+ List<String> result = new ArrayList<>();
+
+ String transformed = keyValue;
+ for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
+ List<Object> output = transformer.beforePull(
+ null,
+ null,
+ Collections.<Object>singletonList(transformed));
+ if (output != null && !output.isEmpty()) {
+ transformed = output.get(0).toString();
+ }
+ }
+
+ IntAttrName intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER);
+
+ if (intAttrName.getField() != null) {
+ switch (intAttrName.getField()) {
+ case "key":
+ User byKey = userDAO.find(transformed);
+ if (byKey != null) {
+ result.add(byKey.getUsername());
+ }
+ break;
+
+ case "username":
+ User byUsername = userDAO.findByUsername(transformed);
+ if (byUsername != null) {
+ result.add(byUsername.getUsername());
+ }
+ break;
+
+ default:
+ }
+ } else if (intAttrName.getSchemaType() != null) {
+ switch (intAttrName.getSchemaType()) {
+ case PLAIN:
+ PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
+
+ PlainSchema schema = plainSchemaDAO.find(intAttrName.getSchemaName());
+ if (schema == null) {
+ value.setStringValue(transformed);
+ } else {
+ try {
+ value.parseValue(schema, transformed);
+ } catch (ParsingValidationException e) {
+ LOG.error("While parsing provided key value {}", transformed, e);
+ value.setStringValue(transformed);
+ }
+ }
+
+ CollectionUtils.collect(
+ userDAO.findByAttrValue(intAttrName.getSchemaName(), value),
+ new Transformer<User, String>() {
+
+ @Override
+ public String transform(final User input) {
+ return input.getUsername();
+ }
+ }, result);
+ break;
+
+ case DERIVED:
+ CollectionUtils.collect(
+ userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed),
+ new Transformer<User, String>() {
+
+ @Override
+ public String transform(final User input) {
+ return input.getUsername();
+ }
+ }, result);
+ break;
+
+ default:
+ }
+ }
+
+ return result;
+ }
+
+ private List<SAML2IdPActions> getActions(final SAML2IdPEntity idp) {
+ List<SAML2IdPActions> actions = new ArrayList<>();
+
+ for (String className : idp.getActionsClassNames()) {
+ 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);
+ }
+ }
+
+ return actions;
+ }
+
+ private void fill(final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO, final UserTO userTO) {
+ for (ItemTO item : idp.getItems()) {
+ IntAttrName intAttrName = intAttrNameParser.parse(item.getIntAttrName(), AnyTypeKind.USER);
+
+ List<String> values = Collections.emptyList();
+ AttrTO samlAttr = responseTO.getAttr(item.getExtAttrName());
+ if (samlAttr != null && !samlAttr.getValues().isEmpty()) {
+ values = samlAttr.getValues();
+
+ List<Object> transformed = new ArrayList<Object>(values);
+ for (ItemTransformer transformer : MappingUtils.getItemTransformers(item)) {
+ transformed = transformer.beforePull(null, userTO, transformed);
+ }
+ values.clear();
+ for (Object value : transformed) {
+ values.add(value.toString());
+ }
+ }
+
+ if (intAttrName.getField() != null) {
+ switch (intAttrName.getField()) {
+ case "username":
+ if (!values.isEmpty()) {
+ userTO.setUsername(values.get(0));
+ }
+ break;
+
+ default:
+ LOG.warn("Unsupported: {}", intAttrName.getField());
+ }
+ } else if (intAttrName.getSchemaType() != null) {
+ switch (intAttrName.getSchemaType()) {
+ case PLAIN:
+ AttrTO attr = userTO.getPlainAttr(intAttrName.getSchemaName());
+ if (attr == null) {
+ attr = new AttrTO.Builder().schema(intAttrName.getSchemaName()).build();
+ userTO.getPlainAttrs().add(attr);
+ }
+ attr.getValues().clear();
+ attr.getValues().addAll(values);
+ break;
+
+ default:
+ LOG.warn("Unsupported: {} {}", intAttrName.getSchemaType(), intAttrName.getSchemaName());
+ }
+ }
+ }
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public String create(final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO, final String nameID) {
+ UserTO userTO = new UserTO();
+
+ if (idp.getUserTemplate() != null) {
+ templateUtils.apply(userTO, idp.getUserTemplate());
+ }
+
+ List<SAML2IdPActions> actions = getActions(idp);
+ for (SAML2IdPActions action : actions) {
+ userTO = action.beforeCreate(userTO, responseTO);
+ }
+
+ fill(idp, responseTO, userTO);
+
+ if (userTO.getRealm() == null) {
+ userTO.setRealm(SyncopeConstants.ROOT_REALM);
+ }
+ if (userTO.getUsername() == null) {
+ userTO.setUsername(nameID);
+ }
+
+ Pair<String, List<PropagationStatus>> created = provisioningManager.create(userTO, false, false);
+ userTO = binder.getUserTO(created.getKey());
+
+ for (SAML2IdPActions action : actions) {
+ userTO = action.afterCreate(userTO, responseTO);
+ }
+
+ return userTO.getUsername();
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public String update(final String username, final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO) {
+ UserTO userTO = binder.getUserTO(username);
+ UserTO original = SerializationUtils.clone(userTO);
+
+ fill(idp, responseTO, userTO);
+
+ UserPatch userPatch = AnyOperations.diff(userTO, original, true);
+
+ List<SAML2IdPActions> actions = getActions(idp);
+ for (SAML2IdPActions action : actions) {
+ userPatch = action.beforeUpdate(userPatch, responseTO);
+ }
+
+ Pair<String, List<PropagationStatus>> updated = provisioningManager.update(userPatch, false);
+ userTO = binder.getUserTO(updated.getKey());
+
+ for (SAML2IdPActions action : actions) {
+ userTO = action.afterUpdate(userTO, responseTO);
+ }
+
+ return userTO.getUsername();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/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 7d1a5da..5588334 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
@@ -19,6 +19,7 @@
package org.apache.syncope.core.persistence.api.entity;
import java.util.List;
+import java.util.Set;
import org.apache.syncope.common.lib.types.SAML2BindingType;
public interface SAML2IdP extends Entity {
@@ -35,6 +36,14 @@ public interface SAML2IdP extends Entity {
void setMetadata(byte[] metadata);
+ boolean isCreateUnmatching();
+
+ void setCreateUnmatching(boolean createUnmatching);
+
+ boolean isUpdateMatching();
+
+ void setUpdateMatching(boolean updateMatching);
+
boolean isUseDeflateEncoding();
void setUseDeflateEncoding(boolean useDeflateEncoding);
@@ -43,6 +52,10 @@ public interface SAML2IdP extends Entity {
void setBindingType(SAML2BindingType bindingType);
+ SAML2UserTemplate getUserTemplate();
+
+ void setUserTemplate(SAML2UserTemplate userTemplate);
+
SAML2IdPItem getConnObjectKeyItem();
void setConnObjectKeyItem(SAML2IdPItem item);
@@ -51,4 +64,6 @@ public interface SAML2IdP extends Entity {
List<? extends SAML2IdPItem> getItems();
+ Set<String> getActionsClassNames();
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/1cf0d2a0/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java
new file mode 100644
index 0000000..a26227b
--- /dev/null
+++ b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.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.core.persistence.api.entity;
+
+public interface SAML2UserTemplate extends AnyTemplate {
+
+ SAML2IdP getIdP();
+
+ void setIdP(SAML2IdP idp);
+}
[4/4] syncope git commit: [SYNCOPE-1146][SYNCOPE-1147] Now it
possible to configure an IdP to create unmatching users / update matching
users;
the defined mapping, alongside with user template and SAML2IdPActions
implementations are taken into account to
Posted by il...@apache.org.
[SYNCOPE-1146][SYNCOPE-1147] Now it possible to configure an IdP to create unmatching users / update matching users; the defined mapping, alongside with user template and SAML2IdPActions implementations are taken into account to provide the actual user data
Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/f1c004bf
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/f1c004bf
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/f1c004bf
Branch: refs/heads/master
Commit: f1c004bfcd30c529757e37743e666c935beeeeb5
Parents: 7eb33dc
Author: Francesco Chicchiriccò <il...@apache.org>
Authored: Thu Aug 3 17:53:38 2017 +0200
Committer: Francesco Chicchiriccò <il...@apache.org>
Committed: Thu Aug 3 17:55:29 2017 +0200
----------------------------------------------------------------------
.../console/tasks/SchedTaskDirectoryPanel.java | 5 +-
.../markup/html/bootstrap/dialog/BaseModal.java | 4 +-
.../wizards/any/UserTemplateWizardBuilder.java | 17 ++
.../console/panels/RealmDetails_it.properties | 2 +-
.../jpa/entity/JPAAnyTemplateRealm.java | 4 +-
.../provisioning/java/utils/MappingUtils.java | 6 +-
.../provisioning/java/utils/TemplateUtils.java | 74 ++---
.../saml2lsp/agent/AbstractSAML2SPServlet.java | 1 -
.../console/panels/SAML2IdPsDirectoryPanel.java | 110 ++++++-
.../console/rest/SAML2IdPsRestClient.java | 5 +
.../console/wizards/SAML2IdPWizardBuilder.java | 36 ++-
.../panels/SAML2IdPsDirectoryPanel.properties | 4 +
.../SAML2IdPsDirectoryPanel_it.properties | 4 +
.../SAML2IdPsDirectoryPanel_pt_BR.properties | 4 +
.../SAML2IdPsDirectoryPanel_ru.properties | 4 +
.../syncope/common/lib/to/SAML2IdPTO.java | 41 +++
.../common/lib/to/SAML2LoginResponseTO.java | 14 +
.../common/lib/to/SAML2ReceivedResponseTO.java | 10 -
.../syncope/core/logic/SAML2IdPLogic.java | 16 +-
.../apache/syncope/core/logic/SAML2SPLogic.java | 140 +++------
...AML2SPClassPathScanImplementationLookup.java | 78 +++++
.../syncope/core/logic/saml2/SAML2IdPCache.java | 16 +-
.../core/logic/saml2/SAML2IdPEntity.java | 51 ++--
.../core/logic/saml2/SAML2ReaderWriter.java | 1 -
.../core/logic/saml2/SAML2UserManager.java | 292 +++++++++++++++++++
.../core/persistence/api/entity/SAML2IdP.java | 15 +
.../api/entity/SAML2UserTemplate.java | 26 ++
.../jpa/entity/JPASAML2EntityFactory.java | 3 +
.../persistence/jpa/entity/JPASAML2IdP.java | 62 ++++
.../jpa/entity/JPASAML2UserTemplate.java | 52 ++++
.../core/provisioning/api/SAML2IdPActions.java | 34 +++
.../java/DefaultSAML2IdPActions.java | 48 +++
.../java/data/SAML2IdPDataBinderImpl.java | 28 ++
.../rest/api/service/SAML2IdPService.java | 11 +
.../rest/cxf/service/SAML2IdPServiceImpl.java | 6 +
.../apache/syncope/fit/core/SAML2ITCase.java | 13 +-
36 files changed, 1026 insertions(+), 211 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
index f09c0dc..7663235 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/SchedTaskDirectoryPanel.java
@@ -72,8 +72,8 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
private static final long serialVersionUID = 4984337552918213290L;
- private static final String GROUP_MEMBER_PROVISION_TASKJOB
- = "org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate";
+ private static final String GROUP_MEMBER_PROVISION_TASKJOB =
+ "org.apache.syncope.core.provisioning.java.job.GroupMemberProvisionTaskJobDelegate";
protected final Class<T> reference;
@@ -116,6 +116,7 @@ public abstract class SchedTaskDirectoryPanel<T extends SchedTaskTO>
@Override
protected Serializable onApplyInternal(
final TemplatableTO targetObject, final String type, final AnyTO anyTO) {
+
targetObject.getTemplates().put(type, anyTO);
new TaskRestClient().update(SchedTaskTO.class.cast(targetObject));
return targetObject;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
index a5716e6..1df1e6c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/bootstrap/dialog/BaseModal.java
@@ -164,8 +164,8 @@ public class BaseModal<T extends Serializable> extends Modal<T> {
private BaseModal<T> setInternalContent(final Panel component) {
if (!component.getId().equals(getContentId())) {
- throw new WicketRuntimeException(
- "Modal content id is wrong. Component ID:" + component.getId() + "; content ID: " + getContentId());
+ throw new WicketRuntimeException("Modal content id is wrong. "
+ + "Component ID: " + component.getId() + "; content ID: " + getContentId());
}
content.replaceWith(component);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
index 8d0dc5b..3c8111c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserTemplateWizardBuilder.java
@@ -34,6 +34,23 @@ public class UserTemplateWizardBuilder extends UserWizardBuilder implements Temp
private final TemplatableTO templatable;
public UserTemplateWizardBuilder(
+ final UserTO template,
+ final List<String> anyTypeClasses,
+ final UserFormLayoutInfo formLayoutInfo,
+ final PageReference pageRef) {
+
+ super(anyTypeClasses, formLayoutInfo, pageRef);
+ templatable = null;
+
+ if (template == null) {
+ setItem(new UserWrapper(new UserTO()));
+ } else {
+ setItem(new UserWrapper(template));
+ }
+
+ }
+
+ public UserTemplateWizardBuilder(
final TemplatableTO templatable,
final List<String> anyTypeClasses,
final UserFormLayoutInfo formLayoutInfo,
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
index 05d20c2..80a008a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/RealmDetails_it.properties
@@ -17,5 +17,5 @@
fullPath=Percorso
accountPolicy=Account Policy
passwordPolicy=Password Policy
-actionsClassNames=Actions
+actionsClassNames=Azioni
resources=Risorse assegnate
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
index 46949ee..05ecf6b 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPAAnyTemplateRealm.java
@@ -31,10 +31,10 @@ import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTempla
@UniqueConstraint(columnNames = { "realm_id", "anyType_id" }))
public class JPAAnyTemplateRealm extends AbstractAnyTemplate implements AnyTemplateRealm {
- public static final String TABLE = "AnyTemplateRealm";
-
private static final long serialVersionUID = 1863029633568957907L;
+ public static final String TABLE = "AnyTemplateRealm";
+
@ManyToOne
private JPARealm realm;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
index 2c71f37..ce794af 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/MappingUtils.java
@@ -189,7 +189,7 @@ public final class MappingUtils {
return evaluateNAME(evalConnObjectLink, connObjectKey);
}
- private static List<ItemTransformer> getMappingItemTransformers(
+ private static List<ItemTransformer> getItemTransformers(
final String propagationJEXLTransformer,
final String pullJEXLTransformer,
final List<String> mappingItemTransformerClassNames) {
@@ -224,14 +224,14 @@ public final class MappingUtils {
}
public static List<ItemTransformer> getItemTransformers(final ItemTO item) {
- return getMappingItemTransformers(
+ return getItemTransformers(
item.getPropagationJEXLTransformer(),
item.getPullJEXLTransformer(),
item.getTransformerClassNames());
}
public static List<ItemTransformer> getItemTransformers(final Item item) {
- return getMappingItemTransformers(
+ return getItemTransformers(
item.getPropagationJEXLTransformer(),
item.getPullJEXLTransformer(),
item.getTransformerClassNames());
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
----------------------------------------------------------------------
diff --git a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
index d56f651..ef47ef1 100644
--- a/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
+++ b/core/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/utils/TemplateUtils.java
@@ -126,48 +126,52 @@ public class TemplateUtils {
@Transactional(readOnly = true)
public <T extends AnyTO> void apply(final T anyTO, final AnyTemplate anyTemplate) {
if (anyTemplate != null) {
- AnyTO template = anyTemplate.get();
- fill(anyTO, template);
-
- if (template instanceof AnyObjectTO) {
- fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- } else if (template instanceof UserTO) {
- if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setUsername(evaluated);
- }
+ apply(anyTO, anyTemplate.get());
+ }
+ }
+
+ @Transactional(readOnly = true)
+ public <T extends AnyTO> void apply(final T anyTO, final AnyTO template) {
+ fill(anyTO, template);
+
+ if (template instanceof AnyObjectTO) {
+ fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ } else if (template instanceof UserTO) {
+ if (StringUtils.isNotBlank(((UserTO) template).getUsername())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getUsername(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setUsername(evaluated);
}
+ }
- if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
- String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((UserTO) anyTO).setPassword(evaluated);
- }
+ if (StringUtils.isNotBlank(((UserTO) template).getPassword())) {
+ String evaluated = JexlUtils.evaluate(((UserTO) template).getPassword(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((UserTO) anyTO).setPassword(evaluated);
}
+ }
- fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
- } else if (template instanceof GroupTO) {
- if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
- String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO, new MapContext());
- if (StringUtils.isNotBlank(evaluated)) {
- ((GroupTO) anyTO).setName(evaluated);
- }
+ fillRelationships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ fillMemberships((GroupableRelatableTO) anyTO, ((GroupableRelatableTO) template));
+ } else if (template instanceof GroupTO) {
+ if (StringUtils.isNotBlank(((GroupTO) template).getName())) {
+ String evaluated = JexlUtils.evaluate(((GroupTO) template).getName(), anyTO, new MapContext());
+ if (StringUtils.isNotBlank(evaluated)) {
+ ((GroupTO) anyTO).setName(evaluated);
}
+ }
- if (((GroupTO) template).getUserOwner() != null) {
- final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
- if (userOwner != null) {
- ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
- }
+ if (((GroupTO) template).getUserOwner() != null) {
+ final User userOwner = userDAO.find(((GroupTO) template).getUserOwner());
+ if (userOwner != null) {
+ ((GroupTO) anyTO).setUserOwner(userOwner.getKey());
}
- if (((GroupTO) template).getGroupOwner() != null) {
- final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
- if (groupOwner != null) {
- ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
- }
+ }
+ if (((GroupTO) template).getGroupOwner() != null) {
+ final Group groupOwner = groupDAO.find(((GroupTO) template).getGroupOwner());
+ if (groupOwner != null) {
+ ((GroupTO) anyTO).setGroupOwner(groupOwner.getKey());
}
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
index ecc14fe..f2bbabf 100644
--- a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
+++ b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AbstractSAML2SPServlet.java
@@ -97,7 +97,6 @@ public abstract class AbstractSAML2SPServlet extends HttpServlet {
SAML2ReceivedResponseTO receivedResponseTO = new SAML2ReceivedResponseTO();
receivedResponseTO.setSpEntityID(spEntityID);
receivedResponseTO.setUrlContext(urlContext);
- receivedResponseTO.setClientAddress(clientAddress);
receivedResponseTO.setSamlResponse(samlResponse);
receivedResponseTO.setRelayState(relayState);
return receivedResponseTO;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
index 2ab6d8d..2874a84 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.java
@@ -19,6 +19,7 @@
package org.apache.syncope.client.console.panels;
import de.agilecoders.wicket.core.markup.html.bootstrap.dialog.Modal;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -30,8 +31,10 @@ import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.client.console.commons.Constants;
import org.apache.syncope.client.console.commons.DirectoryDataProvider;
import org.apache.syncope.client.console.commons.SortableDataProviderComparator;
+import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
import org.apache.syncope.client.console.pages.BasePage;
import org.apache.syncope.client.console.panels.SAML2IdPsDirectoryPanel.SAML2IdPsProvider;
+import org.apache.syncope.client.console.rest.AnyTypeRestClient;
import org.apache.syncope.client.console.rest.SAML2IdPsRestClient;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.BooleanPropertyColumn;
import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.KeyPropertyColumn;
@@ -42,13 +45,18 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.XMLEditorPanel;
import org.apache.syncope.client.console.wizards.AjaxWizard;
import org.apache.syncope.client.console.wizards.WizardMgtPanel;
+import org.apache.syncope.client.console.wizards.any.AnyWrapper;
+import org.apache.syncope.client.console.wizards.any.UserTemplateWizardBuilder;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.SAML2SPEntitlement;
import org.apache.wicket.PageReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.event.Broadcast;
+import org.apache.wicket.event.IEvent;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
@@ -58,6 +66,7 @@ import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.ResourceModel;
+import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.util.crypt.Base64;
public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
@@ -69,6 +78,8 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
private final BaseModal<String> metadataModal = new BaseModal<>("outer");
+ private final BaseModal<Serializable> templateModal;
+
public SAML2IdPsDirectoryPanel(final String id, final PageReference pageRef) {
super(id, new Builder<SAML2IdPTO, SAML2IdPTO, SAML2IdPsRestClient>(new SAML2IdPsRestClient(), pageRef) {
@@ -117,6 +128,29 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
setWindowClosedReloadCallback(metadataModal);
metadataModal.size(Modal.Size.Large);
+ templateModal = new BaseModal<Serializable>("outer") {
+
+ private static final long serialVersionUID = 5787433530654262016L;
+
+ @Override
+ protected void onConfigure() {
+ super.onConfigure();
+ setFooterVisible(false);
+ }
+ };
+ templateModal.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
+
+ private static final long serialVersionUID = 8804221891699487139L;
+
+ @Override
+ public void onClose(final AjaxRequestTarget target) {
+// target.add(content);
+ templateModal.show(false);
+ }
+ });
+ templateModal.size(Modal.Size.Large);
+ addOuterObject(templateModal);
+
initResultTable();
final ImportMetadata importMetadata = new ImportMetadata("importMetadata", container, pageRef);
@@ -172,17 +206,6 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
panel.add(new ActionLink<SAML2IdPTO>() {
- private static final long serialVersionUID = -3722207913631435501L;
-
- @Override
- public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
- SAML2IdPTO object = restClient.read(model.getObject().getKey());
- send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
- new AjaxWizard.EditItemActionEvent<>(object, target));
- }
- }, ActionLink.ActionType.EDIT, SAML2SPEntitlement.IDP_UPDATE);
- panel.add(new ActionLink<SAML2IdPTO>() {
-
private static final long serialVersionUID = -7978723352517770645L;
@Override
@@ -200,6 +223,49 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
}, ActionLink.ActionType.HTML, SAML2SPEntitlement.IDP_READ);
panel.add(new ActionLink<SAML2IdPTO>() {
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
+ SAML2IdPTO object = restClient.read(model.getObject().getKey());
+ send(SAML2IdPsDirectoryPanel.this, Broadcast.EXACT,
+ new AjaxWizard.EditItemActionEvent<>(object, target));
+ }
+ }, ActionLink.ActionType.EDIT, SAML2SPEntitlement.IDP_UPDATE);
+ panel.add(new ActionLink<SAML2IdPTO>() {
+
+ private static final long serialVersionUID = -3722207913631435501L;
+
+ @Override
+ public void onClick(final AjaxRequestTarget target, final SAML2IdPTO ignore) {
+ final SAML2IdPTO object = restClient.read(model.getObject().getKey());
+
+ UserTemplateWizardBuilder builder = new UserTemplateWizardBuilder(
+ object.getUserTemplate(),
+ new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(),
+ new UserFormLayoutInfo(),
+ pageRef) {
+
+ private static final long serialVersionUID = -7978723352517770634L;
+
+ @Override
+ protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
+ object.setUserTemplate(modelObject.getInnerObject());
+ restClient.update(object);
+
+ return modelObject;
+ }
+ };
+ templateModal.header(Model.of(StringUtils.capitalize(
+ new StringResourceModel("template.title", SAML2IdPsDirectoryPanel.this).getString())));
+ templateModal.setContent(builder.build(BaseModal.CONTENT_ID));
+ templateModal.show(true);
+ target.add(templateModal);
+
+ }
+ }, ActionLink.ActionType.TEMPLATE, SAML2SPEntitlement.IDP_UPDATE);
+ panel.add(new ActionLink<SAML2IdPTO>() {
+
private static final long serialVersionUID = -5467832321897812767L;
@Override
@@ -220,6 +286,28 @@ public class SAML2IdPsDirectoryPanel extends DirectoryPanel<
return panel;
}
+ @Override
+ public void onEvent(final IEvent<?> event) {
+ super.onEvent(event);
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemEvent) {
+ AjaxWizard.NewItemEvent<?> newItemEvent = AjaxWizard.NewItemEvent.class.cast(event.getPayload());
+ WizardModalPanel<?> modalPanel = newItemEvent.getModalPanel();
+
+ if (event.getPayload() instanceof AjaxWizard.NewItemActionEvent && modalPanel != null) {
+ final IModel<Serializable> model = new CompoundPropertyModel<>(modalPanel.getItem());
+ templateModal.setFormModel(model);
+ templateModal.header(newItemEvent.getResourceModel());
+ newItemEvent.getTarget().add(templateModal.setContent(modalPanel));
+ templateModal.show(true);
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemCancelEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ } else if (event.getPayload() instanceof AjaxWizard.NewItemFinishEvent) {
+ templateModal.close(newItemEvent.getTarget());
+ }
+ }
+ }
+
protected final class SAML2IdPsProvider extends DirectoryDataProvider<SAML2IdPTO> {
private static final long serialVersionUID = -185944053385660794L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
index ba67f57..c7e6e0c 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/rest/SAML2IdPsRestClient.java
@@ -20,6 +20,7 @@ package org.apache.syncope.client.console.rest;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.MediaType;
import org.apache.syncope.client.console.SyncopeConsoleSession;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
@@ -33,6 +34,10 @@ public class SAML2IdPsRestClient extends BaseRestClient {
return getService(SAML2IdPService.class).list();
}
+ public Set<String> getActionsClasses() {
+ return getService(SAML2IdPService.class).getActionsClasses();
+ }
+
public void importIdPs(final InputStream input) {
SyncopeConsoleSession.get().
getService(MediaType.APPLICATION_XML_TYPE, SAML2IdPService.class).importFromMetadata(input);
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
index 8567dd2..0fc7b22 100644
--- a/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
+++ b/ext/saml2sp/client-console/src/main/java/org/apache/syncope/client/console/wizards/SAML2IdPWizardBuilder.java
@@ -29,6 +29,7 @@ import org.apache.syncope.client.console.panels.SAML2IdPsDirectoryPanel;
import org.apache.syncope.client.console.rest.SAML2IdPsRestClient;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPalettePanel;
import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel;
import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel;
import org.apache.syncope.client.console.wizards.resources.JEXLTransformersTogglePanel;
@@ -42,9 +43,12 @@ import org.apache.wicket.extensions.wizard.WizardModel;
import org.apache.wicket.extensions.wizard.WizardStep;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.model.util.ListModel;
public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
@@ -54,6 +58,16 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
private final SAML2IdPsDirectoryPanel directoryPanel;
+ private final IModel<List<String>> actionsClasses = new LoadableDetachableModel<List<String>>() {
+
+ private static final long serialVersionUID = 5275935387613157437L;
+
+ @Override
+ protected List<String> load() {
+ return new ArrayList<>(restClient.getActionsClasses());
+ }
+ };
+
public SAML2IdPWizardBuilder(
final SAML2IdPsDirectoryPanel directoryPanel, final SAML2IdPTO idpTO, final PageReference pageRef) {
@@ -68,8 +82,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
Mapping mapping = new Mapping(modelObject);
mapping.setOutputMarkupId(true);
- ItemTransformersTogglePanel mapItemTransformers =
- new ItemTransformersTogglePanel(mapping, pageRef);
+ ItemTransformersTogglePanel mapItemTransformers = new ItemTransformersTogglePanel(mapping, pageRef);
addOuterObject(mapItemTransformers);
JEXLTransformersTogglePanel jexlTransformers = new JEXLTransformersTogglePanel(mapping, pageRef);
addOuterObject(jexlTransformers);
@@ -80,7 +93,7 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
return wizardModel;
}
- private static final class IdP extends WizardStep {
+ private final class IdP extends WizardStep {
private static final long serialVersionUID = 854012593185195024L;
@@ -94,6 +107,14 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
name.setRequired(true);
fields.add(name);
+ AjaxCheckBoxPanel createUnmatching = new AjaxCheckBoxPanel(
+ "field", "createUnmatching", new PropertyModel<Boolean>(idpTO, "createUnmatching"), false);
+ fields.add(createUnmatching);
+
+ AjaxCheckBoxPanel updateMatching = new AjaxCheckBoxPanel(
+ "field", "updateMatching", new PropertyModel<Boolean>(idpTO, "updateMatching"), false);
+ fields.add(updateMatching);
+
AjaxCheckBoxPanel useDeflateEncoding = new AjaxCheckBoxPanel(
"field", "useDeflateEncoding", new PropertyModel<Boolean>(idpTO, "useDeflateEncoding"), false);
fields.add(useDeflateEncoding);
@@ -104,6 +125,15 @@ public class SAML2IdPWizardBuilder extends AjaxWizardBuilder<SAML2IdPTO> {
bindingType.setChoices(Arrays.asList(SAML2BindingType.values()));
fields.add(bindingType);
+ AjaxPalettePanel<String> actionsClassNames = new AjaxPalettePanel.Builder<String>().
+ setAllowMoveAll(true).setAllowOrder(true).
+ setName(new StringResourceModel("actionsClassNames", directoryPanel).getString()).
+ build("field",
+ new PropertyModel<List<String>>(idpTO, "actionsClassNames"),
+ new ListModel<>(actionsClasses.getObject()));
+ actionsClassNames.setOutputMarkupId(true);
+ fields.add(actionsClassNames);
+
add(new ListView<Component>("fields", fields) {
private static final long serialVersionUID = -9180479401817023838L;
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
index f9c6403..97d8690 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel.properties
@@ -21,3 +21,7 @@ any.edit=Edit ${entityID}
connObjectKeyValidation=There must be exactly one Remote Key
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Actions
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
index 312da5d..76464c0 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_it.properties
@@ -21,3 +21,7 @@ any.edit=Modifica ${entityID}
connObjectKeyValidation=Deve essere definito esattamente una Chiave remota
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Azioni
+template.title=template utenti
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
index 4e053f7..d81f0a8 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_pt_BR.properties
@@ -21,3 +21,7 @@ any.edit=Alterar ${entityID}
connObjectKeyValidation=Precisa ser exatamente um Remote Key
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=Actions
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
----------------------------------------------------------------------
diff --git a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
index 8bedf47..8712eeb 100644
--- a/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
+++ b/ext/saml2sp/client-console/src/main/resources/org/apache/syncope/client/console/panels/SAML2IdPsDirectoryPanel_ru.properties
@@ -21,3 +21,7 @@ any.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c ${entityID}
connObjectKeyValidation=\u0422\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0440\u043e\u0432\u043d\u043e \u043e\u0434\u0438\u043d \u0434\u0438\u0441\u0442\u0430\u043d\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u044e\u0447\u0430
bindingType=Binding
html.title=metadata
+createUnmatching=Create unmatching users
+updateMatching=Update matching users
+actionsClassNames=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f
+template.title=user template
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
index ffda86d..022267d 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2IdPTO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.common.lib.to;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.PathParam;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
@@ -45,14 +47,22 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
private String metadata;
+ private boolean createUnmatching;
+
+ private boolean updateMatching;
+
private boolean useDeflateEncoding;
private SAML2BindingType bindingType;
private boolean logoutSupported;
+ private UserTO userTemplate;
+
private final List<ItemTO> items = new ArrayList<>();
+ private final Set<String> actionsClassNames = new HashSet<>();
+
@Override
public String getKey() {
return key;
@@ -88,6 +98,22 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
this.metadata = metadata;
}
+ public boolean isCreateUnmatching() {
+ return createUnmatching;
+ }
+
+ public void setCreateUnmatching(final boolean createUnmatching) {
+ this.createUnmatching = createUnmatching;
+ }
+
+ public boolean isUpdateMatching() {
+ return updateMatching;
+ }
+
+ public void setUpdateMatching(final boolean updateMatching) {
+ this.updateMatching = updateMatching;
+ }
+
public boolean isUseDeflateEncoding() {
return useDeflateEncoding;
}
@@ -112,6 +138,14 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
this.logoutSupported = logoutSupported;
}
+ public UserTO getUserTemplate() {
+ return userTemplate;
+ }
+
+ public void setUserTemplate(final UserTO userTemplate) {
+ this.userTemplate = userTemplate;
+ }
+
@Override
public ItemTO getConnObjectKeyItem() {
return IterableUtils.find(getItems(), new Predicate<ItemTO>() {
@@ -154,4 +188,11 @@ public class SAML2IdPTO extends AbstractBaseBean implements EntityTO, ItemContai
return this.items.remove(item);
}
+ @XmlElementWrapper(name = "actionsClassNames")
+ @XmlElement(name = "actionsClassName")
+ @JsonProperty("actionsClassNames")
+ public Set<String> getActionsClassNames() {
+ return actionsClassNames;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
index f905035..2b02eb4 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2LoginResponseTO.java
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.common.lib.to;
+import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Date;
import java.util.HashSet;
@@ -26,6 +27,8 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.collections4.IterableUtils;
+import org.apache.commons.collections4.Predicate;
import org.apache.syncope.common.lib.AbstractBaseBean;
@XmlRootElement(name = "saml2LoginResponse")
@@ -124,6 +127,17 @@ public class SAML2LoginResponseTO extends AbstractBaseBean {
this.username = username;
}
+ @JsonIgnore
+ public AttrTO getAttr(final String schema) {
+ return IterableUtils.find(attrs, new Predicate<AttrTO>() {
+
+ @Override
+ public boolean evaluate(final AttrTO object) {
+ return object.getSchema().equals(schema);
+ }
+ });
+ }
+
@XmlElementWrapper(name = "attrs")
@XmlElement(name = "attr")
@JsonProperty("attrs")
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
index 4ea2dec..556be9b 100644
--- a/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
+++ b/ext/saml2sp/common-lib/src/main/java/org/apache/syncope/common/lib/to/SAML2ReceivedResponseTO.java
@@ -33,8 +33,6 @@ public class SAML2ReceivedResponseTO extends AbstractBaseBean {
private String urlContext;
- private String clientAddress;
-
private String samlResponse;
private String relayState;
@@ -55,14 +53,6 @@ public class SAML2ReceivedResponseTO extends AbstractBaseBean {
this.urlContext = urlContext;
}
- public String getClientAddress() {
- return clientAddress;
- }
-
- public void setClientAddress(final String clientAddress) {
- this.clientAddress = clientAddress;
- }
-
public String getSamlResponse() {
return samlResponse;
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
index b432c04..ae3f075 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/SAML2IdPLogic.java
@@ -26,6 +26,7 @@ import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
+import java.util.Set;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Transformer;
import org.apache.commons.lang3.ArrayUtils;
@@ -35,6 +36,7 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SAML2BindingType;
import org.apache.syncope.common.lib.types.SAML2SPEntitlement;
+import org.apache.syncope.core.logic.init.SAML2SPClassPathScanImplementationLookup;
import org.apache.syncope.core.logic.saml2.SAML2ReaderWriter;
import org.apache.syncope.core.logic.saml2.SAML2IdPCache;
import org.apache.syncope.core.logic.saml2.SAML2IdPEntity;
@@ -68,8 +70,16 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
private SAML2IdPDAO idpDAO;
@Autowired
+ private SAML2SPClassPathScanImplementationLookup implLookup;
+
+ @Autowired
private SAML2ReaderWriter saml2rw;
+ @PreAuthorize("isAuthenticated()")
+ public Set<String> getActionsClasses() {
+ return implLookup.getActionsClasses();
+ }
+
private SAML2IdPTO complete(final SAML2IdP idp, final SAML2IdPTO idpTO) {
SAML2IdPEntity idpEntity = cache.get(idpTO.getEntityID());
if (idpEntity == null) {
@@ -159,7 +169,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
connObjectKeyItem.setExtAttrName("NameID");
idpTO.setConnObjectKeyItem(connObjectKeyItem);
- SAML2IdPEntity idp = cache.put(idpEntityDescriptor, connObjectKeyItem, false, SAML2BindingType.POST);
+ SAML2IdPEntity idp = cache.put(idpEntityDescriptor, idpTO);
if (idp.getSSOLocation(SAML2BindingType.POST) != null) {
idpTO.setBindingType(SAML2BindingType.POST);
} else if (idp.getSSOLocation(SAML2BindingType.REDIRECT) != null) {
@@ -225,9 +235,7 @@ public class SAML2IdPLogic extends AbstractSAML2Logic<SAML2IdPTO> {
saml2Idp = idpDAO.save(binder.update(saml2Idp, saml2IdpTO));
- idpEntity.setUseDeflateEncoding(saml2Idp.isUseDeflateEncoding());
- idpEntity.setBindingType(saml2Idp.getBindingType());
- idpEntity.setConnObjectKeyItem(binder.getIdPTO(saml2Idp).getConnObjectKeyItem());
+ idpEntity.setIdpTO(binder.getIdPTO(saml2Idp));
}
@PreAuthorize("hasRole('" + SAML2SPEntitlement.IDP_DELETE + "')")
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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 a9b63ed..f6953e6 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
@@ -18,6 +18,7 @@
*/
package org.apache.syncope.core.logic;
+import org.apache.syncope.core.logic.saml2.SAML2UserManager;
import com.fasterxml.uuid.Generators;
import com.fasterxml.uuid.impl.RandomBasedGenerator;
import java.io.OutputStream;
@@ -25,14 +26,12 @@ import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
-import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.lang3.tuple.Triple;
@@ -43,9 +42,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AttrTO;
import org.apache.syncope.common.lib.to.SAML2RequestTO;
import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
-import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
-import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.CipherAlgorithm;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.SAML2BindingType;
@@ -53,23 +50,11 @@ import org.apache.syncope.common.lib.types.StandardEntitlement;
import org.apache.syncope.core.logic.saml2.SAML2ReaderWriter;
import org.apache.syncope.core.logic.saml2.SAML2IdPCache;
import org.apache.syncope.core.logic.saml2.SAML2IdPEntity;
-import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException;
import org.apache.syncope.core.persistence.api.dao.AccessTokenDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
-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.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;
import org.apache.syncope.core.provisioning.api.data.AccessTokenDataBinder;
-import org.apache.syncope.core.provisioning.api.utils.EntityUtils;
-import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
-import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
import org.joda.time.DateTime;
import org.opensaml.core.xml.XMLObject;
import org.opensaml.core.xml.schema.XSString;
@@ -118,8 +103,8 @@ import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
-import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
+import org.apache.syncope.core.spring.security.AuthContextUtils;
import org.apache.syncope.core.spring.security.AuthDataAccessor;
import org.apache.syncope.core.spring.security.Encryptor;
@@ -149,27 +134,18 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
private SAML2IdPCache cache;
@Autowired
- private UserDAO userDAO;
+ private SAML2UserManager userManager;
@Autowired
private SAML2IdPDAO saml2IdPDAO;
@Autowired
- private PlainSchemaDAO plainSchemaDAO;
-
- @Autowired
private AccessTokenDAO accessTokenDAO;
@Autowired
- private IntAttrNameParser intAttrNameParser;
-
- @Autowired
private AuthDataAccessor authDataAccessor;
@Autowired
- private EntityFactory entityFactory;
-
- @Autowired
private SAML2ReaderWriter saml2rw;
@Resource(name = "syncopeJWTSSOProviderDelegate")
@@ -352,73 +328,6 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
return requestTO;
}
- private List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
- List<String> result = new ArrayList<>();
-
- String transformed = keyValue;
- for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
- List<Object> output = transformer.beforePull(
- null,
- null,
- Collections.<Object>singletonList(transformed));
- if (output != null && !output.isEmpty()) {
- transformed = output.get(0).toString();
- }
- }
-
- IntAttrName intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER);
-
- if (intAttrName.getField() != null) {
- switch (intAttrName.getField()) {
- case "key":
- User byKey = userDAO.find(transformed);
- if (byKey != null) {
- result.add(byKey.getKey());
- }
- break;
-
- case "username":
- User byUsername = userDAO.findByUsername(transformed);
- if (byUsername != null) {
- result.add(byUsername.getKey());
- }
- break;
-
- default:
- }
- } else if (intAttrName.getSchemaType() != null) {
- switch (intAttrName.getSchemaType()) {
- case PLAIN:
- PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
-
- PlainSchema schema = plainSchemaDAO.find(intAttrName.getSchemaName());
- if (schema == null) {
- value.setStringValue(transformed);
- } else {
- try {
- value.parseValue(schema, transformed);
- } catch (ParsingValidationException e) {
- LOG.error("While parsing provided key value {}", transformed, e);
- value.setStringValue(transformed);
- }
- }
-
- CollectionUtils.collect(userDAO.findByAttrValue(intAttrName.getSchemaName(), value),
- EntityUtils.keyTransformer(), result);
- break;
-
- case DERIVED:
- CollectionUtils.collect(userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed),
- EntityUtils.keyTransformer(), result);
- break;
-
- default:
- }
- }
-
- return result;
- }
-
@PreAuthorize("hasRole('" + StandardEntitlement.ANONYMOUS + "')")
public SAML2LoginResponseTO validateLoginResponse(final SAML2ReceivedResponseTO response) {
check();
@@ -454,7 +363,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
}
// 3. validate the SAML response and, if needed, decrypt the provided assertion(s)
- SAML2IdPEntity idp = getIdP(samlResponse.getIssuer().getValue());
+ final SAML2IdPEntity idp = getIdP(samlResponse.getIssuer().getValue());
if (idp.getConnObjectKeyItem() == null) {
throw new IllegalArgumentException("No mapping provided for SAML 2.0 IdP '" + idp.getId() + "'");
}
@@ -463,7 +372,6 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
samlResponse,
idp,
getAssertionConsumerURL(response.getSpEntityID(), response.getUrlContext()),
- response.getClientAddress(),
relayState.getJwtClaims().getSubject(),
response.getSpEntityID());
} catch (Exception e) {
@@ -474,7 +382,7 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
}
// 4. prepare the result: find matching user (if any) and return the received attributes
- SAML2LoginResponseTO responseTO = new SAML2LoginResponseTO();
+ final SAML2LoginResponseTO responseTO = new SAML2LoginResponseTO();
responseTO.setIdp(idp.getId());
responseTO.setSloSupported(idp.getSLOLocation(idp.getBindingType()) != null);
@@ -525,19 +433,49 @@ public class SAML2SPLogic extends AbstractSAML2Logic<AbstractBaseBean> {
if (nameID == null) {
throw new IllegalArgumentException("NameID not found");
}
+ final String nameIDValue = nameID.getValue();
- List<String> matchingUsers = keyValue == null
+ final List<String> matchingUsers = keyValue == null
? Collections.<String>emptyList()
- : findMatchingUser(keyValue, idp.getConnObjectKeyItem());
+ : userManager.findMatchingUser(keyValue, idp.getConnObjectKeyItem());
LOG.debug("Found {} matching users for NameID {}", matchingUsers.size(), nameID.getValue());
+ String username;
if (matchingUsers.isEmpty()) {
- throw new NotFoundException("User matching the provided NameID value " + nameID.getValue());
+ if (idp.isCreateUnmatching()) {
+ LOG.debug("No user matching NameID {}, about to create", nameID.getValue());
+
+ username = AuthContextUtils.execWithAuthContext(
+ AuthContextUtils.getDomain(), new AuthContextUtils.Executable<String>() {
+
+ @Override
+ public String exec() {
+ return userManager.create(idp, responseTO, nameIDValue);
+ }
+ });
+ } else {
+ throw new NotFoundException("User matching the provided NameID value " + nameID.getValue());
+ }
} else if (matchingUsers.size() > 1) {
throw new IllegalArgumentException("Several users match the provided NameID value " + nameID.getValue());
+ } else {
+ if (idp.isUpdateMatching()) {
+ LOG.debug("About to update {} for NameID {}", matchingUsers.get(0), nameID.getValue());
+
+ username = AuthContextUtils.execWithAuthContext(
+ AuthContextUtils.getDomain(), new AuthContextUtils.Executable<String>() {
+
+ @Override
+ public String exec() {
+ return userManager.update(matchingUsers.get(0), idp, responseTO);
+ }
+ });
+ } else {
+ username = matchingUsers.get(0);
+ }
}
- responseTO.setUsername(userDAO.find(matchingUsers.get(0)).getUsername());
+ responseTO.setUsername(username);
responseTO.setNameID(nameID.getValue());
// 5. generate JWT for further access
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
new file mode 100644
index 0000000..13b3cab
--- /dev/null
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/init/SAML2SPClassPathScanImplementationLookup.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.init;
+
+import java.lang.reflect.Modifier;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import org.apache.syncope.core.persistence.api.ImplementationLookup;
+import org.apache.syncope.core.persistence.api.SyncopeLoader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ClassUtils;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+
+@Component
+public class SAML2SPClassPathScanImplementationLookup implements SyncopeLoader {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ImplementationLookup.class);
+
+ private static final String DEFAULT_BASE_PACKAGE = "org.apache.syncope.core";
+
+ private Set<String> actionsClasses;
+
+ @Override
+ public Integer getPriority() {
+ return Integer.MIN_VALUE;
+ }
+
+ @Override
+ public void load() {
+ actionsClasses = new HashSet<>();
+
+ ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
+ scanner.addIncludeFilter(new AssignableTypeFilter(SAML2IdPActions.class));
+
+ for (BeanDefinition bd : scanner.findCandidateComponents(DEFAULT_BASE_PACKAGE)) {
+ try {
+ Class<?> clazz = ClassUtils.resolveClassName(
+ bd.getBeanClassName(), ClassUtils.getDefaultClassLoader());
+ boolean isAbstractClazz = Modifier.isAbstract(clazz.getModifiers());
+
+ if (SAML2IdPActions.class.isAssignableFrom(clazz) && !isAbstractClazz) {
+ actionsClasses.add(clazz.getName());
+ }
+ } catch (Throwable t) {
+ LOG.warn("Could not inspect class {}", bd.getBeanClassName(), t);
+ }
+ }
+
+ actionsClasses = Collections.unmodifiableSet(actionsClasses);
+ }
+
+ public Set<String> getActionsClasses() {
+ return actionsClasses;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
index ed244d0..e56b4f8 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2IdPCache.java
@@ -28,8 +28,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import net.shibboleth.utilities.java.support.xml.XMLParserException;
-import org.apache.syncope.common.lib.to.ItemTO;
-import org.apache.syncope.common.lib.types.SAML2BindingType;
+import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.core.logic.init.SAML2SPLoader;
import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
import org.apache.syncope.core.provisioning.api.data.SAML2IdPDataBinder;
@@ -66,13 +65,10 @@ public class SAML2IdPCache {
public SAML2IdPEntity put(
final EntityDescriptor entityDescriptor,
- final ItemTO connObjectKeyItem,
- final boolean useDeflateEncoding,
- final SAML2BindingType bindingType)
+ final SAML2IdPTO idpTO)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
- SAML2IdPEntity idp = new SAML2IdPEntity(
- entityDescriptor, connObjectKeyItem, useDeflateEncoding, bindingType, loader.getKeyPass());
+ SAML2IdPEntity idp = new SAML2IdPEntity(entityDescriptor, idpTO, loader.getKeyPass());
cache.put(entityDescriptor.getEntityID(), idp);
return idp;
}
@@ -85,11 +81,7 @@ public class SAML2IdPCache {
Element element = OpenSAMLUtil.getParserPool().parse(
new InputStreamReader(new ByteArrayInputStream(idp.getMetadata()))).getDocumentElement();
EntityDescriptor entityDescriptor = (EntityDescriptor) OpenSAMLUtil.fromDom(element);
- return put(
- entityDescriptor,
- binder.getIdPTO(idp).getConnObjectKeyItem(),
- idp.isUseDeflateEncoding(),
- idp.getBindingType());
+ return put(entityDescriptor, binder.getIdPTO(idp));
}
public SAML2IdPEntity remove(final String entityID) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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 c060e58..58ccfca 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,10 @@ 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;
import org.apache.syncope.common.lib.types.SAML2BindingType;
import org.opensaml.saml.common.xml.SAMLConstants;
import org.opensaml.saml.saml2.metadata.Endpoint;
@@ -51,11 +54,7 @@ public class SAML2IdPEntity {
private final String id;
- private boolean useDeflateEncoding;
-
- private SAML2BindingType bindingType;
-
- private ItemTO connObjectKeyItem;
+ private SAML2IdPTO idpTO;
private final Map<String, Endpoint> ssoBindings = new HashMap<>();
@@ -67,16 +66,12 @@ public class SAML2IdPEntity {
public SAML2IdPEntity(
final EntityDescriptor entityDescriptor,
- final ItemTO connObjectKeyItem,
- final boolean useDeflateEncoding,
- final SAML2BindingType bindingType,
+ final SAML2IdPTO idpTO,
final String keyPass)
throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException {
this.id = entityDescriptor.getEntityID();
- this.connObjectKeyItem = connObjectKeyItem;
- this.useDeflateEncoding = useDeflateEncoding;
- this.bindingType = bindingType;
+ this.idpTO = idpTO;
IDPSSODescriptor idpdescriptor = entityDescriptor.getIDPSSODescriptor(SAMLConstants.SAML20P_NS);
@@ -122,32 +117,44 @@ public class SAML2IdPEntity {
}
}
+ public void setIdpTO(final SAML2IdPTO idpTO) {
+ this.idpTO = idpTO;
+ }
+
public String getId() {
return id;
}
- public boolean isUseDeflateEncoding() {
- return useDeflateEncoding;
+ public boolean isCreateUnmatching() {
+ return idpTO.isCreateUnmatching();
}
- public void setUseDeflateEncoding(final boolean useDeflateEncoding) {
- this.useDeflateEncoding = useDeflateEncoding;
+ public boolean isUpdateMatching() {
+ return idpTO.isUpdateMatching();
}
- public SAML2BindingType getBindingType() {
- return bindingType;
+ public boolean isUseDeflateEncoding() {
+ return idpTO.isUseDeflateEncoding();
}
- public void setBindingType(final SAML2BindingType bindingType) {
- this.bindingType = bindingType;
+ public SAML2BindingType getBindingType() {
+ return idpTO.getBindingType();
}
public ItemTO getConnObjectKeyItem() {
- return connObjectKeyItem;
+ return idpTO.getConnObjectKeyItem();
+ }
+
+ public List<ItemTO> getItems() {
+ return idpTO.getItems();
+ }
+
+ public UserTO getUserTemplate() {
+ return idpTO.getUserTemplate();
}
- public void setConnObjectKeyItem(final ItemTO connObjectKeyItem) {
- this.connObjectKeyItem = connObjectKeyItem;
+ public Set<String> getActionsClassNames() {
+ return idpTO.getActionsClassNames();
}
public Endpoint getSSOLocation(final SAML2BindingType bindingType) {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
index 1852a39..3431a86 100644
--- a/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2ReaderWriter.java
@@ -214,7 +214,6 @@ public class SAML2ReaderWriter {
final Response samlResponse,
final SAML2IdPEntity idp,
final String assertionConsumerURL,
- final String clientAddress,
final String requestId,
final String spEntityID)
throws WSSecurityException {
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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
new file mode 100644
index 0000000..a7af5e2
--- /dev/null
+++ b/ext/saml2sp/logic/src/main/java/org/apache/syncope/core/logic/saml2/SAML2UserManager.java
@@ -0,0 +1,292 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.logic.saml2;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.tuple.Pair;
+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.PlainSchemaDAO;
+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.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+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;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+import org.apache.syncope.core.provisioning.api.UserProvisioningManager;
+import org.apache.syncope.core.provisioning.api.data.ItemTransformer;
+import org.apache.syncope.core.provisioning.api.data.UserDataBinder;
+import org.apache.syncope.core.provisioning.java.IntAttrNameParser;
+import org.apache.syncope.core.provisioning.java.utils.MappingUtils;
+import org.apache.syncope.core.provisioning.java.utils.TemplateUtils;
+import org.apache.syncope.core.spring.ApplicationContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+@Component
+public class SAML2UserManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SAML2UserManager.class);
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ private IntAttrNameParser intAttrNameParser;
+
+ @Autowired
+ private EntityFactory entityFactory;
+
+ @Autowired
+ private TemplateUtils templateUtils;
+
+ @Autowired
+ private UserProvisioningManager provisioningManager;
+
+ @Autowired
+ private UserDataBinder binder;
+
+ @Transactional(readOnly = true)
+ public List<String> findMatchingUser(final String keyValue, final ItemTO connObjectKeyItem) {
+ List<String> result = new ArrayList<>();
+
+ String transformed = keyValue;
+ for (ItemTransformer transformer : MappingUtils.getItemTransformers(connObjectKeyItem)) {
+ List<Object> output = transformer.beforePull(
+ null,
+ null,
+ Collections.<Object>singletonList(transformed));
+ if (output != null && !output.isEmpty()) {
+ transformed = output.get(0).toString();
+ }
+ }
+
+ IntAttrName intAttrName = intAttrNameParser.parse(connObjectKeyItem.getIntAttrName(), AnyTypeKind.USER);
+
+ if (intAttrName.getField() != null) {
+ switch (intAttrName.getField()) {
+ case "key":
+ User byKey = userDAO.find(transformed);
+ if (byKey != null) {
+ result.add(byKey.getUsername());
+ }
+ break;
+
+ case "username":
+ User byUsername = userDAO.findByUsername(transformed);
+ if (byUsername != null) {
+ result.add(byUsername.getUsername());
+ }
+ break;
+
+ default:
+ }
+ } else if (intAttrName.getSchemaType() != null) {
+ switch (intAttrName.getSchemaType()) {
+ case PLAIN:
+ PlainAttrValue value = entityFactory.newEntity(UPlainAttrValue.class);
+
+ PlainSchema schema = plainSchemaDAO.find(intAttrName.getSchemaName());
+ if (schema == null) {
+ value.setStringValue(transformed);
+ } else {
+ try {
+ value.parseValue(schema, transformed);
+ } catch (ParsingValidationException e) {
+ LOG.error("While parsing provided key value {}", transformed, e);
+ value.setStringValue(transformed);
+ }
+ }
+
+ CollectionUtils.collect(
+ userDAO.findByAttrValue(intAttrName.getSchemaName(), value),
+ new Transformer<User, String>() {
+
+ @Override
+ public String transform(final User input) {
+ return input.getUsername();
+ }
+ }, result);
+ break;
+
+ case DERIVED:
+ CollectionUtils.collect(
+ userDAO.findByDerAttrValue(intAttrName.getSchemaName(), transformed),
+ new Transformer<User, String>() {
+
+ @Override
+ public String transform(final User input) {
+ return input.getUsername();
+ }
+ }, result);
+ break;
+
+ default:
+ }
+ }
+
+ return result;
+ }
+
+ private List<SAML2IdPActions> getActions(final SAML2IdPEntity idp) {
+ List<SAML2IdPActions> actions = new ArrayList<>();
+
+ for (String className : idp.getActionsClassNames()) {
+ 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);
+ }
+ }
+
+ return actions;
+ }
+
+ private void fill(final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO, final UserTO userTO) {
+ for (ItemTO item : idp.getItems()) {
+ IntAttrName intAttrName = intAttrNameParser.parse(item.getIntAttrName(), AnyTypeKind.USER);
+
+ List<String> values = Collections.emptyList();
+ AttrTO samlAttr = responseTO.getAttr(item.getExtAttrName());
+ if (samlAttr != null && !samlAttr.getValues().isEmpty()) {
+ values = samlAttr.getValues();
+
+ List<Object> transformed = new ArrayList<Object>(values);
+ for (ItemTransformer transformer : MappingUtils.getItemTransformers(item)) {
+ transformed = transformer.beforePull(null, userTO, transformed);
+ }
+ values.clear();
+ for (Object value : transformed) {
+ values.add(value.toString());
+ }
+ }
+
+ if (intAttrName.getField() != null) {
+ switch (intAttrName.getField()) {
+ case "username":
+ if (!values.isEmpty()) {
+ userTO.setUsername(values.get(0));
+ }
+ break;
+
+ default:
+ LOG.warn("Unsupported: {}", intAttrName.getField());
+ }
+ } else if (intAttrName.getSchemaType() != null) {
+ switch (intAttrName.getSchemaType()) {
+ case PLAIN:
+ AttrTO attr = userTO.getPlainAttr(intAttrName.getSchemaName());
+ if (attr == null) {
+ attr = new AttrTO.Builder().schema(intAttrName.getSchemaName()).build();
+ userTO.getPlainAttrs().add(attr);
+ }
+ attr.getValues().clear();
+ attr.getValues().addAll(values);
+ break;
+
+ default:
+ LOG.warn("Unsupported: {} {}", intAttrName.getSchemaType(), intAttrName.getSchemaName());
+ }
+ }
+ }
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public String create(final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO, final String nameID) {
+ UserTO userTO = new UserTO();
+
+ if (idp.getUserTemplate() != null) {
+ templateUtils.apply(userTO, idp.getUserTemplate());
+ }
+
+ List<SAML2IdPActions> actions = getActions(idp);
+ for (SAML2IdPActions action : actions) {
+ userTO = action.beforeCreate(userTO, responseTO);
+ }
+
+ fill(idp, responseTO, userTO);
+
+ if (userTO.getRealm() == null) {
+ userTO.setRealm(SyncopeConstants.ROOT_REALM);
+ }
+ if (userTO.getUsername() == null) {
+ userTO.setUsername(nameID);
+ }
+
+ Pair<String, List<PropagationStatus>> created = provisioningManager.create(userTO, false, false);
+ userTO = binder.getUserTO(created.getKey());
+
+ for (SAML2IdPActions action : actions) {
+ userTO = action.afterCreate(userTO, responseTO);
+ }
+
+ return userTO.getUsername();
+ }
+
+ @Transactional(propagation = Propagation.REQUIRES_NEW)
+ public String update(final String username, final SAML2IdPEntity idp, final SAML2LoginResponseTO responseTO) {
+ UserTO userTO = binder.getUserTO(username);
+ UserTO original = SerializationUtils.clone(userTO);
+
+ fill(idp, responseTO, userTO);
+
+ UserPatch userPatch = AnyOperations.diff(userTO, original, true);
+
+ List<SAML2IdPActions> actions = getActions(idp);
+ for (SAML2IdPActions action : actions) {
+ userPatch = action.beforeUpdate(userPatch, responseTO);
+ }
+
+ Pair<String, List<PropagationStatus>> updated = provisioningManager.update(userPatch, false);
+ userTO = binder.getUserTO(updated.getKey());
+
+ for (SAML2IdPActions action : actions) {
+ userTO = action.afterUpdate(userTO, responseTO);
+ }
+
+ return userTO.getUsername();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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 7d1a5da..5588334 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
@@ -19,6 +19,7 @@
package org.apache.syncope.core.persistence.api.entity;
import java.util.List;
+import java.util.Set;
import org.apache.syncope.common.lib.types.SAML2BindingType;
public interface SAML2IdP extends Entity {
@@ -35,6 +36,14 @@ public interface SAML2IdP extends Entity {
void setMetadata(byte[] metadata);
+ boolean isCreateUnmatching();
+
+ void setCreateUnmatching(boolean createUnmatching);
+
+ boolean isUpdateMatching();
+
+ void setUpdateMatching(boolean updateMatching);
+
boolean isUseDeflateEncoding();
void setUseDeflateEncoding(boolean useDeflateEncoding);
@@ -43,6 +52,10 @@ public interface SAML2IdP extends Entity {
void setBindingType(SAML2BindingType bindingType);
+ SAML2UserTemplate getUserTemplate();
+
+ void setUserTemplate(SAML2UserTemplate userTemplate);
+
SAML2IdPItem getConnObjectKeyItem();
void setConnObjectKeyItem(SAML2IdPItem item);
@@ -51,4 +64,6 @@ public interface SAML2IdP extends Entity {
List<? extends SAML2IdPItem> getItems();
+ Set<String> getActionsClassNames();
+
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.java
new file mode 100644
index 0000000..a26227b
--- /dev/null
+++ b/ext/saml2sp/persistence-api/src/main/java/org/apache/syncope/core/persistence/api/entity/SAML2UserTemplate.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.core.persistence.api.entity;
+
+public interface SAML2UserTemplate extends AnyTemplate {
+
+ SAML2IdP getIdP();
+
+ void setIdP(SAML2IdP idp);
+}
[3/4] syncope git commit: [SYNCOPE-1146][SYNCOPE-1147] Now it
possible to configure an IdP to create unmatching users / update matching
users;
the defined mapping, alongside with user template and SAML2IdPActions
implementations are taken into account to
Posted by il...@apache.org.
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
index 2277c14..888e870 100644
--- a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2EntityFactory.java
@@ -22,6 +22,7 @@ import org.apache.syncope.core.persistence.api.entity.Entity;
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;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
import org.springframework.stereotype.Component;
@Component
@@ -36,6 +37,8 @@ public class JPASAML2EntityFactory implements SAML2EntityFactory {
result = (E) new JPASAML2IdP();
} else if (reference.equals(SAML2IdPItem.class)) {
result = (E) new JPASAML2IdPItem();
+ } else if (reference.equals(SAML2UserTemplate.class)) {
+ result = (E) new JPASAML2UserTemplate();
} else {
throw new IllegalArgumentException("Could not find a JPA implementation of " + reference.getName());
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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 cf1e3a8..d6df04d 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,15 +19,21 @@
package org.apache.syncope.core.persistence.jpa.entity;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+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.Lob;
import javax.persistence.OneToMany;
+import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
@@ -37,6 +43,7 @@ import org.apache.commons.lang3.ArrayUtils;
import org.apache.syncope.common.lib.types.SAML2BindingType;
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;
import org.apache.syncope.core.persistence.jpa.validation.entity.SAML2IdPCheck;
@Entity
@@ -65,11 +72,31 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
@Min(0)
@Max(1)
@Column(nullable = false)
+ private Integer createUnmatching;
+
+ @Min(0)
+ @Max(1)
+ @Column(nullable = false)
+ private Integer updateMatching;
+
+ @Min(0)
+ @Max(1)
+ @Column(nullable = false)
private Integer useDeflateEncoding;
@Column(nullable = false)
private SAML2BindingType bindingType;
+ @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",
+ joinColumns =
+ @JoinColumn(name = "saml2IdP_id", referencedColumnName = "id"))
+ private Set<String> actionsClassNames = new HashSet<>();
+
@Override
public String getEntityID() {
return entityID;
@@ -101,6 +128,26 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
}
@Override
+ public boolean isCreateUnmatching() {
+ return isBooleanAsInteger(createUnmatching);
+ }
+
+ @Override
+ public void setCreateUnmatching(final boolean createUnmatching) {
+ this.createUnmatching = getBooleanAsInteger(createUnmatching);
+ }
+
+ @Override
+ public boolean isUpdateMatching() {
+ return isBooleanAsInteger(updateMatching);
+ }
+
+ @Override
+ public void setUpdateMatching(final boolean updateMatching) {
+ this.updateMatching = getBooleanAsInteger(updateMatching);
+ }
+
+ @Override
public boolean isUseDeflateEncoding() {
return isBooleanAsInteger(useDeflateEncoding);
}
@@ -121,6 +168,17 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
}
@Override
+ public SAML2UserTemplate getUserTemplate() {
+ return userTemplate;
+ }
+
+ @Override
+ public void setUserTemplate(final SAML2UserTemplate userTemplate) {
+ checkType(userTemplate, JPASAML2UserTemplate.class);
+ this.userTemplate = (JPASAML2UserTemplate) userTemplate;
+ }
+
+ @Override
public boolean add(final SAML2IdPItem item) {
checkType(item, JPASAML2IdPItem.class);
return items.contains((JPASAML2IdPItem) item) || items.add((JPASAML2IdPItem) item);
@@ -148,4 +206,8 @@ public class JPASAML2IdP extends AbstractGeneratedKeyEntity implements SAML2IdP
this.add(item);
}
+ @Override
+ public Set<String> getActionsClassNames() {
+ return actionsClassNames;
+ }
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
new file mode 100644
index 0000000..538fa94
--- /dev/null
+++ b/ext/saml2sp/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/JPASAML2UserTemplate.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.UniqueConstraint;
+import org.apache.syncope.core.persistence.api.entity.SAML2IdP;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.resource.AbstractAnyTemplate;
+
+@Entity
+@Table(name = JPASAML2UserTemplate.TABLE, uniqueConstraints =
+ @UniqueConstraint(columnNames = { "idp_id" }))
+public class JPASAML2UserTemplate extends AbstractAnyTemplate implements SAML2UserTemplate {
+
+ private static final long serialVersionUID = -4575039890434426856L;
+
+ public static final String TABLE = "SAML2UserTemplate";
+
+ @ManyToOne
+ private JPASAML2IdP idp;
+
+ @Override
+ public SAML2IdP getIdP() {
+ return idp;
+ }
+
+ @Override
+ public void setIdP(final SAML2IdP idp) {
+ checkType(idp, JPASAML2IdP.class);
+ this.idp = (JPASAML2IdP) idp;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java b/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
new file mode 100644
index 0000000..6f23804
--- /dev/null
+++ b/ext/saml2sp/provisioning-api/src/main/java/org/apache/syncope/core/provisioning/api/SAML2IdPActions.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.api;
+
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+public interface SAML2IdPActions {
+
+ UserTO beforeCreate(UserTO input, SAML2LoginResponseTO loginResponse);
+
+ UserTO afterCreate(UserTO input, SAML2LoginResponseTO loginResponse);
+
+ UserPatch beforeUpdate(UserPatch input, SAML2LoginResponseTO loginResponse);
+
+ UserTO afterUpdate(UserTO input, SAML2LoginResponseTO loginResponse);
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
new file mode 100644
index 0000000..ba5fc40
--- /dev/null
+++ b/ext/saml2sp/provisioning-java/src/main/java/org/apache/syncope/core/provisioning/java/DefaultSAML2IdPActions.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.provisioning.java;
+
+import org.apache.syncope.common.lib.patch.UserPatch;
+import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.core.provisioning.api.SAML2IdPActions;
+
+public class DefaultSAML2IdPActions implements SAML2IdPActions {
+
+ @Override
+ public UserTO beforeCreate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserTO afterCreate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserPatch beforeUpdate(final UserPatch input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+ @Override
+ public UserTO afterUpdate(final UserTO input, final SAML2LoginResponseTO loginResponse) {
+ return input;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/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 b2668c5..2f2f9d0 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
@@ -24,6 +24,7 @@ import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.to.AnyTypeClassTO;
import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
+import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.MappingPurpose;
@@ -36,6 +37,7 @@ import org.apache.syncope.core.persistence.api.entity.PlainSchema;
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;
+import org.apache.syncope.core.persistence.api.entity.SAML2UserTemplate;
import org.apache.syncope.core.persistence.api.entity.VirSchema;
import org.apache.syncope.core.provisioning.api.IntAttrName;
import org.apache.syncope.core.provisioning.api.data.SAML2IdPDataBinder;
@@ -168,9 +170,24 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
idp.setEntityID(idpTO.getEntityID());
idp.setName(idpTO.getName());
idp.setMetadata(Base64.decode(idpTO.getMetadata()));
+ idp.setCreateUnmatching(idpTO.isCreateUnmatching());
+ idp.setUpdateMatching(idpTO.isUpdateMatching());
idp.setUseDeflateEncoding(idpTO.isUseDeflateEncoding());
idp.setBindingType(idpTO.getBindingType());
+ if (idpTO.getUserTemplate() == null) {
+ idp.setUserTemplate(null);
+ } else {
+ SAML2UserTemplate userTemplate = idp.getUserTemplate();
+ if (userTemplate == null) {
+ userTemplate = entityFactory.newEntity(SAML2UserTemplate.class);
+ userTemplate.setAnyType(anyTypeDAO.findUser());
+ userTemplate.setIdP(idp);
+ idp.setUserTemplate(userTemplate);
+ }
+ userTemplate.set(idpTO.getUserTemplate());
+ }
+
idp.getItems().clear();
AnyTypeClassTO allowedSchemas = new AnyTypeClassTO();
for (AnyTypeClass anyTypeClass : anyTypeDAO.findUser().getClasses()) {
@@ -186,6 +203,9 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
}
populateItems(idpTO, idp, allowedSchemas);
+ idp.getActionsClassNames().clear();
+ idp.getActionsClassNames().addAll(idpTO.getActionsClassNames());
+
return saml2IdPDAO.save(idp);
}
@@ -213,10 +233,18 @@ public class SAML2IdPDataBinderImpl implements SAML2IdPDataBinder {
idpTO.setName(idp.getName());
idpTO.setUseDeflateEncoding(idp.isUseDeflateEncoding());
idpTO.setBindingType(idp.getBindingType());
+ idpTO.setCreateUnmatching(idp.isCreateUnmatching());
+ idpTO.setUpdateMatching(idp.isUpdateMatching());
idpTO.setMetadata(Base64.encode(idp.getMetadata()));
+ if (idp.getUserTemplate() != null) {
+ idpTO.setUserTemplate((UserTO) idp.getUserTemplate().get());
+ }
+
populateItems(idp, idpTO);
+ idpTO.getActionsClassNames().addAll(idp.getActionsClassNames());
+
return idpTO;
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java b/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
index 5761c01..0d528c3 100644
--- a/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
+++ b/ext/saml2sp/rest-api/src/main/java/org/apache/syncope/common/rest/api/service/SAML2IdPService.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.rest.api.service;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.validation.constraints.NotNull;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -40,6 +41,16 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
public interface SAML2IdPService extends JAXRSService {
/**
+ * Returns the list of available SAML2IdPActions implementations.
+ *
+ * @return the list of available SAML2IdPActions implementations
+ */
+ @GET
+ @Path("actionsClasses")
+ @Produces({ MediaType.APPLICATION_JSON })
+ Set<String> getActionsClasses();
+
+ /**
* Returns a list of all defined SAML 2.0 Identity Providers.
*
* @return list of all defined SAML 2.0 Identity Providers
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
----------------------------------------------------------------------
diff --git a/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java b/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
index 1f2790f..ebda30d 100644
--- a/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
+++ b/ext/saml2sp/rest-cxf/src/main/java/org/apache/syncope/core/rest/cxf/service/SAML2IdPServiceImpl.java
@@ -20,6 +20,7 @@ package org.apache.syncope.core.rest.cxf.service;
import java.io.InputStream;
import java.util.List;
+import java.util.Set;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.rest.api.RESTHeaders;
@@ -35,6 +36,11 @@ public class SAML2IdPServiceImpl extends AbstractServiceImpl implements SAML2IdP
private SAML2IdPLogic logic;
@Override
+ public Set<String> getActionsClasses() {
+ return logic.getActionsClasses();
+ }
+
+ @Override
public List<SAML2IdPTO> list() {
return logic.list();
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/f1c004bf/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
----------------------------------------------------------------------
diff --git a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
index f0cd386..b87db1b 100644
--- a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
+++ b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2ITCase.java
@@ -22,6 +22,7 @@ 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;
@@ -48,6 +49,7 @@ import org.apache.syncope.common.lib.to.SAML2IdPTO;
import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
import org.apache.syncope.common.lib.to.SAML2ReceivedResponseTO;
import org.apache.syncope.common.lib.to.SAML2RequestTO;
+import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.rest.api.service.SAML2SPService;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.SAML2SPDetector;
@@ -171,13 +173,20 @@ public class SAML2ITCase extends AbstractITCase {
SAML2IdPTO ssoCircle = ssoCircleOpt.get();
assertNotNull(ssoCircle);
+ assertFalse(ssoCircle.isCreateUnmatching());
+ assertNull(ssoCircle.getUserTemplate());
assertFalse(ssoCircle.getItems().isEmpty());
assertNotNull(ssoCircle.getConnObjectKeyItem());
assertNotEquals("email", ssoCircle.getConnObjectKeyItem().getIntAttrName());
assertNotEquals("EmailAddress", ssoCircle.getConnObjectKeyItem().getExtAttrName());
- ssoCircle.getItems().clear();
+ ssoCircle.setCreateUnmatching(true);
+
+ UserTO userTemplate = new UserTO();
+ userTemplate.setRealm("'/'");
+ ssoCircle.setUserTemplate(userTemplate);
+ ssoCircle.getItems().clear();
ItemTO keyMapping = new ItemTO();
keyMapping.setIntAttrName("email");
keyMapping.setExtAttrName("EmailAddress");
@@ -186,6 +195,8 @@ public class SAML2ITCase extends AbstractITCase {
saml2IdPService.update(ssoCircle);
ssoCircle = saml2IdPService.read(ssoCircle.getKey());
+ assertTrue(ssoCircle.isCreateUnmatching());
+ assertEquals(userTemplate, ssoCircle.getUserTemplate());
assertEquals("email", ssoCircle.getConnObjectKeyItem().getIntAttrName());
assertEquals("EmailAddress", ssoCircle.getConnObjectKeyItem().getExtAttrName());
}