You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2015/10/30 12:34:57 UTC

[18/50] [abbrv] syncope git commit: Fixed SYNCOPE-595 and SYNCOPE-583, SYNCOPE-158

Fixed SYNCOPE-595 and SYNCOPE-583, SYNCOPE-158


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

Branch: refs/heads/SYNCOPE-156
Commit: 3c36fe10e73bc14fb4512a88127d8b2d11919bee
Parents: 207d93c
Author: massi <ma...@tirasa.net>
Authored: Wed Oct 28 17:21:15 2015 +0100
Committer: massi <ma...@tirasa.net>
Committed: Wed Oct 28 17:21:15 2015 +0100

----------------------------------------------------------------------
 .../entitlement/AbstractEntitlementCommand.java |  27 +++++
 .../entitlement/EntitlementCommand.java         | 121 +++++++++++++++++++
 .../commands/entitlement/EntitlementList.java   |  26 ++++
 .../entitlement/EntitlementListRole.java        |  62 ++++++++++
 .../entitlement/EntitlementReadByUserId.java    |  53 ++++++++
 .../entitlement/EntitlementReadByUsername.java  |  53 ++++++++
 .../entitlement/EntitlementResultManager.java   |  54 +++++++++
 .../entitlement/EntitlementSearchByRole.java    |  54 +++++++++
 .../EntitlementSyncopeOperations.java           |  74 ++++++++++++
 .../cli/commands/question/QuestionCommand.java  |   6 -
 .../commands/question/QuestionReadByUser.java   |  53 --------
 .../commands/self/AbstractWorkflowCommand.java  |  27 +++++
 .../cli/commands/self/WorkflowCommand.java      | 104 ++++++++++++++++
 .../commands/self/WorkflowExportDefinition.java |  56 +++++++++
 .../commands/self/WorkflowExportDiagram.java    |  68 +++++++++++
 .../commands/self/WorkflowResultManager.java    |  38 ++++++
 .../self/WorkflowSyncopeOperations.java         |  41 +++++++
 17 files changed, 858 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/AbstractEntitlementCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/AbstractEntitlementCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/AbstractEntitlementCommand.java
new file mode 100644
index 0000000..acc8aa5
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/AbstractEntitlementCommand.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.commands.entitlement;
+
+public class AbstractEntitlementCommand {
+
+    protected final EntitlementSyncopeOperations entitlementSyncopeOperations = new EntitlementSyncopeOperations();
+
+    protected final EntitlementResultManager entitlementResultManager = new EntitlementResultManager();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementCommand.java
new file mode 100644
index 0000000..5ca478c
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementCommand.java
@@ -0,0 +1,121 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.commands.AbstractCommand;
+
+@Command(name = "entitlement")
+public class EntitlementCommand extends AbstractCommand {
+
+    private static final String HELP_MESSAGE = "Usage: entitlement [options]\n"
+            + "  Options:\n"
+            + "    --help \n"
+            + "    --list\n"
+            + "    --list-role\n"
+            + "       Syntax: --list-role {ENTITLEMENT-NAME}\n"
+            + "    --read-by-username\n"
+            + "       Syntax: --read-by-username {USERNAME}\n"
+            + "    --read-by-userid\n"
+            + "       Syntax: --read-by-userid {USERID}\n"
+            + "    --search-by-role\n"
+            + "       Syntax: --search-by-role {ROLE-ID}";
+
+    @Override
+    public void execute(final Input input) {
+        if (StringUtils.isBlank(input.getOption())) {
+            input.setOption(EntitlementOptions.HELP.getOptionName());
+        }
+
+        switch (EntitlementOptions.fromName(input.getOption())) {
+            case LIST:
+                new EntitlementList().list();
+                break;
+            case READ_BY_USERNAME:
+                new EntitlementReadByUsername(input).read();
+                break;
+            case READ_BY_USERID:
+                new EntitlementReadByUserId(input).read();
+                break;
+            case SEARCH_BY_ROLE:
+                new EntitlementSearchByRole(input).search();
+                break;
+            case LIST_ROLE:
+                new EntitlementListRole(input).list();
+                break;
+            case HELP:
+                System.out.println(HELP_MESSAGE);
+                break;
+            default:
+                new EntitlementResultManager().defaultError(input.getOption(), HELP_MESSAGE);
+        }
+    }
+
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
+
+    private enum EntitlementOptions {
+
+        HELP("--help"),
+        LIST("--list"),
+        READ_BY_USERNAME("--read-by-username"),
+        READ_BY_USERID("--read-by-userid"),
+        SEARCH_BY_ROLE("--search-by-role"),
+        LIST_ROLE("--list-role");
+
+        private final String optionName;
+
+        EntitlementOptions(final String optionName) {
+            this.optionName = optionName;
+        }
+
+        public String getOptionName() {
+            return optionName;
+        }
+
+        public boolean equalsOptionName(final String otherName) {
+            return (otherName == null) ? false : optionName.equals(otherName);
+        }
+
+        public static EntitlementOptions fromName(final String name) {
+            EntitlementOptions optionToReturn = HELP;
+            for (final EntitlementOptions option : EntitlementOptions.values()) {
+                if (option.equalsOptionName(name)) {
+                    optionToReturn = option;
+                }
+            }
+            return optionToReturn;
+        }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final EntitlementOptions value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementList.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementList.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementList.java
new file mode 100644
index 0000000..d0c532c
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementList.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.client.cli.commands.entitlement;
+
+public class EntitlementList extends AbstractEntitlementCommand {
+
+    public void list() {
+        entitlementResultManager.toView(entitlementSyncopeOperations.list());
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementListRole.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementListRole.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementListRole.java
new file mode 100644
index 0000000..f65757c
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementListRole.java
@@ -0,0 +1,62 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import java.util.Set;
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.RoleTO;
+
+public class EntitlementListRole extends AbstractEntitlementCommand {
+
+    private static final String READ_HELP_MESSAGE = "entitlement --list-role {ENTITLEMENT-NAME}";
+
+    private final Input input;
+
+    public EntitlementListRole(final Input input) {
+        this.input = input;
+    }
+
+    public void list() {
+        if (input.getParameters().length == 1) {
+            try {
+                final Set<RoleTO> roleTOs = entitlementSyncopeOperations.rolePerEntitlements(input.firstParameter());
+                if (!entitlementSyncopeOperations.exists(input.firstParameter())) {
+                    entitlementResultManager.notFoundError("Entitlement", input.firstParameter());
+                } else if (roleTOs != null && !roleTOs.isEmpty()) {
+                    entitlementResultManager.rolesToView(roleTOs);
+                } else {
+                    entitlementResultManager.generic("No roles found for entitlement " + input.firstParameter());
+                }
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    entitlementResultManager.notFoundError("User", input.firstParameter());
+                } else {
+                    entitlementResultManager.generic("Error: " + ex.getMessage());
+                }
+            } catch (final NumberFormatException ex) {
+                entitlementResultManager.numberFormatException("user", input.firstParameter());
+            }
+        } else {
+            entitlementResultManager.commandOptionError(READ_HELP_MESSAGE);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUserId.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUserId.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUserId.java
new file mode 100644
index 0000000..99f6305
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUserId.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+
+public class EntitlementReadByUserId extends AbstractEntitlementCommand {
+
+    private static final String READ_HELP_MESSAGE = "entitlement --read-by-userid {USER-ID}";
+
+    private final Input input;
+
+    public EntitlementReadByUserId(final Input input) {
+        this.input = input;
+    }
+
+    public void read() {
+        if (input.getParameters().length == 1) {
+            try {
+                entitlementResultManager.toView(
+                        entitlementSyncopeOperations.userIdEntitlements(input.firstParameter()));
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    entitlementResultManager.notFoundError("User", input.firstParameter());
+                } else {
+                    entitlementResultManager.generic("Error: " + ex.getMessage());
+                }
+            } catch (final NumberFormatException ex) {
+                entitlementResultManager.numberFormatException("user", input.firstParameter());
+            }
+        } else {
+            entitlementResultManager.commandOptionError(READ_HELP_MESSAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUsername.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUsername.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUsername.java
new file mode 100644
index 0000000..bfcec00
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementReadByUsername.java
@@ -0,0 +1,53 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+
+public class EntitlementReadByUsername extends AbstractEntitlementCommand {
+
+    private static final String READ_HELP_MESSAGE = "entitlement --read-by-username {USERNAME}";
+
+    private final Input input;
+
+    public EntitlementReadByUsername(final Input input) {
+        this.input = input;
+    }
+
+    public void read() {
+        if (input.getParameters().length == 1) {
+            try {
+                entitlementResultManager.toView(
+                        entitlementSyncopeOperations.usernameEntitlements(input.firstParameter()));
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    entitlementResultManager.notFoundError("User", input.firstParameter());
+                } else {
+                    entitlementResultManager.generic("Error: " + ex.getMessage());
+                }
+            } catch (final NumberFormatException ex) {
+                entitlementResultManager.numberFormatException("user", input.firstParameter());
+            }
+        } else {
+            entitlementResultManager.commandOptionError(READ_HELP_MESSAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementResultManager.java
new file mode 100644
index 0000000..01585d2
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementResultManager.java
@@ -0,0 +1,54 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import java.util.List;
+import java.util.Set;
+import org.apache.syncope.client.cli.commands.CommonsResultManager;
+import org.apache.syncope.common.lib.to.RoleTO;
+
+public class EntitlementResultManager extends CommonsResultManager {
+
+    public void toView(final Set<String> entitlements) {
+        for (final String entitlement : entitlements) {
+            System.out.println("- " + entitlement);
+        }
+    }
+
+    public void rolesToView(final Set<RoleTO> roles) {
+        for (final RoleTO role : roles) {
+            printRole(role);
+        }
+    }
+
+    private void printRole(final RoleTO roleTO) {
+        System.out.println(" > ROLE ID: " + roleTO.getKey());
+        System.out.println("    name: " + roleTO.getName());
+        System.out.println("    REALMS: ");
+        printRealms(roleTO.getRealms());
+        System.out.println("");
+    }
+
+    private void printRealms(final List<String> realms) {
+        for (final String realm : realms) {
+            System.out.println("       - " + realm);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSearchByRole.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSearchByRole.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSearchByRole.java
new file mode 100644
index 0000000..6d756f0
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSearchByRole.java
@@ -0,0 +1,54 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.common.lib.SyncopeClientException;
+
+public class EntitlementSearchByRole extends AbstractEntitlementCommand {
+
+    private static final String READ_HELP_MESSAGE = "entitlement --search-by-role {ROLE-ID}";
+
+    private final Input input;
+
+    public EntitlementSearchByRole(final Input input) {
+        this.input = input;
+    }
+
+    public void search() {
+        if (input.getParameters().length == 1) {
+            try {
+                entitlementResultManager.toView(
+                        entitlementSyncopeOperations.entitlementsPerRole(input.firstParameter()));
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    entitlementResultManager.notFoundError("User", input.firstParameter());
+                } else {
+                    entitlementResultManager.generic("Error: " + ex.getMessage());
+                }
+            } catch (final NumberFormatException ex) {
+                entitlementResultManager.numberFormatException("user", input.firstParameter());
+            }
+        } else {
+            entitlementResultManager.commandOptionError(READ_HELP_MESSAGE);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
new file mode 100644
index 0000000..17c8eee
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/entitlement/EntitlementSyncopeOperations.java
@@ -0,0 +1,74 @@
+/*
+ * 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.cli.commands.entitlement;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+import org.apache.syncope.client.cli.commands.role.RoleSyncopeOperations;
+import org.apache.syncope.client.cli.commands.user.UserSyncopeOperations;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.Entitlement;
+
+public class EntitlementSyncopeOperations {
+
+    private final UserSyncopeOperations userSyncopeOperations = new UserSyncopeOperations();
+
+    private final RoleSyncopeOperations roleSyncopeOperations = new RoleSyncopeOperations();
+
+    public Set<String> list() {
+        return Entitlement.values();
+    }
+    
+    public boolean exists(final String entitlement) {
+        return list().contains(entitlement);
+    }
+
+    public Set<String> usernameEntitlements(final String username) {
+        final Set<String> entitlements = new TreeSet<>();
+        final UserTO userTO = userSyncopeOperations.read(userSyncopeOperations.getIdFromUsername(username));
+        for (final Long role : userTO.getRoles()) {
+            entitlements.addAll(roleSyncopeOperations.read(String.valueOf(role)).getEntitlements());
+        }
+        return entitlements;
+    }
+
+    public Set<String> userIdEntitlements(final String userId) {
+        final Set<String> entitlements = new TreeSet<>();
+        final UserTO userTO = userSyncopeOperations.read(userId);
+        for (final Long role : userTO.getRoles()) {
+            entitlements.addAll(roleSyncopeOperations.read(String.valueOf(role)).getEntitlements());
+        }
+        return entitlements;
+    }
+
+    public Set<String> entitlementsPerRole(final String roleId) {
+        return roleSyncopeOperations.read(roleId).getEntitlements();
+    }
+
+    public Set<RoleTO> rolePerEntitlements(final String entitlement) {
+        final Set<RoleTO> roles = new HashSet<>();
+        for (final RoleTO role : roleSyncopeOperations.list()) {
+            role.getEntitlements().contains(entitlement);
+            roles.add(role);
+        }
+        return roles;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionCommand.java
index 2427203..4d48b8d 100644
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionCommand.java
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionCommand.java
@@ -34,8 +34,6 @@ public class QuestionCommand extends AbstractCommand {
             + "    --list \n"
             + "    --read \n"
             + "       Syntax: --read {QUESTION-ID} {QUESTION-ID} [...]\n"
-            + "    --read-by-user \n"
-            + "       Syntax: --read-by-user {USERNAME}\n"
             + "    --delete \n"
             + "       Syntax: --delete {QUESTION-ID} {QUESTION-ID} [...]";
 
@@ -52,9 +50,6 @@ public class QuestionCommand extends AbstractCommand {
             case READ:
                 new QuestionRead(input).read();
                 break;
-            case READ_BY_USER:
-                new QuestionReadByUser(input).read();
-                break;
             case DELETE:
                 break;
             case HELP:
@@ -75,7 +70,6 @@ public class QuestionCommand extends AbstractCommand {
         HELP("--help"),
         LIST("--list"),
         READ("--read"),
-        READ_BY_USER("--read-by-user"),
         DELETE("--delete");
 
         private final String optionName;

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionReadByUser.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionReadByUser.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionReadByUser.java
deleted file mode 100644
index fa7b23d..0000000
--- a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/question/QuestionReadByUser.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.syncope.client.cli.commands.question;
-
-import javax.xml.ws.WebServiceException;
-import org.apache.syncope.client.cli.Input;
-import org.apache.syncope.common.lib.SyncopeClientException;
-
-public class QuestionReadByUser extends AbstractQuestionCommand {
-
-    private static final String READ_HELP_MESSAGE = "question --read-by-user {USERNAME}";
-
-    private final Input input;
-
-    public QuestionReadByUser(final Input input) {
-        this.input = input;
-    }
-
-    public void read() {
-        if (input.getParameters().length == 1) {
-            try {
-                questionResultManager.printQuestion(questionSyncopeOperations.readByUser(input.firstParameter()));
-            } catch (final SyncopeClientException | WebServiceException ex) {
-                if (ex.getMessage().startsWith("NotFound")) {
-                    questionResultManager.notFoundError("Security question", input.firstParameter());
-                } else {
-                    questionResultManager.generic("Error: " + ex.getMessage());
-                }
-            } catch (final NumberFormatException ex) {
-                questionResultManager.numberFormatException("security question", input.firstParameter());
-            }
-        } else {
-            questionResultManager.commandOptionError(READ_HELP_MESSAGE);
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/AbstractWorkflowCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/AbstractWorkflowCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/AbstractWorkflowCommand.java
new file mode 100644
index 0000000..c48eb8c
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/AbstractWorkflowCommand.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.commands.self;
+
+public class AbstractWorkflowCommand {
+
+    protected final WorkflowResultManager workflowResultManager = new WorkflowResultManager();
+
+    protected final WorkflowSyncopeOperations workflowSyncopeOperations = new WorkflowSyncopeOperations();
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowCommand.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowCommand.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowCommand.java
new file mode 100644
index 0000000..c40dda9
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowCommand.java
@@ -0,0 +1,104 @@
+/*
+ * 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.cli.commands.self;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.client.cli.Command;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.commands.AbstractCommand;
+
+@Command(name = "workflow")
+public class WorkflowCommand extends AbstractCommand {
+
+    private static final String HELP_MESSAGE = "Usage: workflow [options]\n"
+            + "  Options:\n"
+            + "    --help \n"
+            + "    --export-diagram {ANY-TYPE-KIND}\n"
+            + "        Any type kind: ANY_OBJECT / USER / GROUP\n"
+            + "    --export-definition {ANY-TYPE-KIND}\n"
+            + "        Any type kind: ANY_OBJECT / USER / GROUP";
+
+    @Override
+    public void execute(final Input input) {
+        if (StringUtils.isBlank(input.getOption())) {
+            input.setOption(UserWorkflowOptions.HELP.getOptionName());
+        }
+
+        switch (UserWorkflowOptions.fromName(input.getOption())) {
+            case EXPORT_DIAGRAM:
+                new WorkflowExportDiagram(input).export();
+                break;
+            case EXPORT_DEFINITION:
+                new WorkflowExportDefinition(input).export();
+                break;
+            case HELP:
+                System.out.println(HELP_MESSAGE);
+                break;
+            default:
+                new WorkflowResultManager().defaultError(input.getOption(), HELP_MESSAGE);
+        }
+    }
+
+    @Override
+    public String getHelpMessage() {
+        return HELP_MESSAGE;
+    }
+
+    private enum UserWorkflowOptions {
+
+        HELP("--help"),
+        EXPORT_DIAGRAM("--export-diagram"),
+        EXPORT_DEFINITION("--export-definition");
+
+        private final String optionName;
+
+        UserWorkflowOptions(final String optionName) {
+            this.optionName = optionName;
+        }
+
+        public String getOptionName() {
+            return optionName;
+        }
+
+        public boolean equalsOptionName(final String otherName) {
+            return (otherName == null) ? false : optionName.equals(otherName);
+        }
+
+        public static UserWorkflowOptions fromName(final String name) {
+            UserWorkflowOptions optionToReturn = HELP;
+            for (final UserWorkflowOptions option : UserWorkflowOptions.values()) {
+                if (option.equalsOptionName(name)) {
+                    optionToReturn = option;
+                }
+            }
+            return optionToReturn;
+        }
+
+        public static List<String> toList() {
+            final List<String> options = new ArrayList<>();
+            for (final UserWorkflowOptions value : values()) {
+                options.add(value.getOptionName());
+            }
+            return options;
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDefinition.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDefinition.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDefinition.java
new file mode 100644
index 0000000..89443da
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDefinition.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.cli.commands.self;
+
+import javax.xml.ws.WebServiceException;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.util.CommandUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public class WorkflowExportDefinition extends AbstractWorkflowCommand {
+
+    private static final String EXPORT_HELP_MESSAGE = "workflow --export-definition {ANY-TYPE-KIND}\n";
+
+    private final Input input;
+
+    public WorkflowExportDefinition(final Input input) {
+        this.input = input;
+    }
+
+    public void export() {
+        if (input.parameterNumber() == 1) {
+            try {
+                final AnyTypeKind anyTypeKind = AnyTypeKind.valueOf(input.firstParameter());
+                System.out.println(" > > > > " + workflowSyncopeOperations.exportDefinition(anyTypeKind).getEntity());
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    workflowResultManager.notFoundError("Workflow", input.firstParameter());
+                } else {
+                    workflowResultManager.generic(ex.getMessage());
+                }
+            } catch (final IllegalArgumentException ex) {
+                workflowResultManager.typeNotValidError(
+                        "workflow", input.firstParameter(), CommandUtils.fromEnumToArray(AnyTypeKind.class));
+            }
+        } else {
+            workflowResultManager.commandOptionError(EXPORT_HELP_MESSAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDiagram.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDiagram.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDiagram.java
new file mode 100644
index 0000000..f65bf2f
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowExportDiagram.java
@@ -0,0 +1,68 @@
+/*
+ * 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.cli.commands.self;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.ws.rs.core.Response;
+import javax.xml.ws.WebServiceException;
+import org.apache.cxf.helpers.IOUtils;
+import org.apache.syncope.client.cli.Input;
+import org.apache.syncope.client.cli.util.CommandUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+
+public class WorkflowExportDiagram extends AbstractWorkflowCommand {
+
+    private static final String EXPORT_HELP_MESSAGE = "workflow --export-diagram {ANY-TYPE-KIND}\n";
+
+    private final Input input;
+
+    public WorkflowExportDiagram(final Input input) {
+        this.input = input;
+    }
+
+    public void export() {
+        if (input.parameterNumber() == 1) {
+            try {
+                final AnyTypeKind anyTypeKind = AnyTypeKind.valueOf(input.firstParameter());
+                final Response response = workflowSyncopeOperations.exportDiagram(anyTypeKind);
+                final byte[] diagram = IOUtils.readBytesFromStream((InputStream) response.getEntity());
+                final FileOutputStream fos = new FileOutputStream("/tmp/diagram.png");
+                fos.write(diagram);
+                fos.close();
+                workflowResultManager.generic("Diagram created: /tmp/diagram.png");
+            } catch (final SyncopeClientException | WebServiceException ex) {
+                if (ex.getMessage().startsWith("NotFound")) {
+                    workflowResultManager.notFoundError("Workflow", input.firstParameter());
+                } else {
+                    workflowResultManager.generic(ex.getMessage());
+                }
+            } catch (final IllegalArgumentException ex) {
+                workflowResultManager.typeNotValidError(
+                        "workflow", input.firstParameter(), CommandUtils.fromEnumToArray(AnyTypeKind.class));
+            } catch (final IOException ex) {
+
+            }
+        } else {
+            workflowResultManager.commandOptionError(EXPORT_HELP_MESSAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowResultManager.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowResultManager.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowResultManager.java
new file mode 100644
index 0000000..2737a6a
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowResultManager.java
@@ -0,0 +1,38 @@
+/*
+ * 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.cli.commands.self;
+
+import java.util.List;
+import org.apache.syncope.client.cli.commands.CommonsResultManager;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+
+public class WorkflowResultManager extends CommonsResultManager {
+
+    public void toView(final List<WorkflowFormTO> workflowFormTOs) {
+        for (final WorkflowFormTO workflowFormTO : workflowFormTOs) {
+            printQuestion(workflowFormTO);
+        }
+    }
+
+    public void printQuestion(final WorkflowFormTO workflowFormTO) {
+        System.out.println(" > WORKFLOW FORM ID: " + workflowFormTO.getKey());
+        System.out.println("    description: " + workflowFormTO.getDescription());
+        System.out.println("");
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/3c36fe10/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowSyncopeOperations.java
----------------------------------------------------------------------
diff --git a/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowSyncopeOperations.java b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowSyncopeOperations.java
new file mode 100644
index 0000000..2add12d
--- /dev/null
+++ b/client/cli/src/main/java/org/apache/syncope/client/cli/commands/self/WorkflowSyncopeOperations.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.client.cli.commands.self;
+
+import javax.ws.rs.core.Response;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.syncope.client.cli.SyncopeServices;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.rest.api.RESTHeaders;
+import org.apache.syncope.common.rest.api.service.WorkflowService;
+
+public class WorkflowSyncopeOperations {
+
+    private final WorkflowService workflowService = SyncopeServices.get(WorkflowService.class);
+
+    public Response exportDiagram(final AnyTypeKind anyTypeKind) {
+        WebClient.client(workflowService).accept(RESTHeaders.MEDIATYPE_IMAGE_PNG);
+        return workflowService.exportDiagram(anyTypeKind);
+    }
+
+    public Response exportDefinition(final AnyTypeKind anyTypeKind) {
+        return workflowService.exportDefinition(anyTypeKind);
+    }
+
+}