ONOS-1858, ONOS-1857, ONOS-1860, ONOS-1862, ONOS-1898 : SM-ONOS

Change-Id: I206e72521cf663466bfcc612e1896bb22d87da06
diff --git a/cli/src/main/java/org/onosproject/cli/security/PermissionApplicationNameCompleter.java b/cli/src/main/java/org/onosproject/cli/security/PermissionApplicationNameCompleter.java
new file mode 100644
index 0000000..36b85d9
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/security/PermissionApplicationNameCompleter.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.cli.security;
+
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.cli.AbstractCompleter;
+import org.onosproject.core.Application;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+
+import static org.onosproject.cli.AbstractShellCommand.get;
+
+/**
+ * Application name completer for permission command.
+ */
+public class PermissionApplicationNameCompleter extends AbstractCompleter {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+
+        // Fetch our service and feed it's offerings to the string completer
+        ApplicationService service = get(ApplicationService.class);
+        Iterator<Application> it = service.getApplications().iterator();
+        SortedSet<String> strings = delegate.getStrings();
+        while (it.hasNext()) {
+            Application app = it.next();
+            strings.add(app.id().name());
+        }
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(buffer, cursor, candidates);
+    }
+}
diff --git a/cli/src/main/java/org/onosproject/cli/security/PermissionCommand.java b/cli/src/main/java/org/onosproject/cli/security/PermissionCommand.java
new file mode 100644
index 0000000..f72b0b2
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/security/PermissionCommand.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.cli.security;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.app.ApplicationAdminService;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.core.Application;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.Permission;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Manages application permissions.
+ */
+@Command(scope = "onos", name = "perm",
+        description = "Manages application permissions")
+public class PermissionCommand extends AbstractShellCommand {
+
+    static final String ADD = "add";
+    static final String REMOVE = "remove";
+    static final String LIST = "list";
+    static final String CLEAR = "clear";
+
+
+    @Argument(index = 0, name = "command",
+            description = "Command name (add|remove)",
+            required = true, multiValued = false)
+    String command = null;
+
+    @Argument(index = 1, name = "name", description = "Application name",
+            required = true, multiValued = false)
+    String name = null;
+
+    @Argument(index = 2, name = "permissions", description = "List of permissions",
+            required = false, multiValued = true)
+    String[] permissions = null;
+
+    @Override
+    protected void execute() {
+        ApplicationAdminService applicationAdminService = get(ApplicationAdminService.class);
+        Set<Permission> newPermSet = Sets.newHashSet();
+        if (command.equals(ADD)) {
+            ApplicationId appId = applicationAdminService.getId(name);
+            if (appId == null) {
+                print("No such application: %s", name);
+                return;
+            }
+            Application app = applicationAdminService.getApplication(appId);
+
+            for (String perm : permissions) {
+                try {
+                    Permission permission = Permission.valueOf(perm);
+                    newPermSet.add(permission);
+                } catch (IllegalArgumentException e) {
+                    print("%s is not a valid permission.", perm);
+                    return;
+                }
+
+            }
+            Set<Permission> oldPermSet = applicationAdminService.getPermissions(appId);
+            if (oldPermSet != null) {
+                newPermSet.addAll(oldPermSet);
+            } else {
+                newPermSet.addAll(app.permissions());
+            }
+            applicationAdminService.setPermissions(appId, ImmutableSet.copyOf(newPermSet));
+
+        } else if (command.equals(REMOVE)) {
+            ApplicationId appId = applicationAdminService.getId(name);
+            Application app = applicationAdminService.getApplication(appId);
+            if (appId == null) {
+                print("No such application: %s", name);
+                return;
+            }
+            Set<Permission> oldPermSet = applicationAdminService.getPermissions(appId);
+            if (oldPermSet == null) {
+                oldPermSet = app.permissions();
+            }
+            Set<String> clearPermSet = Sets.newHashSet(permissions);
+            newPermSet.addAll(oldPermSet.stream().filter(
+                    perm -> !clearPermSet.contains(perm.name().toUpperCase())).collect(Collectors.toList()));
+            applicationAdminService.setPermissions(appId, ImmutableSet.copyOf(newPermSet));
+        } else if (command.equals(CLEAR)) {
+            ApplicationId appId = applicationAdminService.getId(name);
+            if (appId == null) {
+                print("No such application: %s", name);
+                return;
+            }
+            applicationAdminService.setPermissions(appId, ImmutableSet.of());
+            print("Cleared the permission list of %s.", appId.name());
+        } else if (command.equals(LIST)) {
+            ApplicationId appId = applicationAdminService.getId(name);
+            if (appId == null) {
+                print("No such application: %s", name);
+                return;
+            }
+            Application app = applicationAdminService.getApplication(appId);
+            Set<Permission> userPermissions = applicationAdminService.getPermissions(appId);
+            Set<Permission> defaultPermissions = app.permissions();
+            print("Application Role");
+            print("\trole=%s", app.role().name());
+
+            if (defaultPermissions != null) {
+                if (!defaultPermissions.isEmpty()) {
+                    print("Default permissions (specified in app.xml)");
+                    for (Permission perm : defaultPermissions) {
+                        print("\tpermission=%s", perm.name());
+                    }
+                } else {
+                    print("(No default permissions specified in app.xml)");
+                }
+            }
+            if (userPermissions != null) {
+                if (!userPermissions.isEmpty()) {
+                    print("User permissions");
+                    for (Permission perm : userPermissions) {
+                        print("\tpermission=%s", perm.name());
+                    }
+                } else {
+                    print("(User has removed all the permissions");
+                }
+            }
+
+        }
+    }
+}
diff --git a/cli/src/main/java/org/onosproject/cli/security/PermissionCommandCompleter.java b/cli/src/main/java/org/onosproject/cli/security/PermissionCommandCompleter.java
new file mode 100644
index 0000000..1584a05
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/security/PermissionCommandCompleter.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.cli.security;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.cli.AbstractChoicesCompleter;
+
+import java.util.List;
+
+import static org.onosproject.cli.security.PermissionCommand.*;
+/**
+ * Permission command completer.
+ */
+public class PermissionCommandCompleter extends AbstractChoicesCompleter {
+    @Override
+    protected List<String> choices() {
+        return ImmutableList.of(ADD, REMOVE, CLEAR, LIST);
+    }
+}
diff --git a/cli/src/main/java/org/onosproject/cli/security/PermissionNameCompleter.java b/cli/src/main/java/org/onosproject/cli/security/PermissionNameCompleter.java
new file mode 100644
index 0000000..30dff06
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/security/PermissionNameCompleter.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.cli.security;
+
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.onosproject.cli.AbstractChoicesCompleter;
+import org.onosproject.core.Permission;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Permission Name Completer.
+ */
+public class PermissionNameCompleter extends AbstractChoicesCompleter {
+    @Override
+    protected List<String> choices() {
+        List<String> permNames = new ArrayList<>();
+
+        ArgumentCompleter.ArgumentList list = getArgumentList();
+        String cmd = list.getArguments()[1];
+        if (cmd.equals("add") || cmd.equals("remove")) {
+            for (Permission perm : Permission.values()) {
+                permNames.add(perm.name());
+            }
+        }
+        return permNames;
+    }
+
+
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index d530ca8..a5ab272 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -21,6 +21,15 @@
         </command>
 
         <command>
+            <action class="org.onosproject.cli.security.PermissionCommand"/>
+            <completers>
+                <ref component-id="permCommandCompleter"/>
+                <ref component-id="permAppNameCompleter"/>
+                <ref component-id="permNameCompleter"/>
+            </completers>
+        </command>
+
+        <command>
             <action class="org.onosproject.cli.app.ApplicationsListCommand"/>
         </command>
 
@@ -360,6 +369,9 @@
         </command>
     </command-bundle>
 
+    <bean id="permAppNameCompleter" class="org.onosproject.cli.security.PermissionApplicationNameCompleter"/>
+    <bean id="permCommandCompleter" class="org.onosproject.cli.security.PermissionCommandCompleter"/>
+    <bean id="permNameCompleter" class="org.onosproject.cli.security.PermissionNameCompleter"/>
     <bean id="appCommandCompleter" class="org.onosproject.cli.app.ApplicationCommandCompleter"/>
     <bean id="appNameCompleter" class="org.onosproject.cli.app.ApplicationNameCompleter"/>
     <bean id="allAppNameCompleter" class="org.onosproject.cli.app.AllApplicationNamesCompleter"/>