You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by lo...@apache.org on 2020/05/29 11:27:14 UTC

[syncope] branch 2_1_X updated: [SYNCOPE-1568]

This is an automated email from the ASF dual-hosted git repository.

loredicola pushed a commit to branch 2_1_X
in repository https://gitbox.apache.org/repos/asf/syncope.git


The following commit(s) were added to refs/heads/2_1_X by this push:
     new 5ec9231  [SYNCOPE-1568]
5ec9231 is described below

commit 5ec9231b8caecb778b04c621d1fd35f5ccce709e
Author: lorenzo <lo...@tirasa.net>
AuthorDate: Fri May 29 12:50:17 2020 +0200

    [SYNCOPE-1568]
---
 .../console/annotations/UserRequestApplier.java    | 34 ++++++++++++
 .../client/console/commons/ApplierUtils.java       | 56 +++++++++++++++++++
 .../init/ClassPathScanImplementationLookup.java    | 25 +++++++++
 .../syncope/client/console/wizards/AjaxWizard.java |  3 +-
 .../client/console/wizards/any/Applier.java        | 24 +++++++++
 .../console/wizards/any/DefaultApplierImpl.java    | 35 ++++++++++++
 .../console/wizards/any/UserWizardBuilder.java     |  3 ++
 .../panels/UserRequestFormDirectoryPanel.java      | 62 ++--------------------
 .../wizards/any/UserRequestFormApplierImpl.java    | 47 ++++++++++++++++
 9 files changed, 230 insertions(+), 59 deletions(-)

diff --git a/client/console/src/main/java/org/apache/syncope/client/console/annotations/UserRequestApplier.java b/client/console/src/main/java/org/apache/syncope/client/console/annotations/UserRequestApplier.java
new file mode 100644
index 0000000..d2a6682
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/annotations/UserRequestApplier.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.client.console.annotations;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface UserRequestApplier {
+    
+    String[] mode() default {};
+    
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/commons/ApplierUtils.java b/client/console/src/main/java/org/apache/syncope/client/console/commons/ApplierUtils.java
new file mode 100644
index 0000000..bdae41a
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/commons/ApplierUtils.java
@@ -0,0 +1,56 @@
+/*
+ * 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.client.console.commons;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.SyncopeConsoleApplication;
+import org.apache.syncope.client.console.init.ClassPathScanImplementationLookup;
+import org.apache.syncope.client.console.init.ConsoleInitializer;
+import org.apache.syncope.client.console.wizards.any.Applier;
+import org.springframework.util.ClassUtils;
+
+public final class ApplierUtils {
+
+    public static ApplierUtils getInstance() {
+        return new ApplierUtils();
+    }
+
+    private final ClassPathScanImplementationLookup classPathScanImplementationLookup;
+
+    private ApplierUtils() {
+        classPathScanImplementationLookup = (ClassPathScanImplementationLookup) SyncopeConsoleApplication.get().
+                getServletContext().getAttribute(ConsoleInitializer.CLASSPATH_LOOKUP);
+    }
+    
+    public Applier getApplier(final String mode) {
+        if (StringUtils.isBlank(mode)) {
+            return null;
+        }
+
+        Class<? extends Applier> applier = classPathScanImplementationLookup.getApplyerClass(mode);
+        try {
+            return applier == null
+                    ? null
+                    : ClassUtils.getConstructorIfAvailable(applier).
+                    newInstance();
+        } catch (Exception e) {
+            return null;
+        }
+    }
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java b/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
index bc8d879..b5c2811 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/init/ClassPathScanImplementationLookup.java
@@ -35,6 +35,7 @@ import org.apache.syncope.client.console.annotations.BinaryPreview;
 import org.apache.syncope.client.console.annotations.ExtPage;
 import org.apache.syncope.client.console.annotations.ExtWidget;
 import org.apache.syncope.client.console.annotations.Resource;
+import org.apache.syncope.client.console.annotations.UserRequestApplier;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.panels.SSOLoginFormPanel;
 import org.apache.syncope.client.console.wicket.markup.html.form.preview.AbstractBinaryPreviewer;
@@ -54,6 +55,7 @@ import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
 import org.springframework.core.type.filter.AssignableTypeFilter;
 import org.springframework.util.ClassUtils;
+import org.apache.syncope.client.console.wizards.any.Applier;
 
 public class ClassPathScanImplementationLookup {
 
@@ -112,6 +114,8 @@ public class ClassPathScanImplementationLookup {
 
     private List<Class<? extends AbstractResource>> resources;
 
+    private List<Class<? extends Applier>> appliers;
+
     /**
      * This method can be overridden by subclasses to customize classpath scan.
      *
@@ -135,6 +139,7 @@ public class ClassPathScanImplementationLookup {
         pullCorrelationRuleConfs = new HashMap<>();
         pushCorrelationRuleConfs = new HashMap<>();
         resources = new ArrayList<>();
+        appliers = new ArrayList<>();
 
         ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
         scanner.addIncludeFilter(new AssignableTypeFilter(BasePage.class));
@@ -149,6 +154,7 @@ public class ClassPathScanImplementationLookup {
         scanner.addIncludeFilter(new AssignableTypeFilter(PullCorrelationRuleConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(PushCorrelationRuleConf.class));
         scanner.addIncludeFilter(new AssignableTypeFilter(AbstractResource.class));
+        scanner.addIncludeFilter(new AssignableTypeFilter(Applier.class));
 
         scanner.findCandidateComponents(getBasePackage()).forEach(bd -> {
             try {
@@ -201,6 +207,8 @@ public class ClassPathScanImplementationLookup {
                             LOG.error("Could not find annotation {} in {}, ignoring",
                                     Resource.class.getName(), clazz.getName());
                         }
+                    } else if (Applier.class.isAssignableFrom(clazz)) {
+                        appliers.add((Class<? extends Applier>) clazz);
                     }
                 }
             } catch (Throwable t) {
@@ -229,6 +237,8 @@ public class ClassPathScanImplementationLookup {
 
         resources = Collections.unmodifiableList(resources);
 
+        appliers = Collections.unmodifiableList(appliers);
+
         LOG.debug("Binary previewers found: {}", previewers);
         LOG.debug("Extension pages found: {}", extPages);
         LOG.debug("Extension widgets found: {}", extWidgets);
@@ -240,6 +250,7 @@ public class ClassPathScanImplementationLookup {
         LOG.debug("Pull Correlation Rule configurations found: {}", pullCorrelationRuleConfs);
         LOG.debug("Push Correlation Rule configurations found: {}", pushCorrelationRuleConfs);
         LOG.debug("Resources found: {}", resources);
+        LOG.debug("Applyer found {}", appliers);
     }
 
     public Class<? extends AbstractBinaryPreviewer> getPreviewerClass(final String mimeType) {
@@ -299,4 +310,18 @@ public class ClassPathScanImplementationLookup {
     public List<Class<? extends AbstractResource>> getResources() {
         return resources;
     }
+
+    public Class<? extends Applier> getApplyerClass(final String mode) {
+        LOG.debug("Searching for applier class for mode: {}", mode);
+        Class<? extends Applier> applier = null;
+        for (Class<? extends Applier> candidate : appliers) {
+            LOG.debug("Evaluating applier class {} for mode {}", candidate.getName(), mode);
+            if (candidate.isAnnotationPresent(UserRequestApplier.class)
+                    && ArrayUtils.contains(candidate.getAnnotation(UserRequestApplier.class).mode(), mode)) {
+                LOG.debug("Found existing applier for mode {}: {}", mode, candidate.getName());
+                applier = candidate;
+            }
+        }
+        return applier;
+    }
 }
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
index f756c9d..a1bc067 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/AjaxWizard.java
@@ -67,7 +67,8 @@ public abstract class AjaxWizard<T extends Serializable> extends Wizard
         CREATE,
         EDIT,
         TEMPLATE,
-        READONLY;
+        READONLY,
+        EDIT_APPROVAL;
 
     }
 
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Applier.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Applier.java
new file mode 100644
index 0000000..59a4cfe
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/Applier.java
@@ -0,0 +1,24 @@
+/*
+ * 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.client.console.wizards.any;
+
+public interface Applier {
+    
+     void getClaimerForm(String key);
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DefaultApplierImpl.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DefaultApplierImpl.java
new file mode 100644
index 0000000..76beeb5
--- /dev/null
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/DefaultApplierImpl.java
@@ -0,0 +1,35 @@
+/*
+ * 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.client.console.wizards.any;
+
+import org.apache.syncope.client.console.annotations.UserRequestApplier;
+
+@UserRequestApplier(mode = "EDIT")
+public class DefaultApplierImpl implements Applier {
+
+    public DefaultApplierImpl() {
+
+    }
+
+    @Override
+    public void getClaimerForm(final String key) {
+
+    }
+
+}
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
index 25b8adb..ed8d8b7 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/any/UserWizardBuilder.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
 import java.util.List;
 import java.util.Optional;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.console.commons.ApplierUtils;
 import org.apache.syncope.client.console.layout.UserForm;
 import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.console.rest.UserRestClient;
@@ -82,6 +83,8 @@ public class UserWizardBuilder extends AnyWizardBuilder<UserTO> implements UserF
                 result.setEntity(inner);
             } else {
                 result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
+
+                ApplierUtils.getInstance().getApplier(this.mode.name()).getClaimerForm(result.getEntity().getKey());
             }
         }
 
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
index 3a39b7d..66ee573 100644
--- a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/panels/UserRequestFormDirectoryPanel.java
@@ -25,14 +25,12 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
-import org.apache.commons.lang3.StringUtils;
 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.layout.AnyLayoutUtils;
 import org.apache.syncope.client.console.rest.UserRequestRestClient;
 import org.apache.syncope.client.console.panels.UserRequestFormDirectoryPanel.UserRequestFormProvider;
-import org.apache.syncope.client.console.layout.UserFormLayoutInfo;
 import org.apache.syncope.client.console.pages.BasePage;
 import org.apache.syncope.client.console.rest.AnyTypeRestClient;
 import org.apache.syncope.client.console.wicket.extensions.markup.html.repeater.data.table.DatePropertyColumn;
@@ -41,13 +39,9 @@ import org.apache.syncope.client.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.client.console.wicket.markup.html.form.ActionsPanel;
 import org.apache.syncope.client.console.widgets.UserRequestFormsWidget;
 import org.apache.syncope.client.console.wizards.AjaxWizard;
-import org.apache.syncope.client.console.wizards.any.AnyWrapper;
 import org.apache.syncope.client.console.wizards.any.UserWizardBuilder;
 import org.apache.syncope.common.lib.AnyOperations;
 import org.apache.syncope.common.lib.SyncopeClientException;
-import org.apache.syncope.common.lib.patch.PasswordPatch;
-import org.apache.syncope.common.lib.patch.UserPatch;
-import org.apache.syncope.common.lib.to.ProvisioningResult;
 import org.apache.syncope.common.lib.to.UserTO;
 import org.apache.syncope.common.lib.to.UserRequestForm;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
@@ -247,14 +241,11 @@ public class UserRequestFormDirectoryPanel
 
                 AjaxWizard.EditItemActionEvent<UserTO> editItemActionEvent =
                         new AjaxWizard.EditItemActionEvent<>(newUserTO, target);
-                editItemActionEvent.forceModalPanel(new FormUserWizardBuilder(
-                        model.getObject(),
-                        previousUserTO,
-                        newUserTO,
+                editItemActionEvent.forceModalPanel(UserWizardBuilder.class.cast(AnyLayoutUtils.newLayoutInfo(newUserTO,
                         new AnyTypeRestClient().read(AnyTypeKind.USER.name()).getClasses(),
-                        AnyLayoutUtils.fetch(Collections.singletonList(AnyTypeKind.USER.name())).getUser(),
-                        pageRef
-                ).build(BaseModal.CONTENT_ID, AjaxWizard.Mode.EDIT));
+                        AnyLayoutUtils.fetch(Collections.singletonList(AnyTypeKind.USER.name())).getUser(), pageRef))
+                        .build(BaseModal.CONTENT_ID, 0, AjaxWizard.Mode.EDIT_APPROVAL)
+                );
 
                 send(UserRequestFormDirectoryPanel.this, Broadcast.EXACT, editItemActionEvent);
             }
@@ -338,49 +329,4 @@ public class UserRequestFormDirectoryPanel
         }
     }
 
-    private class FormUserWizardBuilder extends UserWizardBuilder {
-
-        private static final long serialVersionUID = 1854981134836384069L;
-
-        private final UserRequestForm formTO;
-
-        FormUserWizardBuilder(
-                final UserRequestForm formTO,
-                final UserTO previousUserTO,
-                final UserTO userTO,
-                final List<String> anyTypeClasses,
-                final UserFormLayoutInfo formLayoutInfo,
-                final PageReference pageRef) {
-
-            super(previousUserTO, userTO, anyTypeClasses, formLayoutInfo, pageRef);
-            this.formTO = formTO;
-        }
-
-        @Override
-        protected Serializable onApplyInternal(final AnyWrapper<UserTO> modelObject) {
-            UserTO inner = modelObject.getInnerObject();
-
-            UserPatch patch = AnyOperations.diff(inner, formTO.getUserTO(), false);
-
-            if (StringUtils.isNotBlank(inner.getPassword())) {
-                PasswordPatch passwordPatch = new PasswordPatch.Builder().
-                        value(inner.getPassword()).onSyncope(true).resources(inner.
-                        getResources()).
-                        build();
-                patch.setPassword(passwordPatch);
-            }
-
-            // update just if it is changed
-            ProvisioningResult<UserTO> result;
-            if (patch.isEmpty()) {
-                result = new ProvisioningResult<>();
-                result.setEntity(inner);
-            } else {
-                result = userRestClient.update(getOriginalItem().getInnerObject().getETagValue(), patch);
-                restClient.getForm(result.getEntity().getKey()).ifPresent(form -> claimForm(form.getTaskId()));
-            }
-
-            return result;
-        }
-    }
 }
diff --git a/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/wizards/any/UserRequestFormApplierImpl.java b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/wizards/any/UserRequestFormApplierImpl.java
new file mode 100644
index 0000000..6fd0f58
--- /dev/null
+++ b/ext/flowable/client-console/src/main/java/org/apache/syncope/client/console/wizards/any/UserRequestFormApplierImpl.java
@@ -0,0 +1,47 @@
+/*
+ * 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.client.console.wizards.any;
+
+import org.apache.syncope.client.console.SyncopeConsoleSession;
+import org.apache.syncope.client.console.annotations.UserRequestApplier;
+import org.apache.syncope.client.console.rest.UserRequestRestClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+
+@UserRequestApplier(mode = "EDIT_APPROVAL")
+public class UserRequestFormApplierImpl implements Applier {
+
+    private final UserRequestRestClient restClient = new UserRequestRestClient();
+
+    public UserRequestFormApplierImpl() {
+
+    }
+
+    @Override
+    public void getClaimerForm(String key) {
+        restClient.getForm(key).ifPresent(form -> claimForm(form.getTaskId()));
+    }
+
+    private void claimForm(final String taskId) {
+        try {
+            restClient.claimForm(taskId);
+        } catch (SyncopeClientException e) {
+            SyncopeConsoleSession.get().onException(e);
+        }
+    }
+}