Merge "Declare a property for commons-lang version in poms and use it."
[controller.git] / opendaylight / web / root / src / main / java / org / opendaylight / controller / web / DaylightWebAdmin.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.web;
10
11 import java.net.InetAddress;
12 import java.net.UnknownHostException;
13 import java.util.ArrayList;
14 import java.util.List;
15 import java.util.Set;
16
17 import javax.servlet.http.HttpServletRequest;
18
19 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
20 import org.opendaylight.controller.connectionmanager.IConnectionManager;
21 import org.opendaylight.controller.sal.authorization.UserLevel;
22 import org.opendaylight.controller.sal.core.Description;
23 import org.opendaylight.controller.sal.core.Node;
24 import org.opendaylight.controller.sal.utils.GlobalConstants;
25 import org.opendaylight.controller.sal.utils.ServiceHelper;
26 import org.opendaylight.controller.sal.utils.Status;
27 import org.opendaylight.controller.sal.utils.StatusCode;
28 import org.opendaylight.controller.switchmanager.ISwitchManager;
29 import org.opendaylight.controller.usermanager.IUserManager;
30 import org.opendaylight.controller.usermanager.UserConfig;
31 import org.springframework.stereotype.Controller;
32 import org.springframework.web.bind.annotation.PathVariable;
33 import org.springframework.web.bind.annotation.RequestMapping;
34 import org.springframework.web.bind.annotation.RequestMethod;
35 import org.springframework.web.bind.annotation.RequestParam;
36 import org.springframework.web.bind.annotation.ResponseBody;
37
38 import com.google.gson.Gson;
39
40 @Controller
41 @RequestMapping("/admin")
42 public class DaylightWebAdmin {
43     Gson gson = new Gson();
44
45     /**
46      * Returns list of clustered controllers. Highlights "this" controller and
47      * if controller is coordinator
48      * @return List<ClusterBean>
49      */
50     @RequestMapping("/cluster")
51     @ResponseBody
52     public String getClusteredControllers() {
53         IClusterGlobalServices clusterServices = (IClusterGlobalServices) ServiceHelper.getGlobalInstance(
54                 IClusterGlobalServices.class, this);
55         if (clusterServices == null) {
56             return null;
57         }
58         IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
59                 IConnectionManager.class, this);
60         if (connectionManager == null) {
61             return null;
62         }
63
64         List<ClusterNodeBean> clusterNodes = new ArrayList<ClusterNodeBean>();
65
66         List<InetAddress> controllers = clusterServices.getClusteredControllers();
67         for (InetAddress controller : controllers) {
68             ClusterNodeBean.Builder clusterBeanBuilder = new ClusterNodeBean.Builder(controller);
69
70             //get number of connected nodes
71             Set<Node> connectedNodes = connectionManager.getNodes(controller);
72             int numNodes = connectedNodes == null ? 0 : connectedNodes.size();
73             clusterBeanBuilder.nodesConnected(numNodes);
74
75             //determine if this is the executing controller
76             if (controller.equals(clusterServices.getMyAddress())) {
77                 clusterBeanBuilder.highlightMe();
78             }
79
80             //determine whether this is coordinator
81             if (clusterServices.getCoordinatorAddress().equals(controller)) {
82                 clusterBeanBuilder.iAmCoordinator();
83             }
84             clusterNodes.add(clusterBeanBuilder.build());
85         }
86
87         return gson.toJson(clusterNodes);
88     }
89
90     /**
91      * Return nodes connected to controller {controller}
92      * @param controller
93      *            - byte[] of the address of the controller
94      * @return List<NodeBean>
95      */
96     @RequestMapping("/cluster/controller/{controller}")
97     @ResponseBody
98     public String getNodesConnectedToController(@PathVariable("controller") String controller) {
99         IClusterGlobalServices clusterServices = (IClusterGlobalServices) ServiceHelper.getGlobalInstance(
100                 IClusterGlobalServices.class, this);
101         if (clusterServices == null) {
102             return null;
103         }
104         IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
105                 IConnectionManager.class, this);
106         if (connectionManager == null) {
107             return null;
108         }
109         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
110                 GlobalConstants.DEFAULT.toString(), this);
111         if (switchManager == null) {
112             return null;
113         }
114
115         byte[] address = gson.fromJson(controller, byte[].class);
116         InetAddress controllerAddress = null;
117         try {
118             controllerAddress = InetAddress.getByAddress(address);
119         } catch (UnknownHostException e) {
120             return null;
121         }
122
123         List<NodeBean> result = new ArrayList<NodeBean>();
124
125         Set<Node> nodes = connectionManager.getNodes(controllerAddress);
126         if (nodes == null) {
127             return gson.toJson(result);
128         }
129         for (Node node : nodes) {
130             Description description = (Description) switchManager.getNodeProp(node, Description.propertyName);
131             NodeBean nodeBean;
132             if (description == null || description.getValue().equals("None")) {
133                 nodeBean = new NodeBean(node);
134             } else {
135                 nodeBean = new NodeBean(node, description.getValue());
136             }
137             result.add(nodeBean);
138         }
139
140         return gson.toJson(result);
141     }
142
143     @RequestMapping("/users")
144     @ResponseBody
145     public List<UserConfig> getUsers() {
146         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
147         if (userManager == null) {
148             return null;
149         }
150
151         List<UserConfig> userConfList = userManager.getLocalUserList();
152
153         return userConfList;
154     }
155
156     /*
157      * Password in clear text, moving to HTTP/SSL soon
158      */
159     @RequestMapping(value = "/users", method = RequestMethod.POST)
160     @ResponseBody
161     public String saveLocalUserConfig(@RequestParam(required = true) String json,
162             @RequestParam(required = true) String action, HttpServletRequest request) {
163
164         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
165         if (userManager == null) {
166             return "Internal Error";
167         }
168
169         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
170             return "Operation not permitted";
171         }
172
173         Gson gson = new Gson();
174         UserConfig config = gson.fromJson(json, UserConfig.class);
175
176         Status result = (action.equals("add")) ? userManager.addLocalUser(config) : userManager.removeLocalUser(config);
177         if (result.isSuccess()) {
178             String userAction = (action.equals("add")) ? "added" : "removed";
179             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), userAction, config.getUser());
180             return "Success";
181         }
182         return result.getDescription();
183     }
184
185     @RequestMapping(value = "/users/{username}", method = RequestMethod.POST)
186     @ResponseBody
187     public String removeLocalUser(@PathVariable("username") String userName, HttpServletRequest request) {
188
189         String username = request.getUserPrincipal().getName();
190         if (username.equals(userName)) {
191             return "Invalid Request: User cannot delete itself";
192         }
193
194         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
195         if (userManager == null) {
196             return "Internal Error";
197         }
198
199         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
200             return "Operation not permitted";
201         }
202
203         Status result = userManager.removeLocalUser(userName);
204         if (result.isSuccess()) {
205             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "removed", userName);
206             return "Success";
207         }
208         return result.getDescription();
209     }
210
211     @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
212     @ResponseBody
213     public Status changePassword(@PathVariable("username") String username, HttpServletRequest request,
214             @RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword) {
215         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
216         if (userManager == null) {
217             return new Status(StatusCode.GONE, "User Manager not found");
218         }
219
220         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
221             return new Status(StatusCode.FORBIDDEN, "Operation not permitted");
222         }
223
224         if (newPassword.isEmpty()) {
225             return new Status(StatusCode.BADREQUEST, "Empty passwords not allowed");
226         }
227
228         Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
229         if (status.isSuccess()) {
230             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username);
231         }
232         return status;
233     }
234
235     /**
236      * Is the operation permitted for the given level
237      * @param level
238      */
239     private boolean authorize(IUserManager userManager, UserLevel level, HttpServletRequest request) {
240         String username = request.getUserPrincipal().getName();
241         UserLevel userLevel = userManager.getUserLevel(username);
242         return userLevel.toNumber() <= level.toNumber();
243     }
244 }