Merge "Sal Models for meter table. Removed tab space from group models and formatted...
authorGiovanni Meo <gmeo@cisco.com>
Thu, 19 Sep 2013 15:23:23 +0000 (15:23 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 19 Sep 2013 15:23:23 +0000 (15:23 +0000)
46 files changed:
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/forwardingrulesmanager/api/src/main/java/org/opendaylight/controller/forwardingrulesmanager/FlowConfig.java
opendaylight/northbound/integrationtest/src/test/java/org/opendaylight/controller/northbound/integrationtest/NorthboundIT.java
opendaylight/northbound/switchmanager/pom.xml
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeConnectorProperties.java
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/NodeProperties.java
opendaylight/northbound/topology/pom.xml
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/EdgeProperties.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/AppRoleLevel.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Actions.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/AdvertisedBandwidth.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Bandwidth.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Buffers.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Capabilities.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Config.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Description.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ForwardingMode.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Latency.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Name.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Node.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeConnector.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/PeerBandwidth.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Property.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/State.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/SupportedBandwidth.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tables.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/Tier.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/TimeStamp.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/IPProtocols.java
opendaylight/topologymanager/implementation/pom.xml [moved from opendaylight/topologymanager/pom.xml with 97% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManager.java with 100% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerAware.java with 100% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/ITopologyManagerClusterWideAware.java with 100% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/TopologyUserLinkConfig.java with 100% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/Activator.java with 100% similarity]
opendaylight/topologymanager/implementation/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java [moved from opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java with 100% similarity]
opendaylight/topologymanager/implementation/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java [moved from opendaylight/topologymanager/src/test/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImplTest.java with 100% similarity]
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/UserConfig.java
opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthorizationUserConfigTest.java
opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/Activator.java
opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/UserManager.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java
opendaylight/web/root/src/main/resources/WEB-INF/jsp/main.jsp
opendaylight/web/root/src/main/resources/js/open.js

index 1fb131e4aff8fc6e5c505e6437bc8a5dc6c2e2b9..3efd97e2aa3857fa549e752ae16d1aa6990ab0f3 100644 (file)
@@ -74,7 +74,7 @@
     <module>../../statisticsmanager/api</module>
     <module>../../statisticsmanager/implementation</module>
     <module>../../statisticsmanager/integrationtest</module>
-    <module>../../topologymanager</module>
+    <module>../../topologymanager/implementation</module>
     <module>../../usermanager/api</module>
     <module>../../usermanager/implementation</module>
     <module>../../connectionmanager/api</module>
index 970929f794b93d2e329ddbfa7b5684b51fbf043a..12f18ff6452b1cbec6f9a6d4bec1c6949b1d2836 100644 (file)
@@ -94,3 +94,6 @@ controllerKeyStore=
 controllerKeyStorePassword=
 controllerTrustStore=
 controllerTrustStorePassword=
+
+# User Manager configurations
+enableStrongPasswordCheck = false
index ba69c8a3d29f8286f2d4f3157f6547a8f54c717b..62d6855e109f77ac97baf5107fb2c0efbcaa603e 100644 (file)
@@ -655,6 +655,14 @@ public class FlowConfig implements Serializable {
         return ((to >= 0) && (to <= 0xffff));
     }
 
+    public boolean isProtocolValid(String protocol) {
+        int protocol_number = IPProtocols.getProtocolNumberInt(protocol);
+        if (protocol_number < 1 || protocol_number > 255) {
+            return false;
+        }
+        return true;
+    }
+
     private Status conflictWithContainerFlow(IContainer container) {
         // Return true if it's default container
         if (container.getName().equals(GlobalConstants.DEFAULT.toString())) {
@@ -762,6 +770,10 @@ public class FlowConfig implements Serializable {
                 }
             }
 
+            if ((protocol != null) && !isProtocolValid(protocol)) {
+                return new Status(StatusCode.BADREQUEST, String.format("Protocol %s is not valid", protocol));
+            }
+
             if ((tosBits != null) && !isTOSBitsValid(tosBits)) {
                 return new Status(StatusCode.BADREQUEST, String.format("IP ToS bits %s is not in the range 0 - 63",
                         tosBits));
index e7ca7f57822a438e4243a29115fd38f854dce5ed..e457cbfd6e92f93913b0261bb28758195091bc41 100644 (file)
@@ -208,47 +208,34 @@ public class NorthboundIT {
         Assert.assertEquals(nodeId, (Integer) nodeInfo.getInt("id"));
         Assert.assertEquals(nodeType, nodeInfo.getString("type"));
 
-        JSONArray propsArray = node.getJSONArray("properties");
-
-        for (int j = 0; j < propsArray.length(); j++) {
-            JSONObject properties = propsArray.getJSONObject(j);
-            String propName = properties.getString("name");
-            if (propName.equals("timeStamp")) {
-                if (timestamp == null || timestampName == null) {
-                    Assert.assertFalse("Timestamp exist", true);
-                } else {
-                    Assert.assertEquals(timestamp, (Integer) properties.getInt("value"));
-                    Assert.assertEquals(timestampName, properties.getString("timestampName"));
-                }
-            }
-            if (propName.equals("actions")) {
-                if (actionsValue == null) {
-                    Assert.assertFalse("Actions exist", true);
-                } else {
-                    Assert.assertEquals(actionsValue, (Integer) properties.getInt("value"));
-                }
-            }
-            if (propName.equals("capabilities")) {
-                if (capabilitiesValue == null) {
-                    Assert.assertFalse("Capabilities exist", true);
-                } else {
-                    Assert.assertEquals(capabilitiesValue, (Integer) properties.getInt("value"));
-                }
-            }
-            if (propName.equals("tables")) {
-                if (tablesValue == null) {
-                    Assert.assertFalse("Tables exist", true);
-                } else {
-                    Assert.assertEquals(tablesValue, (Integer) properties.getInt("value"));
-                }
-            }
-            if (propName.equals("buffers")) {
-                if (buffersValue == null) {
-                    Assert.assertFalse("Buffers exist", true);
-                } else {
-                    Assert.assertEquals(buffersValue, (Integer) properties.getInt("value"));
-                }
-            }
+        JSONObject properties = node.getJSONObject("properties");
+
+        if (timestamp == null || timestampName == null) {
+            Assert.assertFalse(properties.has("timeStamp"));
+        } else {
+            Assert.assertEquals(timestamp, (Integer) properties.getJSONObject("timeStamp").getInt("value"));
+            Assert.assertEquals(timestampName, properties.getJSONObject("timeStamp").getString("name"));
+        }
+        if (actionsValue == null) {
+            Assert.assertFalse(properties.has("actions"));
+        } else {
+            Assert.assertEquals(actionsValue, (Integer) properties.getJSONObject("actions").getInt("value"));
+        }
+        if (capabilitiesValue == null) {
+            Assert.assertFalse(properties.has("capabilities"));
+        } else {
+            Assert.assertEquals(capabilitiesValue,
+                    (Integer) properties.getJSONObject("capabilities").getInt("value"));
+        }
+        if (tablesValue == null) {
+            Assert.assertFalse(properties.has("tables"));
+        } else {
+            Assert.assertEquals(tablesValue, (Integer) properties.getJSONObject("tables").getInt("value"));
+        }
+        if (buffersValue == null) {
+            Assert.assertFalse(properties.has("buffers"));
+        } else {
+            Assert.assertEquals(buffersValue, (Integer) properties.getJSONObject("buffers").getInt("value"));
         }
     }
 
@@ -258,37 +245,27 @@ public class NorthboundIT {
 
         JSONObject nodeConnector = nodeConnectorProperties.getJSONObject("nodeconnector");
         JSONObject node = nodeConnector.getJSONObject("node");
+        JSONObject properties = nodeConnectorProperties.getJSONObject("properties");
 
         Assert.assertEquals(ncId, (Integer) nodeConnector.getInt("id"));
         Assert.assertEquals(ncType, nodeConnector.getString("type"));
         Assert.assertEquals(nodeId, (Integer) node.getInt("id"));
         Assert.assertEquals(nodeType, node.getString("type"));
-
-        JSONArray propsArray = nodeConnectorProperties.getJSONArray("properties");
-        for (int j = 0; j < propsArray.length(); j++) {
-            JSONObject properties = propsArray.getJSONObject(j);
-            String propName = properties.getString("name");
-            if (propName.equals("state")) {
-                if (state == null) {
-                    Assert.assertFalse("State exist", true);
-                } else {
-                    Assert.assertEquals(state, (Integer) properties.getInt("value"));
-                }
-            }
-            if (propName.equals("capabilities")) {
-                if (capabilities == null) {
-                    Assert.assertFalse("Capabilities exist", true);
-                } else {
-                    Assert.assertEquals(capabilities, (Integer) properties.getInt("value"));
-                }
-            }
-            if (propName.equals("bandwidth")) {
-                if (bandwidth == null) {
-                    Assert.assertFalse("bandwidth exist", true);
-                } else {
-                    Assert.assertEquals(bandwidth, (Integer) properties.getInt("value"));
-                }
-            }
+        if (state == null) {
+            Assert.assertFalse(properties.has("state"));
+        } else {
+            Assert.assertEquals(state, (Integer) properties.getJSONObject("state").getInt("value"));
+        }
+        if (capabilities == null) {
+            Assert.assertFalse(properties.has("capabilities"));
+        } else {
+            Assert.assertEquals(capabilities,
+                    (Integer) properties.getJSONObject("capabilities").getInt("value"));
+        }
+        if (bandwidth == null) {
+            Assert.assertFalse(properties.has("bandwidth"));
+        } else {
+            Assert.assertEquals(bandwidth, (Integer) properties.getJSONObject("bandwidth").getInt("value"));
         }
     }
 
@@ -610,19 +587,8 @@ public class NorthboundIT {
         json = new JSONObject(jt);
         node = getJsonInstance(json, "nodeProperties", nodeId_1);
         Assert.assertNotNull(node);
-
-        JSONArray propsArray = node.getJSONArray("properties");
-
-        for (int j = 0; j < propsArray.length(); j++) {
-            JSONObject properties = propsArray.getJSONObject(j);
-            String propName = properties.getString("name");
-            if (propName.equals("tier")) {
-                Assert.assertEquals(1001, properties.getInt("value"));
-            }
-            if (propName.equals("description")) {
-                Assert.assertEquals("node1", properties.getString("value"));
-            }
-        }
+        Assert.assertEquals(1001, node.getJSONObject("properties").getJSONObject("tier").getInt("value"));
+        Assert.assertEquals("node1", node.getJSONObject("properties").getJSONObject("description").getString("value"));
 
         // Test delete nodeConnector property
         // Delete state property of nodeconnector1
@@ -1229,26 +1195,10 @@ public class NorthboundIT {
 
             JSONObject headNC = edge.getJSONObject("headNodeConnector");
             JSONObject headNode = headNC.getJSONObject("node");
-
-            JSONArray propsArray = edgeProp.getJSONArray("properties");
-
-            JSONObject bandw = null;
-            JSONObject stt = null;
-            JSONObject ltc = null;
-
-            for (int j = 0; j < propsArray.length(); j++) {
-                JSONObject props = propsArray.getJSONObject(j);
-                String propName = props.getString("name");
-                if (propName.equals("bandwidth")) {
-                    bandw = props;
-                }
-                if (propName.equals("state")) {
-                    stt = props;
-                }
-                if (propName.equals("latency")) {
-                    ltc = props;
-                }
-            }
+            JSONObject Props = edgeProp.getJSONObject("properties");
+            JSONObject bandw = Props.getJSONObject("bandwidth");
+            JSONObject stt = Props.getJSONObject("state");
+            JSONObject ltc = Props.getJSONObject("latency");
 
             if (headNC.getInt("id") == headNC1_nodeConnId) {
                 Assert.assertEquals(headNode.getString("type"), nodeType);
@@ -1280,7 +1230,6 @@ public class NorthboundIT {
         Integer nodeId_1 = 3366;
         String nodeConnectorType_1 = "STUB";
         Integer nodeConnectorId_1 = 12;
-
         String nodeType_2 = "STUB";
         Integer nodeId_2 = 4477;
         String nodeConnectorType_2 = "STUB";
@@ -1369,7 +1318,6 @@ public class NorthboundIT {
             }
         }
     }
-
     // Configure the OSGi container
     @Configuration
     public Option[] config() {
index d46b17e4f7e2d27bebf7bfb401be64bd038b6806..401cc948b888f5ab38ae99157cb141e551094b4c 100644 (file)
@@ -58,6 +58,7 @@
               org.slf4j,
               org.apache.catalina.filters,
               org.codehaus.jackson.jaxrs,
+              org.codehaus.jackson.annotate,
               !org.codehaus.enunciate.jaxrs
             </Import-Package>
             <Web-ContextPath>/controller/nb/v2/switchmanager</Web-ContextPath>
index 4e67fc405858fed4342d1b0c1921bb1f30ec67f7..43d3aae57c71f33f735f5ad35e1f887e7ad52f1c 100644 (file)
@@ -9,6 +9,9 @@
 
 package org.opendaylight.controller.switchmanager.northbound;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlElementRef;
@@ -17,6 +20,8 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
 
@@ -31,6 +36,7 @@ public class NodeConnectorProperties {
     private NodeConnector nodeconnector;
     @XmlElementRef
     @XmlElementWrapper
+    @JsonIgnore
     private Set<Property> properties;
 
     // JAXB required constructor
@@ -44,6 +50,19 @@ public class NodeConnectorProperties {
         this.properties = properties;
     }
 
+    @JsonProperty(value="properties")
+    public Map<String, Property> getMapProperties() {
+        Map<String, Property> map = new HashMap<String, Property>();
+        for (Property p : properties) {
+            map.put(p.getName(), p);
+        }
+        return map;
+    }
+
+    public void setMapProperties(Map<String, Property> propertiesMap) {
+        this.properties = new HashSet<Property>(propertiesMap.values());
+    }
+
     public Set<Property> getProperties() {
         return properties;
     }
index 979a8e9776c6faa1ef798cd36a8557e0aa6f73fc..58a024c928d17be3f8060ed5fc812ce10d66f839 100644 (file)
@@ -9,6 +9,9 @@
 
 package org.opendaylight.controller.switchmanager.northbound;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlElementRef;
@@ -17,6 +20,8 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Property;
 
@@ -31,6 +36,7 @@ public class NodeProperties {
     private Node node;
     @XmlElementRef
     @XmlElementWrapper
+    @JsonIgnore
     private Set<Property> properties;
 
     // JAXB required constructor
@@ -44,6 +50,19 @@ public class NodeProperties {
         this.properties = properties;
     }
 
+    @JsonProperty(value="properties")
+    public Map<String, Property> getMapProperties() {
+        Map<String, Property> map = new HashMap<String, Property>();
+        for (Property p : properties) {
+            map.put(p.getName(), p);
+        }
+        return map;
+    }
+
+    public void setMapProperties(Map<String, Property> propertiesMap) {
+        this.properties = new HashSet<Property>(propertiesMap.values());
+    }
+
     public Set<Property> getProperties() {
         return properties;
     }
index ec3489aca2855b6da48f82364c9b175dda8ff6de..d379164a14f483ddf123224bad12cad9996fb345 100644 (file)
@@ -54,6 +54,7 @@
               org.opendaylight.controller.usermanager,
               org.opendaylight.controller.topologymanager,
               com.sun.jersey.spi.container.servlet,
+              org.codehaus.jackson.annotate,
               javax.ws.rs,
               javax.ws.rs.core,
               javax.xml.bind,
index b8be7c18d3e948fe8dc15bb9a1ac1286d59578f6..6614bbe640d804030c5aa8fd49fb9e26a2ccc45f 100644 (file)
@@ -9,6 +9,9 @@
 
 package org.opendaylight.controller.topology.northbound;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import javax.xml.bind.annotation.XmlAccessType;
@@ -18,6 +21,8 @@ import javax.xml.bind.annotation.XmlElementRef;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonProperty;
 import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Property;
 
@@ -28,6 +33,7 @@ public class EdgeProperties {
     private Edge edge;
     @XmlElementRef
     @XmlElementWrapper
+    @JsonIgnore
     private Set<Property> properties;
 
     // JAXB required constructor
@@ -41,10 +47,22 @@ public class EdgeProperties {
         this.properties = properties;
     }
 
+    @JsonProperty(value="properties")
+    public Map<String, Property> getMapProperties() {
+        Map<String, Property> map = new HashMap<String, Property>();
+        for (Property p : properties) {
+            map.put(p.getName(), p);
+        }
+        return map;
+    }
+
+    public void setMapProperties(Map<String, Property> propertiesMap) {
+        this.properties = new HashSet<Property>(propertiesMap.values());
+    }
+
     public Set<Property> getProperties() {
         return properties;
     }
-
     public void setProperties(Set<Property> properties) {
         this.properties = properties;
     }
index 7e73dd414f4e18dd927b3085b074bd02af56f762..124b495147db61d99b53b24138bf47e5dda4083c 100644 (file)
@@ -45,9 +45,9 @@ public enum AppRoleLevel implements Serializable {
     }
 
     public static AppRoleLevel fromString(String levelString) {
-        for (AppRoleLevel level : AppRoleLevel.values()) {
-                if (level.toString().equals(levelString)) {
-                        return level;
+        for (AppRoleLevel rolelevel : AppRoleLevel.values()) {
+                if (rolelevel.toString().equals(levelString)) {
+                        return rolelevel;
                 }
         }
         return null;
index 7b934edfa78df7ad08cf427545c8d1b3f6f502ff..6cada2c0417788291aa62491513e851645599f08 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -21,6 +23,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  */
 
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Actions extends Property {
         private static final long serialVersionUID = 1L;
     @XmlElement(name="value")
index ab546d73023c6c5fe45a03387969eba0beff58cb..a0b5c0a18c777d61fb884c3d440762a9193265f2 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
@@ -21,6 +23,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * seconds.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @SuppressWarnings("serial")
 public class AdvertisedBandwidth extends Bandwidth {
         public static final String AdvertisedBandwidthPropName = "advertisedBandwidth";
index 8c3a97751804215414c9ae9aaa0c3206482921a1..5083cf57d759bb0a9f118f484e5b0dde36283604 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -22,6 +24,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * seconds.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Bandwidth extends Property {
     private static final long serialVersionUID = 1L;
 
index 4c6e08102b214341f237e01d6280d375aaf30eeb..274b0f481d397795651950b9abc75b7bab0ad0c1 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -20,6 +22,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * Describes supported buffers (#packets)
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Buffers extends Property {
         private static final long serialVersionUID = 1L;
     @XmlElement(name="value")
index b2005913d0dc214d5f2ef9d496969d1452020fde..147f1b13aedc32e6c3f50ebdf5badcaca010a85b 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -20,6 +22,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * Describes supported capabilities
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Capabilities extends Property {
         private static final long serialVersionUID = 1L;
     @XmlElement(name="value")
index 651c2f44e12ac8f3a93612b6dda5c3e8ca820e1c..64562fa6ed9571098edad14c021cafbdd9496f2c 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -18,6 +20,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  */
 @XmlRootElement
 @SuppressWarnings("serial")
+@XmlAccessorType(XmlAccessType.NONE)
 public class Config extends Property {
     @XmlElement(name="value")
     private short configValue;
index ebc12cdbf7a28d86cdafce135e0e98881846806b..88ab11b354341ac4a4888442611173cdc7e66850 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -8,6 +10,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  */
 @XmlRootElement
 @SuppressWarnings("serial")
+@XmlAccessorType(XmlAccessType.NONE)
 public class Description extends Property {
     @XmlElement(name="value")
     private String descriptionValue;
index 1b19f19778ddba6c21ae8437d5e06be44b7d3898..c6d7f634092c2ae8050c54753f2e5d7ae22169d3 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -7,6 +9,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * The class represents the forwarding mode property of a node.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @SuppressWarnings("serial")
 public class ForwardingMode extends Property {
     @XmlElement(name="value")
index a64ee105cf0efab3f7f6559a89f85deb6639872b..1320bbb69333b16a14f072a94be72f11e77482ba 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -20,6 +22,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * Describe a latency in picoseconds or multiple of its.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Latency extends Property {
     private static final long serialVersionUID = 1L;
 
index 92c8454a4d6d77d92bb1b669883a252fe7237087..65c089956a95eb876d21ee3e9f0a169f5b1f1c20 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -16,6 +18,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * The class represents the Name property of an element.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @SuppressWarnings("serial")
 public class Name extends Property {
     @XmlElement(name="value")
index d21a147506dfd8e2f546ddd5210df33b1fc29c20..0ea04c32065e7746518504901abc454f4d5e6281 100644 (file)
@@ -323,10 +323,10 @@ public class Node implements Serializable {
     @Override
     public String toString() {
         if (this.nodeType.equals(NodeIDType.OPENFLOW)) {
-            return this.nodeType.toString() + "|"
+            return this.nodeType + "|"
                 + HexEncode.longToHexString((Long) this.nodeID);
         } else {
-            return this.nodeType.toString() + "|" + this.nodeID.toString();
+            return this.nodeType + "|" + this.nodeID.toString();
         }
     }
 
index 50ccf69b4090ad220aebb5b97b35559f978efd56..46c5a9dae933baee49c47e98476a37dd9222dae5 100644 (file)
@@ -464,9 +464,9 @@ public class NodeConnector implements Serializable {
             .equals(NodeConnectorIDType.SWSTACK) ||
             this.nodeConnectorType
             .equals(NodeConnectorIDType.HWPATH)) {
-            return this.nodeConnectorType.toString();
+            return this.nodeConnectorType;
         } else {
-            return this.nodeConnectorType.toString() + "|"
+            return this.nodeConnectorType + "|"
                     + this.nodeConnectorID.toString();
         }
     }
index 7b7f1ccaeaf22f29dc4fa2a9c35b75854086b46f..9e763eb241a273375edf7c27a6ed40871a9b0a0a 100644 (file)
@@ -292,7 +292,7 @@ public class NodeTable implements Serializable {
     }
 
     public String getNodeTableIdAsString() {
-        return this.nodeTableType.toString() + "|"
+        return this.nodeTableType + "|"
                 + this.nodeTableID.toString();
     }
 
index a1b436ef1a24b52b2a6d8f7578c91147ea80875d..d01e528b57d0a54ecdf5982a105ffd11419b1811 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
@@ -20,6 +22,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  *  bits per seconds.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class PeerBandwidth extends Bandwidth {
         private static final long serialVersionUID = 1L;
 
index a5deb547e351c1f154fd0eade864173aa82c011b..9dc00d0dcd8415bac697b4d9839da226a2e34598 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.controller.sal.core;
 
 import java.io.Serializable;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 
@@ -28,6 +30,7 @@ import javax.xml.bind.annotation.XmlSeeAlso;
  * element
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @XmlSeeAlso({ Config.class, Name.class, State.class, TimeStamp.class,
     Latency.class, Bandwidth.class, Tier.class, Actions.class,
     AdvertisedBandwidth.class, Buffers.class, Capabilities.class,
index e47542a7bef9f259bfab5ca21bbca82fc528e980..d74f7183deeac4c88cb822df21c3547d1c78e00d 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -18,6 +20,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  *
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @SuppressWarnings("serial")
 public class State extends Property {
     @XmlElement(name="value")
index cd6589ed6d3da0d492fa1217dff859dc3dd56d89..7bcc0e01aa7f922af538e688b18a0331199fe859 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
 /**
@@ -21,6 +23,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * seconds.
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class SupportedBandwidth extends Bandwidth {
         private static final long serialVersionUID = 1L;
         public static final String SupportedBandwidthPropName = "supportedBandwidth";
index b92c4b693c063bb6e9a093b84ee32c62de19f8fa..724c8427f6edbe0003ed202930d0267cba04ede4 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -20,6 +22,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  * Describes supported # of datapath tables
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class Tables extends Property {
         private static final long serialVersionUID = 1L;
     @XmlElement(name="value")
index d1af778526bce58b9a1e8841a3cb8d2d64aa5712..33c87db650404f9ca6b79c69e8703844ff047172 100644 (file)
@@ -9,6 +9,8 @@
 
 package org.opendaylight.controller.sal.core;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -18,6 +20,7 @@ import javax.xml.bind.annotation.XmlRootElement;
  *
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 @SuppressWarnings("serial")
 public class Tier extends Property {
     @XmlElement(name="value")
index c0c8da7ae2fa569c20975f91f1ac7f81bd409052..67f2b25bd272a67027a91174163d1b372dc41bb0 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.controller.sal.core;
 
 import java.util.Date;
 
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 
@@ -25,11 +27,12 @@ import javax.xml.bind.annotation.XmlRootElement;
  * to qualify what are we talking about
  */
 @XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
 public class TimeStamp extends Property {
     private static final long serialVersionUID = 1L;
     @XmlElement(name = "value")
     private long timestamp;
-    @XmlElement(name = "timestampName")
+    @XmlElement(name = "name")
     private String timestampName;
 
     public static final String TimeStampPropName = "timeStamp";
index cdb4463c02acb2636a0991053f9e64951e3f3ba5..66e6e65706fc2b23a1498b589a4e94fafbe3e7bf 100644 (file)
@@ -168,7 +168,8 @@ public enum IPProtocols {
      WESP("WESP",141),
      ROHC("ROHC",142);
      */
-    private static final String regexNumberString = "^[0-9]+$";
+    private static final String regexDecimalString = "^[0-9]{3}$";
+    private static final String regexHexString = "^(0(x|X))[0-9a-fA-F]{2}$";
     private String protocolName;
     private int protocolNumber;
 
@@ -215,7 +216,10 @@ public enum IPProtocols {
     }
 
     public static short getProtocolNumberShort(String name) {
-        if (name.matches(regexNumberString)) {
+        if (name.matches(regexHexString)) {
+            return Short.valueOf(Short.decode(name));
+        }
+        if (name.matches(regexDecimalString)) {
             return Short.valueOf(name);
         }
         for (IPProtocols proto : IPProtocols.values()) {
@@ -227,7 +231,10 @@ public enum IPProtocols {
     }
 
     public static int getProtocolNumberInt(String name) {
-        if (name.matches(regexNumberString)) {
+        if (name.matches(regexHexString)) {
+            return Integer.valueOf(Integer.decode(name));
+        }
+        if (name.matches(regexDecimalString)) {
             return Integer.valueOf(name);
         }
         for (IPProtocols proto : IPProtocols.values()) {
@@ -239,7 +246,10 @@ public enum IPProtocols {
     }
 
     public static byte getProtocolNumberByte(String name) {
-        if (name.matches(regexNumberString)) {
+        if (name.matches(regexHexString)) {
+            return Integer.valueOf(Integer.decode(name)).byteValue();
+        }
+        if (name.matches(regexDecimalString)) {
             return Integer.valueOf(name).byteValue();
         }
         for (IPProtocols proto : IPProtocols.values()) {
similarity index 97%
rename from opendaylight/topologymanager/pom.xml
rename to opendaylight/topologymanager/implementation/pom.xml
index 98bc0e42c81cf0cb08b7bcd5225289726c67b84e..399f878223aa639e5acd421ecb55b7134ab83d12 100755 (executable)
@@ -6,7 +6,7 @@
     <groupId>org.opendaylight.controller</groupId>
     <artifactId>commons.opendaylight</artifactId>
     <version>1.4.0-SNAPSHOT</version>
-    <relativePath>../commons/opendaylight</relativePath>
+    <relativePath>../../commons/opendaylight</relativePath>
   </parent>
   <scm>
     <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
index cca194e95337e30877aaff50332e37e6df4be30f..07c814adf14c7b2d35f9991a9bd3e5875296f922 100644 (file)
@@ -34,9 +34,11 @@ public class UserConfig implements Serializable {
     protected String user;
     protected List<String> roles;
     private String password;
+
+    private static final boolean strongPasswordCheck = Boolean.getBoolean("enableStrongPasswordCheck");
+    private static final String BAD_PASSWORD = "Bad Password";
     private static final int USERNAME_MAXLENGTH = 32;
-    private static final int PASSWORD_MINLENGTH = 5;
-    private static final int PASSWORD_MAXLENGTH = 256;
+    protected static final String PASSWORD_REGEX = "(?=.*[^\\w])(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,256}$";
     private static final Pattern INVALID_USERNAME_CHARACTERS = Pattern.compile("([/\\s\\.\\?#%;\\\\]+)");
     private static MessageDigest oneWayFunction = null;
     static {
@@ -63,16 +65,12 @@ public class UserConfig implements Serializable {
     public UserConfig(String user, String password, List<String> roles) {
         this.user = user;
 
-        this.password = password;
-        if (this.validatePassword().isSuccess()) {
-            /*
-             * Only if the password is a valid one, hash it. So in case it is not
-             * valid, when UserConfig.validate() is called, the proper
-             * validation error will be returned to the caller. If we hashed a
-             * priori instead, the mis-configuration would be masked
-             */
-            this.password = hash(this.password);
-        }
+        /*
+         * Password validation to be done on clear text password. If fails, mark
+         * the password with a well known label, so that object validation can
+         * report the proper error. Only if password is a valid one, hash it.
+         */
+        this.password = (validatePassword(password).isSuccess()) ? hash(password) : BAD_PASSWORD;
 
         this.roles = (roles == null) ? new ArrayList<String>() : new ArrayList<String>(roles);
     }
@@ -142,12 +140,15 @@ public class UserConfig implements Serializable {
     }
 
     public Status validate() {
-        Status validCheck = validateRoles();
+        Status validCheck = validateUsername();
         if (validCheck.isSuccess()) {
-            validCheck = validateUsername();
+            validCheck = (!password.equals(BAD_PASSWORD)) ? new Status(StatusCode.SUCCESS) : new Status(
+                    StatusCode.BADREQUEST,
+                    "Password should be 8 to 256 characters long, contain both upper and lower case letters, "
+                            + "at least one number and at least one non alphanumeric character");
         }
         if (validCheck.isSuccess()) {
-            validCheck = validatePassword();
+            validCheck = validateRoles();
         }
         return validCheck;
     }
@@ -168,15 +169,15 @@ public class UserConfig implements Serializable {
         return new Status(StatusCode.SUCCESS);
     }
 
-    private Status validatePassword() {
+    private Status validatePassword(String password) {
         if (password == null || password.isEmpty()) {
             return new Status(StatusCode.BADREQUEST, "Password cannot be empty");
         }
 
-        if (password.length() < UserConfig.PASSWORD_MINLENGTH
-                || password.length() > UserConfig.PASSWORD_MAXLENGTH) {
-            return new Status(StatusCode.BADREQUEST,
-                    "Password should have 5-256 characters");
+        if (strongPasswordCheck && !password.matches(UserConfig.PASSWORD_REGEX)) {
+            return new Status(StatusCode.BADREQUEST, "Password should be 8 to 256 characters long, "
+                    + "contain both upper and lower case letters, at least one number "
+                    + "and at least one non alphanumeric character");
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -247,4 +248,25 @@ public class UserConfig implements Serializable {
         UserConfig.oneWayFunction.reset();
         return HexEncode.bytesToHexString(UserConfig.oneWayFunction.digest(message.getBytes(Charset.defaultCharset())));
     }
+
+    /**
+     * Returns UserConfig instance populated with the passed parameters. It does
+     * not run any checks on the passed parameters.
+     *
+     * @param userName
+     *            the user name
+     * @param password
+     *            the plain text password
+     * @param roles
+     *            the list of roles
+     * @return the UserConfig object populated with the passed parameters. No
+     *         validity check is run on the input parameters.
+     */
+    public static UserConfig getUncheckedUserConfig(String userName, String password, List<String> roles) {
+        UserConfig config = new UserConfig();
+        config.user = userName;
+        config.password = hash(password);
+        config.roles = roles;
+        return config;
+    }
 }
index 4c2a19e426f1a88194b5f223a4245b2e67f3fd27..8c029a7488361b778b2749fe327a48a812d675c0 100644 (file)
@@ -117,4 +117,41 @@ public class AuthorizationUserConfigTest {
         UserConfig userConfig2 = new UserConfig("uname", "ciscocisco", roles);
         assertEquals(userConfig, userConfig2);
     }
+
+    @Test
+    public void userConfigPasswordTest() {
+
+        String regex = UserConfig.PASSWORD_REGEX;
+        String password = null;
+
+        // Good password
+        password = "aBc@eF#h9";
+        assertTrue(password.matches(regex));
+        password = "^aBc@eF#h9$88ad*o&";
+        assertTrue(password.matches(regex));
+        password = "_^aBc@\":eF#h;9$\\8|8ad*o&-(){}/,.><?+-";
+        assertTrue(password.matches(regex));
+        password = "culonE1)";
+        assertTrue(password.matches(regex));
+
+        // Too short
+        password = "aB3@eF#";
+        assertFalse(password.matches(regex));
+
+        // No number
+        password = "#BeCCC#CeDfDf";
+        assertFalse(password.matches(regex));
+
+        // No lower case
+        password = "AB8C#CC@C4";
+        assertFalse(password.matches(regex));
+
+        // No upper case
+        password = "ab8defg9!";
+        assertFalse(password.matches(regex));
+
+        // No special characters
+        password = "aBc4ef7H8";
+        assertFalse(password.matches(regex));
+    }
 }
index 0e7e2a37a73f19aefda0919ea8304ac8b375d34f..3898ca589ae710d36ea847eae03aa3742a6cccd6 100644 (file)
@@ -61,7 +61,7 @@ public class Activator extends ComponentActivatorAbstractBase {
      */
     @Override
     public Object[] getImplementations() {
-        return null;
+        return new Object[]{};
     }
 
     /**
index e53e962aa82590db6d48890278657926de57dfb0..8d9e34717e31651cc4086b5a70798e11aceae9e5 100644 (file)
@@ -204,12 +204,17 @@ public class UserManager implements IUserManager, IObjectReader,
     }
 
     private void checkDefaultNetworkAdmin() {
-        // If startup config is not there, it's old or it was deleted,
-        // need to add Default Network Admin User
+        /*
+         * If startup config is not there, it's old or it was deleted or if a
+         * password recovery was run, need to add Default Network Admin User
+         */
         if (!localUserConfigList.containsKey(DEFAULT_ADMIN)) {
             List<String> roles = new ArrayList<String>(1);
             roles.add(DEFAULT_ADMIN_ROLE);
-            localUserConfigList.put(DEFAULT_ADMIN, new UserConfig(DEFAULT_ADMIN, DEFAULT_ADMIN_PASSWORD, roles));
+            // Need to skip the strong password check for the default admin
+            UserConfig defaultAdmin = UserConfig.getUncheckedUserConfig(UserManager.DEFAULT_ADMIN,
+                    UserManager.DEFAULT_ADMIN_PASSWORD, roles);
+            localUserConfigList.put(UserManager.DEFAULT_ADMIN, defaultAdmin);
         }
     }
 
index 2b58bcc4cb6c1fb50b12801e2e6133078a13e47f..eafd8c54a773eb9bb933dd9f0d3f1cdd14d2b9c5 100644 (file)
@@ -15,6 +15,7 @@ import java.util.List;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
 
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
@@ -212,24 +213,63 @@ public class DaylightWebAdmin {
 
     @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
     @ResponseBody
-    public Status changePassword(@PathVariable("username") String username, HttpServletRequest request,
-            @RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword) {
+    public Status changePassword(
+            @PathVariable("username") String username, HttpServletRequest request,
+            @RequestParam(value = "currentPassword", required=false) String currentPassword,
+            @RequestParam("newPassword") String newPassword) {
         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
         if (userManager == null) {
-            return new Status(StatusCode.GONE, "User Manager not found");
+            return new Status(StatusCode.NOSERVICE, "User Manager unavailable");
         }
 
-        if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
-            return new Status(StatusCode.FORBIDDEN, "Operation not permitted");
-        }
+        Status status;
+        String requestingUser = request.getUserPrincipal().getName();
+
+        //changing own password
+        if (requestingUser.equals(username) ) {
+            status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
+            //enforce the user to re-login with new password
+            if (status.isSuccess() && !newPassword.equals(currentPassword)) {
+                userManager.userLogout(username);
+                HttpSession session = request.getSession(false);
+                if ( session != null) {
+                    session.invalidate();
+                }
+            }
+
+        //admin level user resetting other's password
+        } else if (authorize(userManager, UserLevel.NETWORKADMIN, request)) {
+
+            //Since User Manager doesn't have an unprotected password change API,
+            //we re-create the user with the new password (and current roles).
+            List<String> roles = userManager.getUserRoles(username);
+            UserConfig newConfig = new UserConfig(username, newPassword, roles);
+
+            //validate before removing existing config, so we don't remove but fail to add
+            status = newConfig.validate();
+            if (!status.isSuccess()) {
+                return status;
+            }
+
+            userManager.userLogout(username);
+            status = userManager.removeLocalUser(username);
+            if (!status.isSuccess()) {
+                return status;
+            }
+            if (userManager.addLocalUser(newConfig).isSuccess()) {
+                status = new Status(StatusCode.SUCCESS, "Password for user " + username + " reset successfully.");
+            } else {
+                //unexpected
+                status = new Status(StatusCode.INTERNALERROR, "Failed resetting password for user " + username + ". User is now removed.");
+            }
 
-        if (newPassword.isEmpty()) {
-            return new Status(StatusCode.BADREQUEST, "Empty passwords not allowed");
+        //unauthorized
+        } else {
+            status = new Status(StatusCode.UNAUTHORIZED, "Operation not permitted");
         }
 
-        Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
         if (status.isSuccess()) {
-            DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username);
+            DaylightWebUtil.auditlog("User", requestingUser, "changed password for", username);
         }
         return status;
     }
index c795a5d56b920de6111141bea501a8b3dbcfaa57..4b0ce2d07d3d55a51c2ac873b642ce081c659728 100644 (file)
@@ -67,6 +67,7 @@
    </div>
    <div class="span3">
     <div id="toolbar" class="btn-group">
+    <input type="hidden" id="currentuser" value="${username}" data-role="${role}">
      <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
       <div class="icon-user"></div> ${username} <span class="caret"></span>
      </a>
index 43a7dfdc443ab7447fb472dc31afa1b83402f9d7..619edcaf2cba5ed4bb5d5d08359c13333a702d5a 100644 (file)
@@ -443,9 +443,12 @@ one.main.admin = {
       // change password binding
       $('#'+one.main.admin.id.modal.password.submit, $modal).click(function() {
         one.main.admin.password.submit(id, $modal, function(result) {
-          if (result.code == 'SUCCESS') {
-            $modal.modal('hide');
-            successCallback();
+          if (result.success) {
+            //if changed own password, enforce relogin
+            if (id.trim() == $('#currentuser').val().trim()) {
+                alert("Password changed successfully. Please re-login with your new password.");
+                window.location = '/';
+            }
           } else {
             alert(result.code+': '+result.description);
           }