поменяла классы для юзера, добавила дто для регистрации, обновила сервис (для проверки юзернейма (логина блин, юзернейма аааааааааа))
This commit is contained in:
parent
2173e08c60
commit
6f5fe27b71
Binary file not shown.
@ -0,0 +1,63 @@
|
|||||||
|
package com.example.backend.core.security;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
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.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer.FrameOptionsConfig;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
import com.example.backend.core.configurations.Constants;
|
||||||
|
import com.example.backend.users.api.UserSignupController;
|
||||||
|
import com.example.backend.users.model.UserRole;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
public class SecurityConfiguration {
|
||||||
|
@Bean
|
||||||
|
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
|
||||||
|
httpSecurity.headers(headers -> headers.frameOptions(FrameOptionsConfig::sameOrigin));
|
||||||
|
httpSecurity.csrf(AbstractHttpConfigurer::disable);
|
||||||
|
httpSecurity.cors(Customizer.withDefaults());
|
||||||
|
|
||||||
|
httpSecurity.authorizeHttpRequests(requests -> requests
|
||||||
|
.requestMatchers("/css/**", "/webjars/**", "/*.svg")
|
||||||
|
.permitAll());
|
||||||
|
|
||||||
|
httpSecurity.authorizeHttpRequests(requests -> requests
|
||||||
|
.requestMatchers(Constants.ADMIN_PREFIX + "/**").hasRole(UserRole.ADMIN.name())
|
||||||
|
.requestMatchers("/h2-console/**").hasRole(UserRole.ADMIN.name())
|
||||||
|
.requestMatchers(UserSignupController.URL).anonymous()
|
||||||
|
.requestMatchers(Constants.LOGIN_URL).anonymous()
|
||||||
|
.anyRequest().authenticated());
|
||||||
|
|
||||||
|
httpSecurity.formLogin(formLogin -> formLogin
|
||||||
|
.loginPage(Constants.LOGIN_URL));
|
||||||
|
|
||||||
|
httpSecurity.rememberMe(rememberMe -> rememberMe.key("uniqueAndSecret"));
|
||||||
|
|
||||||
|
httpSecurity.logout(logout -> logout
|
||||||
|
.deleteCookies("JSESSIONID"));
|
||||||
|
|
||||||
|
return httpSecurity.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
DaoAuthenticationProvider authenticationProvider(UserDetailsService userDetailsService) {
|
||||||
|
final DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||||
|
authProvider.setUserDetailsService(userDetailsService);
|
||||||
|
authProvider.setPasswordEncoder(passwordEncoder());
|
||||||
|
return authProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.example.backend.core.security;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import com.example.backend.users.model.UserEntity;
|
||||||
|
|
||||||
|
public class UserPrincipal implements UserDetails {
|
||||||
|
private final long id;
|
||||||
|
private final String username;
|
||||||
|
private final String password;
|
||||||
|
private final Set<? extends GrantedAuthority> roles;
|
||||||
|
private final boolean active;
|
||||||
|
|
||||||
|
public UserPrincipal(UserEntity user) {
|
||||||
|
this.id = user.getId();
|
||||||
|
this.username = user.getLogin();
|
||||||
|
this.password = user.getPassword();
|
||||||
|
this.roles = Set.of(user.getRole());
|
||||||
|
this.active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return isEnabled();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.example.backend.users.api;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.modelmapper.ModelMapper;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import com.example.backend.core.configurations.Constants;
|
||||||
|
import com.example.backend.users.model.UserEntity;
|
||||||
|
import com.example.backend.users.service.UserService;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(UserSignupController.URL)
|
||||||
|
public class UserSignupController {
|
||||||
|
public static final String URL = "/signup";
|
||||||
|
|
||||||
|
private static final String SIGNUP_VIEW = "signup";
|
||||||
|
private static final String USER_ATTRIBUTE = "user";
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
private final ModelMapper modelMapper;
|
||||||
|
|
||||||
|
public UserSignupController(
|
||||||
|
UserService userService,
|
||||||
|
ModelMapper modelMapper) {
|
||||||
|
this.userService = userService;
|
||||||
|
this.modelMapper = modelMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserEntity toEntity(UserSignupDTO dto) {
|
||||||
|
return modelMapper.map(dto, UserEntity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getSignup(Model model) {
|
||||||
|
model.addAttribute(USER_ATTRIBUTE, new UserSignupDTO());
|
||||||
|
return SIGNUP_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public String signup(
|
||||||
|
@ModelAttribute(name = USER_ATTRIBUTE) @Valid UserSignupDTO user,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
return SIGNUP_VIEW;
|
||||||
|
}
|
||||||
|
if (!Objects.equals(user.getPassword(), user.getPasswordConfirm())) {
|
||||||
|
bindingResult.rejectValue("password", "signup:passwords", "Пароли не совпадают.");
|
||||||
|
model.addAttribute(USER_ATTRIBUTE, user);
|
||||||
|
return SIGNUP_VIEW;
|
||||||
|
}
|
||||||
|
userService.create(toEntity(user));
|
||||||
|
return Constants.REDIRECT_VIEW + Constants.LOGIN_URL + "?signup";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.example.backend.users.api;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
|
||||||
|
public class UserSignupDTO {
|
||||||
|
@NotBlank
|
||||||
|
@Size(min = 3, max = 20)
|
||||||
|
private String login;
|
||||||
|
@NotBlank
|
||||||
|
@Size(min = 3, max = 20)
|
||||||
|
private String password;
|
||||||
|
@NotBlank
|
||||||
|
@Size(min = 3, max = 20)
|
||||||
|
private String passwordConfirm;
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogin(String login) {
|
||||||
|
this.login = login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPassword(String password) {
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPasswordConfirm() {
|
||||||
|
return passwordConfirm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPasswordConfirm(String passwordConfirm) {
|
||||||
|
this.passwordConfirm = passwordConfirm;
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ import jakarta.persistence.Table;
|
|||||||
public class UserEntity extends BaseEntity {
|
public class UserEntity extends BaseEntity {
|
||||||
|
|
||||||
@Column(nullable = false, unique = true, length = 15)
|
@Column(nullable = false, unique = true, length = 15)
|
||||||
private String username;
|
private String login;
|
||||||
|
|
||||||
@Column(nullable = false, length = 5)
|
@Column(nullable = false, length = 5)
|
||||||
private String password;
|
private String password;
|
||||||
@ -24,18 +24,18 @@ public class UserEntity extends BaseEntity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserEntity(Integer id, String username, String password) {
|
public UserEntity(Integer id, String login, String password) {
|
||||||
this.username = username;
|
this.login = login;
|
||||||
this.password = password;
|
this.password = password;
|
||||||
this.role = UserRole.USER;
|
this.role = UserRole.USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUsername() {
|
public String getLogin() {
|
||||||
return username;
|
return login;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username) {
|
public void setLogin(String login) {
|
||||||
this.username = username;
|
this.login = login;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
@ -56,7 +56,7 @@ public class UserEntity extends BaseEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(id, username, password, role);
|
return Objects.hash(id, login, password, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -67,7 +67,7 @@ public class UserEntity extends BaseEntity {
|
|||||||
return false;
|
return false;
|
||||||
final UserEntity other = (UserEntity) obj;
|
final UserEntity other = (UserEntity) obj;
|
||||||
return Objects.equals(other.getId(), id) &&
|
return Objects.equals(other.getId(), id) &&
|
||||||
Objects.equals(other.getUsername(), username) &&
|
Objects.equals(other.getLogin(), login) &&
|
||||||
Objects.equals(other.getRole(), role) &&
|
Objects.equals(other.getRole(), role) &&
|
||||||
Objects.equals(other.getPassword(), password);
|
Objects.equals(other.getPassword(), password);
|
||||||
}
|
}
|
||||||
|
@ -7,4 +7,6 @@ import com.example.backend.users.model.UserEntity;
|
|||||||
|
|
||||||
public interface UserRepository extends CrudRepository<UserEntity, Integer> {
|
public interface UserRepository extends CrudRepository<UserEntity, Integer> {
|
||||||
Optional<UserEntity> findByUsernameIgnoreCase(String username);
|
Optional<UserEntity> findByUsernameIgnoreCase(String username);
|
||||||
|
|
||||||
|
Optional<UserEntity> findByLoginIgnoreCase(String login);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,41 @@
|
|||||||
package com.example.backend.users.service;
|
package com.example.backend.users.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import com.example.backend.core.configurations.Constants;
|
||||||
import com.example.backend.core.errors.NotFoundException;
|
import com.example.backend.core.errors.NotFoundException;
|
||||||
|
import com.example.backend.core.security.UserPrincipal;
|
||||||
import com.example.backend.users.model.UserEntity;
|
import com.example.backend.users.model.UserEntity;
|
||||||
|
import com.example.backend.users.model.UserRole;
|
||||||
import com.example.backend.users.repository.UserRepository;
|
import com.example.backend.users.repository.UserRepository;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UserService {
|
public class UserService implements UserDetailsService {
|
||||||
private final UserRepository repository;
|
private final UserRepository repository;
|
||||||
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
public UserService(UserRepository repository) {
|
public UserService(UserRepository repository, PasswordEncoder passwordEncoder) {
|
||||||
this.repository = repository;
|
this.repository = repository;
|
||||||
|
this.passwordEncoder = passwordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkLogin(Integer id, String login) {
|
||||||
|
final Optional<UserEntity> existsUser = repository.findByLoginIgnoreCase(login);
|
||||||
|
if (existsUser.isPresent() && !existsUser.get().getId().equals(id)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
String.format("User with login %s is already exists", login));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@ -29,18 +48,35 @@ public class UserService {
|
|||||||
return repository.findById(id).orElseThrow(() -> new NotFoundException(id));
|
return repository.findById(id).orElseThrow(() -> new NotFoundException(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
private UserEntity getByLogin(String username) {
|
||||||
|
return repository.findByLoginIgnoreCase(username)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("Такого логина нет... хде вы его взяли?"));
|
||||||
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public UserEntity create(UserEntity entity) {
|
public UserEntity create(UserEntity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
throw new IllegalArgumentException("Entity is null");
|
||||||
|
}
|
||||||
|
checkLogin(null, entity.getLogin());
|
||||||
|
final String password = Optional.ofNullable(entity.getPassword()).orElse("");
|
||||||
|
entity.setPassword(
|
||||||
|
passwordEncoder.encode(StringUtils.hasText(password.strip()) ? password : Constants.DEFAULT_PASSWORD));
|
||||||
|
entity.setRole(Optional.ofNullable(entity.getRole()).orElse(UserRole.USER));
|
||||||
|
repository.save(entity);
|
||||||
return repository.save(entity);
|
return repository.save(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public UserEntity update(Integer id, UserEntity entity) {
|
public UserEntity update(Integer id, UserEntity entity) {
|
||||||
final UserEntity existsentity = get(id);
|
final UserEntity existsentity = get(id);
|
||||||
existsentity.setUsername(entity.getUsername());
|
checkLogin(id, entity.getLogin());
|
||||||
|
existsentity.setLogin(entity.getLogin());
|
||||||
existsentity.setPassword(entity.getPassword());
|
existsentity.setPassword(entity.getPassword());
|
||||||
existsentity.setIsAdmin(entity.getIsAdmin());
|
existsentity.setRole(entity.getRole());
|
||||||
return repository.save(existsentity);
|
repository.save(existsentity);
|
||||||
|
return existsentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@ -50,4 +86,10 @@ public class UserService {
|
|||||||
return existsentity;
|
return existsentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
final UserEntity existUser = getByLogin(username);
|
||||||
|
return new UserPrincipal(existUser);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user