/* * This file is part of anycook. The new internet cookbook * Copyright (C) 2014 Jan Graßegger * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see [http://www.gnu.org/licenses/]. */ package de.anycook.api; import de.anycook.api.util.MediaType; import de.anycook.api.views.PrivateView; import de.anycook.api.views.PublicView; import de.anycook.conf.Configuration; import de.anycook.db.mysql.DBUser; import de.anycook.discussion.Discussion; import de.anycook.recipe.Recipe; import de.anycook.recipe.Recipes; import de.anycook.recommendation.Recommendation; import de.anycook.session.Session; import de.anycook.social.facebook.FacebookHandler; import de.anycook.user.User; import de.anycook.utils.enumerations.ImageType; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.io.IOException; import java.lang.annotation.Annotation; import java.net.URI; import java.net.URISyntaxException; import java.sql.SQLException; import java.util.List; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; import javax.ws.rs.DefaultValue; import javax.ws.rs.FormParam; 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.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.GenericEntity; import javax.ws.rs.core.Response; @Path("/user") public class UserApi { private final Logger logger = LogManager.getLogger(getClass()); @Context Session session; @GET @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public Response getUsers(@QueryParam("detailed") boolean isDetailed) { try { Annotation[] annotations = isDetailed ? new Annotation[]{PublicView.Factory.get()} : new Annotation[]{}; return Response.ok().entity(new GenericEntity<List<User>>(User.getAll()) { }, annotations).build(); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @POST public void newUser(@FormParam("mail") String mail, @FormParam("username") String username, @FormParam("password") String password) { try { User.newUser(mail, password, username); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @GET @Path("mail") @Produces(MediaType.APPLICATION_JSON) public boolean checkMail(@QueryParam("mail") String mail) { try { return User.checkMail(mail); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @GET @Path("name") @Produces(MediaType.APPLICATION_JSON) public boolean checkUsername(@QueryParam("username") String username) { try { return User.checkUsername(username); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } /** * returns the number of users */ @GET @Path("number") @Produces(MediaType.APPLICATION_JSON) public int getNum() { try { return User.getTotal(); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @GET @Path("recommendations") @Produces(MediaType.APPLICATION_JSON) public List<Recipe> getRecommendations() { int userId = session.getUser().getId(); try { return Recommendation.recommend(userId, 20); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @GET @Path("{userId}") @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public Response getUser(@PathParam("userId") int userId, @QueryParam("adminDetails") boolean isAdminDetails) { try { if (isAdminDetails) { logger.debug("showing admin details"); session.checkAdminLogin(); return Response.ok() .entity(User.init(userId), new Annotation[]{PrivateView.Factory.get()}) .build(); } return Response.ok() .entity(User.init(userId), new Annotation[]{PublicView.Factory.get()}).build(); } catch (IOException | SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (DBUser.UserNotFoundException e) { throw new WebApplicationException(Response.Status.NOT_FOUND); } } @PUT @Path("{userId}") @Consumes(javax.ws.rs.core.MediaType.APPLICATION_JSON) public void updateUser(@PathParam("userId") int userId, User user) { try { session.checkAdminLogin(); try (DBUser dbUser = new DBUser()) { User old = dbUser.getUser(userId); if (old.getLevel() != user.getLevel()) { dbUser.setUserLevel(userId, user.getLevel()); logger.info(String.format("changed user level for user %d to %d", userId, user.getLevel())); } } } catch (SQLException | IOException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (DBUser.UserNotFoundException e) { logger.warn(e, e); throw new WebApplicationException(Response.Status.BAD_REQUEST); } } @PUT @Path("{userId}/follow") public Response follow(@PathParam("userId") int userId) { try { User user = session.getUser(); user.follow(userId); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } return Response.ok().build(); } @DELETE @Path("{userId}/follow") public Response unfollow(@PathParam("userId") int userId) { try { User user = session.getUser(); user.unFollow(userId); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } return Response.ok().build(); } @GET @Path("{userId}/image") @Produces("image/png") public Response getImage(@PathParam("userId") int userId, @DefaultValue("small") @QueryParam("type") String typeString) { ImageType type = ImageType.valueOf(typeString.toUpperCase()); try { URI uri = new URI(User.getUserImage(userId, type)); return Response.temporaryRedirect(uri).build(); } catch (URISyntaxException e) { logger.warn(e); throw new WebApplicationException(400); } catch (IOException | SQLException e) { logger.error(e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (DBUser.UserNotFoundException e) { logger.warn(e, e); throw new WebApplicationException(Response.Status.NOT_FOUND); } } @GET @Path("{userId}/schmeckt") @Produces(MediaType.APPLICATION_JSON + ";charset=UTF-8") public List<Recipe> schmeckt(@PathParam("userId") int userId) { try { int loginId = session.checkLoginWithoutException() ? session.getUser().getId() : -1; return Recipes.getTastingRecipesForUser(userId, loginId); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @GET @Path("{userId}/discussionnum") @Produces(MediaType.APPLICATION_JSON) public int getDiscussionNum(@PathParam("userId") int userId) { try { return Discussion.getDiscussionNumForUser(userId); } catch (SQLException e) { logger.error(e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } } @POST @Path("{userId}/resendActivationId") @Produces(MediaType.APPLICATION_JSON) public void resendActivationRequest(@PathParam("userId") int userId) { session.checkAdminLogin(); try { User.resendActivationId(userId); } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } catch (DBUser.UserNotFoundException e) { logger.warn(e, e); throw new WebApplicationException(Response.Status.NOT_FOUND); } } @POST @Path("facebook") @Produces(MediaType.TEXT_HTML) public Response registerFacebookUser(@FormParam("signed_request") String requestString) { if (requestString == null) { throw new WebApplicationException(Response.Status.BAD_REQUEST); } FacebookHandler.FacebookRequest request; try { request = FacebookHandler.decode(requestString); } catch (IOException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } String mail = request.registration.get("email"); String name = request.registration.get("name"); String responseText; try { if (User.checkMail(mail) || User.checkUsername(name)) { logger.info("user already exists"); responseText = "exists"; } else { if (User.newFacebookUser(mail, name, Long.parseLong(request.user_id))) { responseText = "success"; } else { responseText = "error"; logger.info("error creating new fb user"); } } } catch (SQLException e) { logger.error(e, e); throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR); } String uri = String.format("http://%s/#fbregistration?response=%s", Configuration.getInstance().getRedirectDomain(), responseText); String content = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n<HTML>" + "<HEAD><META HTTP-EQUIV=\"REFRESH\" content=\"0; url=" + uri + "\"></HEAD>\n<BODY></BODY></HTML>"; return Response.ok(content).build(); } }