d9aa03ea6209a66fa4548ef091694b1e63dd633c
[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
59         List<ClusterNodeBean> clusters = new ArrayList<ClusterNodeBean>();
60
61         List<InetAddress> controllers = clusterServices.getClusteredControllers();
62         for (InetAddress controller : controllers) {
63             ClusterNodeBean.Builder clusterBeanBuilder = new ClusterNodeBean.Builder(controller);
64             if (controller.equals(clusterServices.getMyAddress())) {
65                 clusterBeanBuilder.highlightMe();
66             }
67             if (clusterServices.amICoordinator()) {
68                 clusterBeanBuilder.iAmCoordinator();
69             }
70
71             clusters.add(clusterBeanBuilder.build());
72         }
73
74         return gson.toJson(clusters);
75     }
76
77     /**
78      * Return nodes connected to controller {controller}
79      * @param cluster
80      *            - byte[] of the address of the controller
81      * @return List<NodeBean>
82      */
83     @RequestMapping("/cluster/controller/{controller}")
84     @ResponseBody
85     public String getNodesConnectedToController(@PathVariable("controller") String cluster) {
86         IClusterGlobalServices clusterServices = (IClusterGlobalServices) ServiceHelper.getGlobalInstance(
87                 IClusterGlobalServices.class, this);
88         if (clusterServices == null) {
89             return null;
90         }
91         IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
92                 IConnectionManager.class, this);
93         if (connectionManager == null) {
94             return null;
95         }
96         ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
97                 GlobalConstants.DEFAULT.toString(), this);
98         if (switchManager == null) {
99             return null;
100         }
101
102         byte[] address = gson.fromJson(cluster, byte[].class);
103         InetAddress clusterAddress = null;
104         try {
105             clusterAddress = InetAddress.getByAddress(address);
106         } catch (UnknownHostException e) {
107             return null;
108         }
109         InetAddress thisCluster = clusterServices.getMyAddress();
110
111         List<NodeBean> result = new ArrayList<NodeBean>();
112
113         Set<Node> nodes = connectionManager.getNodes(thisCluster);
114         for (Node node : nodes) {
115             Description description = (Description) switchManager.getNodeProp(node, Description.propertyName);
116             NodeBean nodeBean;
117             if (description == null || description.getValue().equals("None")) {
118                 nodeBean = new NodeBean(node);
119             } else {
120                 nodeBean = new NodeBean(node, description.getValue());
121             }
122             result.add(nodeBean);
123         }
124
125         return gson.toJson(result);
126     }
127
128     @RequestMapping("/users")
129     @ResponseBody
130     public List<UserConfig> getUsers() {
131         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
132         if (userManager == null) {
133             return null;
134         }
135
136         List<UserConfig> userConfList = userManager.getLocalUserList();
137
138         return userConfList;
139     }
140
141     /*
142      * Password in clear text, moving to HTTP/SSL soon
143      */
144     @RequestMapping(value = "/users", method = RequestMethod.POST)
145     @ResponseBody
146     public String saveLocalUserConfig(@RequestParam(required = true) String json,
147             @RequestParam(required = true) String action, HttpServletRequest request) {
148
149         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
150         if (userManager == null) {
151             return "Internal Error";
152         }
153
154         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
155             return "Operation not permitted";
156         }
157
158         Gson gson = new Gson();
159         UserConfig config = gson.fromJson(json, UserConfig.class);
160
161         Status result = (action.equals("add")) ? userManager.addLocalUser(config) : userManager.removeLocalUser(config);
162         if (result.isSuccess()) {
163             String userAction = (action.equals("add")) ? "added" : "removed";
164             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), userAction, config.getUser());
165             return "Success";
166         }
167         return result.getDescription();
168     }
169
170     @RequestMapping(value = "/users/{username}", method = RequestMethod.POST)
171     @ResponseBody
172     public String removeLocalUser(@PathVariable("username") String userName, HttpServletRequest request) {
173
174         String username = request.getUserPrincipal().getName();
175         if (username.equals(userName)) {
176             return "Invalid Request: User cannot delete itself";
177         }
178
179         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
180         if (userManager == null) {
181             return "Internal Error";
182         }
183
184         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
185             return "Operation not permitted";
186         }
187
188         Status result = userManager.removeLocalUser(userName);
189         if (result.isSuccess()) {
190             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "removed", userName);
191             return "Success";
192         }
193         return result.getDescription();
194     }
195
196     @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
197     @ResponseBody
198     public Status changePassword(@PathVariable("username") String username, HttpServletRequest request,
199             @RequestParam("currentPassword") String currentPassword, @RequestParam("newPassword") String newPassword) {
200         IUserManager userManager = (IUserManager) ServiceHelper.getGlobalInstance(IUserManager.class, this);
201         if (userManager == null) {
202             return new Status(StatusCode.GONE, "User Manager not found");
203         }
204
205         if (!authorize(userManager, UserLevel.NETWORKADMIN, request)) {
206             return new Status(StatusCode.FORBIDDEN, "Operation not permitted");
207         }
208
209         if (newPassword.isEmpty()) {
210             return new Status(StatusCode.BADREQUEST, "Empty passwords not allowed");
211         }
212
213         Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
214         if (status.isSuccess()) {
215             DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username);
216         }
217         return status;
218     }
219
220     /**
221      * Is the operation permitted for the given level
222      * @param level
223      */
224     private boolean authorize(IUserManager userManager, UserLevel level, HttpServletRequest request) {
225         String username = request.getUserPrincipal().getName();
226         UserLevel userLevel = userManager.getUserLevel(username);
227         return userLevel.toNumber() <= level.toNumber();
228     }
229 }