From c57bd2d472467b1b3a45aee1b97c9a0aeef5958a Mon Sep 17 00:00:00 2001 From: Rafael Guterres Date: Fri, 27 Nov 2015 03:32:59 -0200 Subject: Initial implementation of new api with jax-rs. Revert servlets to old api and remove plurals. Fix findbugs for header origin. --- src/org/traccar/web/BaseServlet.java | 19 +-- src/org/traccar/web/BaseServletResource.java | 169 --------------------------- src/org/traccar/web/DeviceServlet.java | 67 ++++------- src/org/traccar/web/JsonConverter.java | 17 +++ src/org/traccar/web/PositionServlet.java | 10 +- src/org/traccar/web/ServerServlet.java | 27 ++--- src/org/traccar/web/UserServlet.java | 77 ++++-------- src/org/traccar/web/WebServer.java | 22 +++- 8 files changed, 100 insertions(+), 308 deletions(-) delete mode 100644 src/org/traccar/web/BaseServletResource.java (limited to 'src/org/traccar/web') diff --git a/src/org/traccar/web/BaseServlet.java b/src/org/traccar/web/BaseServlet.java index 916eb6a18..d215c62d0 100644 --- a/src/org/traccar/web/BaseServlet.java +++ b/src/org/traccar/web/BaseServlet.java @@ -19,9 +19,10 @@ import org.traccar.helper.Log; import java.io.IOException; import java.io.Writer; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.security.AccessControlException; import java.util.Collection; -import java.util.Map; import javax.json.Json; import javax.json.JsonObjectBuilder; import javax.json.JsonStructure; @@ -32,8 +33,6 @@ import javax.servlet.http.HttpServletResponse; import org.jboss.netty.handler.codec.http.HttpHeaders; import org.jboss.netty.util.CharsetUtil; import org.traccar.Context; -import org.traccar.helper.Authorization; -import org.traccar.model.User; public abstract class BaseServlet extends HttpServlet { @@ -57,7 +56,8 @@ public abstract class BaseServlet extends HttpServlet { if (allowed == null) { resp.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW_ORIGIN_VALUE); } else if (allowed.contains(origin)) { - resp.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, origin); + String originSafe = URLEncoder.encode(origin, StandardCharsets.UTF_8.displayName()); + resp.setHeader(HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN, originSafe); } if (!handle(getCommand(req), req, resp)) { @@ -66,7 +66,6 @@ public abstract class BaseServlet extends HttpServlet { } catch (Exception error) { if (error instanceof AccessControlException) { resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - resp.addHeader(HttpHeaders.Names.WWW_AUTHENTICATE, Authorization.WWW_AUTHENTICATE_VALUE); } else if (error instanceof SecurityException) { resp.setStatus(HttpServletResponse.SC_FORBIDDEN); } @@ -82,16 +81,6 @@ public abstract class BaseServlet extends HttpServlet { if (userId != null) { return (Long) userId; } - String authorization = req.getHeader(HttpHeaders.Names.AUTHORIZATION); - if (authorization != null && !authorization.isEmpty()) { - Map authMap = Authorization.parse(authorization); - String username = authMap.get(Authorization.USERNAME); - String password = authMap.get(Authorization.PASSWORD); - User user = Context.getDataManager().login(username, password); - if (user != null) { - return user.getId(); - } - } throw new AccessControlException("User not logged in"); } diff --git a/src/org/traccar/web/BaseServletResource.java b/src/org/traccar/web/BaseServletResource.java deleted file mode 100644 index 318f0d7b6..000000000 --- a/src/org/traccar/web/BaseServletResource.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2015 Anton Tananaev (anton.tananaev@gmail.com) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.traccar.web; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.traccar.Context; -import org.traccar.helper.CommandCall; -import org.traccar.helper.Clazz; - -/** - * - * @author Rafael - */ -public abstract class BaseServletResource extends BaseServlet { - - private final Class clazz = Clazz.getGenericArgumentType(getClass()); - - public static final String GET = "GET"; - public static final String POST = "POST"; - public static final String PUT = "PUT"; - public static final String DELETE = "DELETE"; - - public static final String PATH_PARAM_ID = "/\\d"; - public static final String SLASH = "/"; - public static final String VOID = ""; - - @Override - protected String getCommand(HttpServletRequest req) { - String command = req.getPathInfo(); - if (command == null || command.matches(PATH_PARAM_ID)) { - switch (req.getMethod()) { - case GET: - command = "/get"; - break; - case POST: - command = "/add"; - break; - case PUT: - command = "/update"; - break; - case DELETE: - command = "/remove"; - break; - default: - command = ""; - } - } - return command; - } - - protected String getPathParamId(String pathInfo) { - if (pathInfo != null && pathInfo.matches(PATH_PARAM_ID)) { - return pathInfo.replaceAll(SLASH, VOID); - } - return null; - } - - protected abstract void get(HttpServletRequest req, HttpServletResponse resp) throws Exception; - - protected void add(HttpServletRequest req, HttpServletResponse resp) throws Exception { - add(req, resp, null); - } - - protected void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { - update(req, resp, null); - } - - protected void remove(HttpServletRequest req, HttpServletResponse resp) throws Exception { - remove(req, resp, null); - } - - protected void add(HttpServletRequest req, HttpServletResponse resp, CommandCall commandCall) throws Exception { - if (commandCall != null) { - commandCall.before(); - } - - T entity = JsonConverter.objectFromJson(req.getReader(), this.clazz); - long userId = getUserId(req); - if (commandCall != null) { - commandCall.setUserId(userId); - commandCall.setEntity(entity); - commandCall.check(); - } - - Context.getDataManager().add(entity); - - long entityId = Clazz.getId(entity); - Context.getDataManager().link(this.clazz, userId, entityId); - - if (commandCall != null) { - commandCall.after(); - } - - sendResponse(resp.getWriter(), JsonConverter.objectToJson(entity)); - } - - protected void update(HttpServletRequest req, HttpServletResponse resp, - CommandCall commandCall) throws Exception { - if (commandCall != null) { - commandCall.before(); - } - - T entity = JsonConverter.objectFromJson(req.getReader(), this.clazz); - String entityId = getPathParamId(req.getPathInfo()); - if (entityId != null) { - Clazz.setId(entity, Long.parseLong(entityId)); - } - long userId = getUserId(req); - - if (commandCall != null) { - commandCall.setUserId(userId); - commandCall.setEntity(entity); - commandCall.check(); - } - - Context.getDataManager().update(entity); - - if (commandCall != null) { - commandCall.after(); - } - - sendResponse(resp.getWriter(), true); - } - - protected void remove(HttpServletRequest req, HttpServletResponse resp, - CommandCall commandCall) throws Exception { - if (commandCall != null) { - commandCall.before(); - } - - T entity = Clazz.newInstance(this.clazz); - String entityId = getPathParamId(req.getPathInfo()); - if (entityId != null) { - Clazz.setId(entity, Long.parseLong(entityId)); - } else { - entity = JsonConverter.objectFromJson(req.getReader(), this.clazz); - } - long userId = getUserId(req); - - if (commandCall != null) { - commandCall.setUserId(userId); - commandCall.setEntity(entity); - commandCall.check(); - } - - Context.getDataManager().remove(entity); - - if (commandCall != null) { - commandCall.after(); - } - - sendResponse(resp.getWriter(), true); - } - -} diff --git a/src/org/traccar/web/DeviceServlet.java b/src/org/traccar/web/DeviceServlet.java index 7900538bb..8f983ad78 100644 --- a/src/org/traccar/web/DeviceServlet.java +++ b/src/org/traccar/web/DeviceServlet.java @@ -18,11 +18,9 @@ package org.traccar.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.traccar.Context; -import org.traccar.helper.CommandCall; import org.traccar.model.Device; -import org.traccar.model.User; -public class DeviceServlet extends BaseServletResource { +public class DeviceServlet extends BaseServlet { @Override protected boolean handle(String command, HttpServletRequest req, HttpServletResponse resp) throws Exception { @@ -52,8 +50,7 @@ public class DeviceServlet extends BaseServletResource { return true; } - @Override - protected void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { + private void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { if (Boolean.parseBoolean(req.getParameter("all"))) { Context.getPermissionsManager().checkAdmin(getUserId(req)); sendResponse(resp.getWriter(), JsonConverter.arrayToJson( @@ -66,57 +63,39 @@ public class DeviceServlet extends BaseServletResource { } else { userId = getUserId(req); } - Context.getPermissionsManager().check(User.class, getUserId(req), userId); + Context.getPermissionsManager().checkUser(getUserId(req), userId); sendResponse(resp.getWriter(), JsonConverter.arrayToJson( Context.getDataManager().getDevices(userId))); } } - @Override - protected void add(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.add(req, resp, new CommandCall() { - - @Override - public void after() throws Exception { - Context.getDataManager().link(Device.class, getUserId(), getEntity().getId()); - Context.getPermissionsManager().refresh(); - } - - }); + private void add(HttpServletRequest req, HttpServletResponse resp) throws Exception { + Device device = JsonConverter.objectFromJson(req.getReader(), new Device()); + long userId = getUserId(req); + Context.getDataManager().addDevice(device); + Context.getDataManager().linkDevice(userId, device.getId()); + Context.getPermissionsManager().refresh(); + sendResponse(resp.getWriter(), JsonConverter.objectToJson(device)); } - @Override - protected void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.update(req, resp, new CommandCall() { - - @Override - public void check() throws Exception { - Context.getPermissionsManager().check(Device.class, getUserId(), getEntity().getId()); - } - - }); + private void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { + Device device = JsonConverter.objectFromJson(req.getReader(), new Device()); + Context.getPermissionsManager().checkDevice(getUserId(req), device.getId()); + Context.getDataManager().updateDevice(device); + sendResponse(resp.getWriter(), true); } - @Override - protected void remove(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.remove(req, resp, new CommandCall() { - - @Override - public void check() throws Exception { - Context.getPermissionsManager().check(Device.class, getUserId(), getEntity().getId()); - } - - @Override - public void after() throws Exception { - Context.getPermissionsManager().refresh(); - } - - }); + private void remove(HttpServletRequest req, HttpServletResponse resp) throws Exception { + Device device = JsonConverter.objectFromJson(req.getReader(), new Device()); + Context.getPermissionsManager().checkDevice(getUserId(req), device.getId()); + Context.getDataManager().removeDevice(device); + Context.getPermissionsManager().refresh(); + sendResponse(resp.getWriter(), true); } private void link(HttpServletRequest req, HttpServletResponse resp) throws Exception { Context.getPermissionsManager().checkAdmin(getUserId(req)); - Context.getDataManager().link(Device.class, + Context.getDataManager().linkDevice( Long.parseLong(req.getParameter("userId")), Long.parseLong(req.getParameter("deviceId"))); Context.getPermissionsManager().refresh(); @@ -125,7 +104,7 @@ public class DeviceServlet extends BaseServletResource { private void unlink(HttpServletRequest req, HttpServletResponse resp) throws Exception { Context.getPermissionsManager().checkAdmin(getUserId(req)); - Context.getDataManager().unlink(Device.class, + Context.getDataManager().unlinkDevice( Long.parseLong(req.getParameter("userId")), Long.parseLong(req.getParameter("deviceId"))); Context.getPermissionsManager().refresh(); diff --git a/src/org/traccar/web/JsonConverter.java b/src/org/traccar/web/JsonConverter.java index a8b68613b..38721db61 100644 --- a/src/org/traccar/web/JsonConverter.java +++ b/src/org/traccar/web/JsonConverter.java @@ -36,6 +36,7 @@ import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import org.traccar.helper.Clazz; import org.traccar.helper.Log; +import org.traccar.model.Factory; import org.traccar.model.MiscFormatter; public final class JsonConverter { @@ -49,6 +50,18 @@ public final class JsonConverter { return DATE_FORMAT.parseDateTime(value).toDate(); } + public static T objectFromJson(Reader reader, T prototype) throws ParseException { + try (JsonReader jsonReader = Json.createReader(reader)) { + return objectFromJson(jsonReader.readObject(), prototype); + } + } + + public static T objectFromJson(JsonObject json, T prototype) { + T object = (T) prototype.create(); + Method[] methods = object.getClass().getMethods(); + return objectFromJson(json, object, methods); + } + public static T objectFromJson(Reader reader, Class clazz) throws ParseException { try (JsonReader jsonReader = Json.createReader(reader)) { return objectFromJson(jsonReader.readObject(), clazz); @@ -58,6 +71,10 @@ public final class JsonConverter { public static T objectFromJson(JsonObject json, Class clazz) { T object = Clazz.newInstance(clazz); Method[] methods = object.getClass().getMethods(); + return objectFromJson(json, object, methods); + } + + private static T objectFromJson(JsonObject json, T object, Method[] methods) { for (final Method method : methods) { if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { diff --git a/src/org/traccar/web/PositionServlet.java b/src/org/traccar/web/PositionServlet.java index c63968251..796d6a81f 100644 --- a/src/org/traccar/web/PositionServlet.java +++ b/src/org/traccar/web/PositionServlet.java @@ -23,9 +23,8 @@ import org.traccar.model.Position; import java.util.HashMap; import java.util.Map; -import org.traccar.model.Device; -public class PositionServlet extends BaseServletResource { +public class PositionServlet extends BaseServlet { @Override protected boolean handle(String command, HttpServletRequest req, HttpServletResponse resp) throws Exception { @@ -43,10 +42,9 @@ public class PositionServlet extends BaseServletResource { return true; } - @Override - protected void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { + private void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { long deviceId = Long.parseLong(req.getParameter("deviceId")); - Context.getPermissionsManager().check(Device.class, getUserId(req), deviceId); + Context.getPermissionsManager().checkDevice(getUserId(req), deviceId); sendResponse(resp.getWriter(), JsonConverter.arrayToJson( Context.getDataManager().getPositions( getUserId(req), deviceId, @@ -61,7 +59,7 @@ public class PositionServlet extends BaseServletResource { for (String deviceIdString : req.getParameterValues("devicesId")) { Long deviceId = Long.parseLong(deviceIdString); - Context.getPermissionsManager().check(Device.class, userId, deviceId); + Context.getPermissionsManager().checkDevice(userId, deviceId); Position position = Context.getConnectionManager().getLastPosition(deviceId); positions.put(deviceId.toString(), position); diff --git a/src/org/traccar/web/ServerServlet.java b/src/org/traccar/web/ServerServlet.java index 312876f36..7ed096bc6 100644 --- a/src/org/traccar/web/ServerServlet.java +++ b/src/org/traccar/web/ServerServlet.java @@ -18,17 +18,16 @@ package org.traccar.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.traccar.Context; -import org.traccar.helper.CommandCall; import org.traccar.model.Server; -public class ServerServlet extends BaseServletResource { +public class ServerServlet extends BaseServlet { @Override protected boolean handle(String command, HttpServletRequest req, HttpServletResponse resp) throws Exception { switch (command) { case "/get": - get(req, resp); + get(resp); break; case "/update": update(req, resp); @@ -39,22 +38,16 @@ public class ServerServlet extends BaseServletResource { return true; } - @Override - protected void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.update(req, resp, new CommandCall() { - - @Override - public void check() { - Context.getPermissionsManager().checkAdmin(getUserId()); - } - - }); - } - - @Override - protected void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { + private void get(HttpServletResponse resp) throws Exception { sendResponse(resp.getWriter(), JsonConverter.objectToJson( Context.getDataManager().getServer())); } + private void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { + Server server = JsonConverter.objectFromJson(req.getReader(), new Server()); + Context.getPermissionsManager().checkAdmin(getUserId(req)); + Context.getDataManager().updateServer(server); + sendResponse(resp.getWriter(), true); + } + } diff --git a/src/org/traccar/web/UserServlet.java b/src/org/traccar/web/UserServlet.java index f7ae19fa9..6bd870d4d 100644 --- a/src/org/traccar/web/UserServlet.java +++ b/src/org/traccar/web/UserServlet.java @@ -18,10 +18,9 @@ package org.traccar.web; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.traccar.Context; -import org.traccar.helper.CommandCall; import org.traccar.model.User; -public class UserServlet extends BaseServletResource { +public class UserServlet extends BaseServlet { @Override protected boolean handle(String command, HttpServletRequest req, HttpServletResponse resp) throws Exception { @@ -45,64 +44,38 @@ public class UserServlet extends BaseServletResource { return true; } - @Override - protected void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { + private void get(HttpServletRequest req, HttpServletResponse resp) throws Exception { Context.getPermissionsManager().checkAdmin(getUserId(req)); sendResponse(resp.getWriter(), JsonConverter.arrayToJson( Context.getDataManager().getUsers())); } - @Override - protected void add(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.add(req, resp, new CommandCall() { - - @Override - public void check() throws Exception { - Context.getPermissionsManager().check(User.class, getUserId(), getEntity().getId()); - } - - @Override - public void after() throws Exception { - Context.getPermissionsManager().refresh(); - } - }); + private void add(HttpServletRequest req, HttpServletResponse resp) throws Exception { + User user = JsonConverter.objectFromJson(req.getReader(), new User()); + Context.getPermissionsManager().checkUser(getUserId(req), user.getId()); + Context.getDataManager().addUser(user); + Context.getPermissionsManager().refresh(); + sendResponse(resp.getWriter(), JsonConverter.objectToJson(user)); } - @Override - protected void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.update(req, resp, new CommandCall() { - - @Override - public void check() { - if (getEntity().getAdmin()) { - Context.getPermissionsManager().checkAdmin(getUserId()); - } else { - Context.getPermissionsManager().check(User.class, getUserId(), getEntity().getId()); - } - } - - @Override - public void after() { - Context.getPermissionsManager().refresh(); - } - - }); + private void update(HttpServletRequest req, HttpServletResponse resp) throws Exception { + User user = JsonConverter.objectFromJson(req.getReader(), new User()); + if (user.getAdmin()) { + Context.getPermissionsManager().checkAdmin(getUserId(req)); + } else { + Context.getPermissionsManager().checkUser(getUserId(req), user.getId()); + } + Context.getDataManager().updateUser(user); + Context.getPermissionsManager().refresh(); + sendResponse(resp.getWriter(), true); } - @Override - protected void remove(HttpServletRequest req, HttpServletResponse resp) throws Exception { - super.remove(req, resp, new CommandCall() { - - @Override - public void check() throws Exception { - Context.getPermissionsManager().check(User.class, getUserId(), getEntity().getId()); - } - - @Override - public void after() throws Exception { - Context.getPermissionsManager().refresh(); - } - - }); + private void remove(HttpServletRequest req, HttpServletResponse resp) throws Exception { + User user = JsonConverter.objectFromJson(req.getReader(), new User()); + Context.getPermissionsManager().checkUser(getUserId(req), user.getId()); + Context.getDataManager().removeUser(user); + Context.getPermissionsManager().refresh(); + sendResponse(resp.getWriter(), true); } + } diff --git a/src/org/traccar/web/WebServer.java b/src/org/traccar/web/WebServer.java index 2e7e1a31b..146dee613 100644 --- a/src/org/traccar/web/WebServer.java +++ b/src/org/traccar/web/WebServer.java @@ -24,6 +24,8 @@ import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.webapp.WebAppContext; +import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.servlet.ServletContainer; import org.traccar.Config; import org.traccar.helper.Log; @@ -98,23 +100,33 @@ public class WebServer { } private void initApi() { + initOldApi(); + initRestApi(); + } + + @Deprecated + private void initOldApi() { ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.SESSIONS); servletHandler.setContextPath("/api"); servletHandler.addServlet(new ServletHolder(new AsyncServlet()), "/async/*"); servletHandler.addServlet(new ServletHolder(new ServerServlet()), "/server/*"); - servletHandler.addServlet(new ServletHolder(new ServerServlet()), "/servers/*"); servletHandler.addServlet(new ServletHolder(new UserServlet()), "/user/*"); - servletHandler.addServlet(new ServletHolder(new UserServlet()), "/users/*"); servletHandler.addServlet(new ServletHolder(new DeviceServlet()), "/device/*"); - servletHandler.addServlet(new ServletHolder(new DeviceServlet()), "/devices/*"); servletHandler.addServlet(new ServletHolder(new PositionServlet()), "/position/*"); - servletHandler.addServlet(new ServletHolder(new PositionServlet()), "/positions/*"); servletHandler.addServlet(new ServletHolder(new CommandServlet()), "/command/*"); - servletHandler.addServlet(new ServletHolder(new CommandServlet()), "/commands/*"); servletHandler.addServlet(new ServletHolder(new MainServlet()), "/*"); handlers.addHandler(servletHandler); } + private void initRestApi() { + ResourceConfig resourceConfig = new ResourceConfig(); + resourceConfig.packages("org.traccar.api"); + ServletContextHandler servletHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS); + ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig)); + servletHandler.addServlet(servletHolder, "/rest/*"); + handlers.addHandler(servletHandler); + } + public void start() { try { server.start(); -- cgit v1.2.3