UserRestView.java 13.3 KB
/*
 * Copyright Codecrew Ry
 * 
 * All rights reserved.
 * 
 * This license applies to any software containing a notice placed by the 
 * copyright holder. Such software is herein referred to as the Software. 
 * This license covers modification, distribution and use of the Software. 
 * 
 * Any distribution and use in source and binary forms, with or without 
 * modification is not permitted without explicit written permission from the 
 * copyright owner. 
 * 
 * A non-exclusive royalty-free right is granted to the copyright owner of the 
 * Software to use, modify and distribute all modifications to the Software in 
 * future versions of the Software. 
 * 
 */
package fi.codecrew.moya.rest;

import java.io.IOException;
import java.security.Principal;
import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.print.attribute.standard.Media;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.Response.Status;

import fi.codecrew.moya.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;

import fi.codecrew.moya.beans.CardTemplateBeanLocal;
import fi.codecrew.moya.beans.EventBeanLocal;
import fi.codecrew.moya.beans.PermissionBeanLocal;
import fi.codecrew.moya.beans.PlaceBeanLocal;
import fi.codecrew.moya.beans.PlaceGroupBeanLocal;
import fi.codecrew.moya.beans.ReaderBeanLocal;
import fi.codecrew.moya.beans.TicketBeanLocal;
import fi.codecrew.moya.beans.UserBeanLocal;
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.SimpleEventuserRoot;
import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationPlacePojo;
import fi.codecrew.moya.rest.pojo.userinfo.v1.UserReservationRoot;
import fi.codecrew.moya.util.UserSearchQuery;
import fi.codecrew.moya.utilities.SearchQuery.QuerySortOrder;
import fi.codecrew.moya.utilities.SearchResult;
import sun.security.provider.certpath.OCSPResponse;

@RequestScoped
@Path("/user")
@Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Produces({ MediaType.APPLICATION_JSON + "; charset=UTF-8" })
@Api(value = "/user", description = "Administer users")
public class UserRestView {

	@EJB
	private UserBeanLocal userbean;

	@EJB
	private CardTemplateBeanLocal cardbean;

	@Context
	private HttpServletRequest servletRequest;

	@EJB
	private PermissionBeanLocal permbean;

	private static final Logger logger = LoggerFactory.getLogger(UserRestView.class);

	@EJB
	private PlaceGroupBeanLocal placegroupbean;

	@EJB
	private ReaderBeanLocal readerbean;
	@EJB
	private TicketBeanLocal ticketbean;

	@EJB
	private PlaceBeanLocal placebean;

	@POST
	@Path("/giveplace/{placeId}")
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @ApiOperation(value = "Set place status to give/ungive", response = UserReservationPlacePojo.class)
	public Response setPlacesGivenStatus(
			@PathParam("placeId") Integer id,
			@FormParam("action") String status) {

		Place place = placebean.find(id);
		if (place == null) {
			ResponseBuilder resp = Response.status(Status.BAD_REQUEST);
			resp.entity("Place not found with id: " + id);
			return resp.build();
		}
		GroupMembership gm = place.getPlaceReserver();
		if (gm == null) {
			ResponseBuilder resp = Response.status(Status.BAD_REQUEST);
			resp.entity("No group membership for place: " + id);
			return resp.build();
		}

		ResponseBuilder resp = Response.ok();

		switch (status) {
		case "give":
			gm = placegroupbean.markGroupMembershipEntered(gm);
			break;
		case "ungive":
			gm = placegroupbean.markGroupMembershipNotEntered(gm);
			break;
		default:
			resp = Response.status(Status.BAD_REQUEST);
			resp.status(Status.BAD_REQUEST);
			resp.entity("Unknown status" + status + " possible values: 'give' and 'ungive'");
			return resp.build();

		}

		resp.entity(PojoUtils.initUserReservationPlace(gm));
		return resp.build();

	}

	@GET
	@Path("/reservationswithcode/{code}")
    @ApiOperation(value = "Get places with code", response = UserReservationRoot.class)
	public Response getPlacesWithCode(@PathParam("code") String code) {
        try {

            EventUser curruser = permbean.getCurrentUser();
            ReaderEvent revent = readerbean.checkCode("restapi: " + curruser.getLogin(), code);

            if (revent != null && revent.getUser() != null) {
                EventUser eu = revent.getUser();
                List<GroupMembership> gms = ticketbean.findMembershipPrintlistForUser(eu);

                UserReservationRoot ret = new UserReservationRoot();
                ret.setUser(PojoUtils.initEventUserRestPojo(eu));

                for (GroupMembership g : gms) {

                    ret.getReservations().add(PojoUtils.initUserReservationPlace(g));
                }
                return Response.ok(ret).build();
            }
            return Response.status(Status.NOT_FOUND).build();

        } catch (Exception e) {
            logger.error("Getting places failed", e);
            return Response.serverError().build();
        }

	}

	@GET
	@Path("/{userid}/reservations")
    @ApiOperation(value = "Get user's reservations", response = UserReservationRoot.class)
	public Response usersPlaces(@PathParam("userid") Integer userid) {
		EventUser eu = userbean.findByUserId(userid, false);
		if (eu != null) {

			List<GroupMembership> gms = ticketbean.findMembershipPrintlistForUser(eu);

			UserReservationRoot ret = new UserReservationRoot();
			ret.setUser(PojoUtils.initEventUserRestPojo(eu));
			for (GroupMembership g : gms) {
				ret.getReservations().add(PojoUtils.initUserReservationPlace(g));
			}
			return Response.ok(ret).build();
		}
		return Response.status(Status.NOT_FOUND).build();
	}

	@POST
	@Path("/auth")
	@Produces({ MediaType.APPLICATION_JSON })
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @ApiOperation(value = "Authenticate", response = EventUserRestPojo.class)
	public Response auth(
			@FormParam("username") String username,
			@FormParam("password") String password) {
		logger.info("Tried to login with rest {} , {}", username, password);
		boolean success = true;
		try {

			Principal principal = servletRequest.getUserPrincipal();
			if (principal != null) {
				logger.info("Current username {}", principal.getName());

				if (principal.getName() != null && !principal.getName().equals(username)) {
					logger.info("Trying to logout from user {}", principal.getName());
					servletRequest.logout();
				}
			}
			if (principal == null || principal.getName() == null || !principal.getName().equals(username)) {

				servletRequest.getSession(true);
				servletRequest.login(username, password);
			}
		} catch (ServletException e) {
			success = false;
		}
		ResponseBuilder ret = null;
		if (success)
			ret = Response.ok(PojoUtils.initEventUserRestPojo(permbean.getCurrentUser()));
		else
			ret = Response.status(Status.FORBIDDEN);
		return ret.build();
	}

	@GET
	@Path("/eventusers")
	@ApiOperation(value = "Get EventUsers", response = SimpleEventuserRoot.class)
	public SimpleEventuserRoot getEventUsers(
			@DefaultValue("0") @QueryParam("pagesize") Integer pagesize,
			@DefaultValue("0") @QueryParam("page") Integer page,
			@QueryParam("search") String search
			) {

        try {

            UserSearchQuery q = new UserSearchQuery(page, pagesize, null, search, QuerySortOrder.UNSORTED);
            SearchResult<EventUser> users = userbean.getThisEventsUsers(q);
            return PojoUtils.parseEventusers(users.getResults());

        } catch (Exception e) {
            logger.error("Getting EventUsers failed", e);
            throw e;
        }
	}

	@GET
	@Path("/card/{eventuserId}")
	@ApiOperation(value = "Get PrintedCard for EventUser", response = PrintedCardRestPojo.class)
	public PrintedCardRestPojo getUsersCard(
			@ApiParam("EventUser entity ID") @PathParam("eventuserId") Integer eventuserid) {
		EventUser user = userbean.findByEventUserId(eventuserid);
		return PojoUtils.initPrintedCardRestPojo(cardbean.checkPrintedCard(user));

	}

	@GET
	@Path("/eventuser/{cardauthcode}")
	@ApiOperation(value = "Get EventUser by cardAuthCode", response = EventUserRestPojo.class)
	public EventUserRestPojo getEventUser(
			@ApiParam("Card authentication code") @PathParam("cardauthcode") String code) {

		EventUser user = userbean.getUserByAuthcode(code);
		if (user != null)
			return PojoUtils.initEventUserRestPojo(user);
		else
			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();
        }
    }

}