This commit is contained in:
1yuee 2023-06-20 10:35:56 +04:00
parent 072a9514b6
commit a038eba691
10 changed files with 251 additions and 41 deletions

View File

@ -1,5 +1,8 @@
package com.webproglabs.lab1; package com.webproglabs.lab1;
import com.webproglabs.lab1.models.UserRole;
import com.webproglabs.lab1.mvc.UserSignupMvcController;
import com.webproglabs.lab1.services.UserService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@ -29,47 +32,47 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class); private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private static final String LOGIN_URL = "/login"; private static final String LOGIN_URL = "/login";
public static final String SPA_URL_MASK = "/{path:[^\\.]*}"; public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
// private final ProfileService userService; private final UserService userService;
//
// public SecurityConfiguration(ProfileService userService) {
// this.userService = userService;
// createAdminOnStartup();
// }
// private void createAdminOnStartup() { public SecurityConfiguration(UserService userService) {
// final String admin = "admin"; this.userService = userService;
// if (userService.findByLogin(admin) == null) { createAdminOnStartup();
// log.info("Admin user successfully created"); }
// try {
// userService.createUser(admin, admin, admin, UserRole.ADMIN);
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
// }
// }
// @Override private void createAdminOnStartup() {
// protected void configure(HttpSecurity http) throws Exception { final String admin = "admin";
// if (userService.findUserByLogin(admin) == null) {
// http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint()); log.info("Admin user successfully created");
// http.headers().frameOptions().sameOrigin().and() try {
// .cors().and() userService.createUser(admin, admin, admin, UserRole.ADMIN);
// .csrf().disable() } catch (Exception e) {
// .authorizeRequests() throw new RuntimeException(e);
// .antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll() }
// .antMatchers(HttpMethod.GET, LOGIN_URL).permitAll() }
// .anyRequest().authenticated() }
// .and()
// .formLogin()
// .loginPage(LOGIN_URL).permitAll()
// .and()
// .logout().permitAll();
// }
// @Override @Override
// protected void configure(AuthenticationManagerBuilder auth) throws Exception { protected void configure(HttpSecurity http) throws Exception {
// auth.userDetailsService(userService);
// } http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
http.headers().frameOptions().sameOrigin().and()
.cors().and()
.csrf().disable()
.authorizeRequests()
.antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage(LOGIN_URL).permitAll()
.and()
.logout().permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService);
}
@Override @Override
public void configure(WebSecurity web) { public void configure(WebSecurity web) {

View File

@ -28,6 +28,9 @@ public class PostDto {
return id; return id;
} }
public String getText() {return text;} public String getText() {return text;}
public void setText(String text) {
this.text = text;
}
public List<CommentDto> getComments() {return comments;} public List<CommentDto> getComments() {return comments;}
public String getAuthor() {return authorLogin;} public String getAuthor() {return authorLogin;}
} }

View File

@ -0,0 +1,40 @@
package com.webproglabs.lab1.dto;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
public class UserSignupDto {
@NotBlank
@Size(min = 4, max = 64)
private String login;
@NotBlank
@Size(min = 4, max = 64)
private String password;
@NotBlank
@Size(min = 4, max = 64)
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;
}
}

View File

@ -21,7 +21,7 @@ public class User {
@Column(nullable = false, length = 64) @Column(nullable = false, length = 64)
@NotBlank @NotBlank
@Size(min = 6, max = 64) @Size(min = 4, max = 64)
private String password; private String password;
private UserRole role; private UserRole role;

View File

@ -0,0 +1,50 @@
package com.webproglabs.lab1.mvc;
import com.webproglabs.lab1.dto.UserSignupDto;
import com.webproglabs.lab1.models.User;
import com.webproglabs.lab1.services.UserService;
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 javax.validation.Valid;
@Controller
@RequestMapping(UserSignupMvcController.SIGNUP_URL)
public class UserSignupMvcController {
public static final String SIGNUP_URL = "/signup";
private final UserService userService;
public UserSignupMvcController(UserService userService) {
this.userService = userService;
}
@GetMapping
public String showSignupForm(Model model) {
model.addAttribute("userDto", new UserSignupDto());
return "signup";
}
@PostMapping
public String signup(@ModelAttribute("userDto") @Valid UserSignupDto userSignupDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "signup";
}
try {
final User user = userService.createUser(userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
return "redirect:/login?created=" + user.getLogin();
} catch (Exception e) {
model.addAttribute("errors", e.getMessage());
return "signup";
}
}
}

View File

@ -35,8 +35,8 @@ public class UserService implements UserDetailsService {
@Transactional @Transactional
public User findUserByLogin(String login) { public User findUserByLogin(String login) {
final Optional<User> user = userRepository.findOneByLoginIgnoreCase(login); final User user = userRepository.findOneByLoginIgnoreCase(login).orElse(null);
return user.orElseThrow(EntityNotFoundException::new); return user;
} }
@Transactional @Transactional

View File

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
<meta charset="UTF-8"/>
<title>СоцСеточка</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" href="/favicon.svg">
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<div>
<p class='text-center m-3 h3'> СоцСеточка</p>
</div>
<div>
<p class='h4 text-center'>
<a sec:authorize="hasRole('ROLE_ADMIN')" href="/topic" class="text-decoration-none m-3">Топики</a>
<a sec:authorize="hasRole('ROLE_ADMIN')" href="/users" class="text-decoration-none m-3">Пользователи</a>
<a sec:authorize="isAuthenticated()" href="/feed" class="text-decoration-none m-3">Лента</a>
<a sec:authorize="isAuthenticated()" href="/logout" class="text-decoration-none m-3">
Выход
</a>
</p>
</div>
<div >
<div layout:fragment="content"></div>
</div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container" layout:fragment="content">
<div class="alert alert-danger">
<span th:text="${error}"></span>
</div>
<a href="/">На главную</a>
</div>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container" layout:fragment="content">
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
Пользователь не найден или пароль указан не верно
</div>
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
Выход успешно произведен
</div>
<div th:if="${param.created}" class="alert alert-success margin-bottom">
Пользователь '<span th:text="${param.created}"></span>' успешно создан
</div>
<form th:action="@{/login}" method="post" class="container-padding">
<div class="mb-3">
<input type="text" name="username" id="username" class="form-control"
placeholder="Логин" required="true" autofocus="true"/>
</div>
<div class="mb-3">
<input type="password" name="password" id="password" class="form-control"
placeholder="Пароль" required="true"/>
</div>
<button type="submit" class="btn btn-success button-fixed">Войти</button>
<a class="btn btn-primary button-fixed" href="/signup">Регистрация</a>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<body>
<div class="container container-padding" layout:fragment="content">
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
<form action="#" th:action="@{/signup}" th:object="${userDto}" method="post">
<div class="mb-3">
<input type="text" class="form-control" th:field="${userDto.login}"
placeholder="Логин" required="true" autofocus="true" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${userDto.password}"
placeholder="Пароль" required="true" minlength="4" maxlength="64"/>
</div>
<div class="mb-3">
<input type="password" class="form-control" th:field="${userDto.passwordConfirm}"
placeholder="Пароль (подтверждение)" required="true" minlength="4" maxlength="64"/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-success button-fixed">Создать</button>
<a class="btn btn-primary button-fixed" href="/login">Назад</a>
</div>
</form>
</div>
</body>
</html>