diff --git a/pom.xml b/pom.xml
index 1dde8b56b..60be53522 100644
--- a/pom.xml
+++ b/pom.xml
@@ -69,6 +69,11 @@
org.springframework.security
spring-security-taglibs
+
+ org.springframework.boot
+ spring-boot-starter-security
+ 2.4.4
+
diff --git a/src/main/java/org/springframework/cheapy/configuration/ExceptionHandlerConfiguration.java b/src/main/java/org/springframework/cheapy/configuration/ExceptionHandlerConfiguration.java
new file mode 100644
index 000000000..e578e2a7e
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/configuration/ExceptionHandlerConfiguration.java
@@ -0,0 +1,28 @@
+package org.springframework.cheapy.configuration;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * This advice is necessary because MockMvc is not a real servlet environment, therefore it does not redirect error
+ * responses to [ErrorController], which produces validation response. So we need to fake it in tests.
+ * It's not ideal, but at least we can use classic MockMvc tests for testing error response + document it.
+ */
+@ControllerAdvice
+public class ExceptionHandlerConfiguration
+{
+ @Autowired
+ private BasicErrorController errorController;
+ // add any exceptions/validations/binding problems
+
+ @ExceptionHandler(Exception.class)
+ public String defaultErrorHandler(HttpServletRequest request, Exception ex) {
+ request.setAttribute("javax.servlet.error.request_uri", request.getPathInfo());
+ request.setAttribute("javax.servlet.error.status_code", 400);
+ request.setAttribute("exeption", ex);
+ return "exception";
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java
new file mode 100644
index 000000000..46e1b8600
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/configuration/SecurityConfiguration.java
@@ -0,0 +1,72 @@
+
+package org.springframework.cheapy.configuration;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.HttpMethod;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ * @author japarejo
+ */
+@Configuration
+@EnableWebSecurity
+public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
+
+ @Autowired
+ DataSource dataSource;
+
+
+ @Override
+ protected void configure(final HttpSecurity http) throws Exception {
+
+ http.authorizeRequests().antMatchers("/resources/**", "/webjars/**", "/h2-console/**").permitAll()
+ .antMatchers(HttpMethod.GET, "/", "/oups").permitAll()
+ .antMatchers("/users/new").permitAll()
+ .antMatchers("/usuarios/new").permitAll()
+ .antMatchers("/admin/**").hasAnyAuthority("admin")
+ .antMatchers("/owners/**").hasAnyAuthority("owner", "admin")
+ .antMatchers("/vets/**").authenticated().anyRequest().denyAll()
+ .and().formLogin()
+ /* .loginPage("/login") */
+ .failureUrl("/login-error").and().logout().logoutSuccessUrl("/");
+
+ // Configuración para que funcione la consola de administración
+ // de la BD H2 (deshabilitar las cabeceras de protección contra
+ // ataques de tipo csrf y habilitar los framesets si su contenido
+ // se sirve desde esta misma página.
+ http.csrf().ignoringAntMatchers("/h2-console/**");
+ http.headers().frameOptions().sameOrigin();
+ }
+
+ @Override
+
+ public void configure(final AuthenticationManagerBuilder auth) throws Exception {
+ auth.jdbcAuthentication().dataSource(this.dataSource)
+ //[login de admin,owner y vet] .usersByUsernameQuery("select username,password,enabled " + "from users " + "where username = ?")
+ .usersByUsernameQuery("select nombre_usuario,contra,enabled from usuarios where nombre_usuario=?").authoritiesByUsernameQuery("select username, authority " + "from authorities " + "where username = ?") //[login de tallerespaco]
+ .passwordEncoder(this.passwordEncoder());
+
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ PasswordEncoder encoder = NoOpPasswordEncoder.getInstance();
+ return encoder;
+ }
+
+}
diff --git a/src/main/java/org/springframework/cheapy/model/Client.java b/src/main/java/org/springframework/cheapy/model/Client.java
index 06268c32a..37ba216fa 100644
--- a/src/main/java/org/springframework/cheapy/model/Client.java
+++ b/src/main/java/org/springframework/cheapy/model/Client.java
@@ -1,94 +1,93 @@
-package org.springframework.cheapy.model;
-
-import java.util.Set;
-
-import javax.persistence.Entity;
-import javax.persistence.OneToMany;
-import javax.persistence.Table;
-import javax.validation.constraints.Digits;
-import javax.validation.constraints.NotEmpty;
-
-@Entity
-@Table(name = "clients")
-public class Client extends User {
-
- @NotEmpty
- private String address;
-
- @NotEmpty
- private String timetable;
-
- @NotEmpty
- @Digits(fraction = 0, integer = 10)
- private String telephone;
-
- @NotEmpty
- private String description;
-
- @NotEmpty
- private String code;
-
- @NotEmpty
- private String food;
-
- @OneToMany
- private Set foodOffers;
-
- @OneToMany
- private Set nuOffers;
-
- @OneToMany
- private Set speedOffers;
-
- @OneToMany
- private Set timeOffers;
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- public String getTimetable() {
- return timetable;
- }
-
- public void setTimetable(String timetable) {
- this.timetable = timetable;
- }
-
- public String getTelephone() {
- return telephone;
- }
-
- public void setTelephone(String telephone) {
- this.telephone = telephone;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public String getCode() {
- return code;
- }
-
- public void setCode(String code) {
- this.code = code;
- }
-
- public String getFood() {
- return food;
- }
-
- public void setFood(String food) {
- this.food = food;
- }
-
+package org.springframework.cheapy.model;
+
+import java.util.Set;
+
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+import javax.validation.constraints.Digits;
+import javax.validation.constraints.NotEmpty;
+
+@Entity
+@Table(name = "clients")
+public class Client extends User {
+
+ @NotEmpty
+ private String address;
+
+ @NotEmpty
+ private String timetable;
+
+ @NotEmpty
+ @Digits(fraction = 0, integer = 10)
+ private String telephone;
+
+ @NotEmpty
+ private String description;
+
+ @NotEmpty
+ private String code;
+
+ @NotEmpty
+ private String food;
+
+ @OneToMany
+ private Set foodOffers;
+
+ @OneToMany
+ private Set nuOffers;
+
+ @OneToMany
+ private Set speedOffers;
+
+ @OneToMany
+ private Set timeOffers;
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public String getTimetable() {
+ return timetable;
+ }
+
+ public void setTimetable(String timetable) {
+ this.timetable = timetable;
+ }
+
+ public String getTelephone() {
+ return telephone;
+ }
+
+ public void setTelephone(String telephone) {
+ this.telephone = telephone;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getCode() {
+ return code;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getFood() {
+ return food;
+ }
+
+ public void setFood(String food) {
+ this.food = food;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/springframework/cheapy/model/User.java b/src/main/java/org/springframework/cheapy/model/User.java
index 9420b0deb..a0db78bf9 100644
--- a/src/main/java/org/springframework/cheapy/model/User.java
+++ b/src/main/java/org/springframework/cheapy/model/User.java
@@ -1,58 +1,57 @@
-package org.springframework.cheapy.model;
-
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import javax.persistence.OneToOne;
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotBlank;
-
-
-@MappedSuperclass
-public class User extends BaseEntity {
-
- @NotBlank
- String username;
-
- @NotBlank
- String password;
-
- @Email
- @NotBlank
- String email;
-
- @OneToOne
- Authorities authority;
-
- public String getUsername() {
- return username;
- }
-
- public void setUsername(String username) {
- this.username = username;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
-
- public Authorities getAuthority() {
- return authority;
- }
-
- public void setAuthority(Authorities authority) {
- this.authority = authority;
- }
-
-}
+package org.springframework.cheapy.model;
+
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.OneToOne;
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+
+
+@MappedSuperclass
+public class User extends BaseEntity {
+
+ @NotBlank
+ String username;
+
+ @NotBlank
+ String password;
+
+ @Email
+ @NotBlank
+ String email;
+
+ @OneToOne
+ Authorities authority;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public Authorities getAuthority() {
+ return authority;
+ }
+
+ public void setAuthority(Authorities authority) {
+ this.authority = authority;
+ }
+}
diff --git a/src/main/java/org/springframework/cheapy/repository/AuthoritiesRepository.java b/src/main/java/org/springframework/cheapy/repository/AuthoritiesRepository.java
new file mode 100644
index 000000000..0a0647e96
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/repository/AuthoritiesRepository.java
@@ -0,0 +1,13 @@
+package org.springframework.cheapy.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.cheapy.model.Authorities;
+import org.springframework.cheapy.model.User;
+
+
+
+public interface AuthoritiesRepository extends CrudRepository{
+
+ Authorities findByUser(User user);
+
+}
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..a109afcb6
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/repository/UserRepository.java
@@ -0,0 +1,11 @@
+
+package org.springframework.cheapy.repository;
+
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.cheapy.model.User;
+
+public interface UserRepository extends CrudRepository {
+
+ User findByUsername(String currentPrincipalName);
+
+}
diff --git a/src/main/java/org/springframework/cheapy/service/AuthoritiesService.java b/src/main/java/org/springframework/cheapy/service/AuthoritiesService.java
new file mode 100644
index 000000000..092a08ad5
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/service/AuthoritiesService.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cheapy.service;
+
+
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.cheapy.model.Authorities;
+import org.springframework.cheapy.model.User;
+import org.springframework.cheapy.repository.AuthoritiesRepository;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Mostly used as a facade for all Petclinic controllers Also a placeholder
+ * for @Transactional and @Cacheable annotations
+ *
+ * @author Michael Isvy
+ */
+@Service
+public class AuthoritiesService {
+
+ private AuthoritiesRepository authoritiesRepository;
+ private UserService userService;
+
+ @Autowired
+ public AuthoritiesService(AuthoritiesRepository authoritiesRepository,UserService userService) {
+ this.authoritiesRepository = authoritiesRepository;
+ this.userService = userService;
+ }
+
+ @Transactional
+ public Authorities findAuthoritiyByUser(User user) {
+ return this.authoritiesRepository.findByUser(user);
+ }
+
+ @Transactional
+ public void saveAuthorities(Authorities authorities) throws DataAccessException {
+ authoritiesRepository.save(authorities);
+ }
+
+ @Transactional
+ public void saveAuthorities(String username, String role) throws DataAccessException {
+ Authorities authority = new Authorities();
+ Optional user = userService.findUser(username);
+ if(user.isPresent()) {
+ authority.setUser(user.get());
+ authority.setAuthority(role);
+ //user.get().getAuthorities().add(authority);
+ authoritiesRepository.save(authority);
+ }else
+ throw new DataAccessException("User '"+username+"' not found!") {};
+ }
+
+
+}
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..895aae516
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/service/UserService.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cheapy.service;
+
+
+import java.util.Optional;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.cheapy.model.User;
+import org.springframework.cheapy.repository.UserRepository;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+
+/**
+ * Mostly used as a facade for all Petclinic controllers Also a placeholder
+ * for @Transactional and @Cacheable annotations
+ *
+ * @author Michael Isvy
+ */
+
+@Service
+public class UserService {
+
+ private UserRepository userRepository;
+
+ @Autowired
+ public UserService(UserRepository userRepository) {
+ this.userRepository = userRepository;
+ }
+
+ @Transactional
+ public void saveUser(User user) throws DataAccessException {
+ userRepository.save(user);
+ }
+
+ public Optional findUser(String username) {
+ return userRepository.findById(username);
+ }
+
+ @Transactional
+ public User getCurrentUser() throws DataAccessException {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ String currentPrincipalName = authentication.getName(); //Obtiene el nombre del ususario actual
+ return this.userRepository.findByUsername(currentPrincipalName); //Obtiene el usuario con ese nombre
+ }
+}
diff --git a/src/main/java/org/springframework/cheapy/web/UserController.java b/src/main/java/org/springframework/cheapy/web/UserController.java
new file mode 100644
index 000000000..97e921a75
--- /dev/null
+++ b/src/main/java/org/springframework/cheapy/web/UserController.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2002-2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cheapy.web;
+
+import javax.persistence.EntityNotFoundException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cheapy.model.Authorities;
+import org.springframework.cheapy.model.User;
+import org.springframework.cheapy.service.AuthoritiesService;
+import org.springframework.cheapy.service.UserService;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.FieldError;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PostMapping;
+
+/**
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ * @author Michael Isvy
+ */
+@Controller
+public class UserController {
+
+ private UserService userService;
+
+ private AuthoritiesService authoritiesService;
+
+// @Autowired
+// public UserController (UserService userService, AuthoritiesService authoritiesService,
+// ClienteService clienteService, FarmaceuticoService farmaceuticoService, ProveedorService proveedorService) {
+// this.userService = userService;
+// this.authoritiesService = authoritiesService;
+// this.clienteService = clienteService;
+// this.farmaceuticoService = farmaceuticoService;
+// this.proveedorService = proveedorService;
+// }
+//
+// @InitBinder
+// public void setAllowedFields(final WebDataBinder dataBinder) {
+// dataBinder.setDisallowedFields("id");
+// }
+//
+// @GetMapping("users")
+// private String showUserDetails(ModelMap model) {
+// User user = this.userService.getCurrentUser();
+// Authorities authority = this.authoritiesService.findAuthoritiyByUser(user);
+//
+// if(authority.getAuthority().equals("cliente")) {
+// Cliente cliente = this.clienteService.findClienteUser(user);
+// model.addAttribute("cliente", cliente);
+// }else if(authority.getAuthority().equals("proveedor")) {
+// Proveedor proveedor = this.proveedorService.findProveedorUser(user);
+// model.addAttribute("proveedor", proveedor);
+// }else if(authority.getAuthority().equals("farmaceutico")) {
+// Farmaceutico farmaceutico = this.farmaceuticoService.findFarmaceuticoByUser(user);
+// model.addAttribute("farmaceutico", farmaceutico);
+// }
+//
+// log.info("El usuario '" + user.getUsername() + "' ha mostrado su informacion personal");
+// return "users/userDetails";
+// }
+//
+// @GetMapping("/users/new")
+// public String newUser(ModelMap model) {
+// Cliente cliente = new Cliente();
+// model.addAttribute("cliente", cliente);
+// model.addAttribute("dni", new String());
+// return "users/userRegister";
+// }
+//
+// @PostMapping("/users/new")
+// public String creationUser(@ModelAttribute("cliente") Cliente cliente, final BindingResult result, ModelMap model) {
+// if (result.hasErrors()) {
+// return "users/userRegister";
+// } else if(cliente.getUser() == null) {
+// try {
+// cliente = this.clienteService.clienteDni(cliente.getDni());
+// }catch(EntityNotFoundException ex) {
+// result.rejectValue("dni", "clienteNotFound");
+// return "users/userRegister";
+// }
+// cliente.setUser(new User());
+// model.addAttribute("cliente", cliente);
+// return "users/userRegister";
+// }else {
+// this.userService.saveUser(cliente.getUser());
+// this.authoritiesService.saveAuthorities(cliente.getUser().getUsername(), "cliente");
+// this.clienteService.saveCliente(cliente);
+// log.info("El cliente con dni '" + cliente.getDni() + "' se ha registrado como usuario");
+// return "redirect:../";
+// }
+// }
+//
+// @GetMapping("/users/password")
+// public String initChangePassword(ModelMap model) {
+// User currentUser = this.userService.getCurrentUser();
+// UserValidate user = new UserValidate(currentUser.getUsername(), "");
+// model.addAttribute("user", user);
+// return "users/passwordEdit";
+// }
+//
+// @PostMapping("/users/password")
+// public String changePassword(@ModelAttribute("user") UserValidate user, final BindingResult result, ModelMap model) {
+// if(result.hasErrors()) {
+// return "users/passwordEdit";
+// }else {
+// User CurrentUser = this.userService.getCurrentUser();
+// if(CurrentUser.getPassword().equals(user.getPassword()) && user.getNewPassword().equals(user.getValidPassword())) {
+// if(!user.getNewPassword().isEmpty()) {
+// CurrentUser.setPassword(user.getNewPassword());
+// this.userService.saveUser(CurrentUser);
+// log.info("El usuario '" + CurrentUser.getUsername() + "' ha cambiado satisfactoriamente su contraseña");
+// return "redirect:../";
+// }else {
+// FieldError err = new FieldError("PassException", "newPassword", "Introduce una nueva contraseña");
+// result.addError(err);
+// log.warn("El usuario '" + CurrentUser.getUsername() + "' ha tenido un error 'PassException'");
+// return "users/passwordEdit";
+// }
+// }else if(!CurrentUser.getPassword().equals(user.getPassword())){
+// FieldError err = new FieldError("PassException", "password", "Contraseña incorrecta");
+// result.addError(err);
+// log.warn("El usuario '" + CurrentUser.getUsername() + "' ha tenido un error 'PassException'");
+// return "users/passwordEdit";
+// }else {
+// FieldError err = new FieldError("PassException", "newPassword", "Las contraseñas no coinciden");
+// result.addError(err);
+// log.warn("El usuario '" + CurrentUser.getUsername() + "' ha tenido un error 'PassException'");
+// return "users/passwordEdit";
+// }
+// }
+// }
+}
diff --git a/src/main/webapp/WEB-INF/tags/menu.tag b/src/main/webapp/WEB-INF/tags/menu.tag
index 6cda27bee..2d0eeff56 100644
--- a/src/main/webapp/WEB-INF/tags/menu.tag
+++ b/src/main/webapp/WEB-INF/tags/menu.tag
@@ -50,8 +50,6 @@
-
-