diff options
Diffstat (limited to 'src/org/traccar/api')
-rw-r--r-- | src/org/traccar/api/BaseResource.java | 19 | ||||
-rw-r--r-- | src/org/traccar/api/CorsResponseFilter.java | 53 | ||||
-rw-r--r-- | src/org/traccar/api/SecurityRequestFilter.java | 61 | ||||
-rw-r--r-- | src/org/traccar/api/UserPrincipal.java | 39 | ||||
-rw-r--r-- | src/org/traccar/api/UserSecurityContext.java | 49 | ||||
-rw-r--r-- | src/org/traccar/api/resource/DeviceResource.java | 83 | ||||
-rw-r--r-- | src/org/traccar/api/resource/UserResource.java | 83 |
7 files changed, 387 insertions, 0 deletions
diff --git a/src/org/traccar/api/BaseResource.java b/src/org/traccar/api/BaseResource.java new file mode 100644 index 000000000..5a05c6732 --- /dev/null +++ b/src/org/traccar/api/BaseResource.java @@ -0,0 +1,19 @@ +/* + * 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.api; + +public class BaseResource { +} diff --git a/src/org/traccar/api/CorsResponseFilter.java b/src/org/traccar/api/CorsResponseFilter.java new file mode 100644 index 000000000..8aab5ad68 --- /dev/null +++ b/src/org/traccar/api/CorsResponseFilter.java @@ -0,0 +1,53 @@ +/* + * 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.api; + +import java.io.IOException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +public class CorsResponseFilter implements ContainerResponseFilter { + + public static final String ACCESS_CONTROL_ALLOW_ORIGIN_KEY = "Access-Control-Allow-Origin"; + public static final String ACCESS_CONTROL_ALLOW_ORIGIN_VALUE = "*"; + + public static final String ACCESS_CONTROL_ALLOW_HEADERS_KEY = "Access-Control-Allow-Headers"; + public static final String ACCESS_CONTROL_ALLOW_HEADERS_VALUE = "origin, content-type, accept, authorization"; + + public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_KEY = "Access-Control-Allow-Credentials"; + public static final String ACCESS_CONTROL_ALLOW_CREDENTIALS_VALUE = "true"; + + public static final String ACCESS_CONTROL_ALLOW_METHODS_KEY = "Access-Control-Allow-Methods"; + public static final String ACCESS_CONTROL_ALLOW_METHODS_VALUE = "GET, POST, PUT, DELETE"; + + @Override + public void filter(ContainerRequestContext request, ContainerResponseContext response) throws IOException { + if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_ORIGIN_KEY)) { + response.getHeaders().add(ACCESS_CONTROL_ALLOW_ORIGIN_KEY, ACCESS_CONTROL_ALLOW_ORIGIN_VALUE); + } + if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_HEADERS_KEY)) { + response.getHeaders().add(ACCESS_CONTROL_ALLOW_HEADERS_KEY, ACCESS_CONTROL_ALLOW_HEADERS_VALUE); + } + if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_CREDENTIALS_KEY)) { + response.getHeaders().add(ACCESS_CONTROL_ALLOW_CREDENTIALS_KEY, ACCESS_CONTROL_ALLOW_CREDENTIALS_VALUE); + } + if (!response.getHeaders().containsKey(ACCESS_CONTROL_ALLOW_METHODS_KEY)) { + response.getHeaders().add(ACCESS_CONTROL_ALLOW_METHODS_KEY, ACCESS_CONTROL_ALLOW_METHODS_VALUE); + } + } + +} diff --git a/src/org/traccar/api/SecurityRequestFilter.java b/src/org/traccar/api/SecurityRequestFilter.java new file mode 100644 index 000000000..63295a8b7 --- /dev/null +++ b/src/org/traccar/api/SecurityRequestFilter.java @@ -0,0 +1,61 @@ +/* + * 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.api; + +import org.traccar.Context; +import org.traccar.model.User; + +import java.nio.charset.Charset; +import java.sql.SQLException; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Response; +import javax.xml.bind.DatatypeConverter; + +public class SecurityRequestFilter implements ContainerRequestFilter { + + public static final String AUTHORIZATION_HEADER = "Authorization"; + public static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + public static final String BASIC_REALM = "Basic realm=\"api\""; + + public static String[] decodeBasicAuth(String auth) { + auth = auth.replaceFirst("[B|b]asic ", ""); + byte[] decodedBytes = DatatypeConverter.parseBase64Binary(auth); + if (decodedBytes != null && decodedBytes.length > 0) { + return new String(decodedBytes, Charset.defaultCharset()).split(":", 2); + } + return null; + } + + @Override + public void filter(ContainerRequestContext requestContext) { + try { + String[] auth = decodeBasicAuth(requestContext.getHeaderString(AUTHORIZATION_HEADER)); + User user = Context.getDataManager().login(auth[0], auth[1]); + if (user != null) { + requestContext.setSecurityContext( + new UserSecurityContext(new UserPrincipal(user.getId(), user.getName()))); + } else { + throw new WebApplicationException( + Response.status(Response.Status.UNAUTHORIZED).header(WWW_AUTHENTICATE, BASIC_REALM).build()); + } + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + +} diff --git a/src/org/traccar/api/UserPrincipal.java b/src/org/traccar/api/UserPrincipal.java new file mode 100644 index 000000000..d858b6f47 --- /dev/null +++ b/src/org/traccar/api/UserPrincipal.java @@ -0,0 +1,39 @@ +/* + * 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.api; + +import java.security.Principal; + +public class UserPrincipal implements Principal { + + private String name; + private long userId; + + public UserPrincipal(long userId, String name) { + this.userId = userId; + this.name = name; + } + + public Long getUserId() { + return userId; + } + + @Override + public String getName() { + return name; + } + +} diff --git a/src/org/traccar/api/UserSecurityContext.java b/src/org/traccar/api/UserSecurityContext.java new file mode 100644 index 000000000..127aee4b3 --- /dev/null +++ b/src/org/traccar/api/UserSecurityContext.java @@ -0,0 +1,49 @@ +/* + * 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.api; + +import java.security.Principal; +import javax.ws.rs.core.SecurityContext; + +public class UserSecurityContext implements SecurityContext { + + private UserPrincipal principal; + + public UserSecurityContext(UserPrincipal principal) { + this.principal = principal; + } + + @Override + public Principal getUserPrincipal() { + return principal; + } + + @Override + public boolean isUserInRole(String role) { + return true; + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public String getAuthenticationScheme() { + return BASIC_AUTH; + } + +} diff --git a/src/org/traccar/api/resource/DeviceResource.java b/src/org/traccar/api/resource/DeviceResource.java new file mode 100644 index 000000000..00b77e16c --- /dev/null +++ b/src/org/traccar/api/resource/DeviceResource.java @@ -0,0 +1,83 @@ +/* + * 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.api.resource; + +import org.traccar.Context; +import org.traccar.api.BaseResource; + +import java.sql.SQLException; +import java.util.Collection; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.traccar.model.Device; + +@Path("devices") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class DeviceResource extends BaseResource { + + @GET + public Collection<Device> get() { + try { + return Context.getDataManager().getAllDevices(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @POST + public Response add(Device entity) { + try { + Context.getDataManager().addDevice(entity); + return Response.ok(entity).build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @Path("{id}") + @PUT + public Response update(@PathParam("id") long id, Device entity) { + try { + entity.setId(id); + Context.getDataManager().updateDevice(entity); + return Response.ok(entity).build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @Path("{id}") + @DELETE + public Response remove(@PathParam("id") long id) { + try { + Context.getDataManager().removeDevice(id); + return Response.noContent().build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + +} diff --git a/src/org/traccar/api/resource/UserResource.java b/src/org/traccar/api/resource/UserResource.java new file mode 100644 index 000000000..43bef891f --- /dev/null +++ b/src/org/traccar/api/resource/UserResource.java @@ -0,0 +1,83 @@ +/* + * 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.api.resource; + +import java.sql.SQLException; +import java.util.Collection; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.traccar.Context; +import org.traccar.api.BaseResource; +import org.traccar.model.User; + +@Path("users") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +public class UserResource extends BaseResource { + + @GET + public Collection<User> get() { + try { + return Context.getDataManager().getUsers(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @POST + public Response add(User entity) { + try { + Context.getDataManager().addUser(entity); + return Response.ok(entity).build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @Path("{id}") + @PUT + public Response update(@PathParam("id") long id, User entity) { + try { + entity.setId(id); + Context.getDataManager().updateUser(entity); + return Response.ok(entity).build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + + @Path("{id}") + @DELETE + public Response remove(@PathParam("id") long id) { + try { + Context.getDataManager().removeUser(id); + return Response.noContent().build(); + } catch (SQLException e) { + throw new WebApplicationException(e); + } + } + +} |