diff --git a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java index e2c866bb3..542e41f26 100644 --- a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java +++ b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java @@ -37,7 +37,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers("/users/new").permitAll() .antMatchers("/login/**").anonymous() - .antMatchers("/logout").permitAll() + .antMatchers("/logout").authenticated() .antMatchers("/usuarios/new").permitAll() .antMatchers("/admin/**").hasAnyAuthority("admin") @@ -53,11 +53,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers("/offersCreate").hasAuthority("client") + .antMatchers("/reviews/**").authenticated() .and().formLogin() - .loginPage("/login").permitAll() + .loginPage("/login") .failureUrl("/login?error") - .and().logout().logoutSuccessUrl("/login"); + .and().logout().logoutSuccessUrl("/"); // Configuración para que funcione la consola de administración // de la BD H2 (deshabilitar las cabeceras de protección contra diff --git a/src/main/java/org/springframework/cheapy/model/Review.java b/src/main/java/org/springframework/cheapy/model/Review.java new file mode 100644 index 000000000..b8cf0b6d4 --- /dev/null +++ b/src/main/java/org/springframework/cheapy/model/Review.java @@ -0,0 +1,56 @@ +package org.springframework.cheapy.model; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; +import javax.validation.constraints.NotBlank; + +import org.hibernate.validator.constraints.Range; + +import com.sun.istack.NotNull; + +@Entity +@Table(name = "review") +public class Review extends BaseEntity{ + + private static final long serialVersionUID = 1L; + + @NotBlank(message = "Debe rellenar la valoración de Cheapy") + @Column(length=16777215) + private String opinion; + + @NotNull + @Range(min = 1, max = 5) + private Integer stars; + + @ManyToOne + @JoinColumn(name = "username", referencedColumnName = "username") + private User escritor; + + public User getEscritor() { + return escritor; + } + + public void setEscritor(User escritor) { + this.escritor = escritor; + } + + public String getOpinion() { + return opinion; + } + + public void setOpinion(String opinion) { + this.opinion = opinion; + } + + public Integer getStars() { + return stars; + } + + public void setStars(Integer stars) { + this.stars = stars; + } + +} diff --git a/src/main/java/org/springframework/cheapy/repository/ReviewRepository.java b/src/main/java/org/springframework/cheapy/repository/ReviewRepository.java new file mode 100644 index 000000000..754e2650f --- /dev/null +++ b/src/main/java/org/springframework/cheapy/repository/ReviewRepository.java @@ -0,0 +1,22 @@ +package org.springframework.cheapy.repository; + +import java.util.List; + +import org.springframework.cheapy.model.Review; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.query.Param; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; + +public interface ReviewRepository extends Repository { + + @Query("SELECT r FROM Review r") + @Transactional(readOnly = true) + List findAllReviews(); + + void save(Review review); + + @Query("SELECT r FROM Review r WHERE id =:id") + @Transactional(readOnly = true) + Review findReviewById(@Param("id") Integer id); +} diff --git a/src/main/java/org/springframework/cheapy/repository/UserRepository.java b/src/main/java/org/springframework/cheapy/repository/UserRepository.java new file mode 100644 index 000000000..0c29a7bf6 --- /dev/null +++ b/src/main/java/org/springframework/cheapy/repository/UserRepository.java @@ -0,0 +1,15 @@ + +package org.springframework.cheapy.repository; + +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.CrudRepository; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.model.Usuario; + +public interface UserRepository extends CrudRepository { + + @Query("SELECT u FROM User u WHERE username =:username") + @Transactional(readOnly = true) + User findByUsername(String username); +} diff --git a/src/main/java/org/springframework/cheapy/repository/UsuarioRepository.java b/src/main/java/org/springframework/cheapy/repository/UsuarioRepository.java deleted file mode 100644 index 1bd7c8ee2..000000000 --- a/src/main/java/org/springframework/cheapy/repository/UsuarioRepository.java +++ /dev/null @@ -1,11 +0,0 @@ - -package org.springframework.cheapy.repository; - -import org.springframework.data.repository.CrudRepository; -import org.springframework.cheapy.model.Usuario; - -public interface UsuarioRepository extends CrudRepository { - - //Usuario findByUsername(String currentPrincipalName); - -} diff --git a/src/main/java/org/springframework/cheapy/service/ReviewService.java b/src/main/java/org/springframework/cheapy/service/ReviewService.java new file mode 100644 index 000000000..2b7bc9301 --- /dev/null +++ b/src/main/java/org/springframework/cheapy/service/ReviewService.java @@ -0,0 +1,40 @@ +package org.springframework.cheapy.service; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cheapy.model.Review; +import org.springframework.cheapy.model.StatusOffer; +import org.springframework.cheapy.model.TimeOffer; +import org.springframework.cheapy.repository.ReviewRepository; +import org.springframework.cheapy.repository.TimeOfferRepository; + +import org.springframework.dao.DataAccessException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class ReviewService { + private ReviewRepository reviewRepository; + + @Autowired + public ReviewService(final ReviewRepository reviewRepository) { + this.reviewRepository = reviewRepository; + } + + @Transactional + public Review findReviewById(final int id) { + return this.reviewRepository.findReviewById(id); + } + + @Transactional + public List findAllReviews() { + return this.reviewRepository.findAllReviews(); + } + + @Transactional + public void saveReview(final Review Review) throws DataAccessException { + this.reviewRepository.save(Review); + } + +} diff --git a/src/main/java/org/springframework/cheapy/service/UserService.java b/src/main/java/org/springframework/cheapy/service/UserService.java new file mode 100644 index 000000000..92b896e7f --- /dev/null +++ b/src/main/java/org/springframework/cheapy/service/UserService.java @@ -0,0 +1,29 @@ +package org.springframework.cheapy.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.repository.UserRepository; +import org.springframework.dao.DataAccessException; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +public class UserService { + + private UserRepository userRepository; + + @Autowired + public UserService(final UserRepository userRepository) { + this.userRepository = userRepository; + } + + @Transactional + public User getCurrentUser() throws DataAccessException { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + String username = authentication.getName(); + return this.userRepository.findByUsername(username); + } + +} diff --git a/src/main/java/org/springframework/cheapy/web/ReviewController.java b/src/main/java/org/springframework/cheapy/web/ReviewController.java new file mode 100644 index 000000000..1ac9e93d4 --- /dev/null +++ b/src/main/java/org/springframework/cheapy/web/ReviewController.java @@ -0,0 +1,115 @@ +package org.springframework.cheapy.web; + +import java.util.List; +import java.util.Map; + +import javax.validation.Valid; + +import org.springframework.cheapy.model.Review; +import org.springframework.cheapy.model.User; +import org.springframework.cheapy.service.ReviewService; +import org.springframework.cheapy.service.UserService; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; + +@Controller +public class ReviewController { + + + private static final String VIEWS_REVIEWS_CREATE_OR_UPDATE_FORM = "reviews/createOrUpdateReviewForm"; + private final ReviewService reviewService; + private final UserService userService; + + public ReviewController(final ReviewService reviewService, final UserService userService) { + this.reviewService = reviewService; + this.userService = userService; + } + private boolean checkIdentity(final int reviewId) { + boolean res = false; + User user = this.userService.getCurrentUser(); + Review review = this.reviewService.findReviewById(reviewId); + User reviewsAuthor = review.getEscritor(); + if (user.equals(reviewsAuthor)) { + res = true; + } + return res; + } + @GetMapping("/reviews") + public String processFindForm( Map model) { + + List reviewsLs=this.reviewService.findAllReviews(); + model.put("reviewsLs", reviewsLs); + + return "reviews/reviewsList"; + + } + + @GetMapping("/reviews/new") + public String initCreationForm(Map model) { + Review review = new Review(); + model.put("review", review); + return VIEWS_REVIEWS_CREATE_OR_UPDATE_FORM; + } + + @PostMapping("/reviews/new") + public String processCreationForm(@Valid Review review, BindingResult result) { + if (result.hasErrors()) { + return VIEWS_REVIEWS_CREATE_OR_UPDATE_FORM; + } else { + User escritor = this.userService.getCurrentUser(); + review.setEscritor(escritor); + + this.reviewService.saveReview(review); + return "redirect:/reviews/" + review.getId(); + } + } + + + + @GetMapping("/reviews/{reviewId}") + public String processShowForm(@PathVariable("reviewId") int reviewId, Map model) { + + Review review = this.reviewService.findReviewById(reviewId); + + model.put("review", review); + + + return "reviews/reviewsShow"; + + } + + @GetMapping(value = "/reviews/{reviewId}/edit") + public String updateReview(@PathVariable("reviewId") final int reviewId, final ModelMap model) { + if (!this.checkIdentity(reviewId)) { + return "error"; + } + + Review review = this.reviewService.findReviewById(reviewId); + model.addAttribute("review", review); + return ReviewController.VIEWS_REVIEWS_CREATE_OR_UPDATE_FORM; + } + + @PostMapping(value = "/reviews/{reviewId}/edit") + public String updateReview(@Valid final Review reviewEdit, final BindingResult result, final ModelMap model) { + if (!this.checkIdentity(reviewEdit.getId())) { + return "error"; + } + if (result.hasErrors()) { + model.addAttribute("review", reviewEdit); + return ReviewController.VIEWS_REVIEWS_CREATE_OR_UPDATE_FORM; + + } else { + User escritor = this.userService.getCurrentUser(); + reviewEdit.setEscritor(escritor); + + this.reviewService.saveReview(reviewEdit); + return "redirect:/reviews/" + reviewEdit.getId(); + } + + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c93d5eac7..97ef60ff4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -16,7 +16,7 @@ spring.jpa.properties.javax.persistence.schema-generation.drop-script-source=dro # Internationalization spring.messages.basename=messages/messages - +spring.messages.encoding=UTF-8 # Views spring.mvc.view.prefix: /WEB-INF/jsp/ @@ -33,4 +33,4 @@ logging.level.org.springframework=INFO # logging.level.org.springframework.context.annotation=TRACE # Maximum time static resources should be cached -spring.resources.cache.cachecontrol.max-age=12h \ No newline at end of file +spring.resources.cache.cachecontrol.max-age=12h diff --git a/src/main/resources/messages/messages_es.properties b/src/main/resources/messages/messages_es.properties index dc3680cfd..a4aebbe00 100644 --- a/src/main/resources/messages/messages_es.properties +++ b/src/main/resources/messages/messages_es.properties @@ -37,8 +37,13 @@ nonNumeric=Solo debe contener números duplicateFormSubmission=No se permite el envío de formularios duplicados typeMismatch.date=Fecha inválida typeMismatch.birthDate=Fecha inválida -createFoodOffers= Crear ofertas por plato espec�fico -createNuOffers= Crear ofertas por n�mero de comensales +review= Reseña +reviews= Reseñas +stars= Estrellas +opinion= Opinión +user = Nombre de usuario +createFoodOffers= Crear ofertas por plato específico +createNuOffers= Crear ofertas por número de comensales createSpeedOffers= Crear ofertas por rapidez comiendo createTimeOffers= Crear ofertas por franja horaria init= Inicio del intervalo diff --git a/src/main/webapp/WEB-INF/jsp/offers/myOffersList.jsp b/src/main/webapp/WEB-INF/jsp/offers/myOffersList.jsp index d7332bea6..3292e232e 100644 --- a/src/main/webapp/WEB-INF/jsp/offers/myOffersList.jsp +++ b/src/main/webapp/WEB-INF/jsp/offers/myOffersList.jsp @@ -6,7 +6,7 @@ <%@ taglib prefix="cheapy" tagdir="/WEB-INF/tags" %> - +

No hay ninguna oferta por plato específico activa.

diff --git a/src/main/webapp/WEB-INF/jsp/reviews/createOrUpdateReviewForm.jsp b/src/main/webapp/WEB-INF/jsp/reviews/createOrUpdateReviewForm.jsp new file mode 100644 index 000000000..5c8c53660 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/reviews/createOrUpdateReviewForm.jsp @@ -0,0 +1,32 @@ +<%@ page session="false" trimDirectiveWhitespaces="true" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="cheapy" tagdir="/WEB-INF/tags" %> + + +

+ Nueva Reseña +

+ +
+ + + +
+
+
+ + + + + + + + +
+
+
+
diff --git a/src/main/webapp/WEB-INF/jsp/reviews/reviewsList.jsp b/src/main/webapp/WEB-INF/jsp/reviews/reviewsList.jsp new file mode 100644 index 000000000..f09f9dfd9 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/reviews/reviewsList.jsp @@ -0,0 +1,59 @@ +<%@ page session="false" trimDirectiveWhitespaces="true" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="cheapy" tagdir="/WEB-INF/tags" %> + + + +

+ + + + + + + + + + + + + + + + + + + + + <%-- --%> + + + + + + + + + + + +
+ + + + + + + + + +
+ +
+
+
diff --git a/src/main/webapp/WEB-INF/jsp/reviews/reviewsShow.jsp b/src/main/webapp/WEB-INF/jsp/reviews/reviewsShow.jsp new file mode 100644 index 000000000..e10af0bea --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/reviews/reviewsShow.jsp @@ -0,0 +1,38 @@ +<%@ page session="false" trimDirectiveWhitespaces="true" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="cheapy" tagdir="/WEB-INF/tags" %> +<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> + + + + +

+ + + + + + + + + + + + +
+ +
+ +
+ + + + + Editar opinión + + +
diff --git a/src/main/webapp/WEB-INF/tags/menu.tag b/src/main/webapp/WEB-INF/tags/menu.tag index df3b03161..40f426e7e 100644 --- a/src/main/webapp/WEB-INF/tags/menu.tag +++ b/src/main/webapp/WEB-INF/tags/menu.tag @@ -34,30 +34,30 @@ - - - Mis ofertas - - - - - - - Valóranos - + + + Mis ofertas + - - + + + + Reseñas + + + + Valóranos + + - - - - diff --git a/src/main/webapp/WEB-INF/tags/textAreaField.tag b/src/main/webapp/WEB-INF/tags/textAreaField.tag new file mode 100644 index 000000000..37d94fbde --- /dev/null +++ b/src/main/webapp/WEB-INF/tags/textAreaField.tag @@ -0,0 +1,28 @@ +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> +<%@ attribute name="name" required="true" rtexprvalue="true" + description="Name of corresponding property in bean object" %> +<%@ attribute name="label" required="true" rtexprvalue="true" + description="Label appears in red color if input is considered as invalid after submission" %> +<%@ attribute name="placeholder" required="false" rtexprvalue="true" + description="Example for input field" %> + + + + +
+ + +
+ + + + + + + ${status.errorMessage} + +
+
+