Fix container authorization - front end
[controller.git] / opendaylight / web / flows / src / main / java / org / opendaylight / controller / flows / web / Flows.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.flows.web;
10
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16
17 import javax.servlet.http.HttpServletRequest;
18
19 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
20 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
21 import org.opendaylight.controller.sal.authorization.Privilege;
22 import org.opendaylight.controller.sal.authorization.UserLevel;
23 import org.opendaylight.controller.sal.core.Name;
24 import org.opendaylight.controller.sal.core.Node;
25 import org.opendaylight.controller.sal.core.NodeConnector;
26 import org.opendaylight.controller.sal.utils.GlobalConstants;
27 import org.opendaylight.controller.sal.utils.ServiceHelper;
28 import org.opendaylight.controller.sal.utils.Status;
29 import org.opendaylight.controller.sal.utils.StatusCode;
30 import org.opendaylight.controller.switchmanager.ISwitchManager;
31 import org.opendaylight.controller.switchmanager.Switch;
32 import org.opendaylight.controller.switchmanager.SwitchConfig;
33 import org.opendaylight.controller.web.DaylightWebUtil;
34 import org.opendaylight.controller.web.IDaylightWeb;
35 import org.springframework.stereotype.Controller;
36 import org.springframework.web.bind.annotation.PathVariable;
37 import org.springframework.web.bind.annotation.RequestMapping;
38 import org.springframework.web.bind.annotation.RequestMethod;
39 import org.springframework.web.bind.annotation.RequestParam;
40 import org.springframework.web.bind.annotation.ResponseBody;
41
42 import com.google.gson.Gson;
43
44 @Controller
45 @RequestMapping("/")
46 public class Flows implements IDaylightWeb {
47     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
48     private static final String WEB_NAME = "Flows";
49     private static final String WEB_ID = "flows";
50     private static final short WEB_ORDER = 2;
51
52     public Flows() {
53         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
54     }
55
56     @Override
57     public String getWebName() {
58         return WEB_NAME;
59     }
60
61     @Override
62     public String getWebId() {
63         return WEB_ID;
64     }
65
66     @Override
67     public short getWebOrder() {
68         return WEB_ORDER;
69     }
70
71     @Override
72     public boolean isAuthorized(UserLevel userLevel) {
73         return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
74     }
75
76     @RequestMapping(value = "/main")
77     @ResponseBody
78     public Map<String, Object> getFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
79         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
80
81         // Derive the privilege this user has on the current container
82         String userName = request.getUserPrincipal().getName();
83         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
84         if (privilege  == Privilege.NONE) {
85             return null;
86         }
87
88         // fetch frm
89         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
90                 .getInstance(IForwardingRulesManager.class, containerName, this);
91         if (frm == null) {
92             return null;
93         }
94
95         // fetch sm
96         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
97                 .getInstance(ISwitchManager.class, containerName, this);
98         if (switchManager == null) {
99             return null;
100         }
101
102         // get static flow list
103         List<FlowConfig> staticFlowList = frm.getStaticFlows();
104         Set<Map<String, Object>> flowSet = new HashSet<Map<String, Object>>();
105         for (FlowConfig flowConfig : staticFlowList) {
106             Map<String, Object> entry = new HashMap<String, Object>();
107             entry.put("flow", flowConfig);
108             entry.put("name", flowConfig.getName());
109             Node node = flowConfig.getNode();
110             String description = switchManager.getNodeDescription(node);
111             entry.put("node", (description.isEmpty() || description
112                     .equalsIgnoreCase("none")) ? node.toString() : description);
113             entry.put("nodeId", node.toString());
114             flowSet.add(entry);
115         }
116
117         Map <String, Object> output = new HashMap<String, Object>(2);
118         output.put("flows", flowSet);
119         output.put("privilege", privilege);
120         return output;
121     }
122
123     @RequestMapping(value = "/node-ports")
124     @ResponseBody
125     public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
126         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
127
128         // Derive the privilege this user has on the current container
129         String userName = request.getUserPrincipal().getName();
130         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
131             return null;
132         }
133
134         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
135                 .getInstance(ISwitchManager.class, containerName, this);
136         if (switchManager == null) {
137             return null;
138         }
139
140         Map<String, Object> nodes = new HashMap<String, Object>();
141         Map<Short, String> port;
142
143         for (Switch node : switchManager.getNetworkDevices()) {
144             port = new HashMap<Short, String>(); // new port
145             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
146
147             if (nodeConnectorSet != null) {
148                 for (NodeConnector nodeConnector : nodeConnectorSet) {
149                     String nodeConnectorName = ((Name) switchManager
150                             .getNodeConnectorProp(nodeConnector,
151                                     Name.NamePropName)).getValue();
152                     port.put((Short) nodeConnector.getID(), nodeConnectorName
153                             + "(" + nodeConnector.getNodeConnectorIDString()
154                             + ")");
155                 }
156             }
157
158             // add ports
159             Map<String, Object> entry = new HashMap<String, Object>();
160             entry.put("ports", port);
161
162             // add name
163             String description = switchManager.getNodeDescription(node
164                     .getNode());
165             entry.put("name", (description.isEmpty() || description
166                     .equalsIgnoreCase("none")) ? node.getNode().toString()
167                     : description);
168
169             // add to the node
170             nodes.put(node.getNode().toString(), entry);
171         }
172
173         return nodes;
174     }
175
176     @RequestMapping(value = "/node-flows")
177     @ResponseBody
178     public Map<String, Object> getNodeFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
179         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
180
181         // Derive the privilege this user has on the current container
182         String userName = request.getUserPrincipal().getName();
183         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
184             return null;
185         }
186
187         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
188                 .getInstance(ISwitchManager.class, containerName, this);
189         if (switchManager == null) {
190             return null;
191         }
192         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
193                 .getInstance(IForwardingRulesManager.class, containerName, this);
194         if (frm == null) {
195             return null;
196         }
197
198         Map<String, Object> nodes = new HashMap<String, Object>();
199
200         for (Switch sw : switchManager.getNetworkDevices()) {
201             Node node = sw.getNode();
202
203             List<FlowConfig> flows = frm.getStaticFlows(node);
204
205             String nodeDesc = node.toString();
206             SwitchConfig config = switchManager.getSwitchConfig(node
207                     .toString());
208             if (config != null) {
209                 nodeDesc = config.getNodeDescription();
210             }
211
212             nodes.put(nodeDesc, flows.size());
213         }
214
215         return nodes;
216     }
217
218     @RequestMapping(value = "/flow", method = RequestMethod.POST)
219     @ResponseBody
220     public String actionFlow(@RequestParam(required = true) String action,
221             @RequestParam(required = false) String body,
222             @RequestParam(required = true) String nodeId,
223             HttpServletRequest request, @RequestParam(required = false) String container) {
224         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
225
226         // Authorization check
227         String userName = request.getUserPrincipal().getName();
228         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
229             return "Operation not authorized";
230         }
231
232         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
233                 .getInstance(IForwardingRulesManager.class, containerName, this);
234         if (frm == null) {
235             return null;
236         }
237
238         Gson gson = new Gson();
239         FlowConfig flow = gson.fromJson(body, FlowConfig.class);
240         Node node = Node.fromString(nodeId);
241         flow.setNode(node);
242         Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
243         if (action.equals("add")) {
244             result = frm.addStaticFlow(flow, false);
245         }
246
247         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
248                 .getDescription();
249     }
250
251     @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
252     @ResponseBody
253     public String removeFlow(@PathVariable("nodeId") String nodeId,
254             @PathVariable("name") String name,
255             @RequestParam(required = true) String action,
256             HttpServletRequest request, @RequestParam(required = false) String container) {
257         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
258
259         // Authorization check
260         String userName = request.getUserPrincipal().getName();
261         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
262             return "Operation not authorized";
263         }
264
265         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
266                 .getInstance(IForwardingRulesManager.class, containerName, this);
267         if (frm == null) {
268             return null;
269         }
270
271         Status result = null;
272         Node node = Node.fromString(nodeId);
273         if (node == null) {
274             return null;
275         }
276         if (action.equals("remove")) {
277             result = frm.removeStaticFlow(name, node);
278         } else if (action.equals("toggle")) {
279             result = frm.toggleStaticFlowStatus(name, node);
280         } else {
281             result = new Status(StatusCode.BADREQUEST, "Unknown action");
282         }
283
284         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
285                 .getDescription();
286     }
287 }