diff --git a/ass2-service/api/src/main/java/dst/ass2/service/api/auth/rest/IAuthenticationResource.java b/ass2-service/api/src/main/java/dst/ass2/service/api/auth/rest/IAuthenticationResource.java index 56c971e..fe028cc 100644 --- a/ass2-service/api/src/main/java/dst/ass2/service/api/auth/rest/IAuthenticationResource.java +++ b/ass2-service/api/src/main/java/dst/ass2/service/api/auth/rest/IAuthenticationResource.java @@ -1,5 +1,8 @@ package dst.ass2.service.api.auth.rest; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; import javax.ws.rs.core.Response; import dst.ass2.service.api.auth.AuthenticationException; @@ -8,11 +11,12 @@ import dst.ass2.service.api.auth.NoSuchUserException; /** * The IAuthenticationResource exposes parts of the {@code IAuthenticationService} as a RESTful interface. */ +@Path("auth") public interface IAuthenticationResource { - // TODO annotate the class and methods with the correct javax.ws.rs annotations - - Response authenticate(String email, String password) + @POST + @Path("authenticate") + Response authenticate(@FormParam("email") String email, @FormParam("password") String password) throws NoSuchUserException, AuthenticationException; } diff --git a/ass2-service/auth-client/src/main/java/dst/ass2/service/auth/client/impl/GrpcAuthenticationClient.java b/ass2-service/auth-client/src/main/java/dst/ass2/service/auth/client/impl/GrpcAuthenticationClient.java index b3559ea..2a29bde 100644 --- a/ass2-service/auth-client/src/main/java/dst/ass2/service/auth/client/impl/GrpcAuthenticationClient.java +++ b/ass2-service/auth-client/src/main/java/dst/ass2/service/auth/client/impl/GrpcAuthenticationClient.java @@ -7,7 +7,6 @@ import dst.ass2.service.auth.client.AuthenticationClientProperties; import dst.ass2.service.auth.client.IAuthenticationClient; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.grpc.StatusRuntimeException; public class GrpcAuthenticationClient implements IAuthenticationClient { private final ManagedChannel channel; @@ -23,10 +22,10 @@ public class GrpcAuthenticationClient implements IAuthenticationClient { AuthenticationRequest request = AuthenticationRequest.newBuilder().setEmail(email).setPassword(password).build(); AuthenticationResponse response = blockingStub.authenticate(request); - if(response.getStatus().startsWith("NoSuchUserException")) + if(response.getStatus().contains("NoSuchUserException")) throw new NoSuchUserException("User with email " + email + " could not be found"); - if(response.getStatus().startsWith("AuthenticationException")) + if(response.getStatus().contains("AuthenticationException")) throw new AuthenticationException("Password for user with email " + email + " was incorrect"); return response.getToken(); diff --git a/ass2-service/auth/src/main/java/dst/ass2/service/auth/impl/GrpcServerRunner.java b/ass2-service/auth/src/main/java/dst/ass2/service/auth/impl/GrpcServerRunner.java index 891e12a..b197d45 100644 --- a/ass2-service/auth/src/main/java/dst/ass2/service/auth/impl/GrpcServerRunner.java +++ b/ass2-service/auth/src/main/java/dst/ass2/service/auth/impl/GrpcServerRunner.java @@ -11,6 +11,7 @@ import io.grpc.ServerBuilder; import io.grpc.stub.StreamObserver; import javax.annotation.Resource; +import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import java.io.IOException; @@ -20,7 +21,7 @@ import java.io.IOException; public class GrpcServerRunner extends AuthServiceGrpc.AuthServiceImplBase implements IGrpcServerRunner { @Resource private GrpcServerProperties properties; - @Resource + @Inject private IAuthenticationService authenticationService; @Override @@ -37,7 +38,7 @@ public class GrpcServerRunner extends AuthServiceGrpc.AuthServiceImplBase implem AuthenticationResponse response; try { String token = authenticationService.authenticate(request.getEmail(), request.getPassword()); - response = AuthenticationResponse.newBuilder().setToken(token).build(); + response = AuthenticationResponse.newBuilder().setStatus("").setToken(token).build(); } catch (NoSuchUserException e){ response = AuthenticationResponse.newBuilder().setStatus("NoSuchUserException").build(); } catch (AuthenticationException e) { diff --git a/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationBinding.java b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationBinding.java new file mode 100644 index 0000000..45d58dc --- /dev/null +++ b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationBinding.java @@ -0,0 +1,13 @@ +package dst.ass2.service.facade.impl; + +import javax.ws.rs.NameBinding; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@NameBinding +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface AuthenticationBinding { +} diff --git a/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationResource.java b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationResource.java new file mode 100644 index 0000000..1a2945b --- /dev/null +++ b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/AuthenticationResource.java @@ -0,0 +1,27 @@ +package dst.ass2.service.facade.impl; + +import dst.ass2.service.api.auth.AuthenticationException; +import dst.ass2.service.api.auth.NoSuchUserException; +import dst.ass2.service.api.auth.rest.IAuthenticationResource; +import dst.ass2.service.auth.client.IAuthenticationClient; + +import javax.inject.Inject; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +@Provider +public class AuthenticationResource implements IAuthenticationResource { + @Inject + private IAuthenticationClient authenticationClient; + + @Override + public Response authenticate(String email, String password) throws NoSuchUserException, AuthenticationException { + String token = null; + try { + token = authenticationClient.authenticate(email, password); + } catch (NoSuchUserException | AuthenticationException e) { + Response.status(Response.Status.BAD_REQUEST).build(); + } + return Response.ok(token).build(); + } +} diff --git a/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/Filter.java b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/Filter.java new file mode 100644 index 0000000..f03368f --- /dev/null +++ b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/Filter.java @@ -0,0 +1,36 @@ +package dst.ass2.service.facade.impl; + +import dst.ass2.service.auth.client.IAuthenticationClient; + +import javax.annotation.Priority; +import javax.inject.Inject; +import javax.ws.rs.Priorities; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; +import java.io.IOException; + +@Provider +@Priority(Priorities.AUTHENTICATION) +@AuthenticationBinding +public class Filter implements ContainerRequestFilter { + @Inject + private IAuthenticationClient authenticationClient; + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + String header = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION); + + if (header == null) { + requestContext.abortWith(Response.status(Response.Status.BAD_REQUEST).build()); + } else { + String[] splitHeader = header.toLowerCase().split("\\s+"); + if (splitHeader.length != 2 || !splitHeader[0].equals("bearer")) + requestContext.abortWith(Response.status(Response.Status.BAD_REQUEST).build()); + if (!authenticationClient.isTokenValid(splitHeader[1])) + requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build()); + } + } +} diff --git a/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/TripServiceResource.java b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/TripServiceResource.java new file mode 100644 index 0000000..dd52105 --- /dev/null +++ b/ass2-service/facade/src/main/java/dst/ass2/service/facade/impl/TripServiceResource.java @@ -0,0 +1,73 @@ +package dst.ass2.service.facade.impl; + +import dst.ass2.service.api.trip.*; +import dst.ass2.service.api.trip.rest.ITripServiceResource; +import org.glassfish.jersey.client.proxy.WebResourceFactory; + +import javax.inject.Inject; +import javax.ws.rs.Path; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; +import java.net.URI; + +@Provider +@Path("trips") +@AuthenticationBinding +public class TripServiceResource implements ITripServiceResource { + @Inject + private URI tripServiceURI; + + private final ITripServiceResource tripServiceResource; + + public TripServiceResource() { + WebTarget target = ClientBuilder.newClient().target(tripServiceURI); + this.tripServiceResource = WebResourceFactory.newResource(ITripServiceResource.class, target); + } + + @Override + public Response createTrip(Long riderId, Long pickupId, Long destinationId) throws EntityNotFoundException, InvalidTripException { + return tripServiceResource.createTrip(riderId, pickupId, destinationId); + } + + @Override + public Response confirm(Long tripId) throws EntityNotFoundException, InvalidTripException { + return tripServiceResource.confirm(tripId); + } + + @Override + public Response getTrip(Long tripId) throws EntityNotFoundException { + return tripServiceResource.getTrip(tripId); + } + + @Override + public Response deleteTrip(Long tripId) throws EntityNotFoundException { + return tripServiceResource.deleteTrip(tripId); + } + + @Override + public Response addStop(Long tripId, Long locationId) throws InvalidTripException, EntityNotFoundException { + return tripServiceResource.addStop(tripId, locationId); + } + + @Override + public Response removeStop(Long tripId, Long locationId) throws InvalidTripException, EntityNotFoundException { + return tripServiceResource.removeStop(tripId, locationId); + } + + @Override + public Response match(Long tripId, MatchDTO matchDTO) throws EntityNotFoundException, DriverNotAvailableException { + return tripServiceResource.match(tripId, matchDTO); + } + + @Override + public Response complete(Long tripId, TripInfoDTO tripInfoDTO) throws EntityNotFoundException { + return tripServiceResource.complete(tripId, tripInfoDTO); + } + + @Override + public Response cancel(Long tripId) throws EntityNotFoundException { + return tripServiceResource.cancel(tripId); + } +}