Authorization fixes for Northbound bundles
[controller.git] / opendaylight / northbound / subnets / src / main / java / org / opendaylight / controller / subnets / northbound / SubnetsNorthboundJAXRS.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 package org.opendaylight.controller.subnets.northbound;
9
10 import java.util.ArrayList;
11
12 import javax.ws.rs.DELETE;
13 import javax.ws.rs.GET;
14 import javax.ws.rs.POST;
15 import javax.ws.rs.Path;
16 import javax.ws.rs.PathParam;
17 import javax.ws.rs.Produces;
18 import javax.ws.rs.QueryParam;
19 import javax.ws.rs.core.Context;
20 import javax.ws.rs.core.MediaType;
21 import javax.ws.rs.core.Response;
22 import javax.ws.rs.core.SecurityContext;
23
24 import org.codehaus.enunciate.jaxrs.ResponseCode;
25 import org.codehaus.enunciate.jaxrs.StatusCodes;
26 import org.codehaus.enunciate.jaxrs.TypeHint;
27 import org.opendaylight.controller.northbound.commons.RestMessages;
28 import org.opendaylight.controller.northbound.commons.exception.InternalServerErrorException;
29 import org.opendaylight.controller.northbound.commons.exception.ResourceNotFoundException;
30 import org.opendaylight.controller.northbound.commons.exception.UnauthorizedException;
31 import org.opendaylight.controller.northbound.commons.utils.NorthboundUtils;
32 import org.opendaylight.controller.sal.authorization.Privilege;
33 import org.opendaylight.controller.sal.utils.ServiceHelper;
34 import org.opendaylight.controller.sal.utils.Status;
35 import org.opendaylight.controller.switchmanager.ISwitchManager;
36 import org.opendaylight.controller.switchmanager.SubnetConfig;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 @Path("/")
41 public class SubnetsNorthboundJAXRS {
42     protected static final Logger logger = LoggerFactory
43             .getLogger(SubnetsNorthboundJAXRS.class);
44
45     private String username;
46
47     @Context
48     public void setSecurityContext(SecurityContext context) {
49         username = context.getUserPrincipal().getName();
50     }
51
52     protected String getUserName() {
53         return username;
54     }
55
56     /**
57      * List all the subnets in a given container
58      * 
59      * @param containerName
60      *            container in which we want to query the subnets
61      * 
62      * @return a List of SubnetConfig
63      */
64     @Path("/{containerName}")
65     @GET
66     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
67     @StatusCodes({ @ResponseCode(code = 404, condition = "The containerName passed was not found") })
68     @TypeHint(SubnetConfigs.class)
69     public SubnetConfigs listSubnets(
70             @PathParam("containerName") String containerName) {
71         if (!NorthboundUtils.isAuthorized(
72                 getUserName(), containerName, Privilege.READ, this)) {
73             throw new UnauthorizedException(
74                     "User is not authorized to perform this operation on container "
75                             + containerName);
76         }
77         ISwitchManager switchManager = null;
78         switchManager = (ISwitchManager) ServiceHelper.getInstance(
79                 ISwitchManager.class, containerName, this);
80         if (switchManager == null) {
81             throw new ResourceNotFoundException(
82                     RestMessages.NOCONTAINER.toString());
83         }
84         return new SubnetConfigs(switchManager.getSubnetsConfigList());
85     }
86
87     /**
88      * List the configuration of a subnet in a given container
89      * 
90      * @param containerName
91      *            container in which we want to query the subnet
92      * @param subnetName
93      *            of the subnet being queried
94      * 
95      * @return a SubnetConfig
96      */
97     @Path("/{containerName}/{subnetName}")
98     @GET
99     @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
100     @StatusCodes({
101             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
102             @ResponseCode(code = 404, condition = "Subnet does not exist") })
103     @TypeHint(SubnetConfig.class)
104     public SubnetConfig listSubnet(
105             @PathParam("containerName") String containerName,
106             @PathParam("subnetName") String subnetName) {
107
108         if (!NorthboundUtils.isAuthorized(
109                 getUserName(), containerName, Privilege.READ, this)) {
110             throw new UnauthorizedException(
111                     "User is not authorized to perform this operation on container "
112                             + containerName);
113         }
114         ISwitchManager switchManager = null;
115         switchManager = (ISwitchManager) ServiceHelper.getInstance(
116                 ISwitchManager.class, containerName, this);
117         if (switchManager == null) {
118             throw new ResourceNotFoundException(
119                     RestMessages.NOCONTAINER.toString());
120         }
121         SubnetConfig res = switchManager.getSubnetConfig(subnetName);
122         if (res == null) {
123             throw new ResourceNotFoundException(
124                     RestMessages.NOSUBNET.toString());
125         } else {
126             return res;
127         }
128     }
129
130     /**
131      * Add/Update a subnet to a container
132      * 
133      * @param containerName
134      *            container in which we want to add/update the subnet
135      * @param subnetName
136      *            that has to be added
137      * @param subnet
138      *            pair default gateway IP/mask that identify the subnet being
139      *            added modified
140      * 
141      */
142     @Path("/{containerName}/{subnetName}")
143     @POST
144     @StatusCodes({
145             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
146             @ResponseCode(code = 404, condition = "Invalid Data passed"),
147             @ResponseCode(code = 201, condition = "Subnet added/modified"),
148             @ResponseCode(code = 500, condition = "Addition of subnet failed") })
149     public Response addSubnet(@PathParam("containerName") String containerName,
150             @PathParam("subnetName") String subnetName,
151             @QueryParam("subnet") String subnet) {
152
153         if (!NorthboundUtils.isAuthorized(
154                 getUserName(), containerName, Privilege.WRITE, this)) {
155             throw new UnauthorizedException(
156                     "User is not authorized to perform this operation on container "
157                             + containerName);
158         }
159         if (subnetName == null) {
160             throw new ResourceNotFoundException(
161                     RestMessages.INVALIDDATA.toString());
162         }
163         if (subnet == null) {
164             throw new ResourceNotFoundException(
165                     RestMessages.INVALIDDATA.toString());
166         }
167         ISwitchManager switchManager = null;
168         switchManager = (ISwitchManager) ServiceHelper.getInstance(
169                 ISwitchManager.class, containerName, this);
170         if (switchManager == null) {
171             throw new ResourceNotFoundException(
172                     RestMessages.NOCONTAINER.toString());
173         }
174
175         SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet,
176                 new ArrayList<String>(0));
177         Status status = switchManager.addSubnet(cfgObject);
178         if (status.isSuccess()) {
179             return Response.status(Response.Status.CREATED).build();
180         }
181         throw new InternalServerErrorException(status.getDescription());
182     }
183
184     /**
185      * Delete a subnet from a container
186      * 
187      * @param containerName
188      *            container in which we want to delete the subnet by name
189      * @param subnetName
190      *            of the subnet to be remove.
191      * 
192      */
193     @Path("/{containerName}/{subnetName}")
194     @DELETE
195     @StatusCodes({
196             @ResponseCode(code = 404, condition = "The containerName passed was not found"),
197             @ResponseCode(code = 500, condition = "Removal of subnet failed") })
198     public Response removeSubnet(
199             @PathParam("containerName") String containerName,
200             @PathParam("subnetName") String subnetName) {
201         if (subnetName == null) {
202             throw new ResourceNotFoundException(
203                     RestMessages.INVALIDDATA.toString());
204         }
205
206         if (!NorthboundUtils.isAuthorized(
207                 getUserName(), containerName, Privilege.WRITE, this)) {
208             throw new UnauthorizedException(
209                     "User is not authorized to perform this operation on container "
210                             + containerName);
211         }
212
213         ISwitchManager switchManager = null;
214         switchManager = (ISwitchManager) ServiceHelper.getInstance(
215                 ISwitchManager.class, containerName, this);
216         if (switchManager == null) {
217             throw new ResourceNotFoundException(
218                     RestMessages.NOCONTAINER.toString());
219         }
220         Status status = switchManager.removeSubnet(subnetName);
221         if (status.isSuccess()) {
222             return Response.status(Response.Status.OK).build();
223         }
224         throw new InternalServerErrorException(status.getDescription());
225     }
226
227     /*
228      * 
229      * Add or remove switch ports to a subnet POST subnets/green/sw
230      * 
231      * @param model
232      * 
233      * @param containerName
234      * 
235      * @param name
236      * 
237      * @param subnet: the subnet name name
238      * 
239      * @param switchports: datapath ID/port list =>
240      * xx:xx:xx:xx:xx:xx:xx:xx/a,b,c-m,r-t,y
241      * 
242      * @return
243      * 
244      * @RequestMapping(value = "/{containerName}/{name}", method =
245      * RequestMethod.POST)
246      * 
247      * public View addSwitchports(Map<String, Object> model,
248      * 
249      * @PathVariable(value = "containerName") String containerName,
250      * 
251      * @PathVariable(value = "name") String name,
252      * 
253      * @RequestParam(value = "nodeports") String nodePorts,
254      * 
255      * @RequestParam(value = "action") String action) {
256      * 
257      * checkDefaultDisabled(containerName); ISwitchManager switchManager = null;
258      * try { BundleContext bCtx = FrameworkUtil.getBundle(this.getClass())
259      * .getBundleContext();
260      * 
261      * ServiceReference[] services = bCtx.getServiceReferences(
262      * ISwitchManager.class.getName(), "(containerName=" + containerName + ")");
263      * 
264      * if (services != null) { switchManager = (ISwitchManager)
265      * bCtx.getService(services[0]); logger.debug("Switch manager reference is:"
266      * + switchManager); } } catch (Exception e) {
267      * logger.error("Switch Manager reference is NULL"); }
268      * 
269      * checkContainerExists(switchManager);
270      * 
271      * String ret; if (action.equals("add")) { ret =
272      * switchManager.addPortsToSubnet(name, nodePorts); } else if
273      * (action.equals("remove")) { ret =
274      * switchManager.removePortsFromSubnet(name, nodePorts); } else { throw new
275      * UnsupportedMediaTypeException(RestMessages.UNKNOWNACTION .toString() +
276      * ": " + action); }
277      * 
278      * return returnViewOrThrowConflicEx(model, ret); }
279      */
280 }