[2/2] syncope git commit: White noise: format

2017-08-03 Thread ilgrosso
White noise: format


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e3467bf4
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e3467bf4
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e3467bf4

Branch: refs/heads/master
Commit: e3467bf4bfa58db7788f3993c3b333a41e9d37f1
Parents: acf98a4
Author: Francesco Chicchiriccò 
Authored: Thu Aug 3 09:08:06 2017 +0200
Committer: Francesco Chicchiriccò 
Committed: Thu Aug 3 09:10:42 2017 +0200

--
 .../syncope/fit/core/SAML2CallbackHandler.java  | 49 ++---
 .../apache/syncope/fit/core/SAML2ITCase.java| 54 ++
 .../core/SAML2PResponseComponentBuilder.java| 77 +++-
 3 files changed, 76 insertions(+), 104 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/syncope/blob/e3467bf4/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2CallbackHandler.java
--
diff --git 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2CallbackHandler.java
 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2CallbackHandler.java
index f80d4b9..1ffdfb2 100644
--- 
a/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2CallbackHandler.java
+++ 
b/fit/core-reference/src/test/java/org/apache/syncope/fit/core/SAML2CallbackHandler.java
@@ -1,31 +1,28 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
+ * or more contributor license agreements.  See the NOTICE file
  * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
+ * 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
+ * with the License.  You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *   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
+ * KIND, either express or implied.  See the License for the
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.syncope.fit.core;
 
 import java.io.IOException;
 import java.util.Collections;
-
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.UnsupportedCallbackException;
-
 import org.apache.wss4j.common.saml.SAMLCallback;
 import org.apache.wss4j.common.saml.bean.AuthenticationStatementBean;
 import org.apache.wss4j.common.saml.bean.ConditionsBean;
@@ -38,35 +35,37 @@ import org.apache.wss4j.common.saml.builder.SAML2Constants;
  * A Callback Handler implementation for a SAML 2 assertion.
  */
 public class SAML2CallbackHandler implements CallbackHandler {
+
 private String subjectName = 
"uid=joe,ou=people,ou=saml-demo,o=example.com";
+
 private String subjectQualifier = "www.example.com";
+
 private String issuer;
+
 private ConditionsBean conditions;
+
 private SubjectConfirmationDataBean subjectConfirmationData;
+
 private String subjectConfirmationMethod = SAML2Constants.CONF_BEARER;
 
-public void handle(Callback[] callbacks)
-throws IOException, UnsupportedCallbackException {
-for (int i = 0; i < callbacks.length; i++) {
-if (callbacks[i] instanceof SAMLCallback) {
-SAMLCallback callback = (SAMLCallback) callbacks[i];
-callback.setSamlVersion(Version.SAML_20);
-callback.setIssuer(issuer);
+@Override
+public void handle(Callback[] callbacks) throws IOException, 
UnsupportedCallbackException {
+for (Callback callback : callbacks) {
+if (callback instanceof SAMLCallback) {
+SAMLCallback samlCallback = (SAMLCallback) callback;
+samlCallback.setSamlVersion(Version.SAML_20);
+samlCallback.setIssuer(issuer);
 if (conditions != null) {
-callback.setConditions(conditions);
+samlCallback.setConditions(conditions);
 }
-
-SubjectBean subjectBean =
-new SubjectBean(
-subjectName, subjectQualifier, 
subjectConfirmationMethod
-);
+SubjectBean subjectBean = new 

Syncope-2_0_X - Build # 79 - Fixed

2017-08-03 Thread Apache Jenkins Server
The Apache Jenkins build system has built Syncope-2_0_X (build #79)

Status: Fixed

Check console output at https://builds.apache.org/job/Syncope-2_0_X/79/ to view 
the results.

[2/2] syncope git commit: [SYNCOPE-1185] SAMLSSOResponseValidator in action

2017-08-03 Thread ilgrosso
[SYNCOPE-1185] SAMLSSOResponseValidator in action


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/e624f369
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/e624f369
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/e624f369

Branch: refs/heads/master
Commit: e624f369d6a2df12ddc516e6b50ff5cb9d30747b
Parents: e3467bf
Author: Francesco Chicchiriccò 
Authored: Thu Aug 3 12:51:50 2017 +0200
Committer: Francesco Chicchiriccò 
Committed: Thu Aug 3 12:53:58 2017 +0200

--
 .../saml2lsp/agent/AbstractSAML2SPServlet.java  |  10 ++-
 .../ext/saml2lsp/agent/AssertionConsumer.java   |   7 +-
 .../syncope/ext/saml2lsp/agent/Logout.java  |   6 +-
 .../common/lib/to/SAML2ReceivedResponseTO.java  |  31 
 .../apache/syncope/core/logic/SAML2SPLogic.java |  33 
 .../core/logic/saml2/SAML2ReaderWriter.java |  25 +-
 fit/core-reference/pom.xml  |   2 -
 .../apache/syncope/fit/core/SAML2ITCase.java|  76 ++-
 .../src/test/resources/stsrealm_a.jks   | Bin 2061 -> 0 bytes
 9 files changed, 130 insertions(+), 60 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/syncope/blob/e624f369/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 d84bcd7..ecc14fe 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
@@ -76,7 +76,12 @@ public abstract class AbstractSAML2SPServlet extends 
HttpServlet {
 }
 }
 
-protected SAML2ReceivedResponseTO extract(final InputStream response) 
throws IOException {
+protected SAML2ReceivedResponseTO extract(
+final String spEntityID,
+final String urlContext,
+final String clientAddress,
+final InputStream response) throws IOException {
+
 String strForm = IOUtils.toString(response);
 MultivaluedMap params = 
JAXRSUtils.getStructuredParams(strForm, "&", false, false);
 
@@ -90,6 +95,9 @@ public abstract class AbstractSAML2SPServlet extends 
HttpServlet {
 LOG.debug("Received Relay State: {}", relayState);
 
 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/e624f369/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
--
diff --git 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
index 698aa7f..a2fec3a 100644
--- 
a/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
+++ 
b/ext/saml2sp/agent/src/main/java/org/apache/syncope/ext/saml2lsp/agent/AssertionConsumer.java
@@ -25,6 +25,7 @@ import javax.servlet.ServletException;
 import javax.servlet.annotation.WebServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.client.lib.SyncopeClient;
 import org.apache.syncope.common.lib.to.SAML2LoginResponseTO;
 import org.apache.syncope.common.rest.api.service.SAML2SPService;
@@ -42,7 +43,11 @@ public class AssertionConsumer extends 
AbstractSAML2SPServlet {
 getAttribute(Constants.SYNCOPE_ANONYMOUS_CLIENT);
 try {
 SAML2LoginResponseTO responseTO = 
anonymous.getService(SAML2SPService.class).
-validateLoginResponse(extract(request.getInputStream()));
+validateLoginResponse(extract(
+
StringUtils.substringBefore(request.getRequestURL().toString(), "/saml2sp"),
+"saml2sp",
+request.getRemoteAddr(),
+request.getInputStream()));
 
 

[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 SAM

2017-08-03 Thread ilgrosso
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 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 

syncope git commit: changed access of PlainAttrs.getFieldPanel to protected in order to allow easy customization

2017-08-03 Thread andreapatricelli
Repository: syncope
Updated Branches:
  refs/heads/2_0_X 923f64a87 -> 54bc012b1


changed access of PlainAttrs.getFieldPanel to protected in order to allow easy 
customization


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/54bc012b
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/54bc012b
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/54bc012b

Branch: refs/heads/2_0_X
Commit: 54bc012b1faf33b5e92ec2147da450ae5a994099
Parents: 923f64a
Author: Andrea Patricelli 
Authored: Thu Aug 3 16:56:48 2017 +0200
Committer: Andrea Patricelli 
Committed: Thu Aug 3 16:57:06 2017 +0200

--
 .../org/apache/syncope/client/console/wizards/any/PlainAttrs.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
--


http://git-wip-us.apache.org/repos/asf/syncope/blob/54bc012b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
--
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
index bbb218c..1594ca0 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/PlainAttrs.java
@@ -202,7 +202,7 @@ public class PlainAttrs extends 
AbstractAttrs {
 }
 
 @SuppressWarnings({ "rawtypes", "unchecked" })
-private FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
+protected FieldPanel getFieldPanel(final PlainSchemaTO schemaTO) {
 final boolean required;
 final boolean readOnly;
 final AttrSchemaType type;



syncope git commit: [SYNCOPE-1171] 'Relationships' wizard step is now skipped when no relationship types exist

2017-08-03 Thread skylark17
Repository: syncope
Updated Branches:
  refs/heads/2_0_X 50c8df89c -> 923f64a87


[SYNCOPE-1171] 'Relationships' wizard step is now skipped when no relationship 
types exist


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/923f64a8
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/923f64a8
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/923f64a8

Branch: refs/heads/2_0_X
Commit: 923f64a87eae8c7baecb88e110e1d55491acbf42
Parents: 50c8df8
Author: skylark17 
Authored: Thu Aug 3 16:30:04 2017 +0200
Committer: skylark17 
Committed: Thu Aug 3 16:30:04 2017 +0200

--
 .../client/console/wizards/any/Relationships.java | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)
--


http://git-wip-us.apache.org/repos/asf/syncope/blob/923f64a8/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
--
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
index 1cc758c..115da51 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Relationships.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.client.console.wizards.any;
 
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -69,6 +70,7 @@ import org.apache.wicket.event.IEvent;
 import org.apache.wicket.extensions.markup.html.tabs.AbstractTab;
 import org.apache.wicket.extensions.markup.html.tabs.ITab;
 import org.apache.wicket.extensions.wizard.IWizard;
+import org.apache.wicket.extensions.wizard.WizardModel;
 import org.apache.wicket.extensions.wizard.WizardStep;
 import org.apache.wicket.markup.head.IHeaderResponse;
 import org.apache.wicket.markup.head.OnDomReadyHeaderItem;
@@ -82,7 +84,7 @@ import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.util.ListModel;
 
-public class Relationships extends WizardStep {
+public class Relationships extends WizardStep implements 
WizardModel.ICondition {
 
 private static final long serialVersionUID = 855618618337931784L;
 
@@ -93,6 +95,8 @@ public class Relationships extends WizardStep {
 private final AnyTypeClassRestClient anyTypeClassRestClient = new 
AnyTypeClassRestClient();
 
 private final AnyTO anyTO;
+
+private final RelationshipTypeRestClient relationshipTypeRestClient = new 
RelationshipTypeRestClient();
 
 public Relationships(final AnyWrapper modelObject, final PageReference 
pageRef) {
 super();
@@ -233,6 +237,12 @@ public class Relationships extends WizardStep {
 }
 }
 
+@Override
+public boolean evaluate() {
+// [SYNCOPE-1171] - skip current step when the are no relationships 
types in Syncope
+return !relationshipTypeRestClient.list().isEmpty();
+}
+
 public class Specification extends Panel {
 
 private static final long serialVersionUID = 6199050589175839467L;
@@ -243,8 +253,6 @@ public class Relationships extends WizardStep {
 
 private WizardMgtPanel 
anyObjectDirectoryPanel;
 
-private final RelationshipTypeRestClient relationshipTypeRestClient = 
new RelationshipTypeRestClient();
-
 public Specification() {
 super("specification");
 rel = new RelationshipTO();



Syncope-2_0_X - Build # 81 - Still Unstable

2017-08-03 Thread Apache Jenkins Server
The Apache Jenkins build system has built Syncope-2_0_X (build #81)

Status: Still Unstable

Check console output at https://builds.apache.org/job/Syncope-2_0_X/81/ to view 
the results.

syncope git commit: [SYNCOPE-1161] New option to clone a resource

2017-08-03 Thread skylark17
Repository: syncope
Updated Branches:
  refs/heads/master e624f369d -> 0c2414c1a


[SYNCOPE-1161] New option to clone a resource


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/0c2414c1
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/0c2414c1
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/0c2414c1

Branch: refs/heads/master
Commit: 0c2414c1ab7a700d83768dd95e7f6379ff2fa6b6
Parents: e624f36
Author: skylark17 
Authored: Thu Aug 3 14:16:43 2017 +0200
Committer: skylark17 
Committed: Thu Aug 3 15:04:28 2017 +0200

--
 .../console/topology/TopologyTogglePanel.java   | 54 
 .../SyncopeConsoleApplication.properties|  1 +
 .../SyncopeConsoleApplication_it.properties |  1 +
 .../SyncopeConsoleApplication_pt_BR.properties  |  1 +
 .../SyncopeConsoleApplication_ru.properties |  1 +
 .../console/topology/TopologyTogglePanel.html   |  3 ++
 .../topology/TopologyTogglePanel.properties |  1 +
 .../topology/TopologyTogglePanel_it.properties  |  1 +
 .../TopologyTogglePanel_pt_BR.properties|  1 +
 .../topology/TopologyTogglePanel_ru.properties  |  1 +
 10 files changed, 65 insertions(+)
--


http://git-wip-us.apache.org/repos/asf/syncope/blob/0c2414c1/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
--
diff --git 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
index ac55f7a..df1e273 100644
--- 
a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
+++ 
b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyTogglePanel.java
@@ -40,9 +40,12 @@ import org.apache.syncope.client.console.tasks.PullTasks;
 import 
org.apache.syncope.client.console.wicket.markup.html.bootstrap.dialog.BaseModal;
 import 
org.apache.syncope.client.console.wicket.markup.html.form.IndicatingOnConfirmAjaxLink;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
+import 
org.apache.syncope.client.console.wizards.resources.AbstractResourceWizardBuilder;
 import 
org.apache.syncope.client.console.wizards.resources.ResourceProvisionPanel;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ItemTO;
+import org.apache.syncope.common.lib.to.ProvisionTO;
 import org.apache.syncope.common.lib.to.ResourceTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
@@ -583,6 +586,57 @@ public class TopologyTogglePanel extends 
TogglePanel {
 MetaDataRoleAuthorizationStrategy.authorize(history, RENDER, 
StandardEntitlement.RESOURCE_HISTORY_LIST);
 fragment.add(history);
 
+// [SYNCOPE-1161] - Option to clone a resource
+AjaxLink clone = new 
IndicatingOnConfirmAjaxLink("clone", "confirmClone", true) {
+
+private static final long serialVersionUID = -7978723352517770644L;
+
+@Override
+public void onClick(final AjaxRequestTarget target) {
+try {
+ResourceTO resource = 
resourceRestClient.read(node.getKey());
+resource.setKey("Copy of " + resource.getKey());
+// reset some resource objects keys
+if (resource.getOrgUnit() != null) {
+resource.getOrgUnit().setKey(null);
+for (ItemTO item : resource.getOrgUnit().getItems()) {
+item.setKey(null);
+}
+}
+for (ProvisionTO provision : resource.getProvisions()) {
+provision.setKey(null);
+if (provision.getMapping() != null) {
+for (ItemTO item : 
provision.getMapping().getItems()) {
+item.setKey(null);
+}
+provision.getMapping().getLinkingItems().clear();
+}
+provision.getVirSchemas().clear();
+}
+resourceRestClient.create(resource);
+
+// refresh Topology
+send(pageRef.getPage(), Broadcast.DEPTH, new 
AbstractResourceWizardBuilder.CreateEvent(
+resource.getKey(),
+resource.getKey(),
+TopologyNode.Kind.RESOURCE,
+