Commit 1732b012 by Tuukka Kivilahti

Merge branch 'feature/rest-user-creation' into 'master'

User management via REST API

Getting users, checking password and resetting password. Used by Vectorama flow.

See merge request !262
2 parents 7a882794 29987f1f
...@@ -62,6 +62,8 @@ public interface UserBeanLocal { ...@@ -62,6 +62,8 @@ public interface UserBeanLocal {
boolean resetPassword(User user, String password, String hash); boolean resetPassword(User user, String password, String hash);
boolean resetPassword(User user, String password);
public User getUser(Integer id); public User getUser(Integer id);
/** /**
...@@ -157,7 +159,7 @@ public interface UserBeanLocal { ...@@ -157,7 +159,7 @@ public interface UserBeanLocal {
* </ul> * </ul>
* *
* @param source * @param source
* @param dst * @param dstEventuser
* @return Saldo transferred. Zero if no transfer was made, Null if there * @return Saldo transferred. Zero if no transfer was made, Null if there
* was error.. * was error..
*/ */
...@@ -176,4 +178,12 @@ public interface UserBeanLocal { ...@@ -176,4 +178,12 @@ public interface UserBeanLocal {
String findUsernameByEmailUsername(String filter); String findUsernameByEmailUsername(String filter);
EventUser findEventuserByLogin(String username); EventUser findEventuserByLogin(String username);
/**
* Check that user's password matches.
* @param eventUser
* @param password
* @return true if matches, false if does not, null if user not found.
*/
Boolean checkPassword(EventUser eventUser, String password);
} }
...@@ -464,6 +464,15 @@ public class UserBean implements UserBeanLocal { ...@@ -464,6 +464,15 @@ public class UserBean implements UserBeanLocal {
} }
@Override @Override
@RolesAllowed(UserPermission.S_MODIFY)
public boolean resetPassword(User user, String password) {
logger.debug("Changing user {} password", user);
user.resetPassword(password);
userFacade.merge(user);
return true;
}
@Override
public boolean initPasswordResetForUsername(String username, String url) { public boolean initPasswordResetForUsername(String username, String url) {
User user = userFacade.findByLogin(username); User user = userFacade.findByLogin(username);
return initPasswordReset(user, url); return initPasswordReset(user, url);
...@@ -1110,6 +1119,14 @@ public class UserBean implements UserBeanLocal { ...@@ -1110,6 +1119,14 @@ public class UserBean implements UserBeanLocal {
return eventUserFacade.findByLogin(username); return eventUserFacade.findByLogin(username);
} }
@Override
@RolesAllowed(UserPermission.S_VIEW_ALL)
public Boolean checkPassword(EventUser eventUser, String password) {
if (eventUser != null) {
return eventUser.checkPassword(password);
}
return null;
}
@Override @Override
......
package fi.codecrew.moya.rest.pojo.util.v1;
import com.wordnik.swagger.annotations.ApiModel;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@ApiModel
public class ErrorRoot {
private String error;
public String getError() {
return error;
}
public void setError(String error) {
this.error= error;
}
}
...@@ -27,46 +27,39 @@ import java.io.InputStream; ...@@ -27,46 +27,39 @@ import java.io.InputStream;
import org.krysalis.barcode4j.BarcodeDimension; import org.krysalis.barcode4j.BarcodeDimension;
import org.krysalis.barcode4j.BarcodeGenerator; import org.krysalis.barcode4j.BarcodeGenerator;
import org.krysalis.barcode4j.impl.code128.Code128Bean; import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.impl.code39.Code39Bean;
import org.krysalis.barcode4j.impl.upcean.EAN13Bean; import org.krysalis.barcode4j.impl.upcean.EAN13Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider; import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;
public class BarcodeUtils { public class BarcodeUtils {
public static InputStream getBarcode(String message) throws IOException { public static InputStream getBarcode(BarcodeGenerator generator, String message) throws IOException {
// BarcodeGenerator bean = new DataMatrixBean();
BarcodeGenerator bean = new Code128Bean();
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
// System.out.println("created: " + (new Date().getTime() - start));
BitmapCanvasProvider canvas = new BitmapCanvasProvider( BitmapCanvasProvider canvas = new BitmapCanvasProvider(
out, "image/png", 150, BufferedImage.TYPE_BYTE_BINARY, false, 0); out, "image/png", 150, BufferedImage.TYPE_BYTE_BINARY, false, 0);
canvas.establishDimensions(new BarcodeDimension(200, 15)); canvas.establishDimensions(new BarcodeDimension(200, 15));
bean.generateBarcode(canvas, message); generator.generateBarcode(canvas, message);
canvas.finish(); canvas.finish();
ByteArrayInputStream istream = new ByteArrayInputStream(out.toByteArray()); ByteArrayInputStream istream = new ByteArrayInputStream(out.toByteArray());
return istream; return istream;
} }
public static InputStream getBarcodeEAN(String message) throws IOException { public static InputStream getBarcode(String message) throws IOException {
// BarcodeGenerator bean = new DataMatrixBean(); return BarcodeUtils.getBarcode(new Code128Bean(), message);
BarcodeGenerator bean = new EAN13Bean(); }
ByteArrayOutputStream out = new ByteArrayOutputStream();
// System.out.println("created: " + (new Date().getTime() - start));
BitmapCanvasProvider canvas = new BitmapCanvasProvider(
out, "image/png", 150, BufferedImage.TYPE_BYTE_BINARY, false, 0);
canvas.establishDimensions(new BarcodeDimension(200, 15));
bean.generateBarcode(canvas, message); public static InputStream getBarcodeEAN(String message) throws IOException {
canvas.finish(); return BarcodeUtils.getBarcode(new EAN13Bean(), message);
}
ByteArrayInputStream istream = new ByteArrayInputStream(out.toByteArray()); public static InputStream getBarcodeCode39(String message) throws IOException {
return istream; return BarcodeUtils.getBarcode(new Code39Bean(), message);
} }
// public void barcode4j() throws FileNotFoundException, Exception { // public void barcode4j() throws FileNotFoundException, Exception {
// long start = new Date().getTime(); // long start = new Date().getTime();
// //
......
...@@ -29,6 +29,7 @@ import fi.codecrew.moya.rest.pojo.userinfo.v1.EventUserRestPojo; ...@@ -29,6 +29,7 @@ import fi.codecrew.moya.rest.pojo.userinfo.v1.EventUserRestPojo;
import fi.codecrew.moya.rest.pojo.userinfo.v1.PrintedCardRestPojo; import fi.codecrew.moya.rest.pojo.userinfo.v1.PrintedCardRestPojo;
import fi.codecrew.moya.rest.pojo.userinfo.v1.SimpleEventuserRoot; import fi.codecrew.moya.rest.pojo.userinfo.v1.SimpleEventuserRoot;
import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationPlacePojo; import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationPlacePojo;
import fi.codecrew.moya.rest.pojo.util.v1.ErrorRoot;
public class PojoUtils { public class PojoUtils {
public static EventUserRestPojo initEventUserRestPojo(EventUser user) public static EventUserRestPojo initEventUserRestPojo(EventUser user)
...@@ -310,4 +311,11 @@ public class PojoUtils { ...@@ -310,4 +311,11 @@ public class PojoUtils {
} }
return ur; return ur;
} }
public static ErrorRoot initErrorPojo(String errorMessage) {
ErrorRoot errorRoot = new ErrorRoot();
errorRoot.setError(errorMessage);
return errorRoot;
}
} }
...@@ -18,28 +18,26 @@ ...@@ -18,28 +18,26 @@
*/ */
package fi.codecrew.moya.rest; package fi.codecrew.moya.rest;
import java.io.IOException;
import java.security.Principal; import java.security.Principal;
import java.util.Collection;
import java.util.List; import java.util.List;
import javax.ejb.EJB; import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.print.attribute.standard.Media;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes; import javax.servlet.http.Part;
import javax.ws.rs.DefaultValue; import javax.ws.rs.*;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context; import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status;
import fi.codecrew.moya.model.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -55,10 +53,6 @@ import fi.codecrew.moya.beans.PlaceGroupBeanLocal; ...@@ -55,10 +53,6 @@ import fi.codecrew.moya.beans.PlaceGroupBeanLocal;
import fi.codecrew.moya.beans.ReaderBeanLocal; import fi.codecrew.moya.beans.ReaderBeanLocal;
import fi.codecrew.moya.beans.TicketBeanLocal; import fi.codecrew.moya.beans.TicketBeanLocal;
import fi.codecrew.moya.beans.UserBeanLocal; import fi.codecrew.moya.beans.UserBeanLocal;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.Place;
import fi.codecrew.moya.model.ReaderEvent;
import fi.codecrew.moya.rest.pojo.userinfo.v1.EventUserRestPojo; import fi.codecrew.moya.rest.pojo.userinfo.v1.EventUserRestPojo;
import fi.codecrew.moya.rest.pojo.userinfo.v1.PrintedCardRestPojo; import fi.codecrew.moya.rest.pojo.userinfo.v1.PrintedCardRestPojo;
import fi.codecrew.moya.rest.pojo.userinfo.v1.SimpleEventuserRoot; import fi.codecrew.moya.rest.pojo.userinfo.v1.SimpleEventuserRoot;
...@@ -67,12 +61,13 @@ import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationRoot; ...@@ -67,12 +61,13 @@ import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationRoot;
import fi.codecrew.moya.util.UserSearchQuery; import fi.codecrew.moya.util.UserSearchQuery;
import fi.codecrew.moya.utilities.SearchQuery.QuerySortOrder; import fi.codecrew.moya.utilities.SearchQuery.QuerySortOrder;
import fi.codecrew.moya.utilities.SearchResult; import fi.codecrew.moya.utilities.SearchResult;
import sun.security.provider.certpath.OCSPResponse;
@RequestScoped @RequestScoped
@Path("/user") @Path("/user")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" }) @Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" })
@Api("/user") @Api(value = "/user", description = "Administer users")
public class UserRestView { public class UserRestView {
@EJB @EJB
...@@ -103,6 +98,7 @@ public class UserRestView { ...@@ -103,6 +98,7 @@ public class UserRestView {
@POST @POST
@Path("/giveplace/{placeId}") @Path("/giveplace/{placeId}")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@ApiOperation(value = "Set place status to give/ungive", response = UserReservationPlacePojo.class)
public Response setPlacesGivenStatus( public Response setPlacesGivenStatus(
@PathParam("placeId") Integer id, @PathParam("placeId") Integer id,
@FormParam("action") String status) { @FormParam("action") String status) {
...@@ -144,7 +140,9 @@ public class UserRestView { ...@@ -144,7 +140,9 @@ public class UserRestView {
@GET @GET
@Path("/reservationswithcode/{code}") @Path("/reservationswithcode/{code}")
@ApiOperation(value = "Get places with code", response = UserReservationRoot.class)
public Response getPlacesWithCode(@PathParam("code") String code) { public Response getPlacesWithCode(@PathParam("code") String code) {
try {
EventUser curruser = permbean.getCurrentUser(); EventUser curruser = permbean.getCurrentUser();
ReaderEvent revent = readerbean.checkCode("restapi: " + curruser.getLogin(), code); ReaderEvent revent = readerbean.checkCode("restapi: " + curruser.getLogin(), code);
...@@ -164,10 +162,16 @@ public class UserRestView { ...@@ -164,10 +162,16 @@ public class UserRestView {
} }
return Response.status(Status.NOT_FOUND).build(); return Response.status(Status.NOT_FOUND).build();
} catch (Exception e) {
logger.error("Getting places failed", e);
return Response.serverError().build();
}
} }
@GET @GET
@Path("/{userid}/reservations") @Path("/{userid}/reservations")
@ApiOperation(value = "Get user's reservations", response = UserReservationRoot.class)
public Response usersPlaces(@PathParam("userid") Integer userid) { public Response usersPlaces(@PathParam("userid") Integer userid) {
EventUser eu = userbean.findByUserId(userid, false); EventUser eu = userbean.findByUserId(userid, false);
if (eu != null) { if (eu != null) {
...@@ -188,6 +192,7 @@ public class UserRestView { ...@@ -188,6 +192,7 @@ public class UserRestView {
@Path("/auth") @Path("/auth")
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@ApiOperation(value = "Authenticate", response = EventUserRestPojo.class)
public Response auth( public Response auth(
@FormParam("username") String username, @FormParam("username") String username,
@FormParam("password") String password) { @FormParam("password") String password) {
...@@ -229,9 +234,16 @@ public class UserRestView { ...@@ -229,9 +234,16 @@ public class UserRestView {
@QueryParam("search") String search @QueryParam("search") String search
) { ) {
try {
UserSearchQuery q = new UserSearchQuery(page, pagesize, null, search, QuerySortOrder.UNSORTED); UserSearchQuery q = new UserSearchQuery(page, pagesize, null, search, QuerySortOrder.UNSORTED);
SearchResult<EventUser> users = userbean.getThisEventsUsers(q); SearchResult<EventUser> users = userbean.getThisEventsUsers(q);
return PojoUtils.parseEventusers(users.getResults()); return PojoUtils.parseEventusers(users.getResults());
} catch (Exception e) {
logger.error("Getting EventUsers failed", e);
throw e;
}
} }
@GET @GET
...@@ -256,4 +268,114 @@ public class UserRestView { ...@@ -256,4 +268,114 @@ public class UserRestView {
else else
return new EventUserRestPojo(); return new EventUserRestPojo();
} }
@POST
@Path("/create")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@ApiOperation(value = "Create user", response = EventUserRestPojo.class)
public EventUserRestPojo createEventUser() {
return null;
}
@GET
@Path("/")
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Find event user", response = EventUserRestPojo.class)
public Response getEventUser(@QueryParam("email") @ApiParam("Email address") String email,
@QueryParam("login") @ApiParam("Username") String userName) {
try {
// If username not given, try to find username by email
if (userName == null || userName.isEmpty()) {
userName = userbean.findUsernameByEmailUsername(email);
}
// Get the user
EventUser eventUser = userbean.findEventuserByLogin(userName);
if (eventUser == null) {
return Response.status(Status.NOT_FOUND).build();
}
// Return the EventUser
return Response.ok(PojoUtils.initEventUserRestPojo(eventUser)).build();
} catch (Exception e) {
logger.error("Finding event user failed", e);
return Response.serverError().build();
}
}
@POST
@Path("/{userid}/check-password")
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Check user password", response = EventUserRestPojo.class)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response checkPassword(@PathParam("userid") @ApiParam("User ID") Integer userId,
@FormParam("password") @ApiParam("Password") String password) {
try {
EventUser user = userbean.findByUserId(userId, true);
if (user == null) {
return Response.status(Status.NOT_FOUND).build();
}
//boolean passwordOk = user.checkPassword(password);
boolean passwordOk = userbean.checkPassword(user, password);
if (passwordOk) {
return Response.ok(PojoUtils.initEventUserRestPojo(user), MediaType.APPLICATION_JSON_TYPE).build();
}
return Response.status(Status.UNAUTHORIZED).entity(PojoUtils.initErrorPojo("Wrong password")).build();
} catch (Exception e) {
logger.error("Checking user authentication failed", e);
return Response.serverError().entity(PojoUtils.initErrorPojo("Checking password failed")).build();
}
}
@POST
@Path("/{userid}/reset-password")
@Produces({ MediaType.APPLICATION_JSON })
@ApiOperation(value = "Reset user password", response = EventUserRestPojo.class)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response resetPassword(@PathParam("userid") @ApiParam("User ID") Integer userId,
@FormParam("password") @ApiParam("New password") String password) {
try {
EventUser eventUser = userbean.findByUserId(userId, true);
User user = eventUser.getUser();
userbean.resetPassword(user, password);
return Response.ok(PojoUtils.initEventUserRestPojo(eventUser)).build();
} catch (Exception e) {
logger.error("Checking user authentication failed", e);
return Response.serverError().entity(PojoUtils.initErrorPojo("Resetting user password failed")).build();
}
}
/**
* Post forma parameter "image" with the image data in it.
* @param request
* @param userId
* @return
* @throws IOException
*/
@PUT
@Path("/{userid}/image")
@ApiOperation(value = "Upload image", response = EventUserRestPojo.class)
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response updateUserImage(@Context HttpServletRequest request,
@PathParam("userid") @ApiParam("User ID") Integer userId) throws IOException {
try {
Part imagePart = request.getPart("image");
EventUser eventUser = userbean.findByUserId(userId, true);
UserImage userImage = userbean.uploadImage(eventUser, imagePart.getContentType(),
imagePart.getInputStream(), imagePart.getSubmittedFileName(), null);
return Response.ok(PojoUtils.initEventUserRestPojo(eventUser)).build();
} catch (ServletException e) {
logger.error("Updating user image failed", e);
return Response.serverError().entity(PojoUtils.initErrorPojo("Updating user image failed")).build();
}
}
} }
...@@ -23,7 +23,7 @@ public class SwaggerJaxrsConfig extends HttpServlet { ...@@ -23,7 +23,7 @@ public class SwaggerJaxrsConfig extends HttpServlet {
// TODO: Make API url configurable or invent something smart to overcome // TODO: Make API url configurable or invent something smart to overcome
// the need of base url. // the need of base url.
private static final String BASE_URL = "http://localhost:49080/MoyaWeb"; private static final String BASE_URL = "http://localhost:8080/MoyaWeb";
private static final String API_RESOURCE_PACKAGE = "fi.codecrew.moya.rest"; private static final String API_RESOURCE_PACKAGE = "fi.codecrew.moya.rest";
@Override @Override
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!