#95 blocking user

This commit is contained in:
Artem.Arefev 2019-06-03 02:11:35 +04:00
parent 53307c6add
commit 22abf6a27d
11 changed files with 80 additions and 3 deletions

View File

@ -13,8 +13,10 @@ import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import ru.ulstu.core.model.RestAuthenticationFailureHandler;
import ru.ulstu.user.controller.UserController; import ru.ulstu.user.controller.UserController;
import ru.ulstu.user.model.UserRoleConstants; import ru.ulstu.user.model.UserRoleConstants;
import ru.ulstu.user.service.UserService; import ru.ulstu.user.service.UserService;
@ -35,17 +37,20 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private final AuthenticationSuccessHandler authenticationSuccessHandler; private final AuthenticationSuccessHandler authenticationSuccessHandler;
private final LogoutSuccessHandler logoutSuccessHandler; private final LogoutSuccessHandler logoutSuccessHandler;
private final ApplicationProperties applicationProperties; private final ApplicationProperties applicationProperties;
private final AuthenticationFailureHandler authenticationFailureHandler;
public SecurityConfiguration(UserService userService, public SecurityConfiguration(UserService userService,
BCryptPasswordEncoder bCryptPasswordEncoder, BCryptPasswordEncoder bCryptPasswordEncoder,
AuthenticationSuccessHandler authenticationSuccessHandler, AuthenticationSuccessHandler authenticationSuccessHandler,
LogoutSuccessHandler logoutSuccessHandler, LogoutSuccessHandler logoutSuccessHandler,
ApplicationProperties applicationProperties) { ApplicationProperties applicationProperties,
RestAuthenticationFailureHandler authenticationFailureHandler) {
this.userService = userService; this.userService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder; this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.authenticationSuccessHandler = authenticationSuccessHandler; this.authenticationSuccessHandler = authenticationSuccessHandler;
this.logoutSuccessHandler = logoutSuccessHandler; this.logoutSuccessHandler = logoutSuccessHandler;
this.applicationProperties = applicationProperties; this.applicationProperties = applicationProperties;
this.authenticationFailureHandler = authenticationFailureHandler;
} }
@Override @Override
@ -76,6 +81,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.formLogin() .formLogin()
.loginPage("/login") .loginPage("/login")
.successHandler(authenticationSuccessHandler) .successHandler(authenticationSuccessHandler)
.failureHandler(authenticationFailureHandler)
.permitAll() .permitAll()
.and() .and()
.logout() .logout()

View File

@ -12,6 +12,7 @@ import ru.ulstu.core.model.ErrorConstants;
import ru.ulstu.core.model.response.Response; import ru.ulstu.core.model.response.Response;
import ru.ulstu.core.model.response.ResponseExtended; import ru.ulstu.core.model.response.ResponseExtended;
import ru.ulstu.user.error.UserActivationError; import ru.ulstu.user.error.UserActivationError;
import ru.ulstu.user.error.UserBlockedException;
import ru.ulstu.user.error.UserEmailExistsException; import ru.ulstu.user.error.UserEmailExistsException;
import ru.ulstu.user.error.UserIdExistsException; import ru.ulstu.user.error.UserIdExistsException;
import ru.ulstu.user.error.UserIsUndeadException; import ru.ulstu.user.error.UserIsUndeadException;

View File

@ -0,0 +1,20 @@
package ru.ulstu.core.model;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class RestAuthenticationFailureHandler implements AuthenticationFailureHandler {
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException ex) throws IOException, ServletException {
response.sendRedirect("/login.html?error=fail");
}
}

View File

@ -171,4 +171,9 @@ public class UserController extends OdinController<UserListDto, UserDto> {
public void inviteUser(@RequestParam("email") String email) { public void inviteUser(@RequestParam("email") String email) {
userService.inviteUser(email); userService.inviteUser(email);
} }
@PostMapping("/block")
public void blockUser(@RequestParam("userId") Integer userId) {
userService.blockUser(userId);
}
} }

View File

@ -1,6 +1,8 @@
package ru.ulstu.user.error; package ru.ulstu.user.error;
public class UserBlockedException extends RuntimeException { import org.springframework.security.core.AuthenticationException;
public class UserBlockedException extends AuthenticationException {
public UserBlockedException(String message) { public UserBlockedException(String message) {
super(message); super(message);
} }

View File

@ -12,6 +12,7 @@ import javax.persistence.Enumerated;
import javax.persistence.JoinColumn; import javax.persistence.JoinColumn;
import javax.persistence.JoinTable; import javax.persistence.JoinTable;
import javax.persistence.ManyToMany; import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table; import javax.persistence.Table;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
@ -91,6 +92,10 @@ public class User extends BaseEntity {
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
private Date birthDate; private Date birthDate;
@ManyToOne()
@JoinColumn(name = "blocker_id")
private User blocker;
public enum UserDegree { public enum UserDegree {
CANDIDATE("Кандидат технических наук"), CANDIDATE("Кандидат технических наук"),
DOCTOR("Доктор технических наук"); DOCTOR("Доктор технических наук");
@ -229,6 +234,14 @@ public class User extends BaseEntity {
this.degree = degree; this.degree = degree;
} }
public User getBlocker() {
return blocker;
}
public void setBlocker(User blocker) {
this.blocker = blocker;
}
public String getUserAbbreviate() { public String getUserAbbreviate() {
return String.format(USER_ABBREVIATE_TEMPLATE, return String.format(USER_ABBREVIATE_TEMPLATE,
lastName == null ? "" : lastName, lastName == null ? "" : lastName,

View File

@ -14,13 +14,16 @@ 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 org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import ru.ulstu.conference.service.ConferenceService; import ru.ulstu.conference.service.ConferenceService;
import ru.ulstu.configuration.ApplicationProperties; import ru.ulstu.configuration.ApplicationProperties;
import ru.ulstu.core.error.EntityIdIsNullException; import ru.ulstu.core.error.EntityIdIsNullException;
import ru.ulstu.core.jpa.OffsetablePageRequest; import ru.ulstu.core.jpa.OffsetablePageRequest;
import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.BaseEntity;
import ru.ulstu.core.model.response.PageableItems; import ru.ulstu.core.model.response.PageableItems;
import ru.ulstu.core.model.response.Response;
import ru.ulstu.user.error.UserActivationError; import ru.ulstu.user.error.UserActivationError;
import ru.ulstu.user.error.UserBlockedException;
import ru.ulstu.user.error.UserEmailExistsException; import ru.ulstu.user.error.UserEmailExistsException;
import ru.ulstu.user.error.UserIdExistsException; import ru.ulstu.user.error.UserIdExistsException;
import ru.ulstu.user.error.UserIsUndeadException; import ru.ulstu.user.error.UserIsUndeadException;
@ -252,7 +255,7 @@ public class UserService implements UserDetailsService {
mailService.sendChangePasswordMail(user); mailService.sendChangePasswordMail(user);
} }
public boolean requestUserPasswordReset(String email) { public boolean requestUserPasswordReset(String email) {
User user = userRepository.findOneByEmailIgnoreCase(email); User user = userRepository.findOneByEmailIgnoreCase(email);
if (user == null) { if (user == null) {
throw new UserNotFoundException(email); throw new UserNotFoundException(email);
@ -313,6 +316,9 @@ public class UserService implements UserDetailsService {
if (!user.getActivated()) { if (!user.getActivated()) {
throw new UserNotActivatedException(); throw new UserNotActivatedException();
} }
if (user.getBlocker() != null) {
throw new UserBlockedException(String.format("Вы заблокированы пользователем %s", user.getBlocker().getUserAbbreviate()));
}
return new org.springframework.security.core.userdetails.User(user.getLogin(), return new org.springframework.security.core.userdetails.User(user.getLogin(),
user.getPassword(), user.getPassword(),
Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream() Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream()
@ -389,4 +395,10 @@ public class UserService implements UserDetailsService {
} }
return ImmutableMap.of("users", usersInfoNow, "error", err); return ImmutableMap.of("users", usersInfoNow, "error", err);
} }
public void blockUser(int userId) {
User userToBlock = findById(userId);
userToBlock.setBlocker(getCurrentUser());
userRepository.save(userToBlock);
}
} }

View File

@ -49,4 +49,5 @@
<include file="db/changelog-20190523_000000-schema.xml"/> <include file="db/changelog-20190523_000000-schema.xml"/>
<include file="db/changelog-20190528_000000-schema.xml"/> <include file="db/changelog-20190528_000000-schema.xml"/>
<include file="db/changelog-20190528_000002-schema.xml"/> <include file="db/changelog-20190528_000002-schema.xml"/>
<include file="db/changelog-20190531_000002-schema.xml"/>
</databaseChangeLog> </databaseChangeLog>

View File

@ -120,6 +120,20 @@ function resetPassword() {
}) })
} }
function blockUser() {
userId = $('#userId').val();
$.ajax({
url:"/api/1.0/users/block?userId=" + userId,
contentType: "application/json; charset=utf-8",
method: "POST",
success: function() {
showFeedbackMessage("Пользователь заблокирован", MessageTypesEnum.SUCCESS)
},
error: function(errorData) {
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
}
})
}
function isEmailValid(email) { function isEmailValid(email) {
re = /\S+@\S+\.\S+/; re = /\S+@\S+\.\S+/;

View File

@ -109,6 +109,7 @@
<script src="/js/core.js"></script> <script src="/js/core.js"></script>
<script src="/js/config.js"></script> <script src="/js/config.js"></script>
<script src="/js/odin.js"></script> <script src="/js/odin.js"></script>
<script src="/js/users.js"></script>
<script th:inline="javascript"> <script th:inline="javascript">
/*<![CDATA[*/ /*<![CDATA[*/

View File

@ -7,10 +7,12 @@
<div th:fragment="userDashboard (user)" class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card"> <div th:fragment="userDashboard (user)" class="col-12 col-sm-12 col-md-12 col-lg-4 col-xl-3 dashboard-card">
<div class="row"> <div class="row">
<div class="col col-10"> <div class="col col-10">
<input type="hidden" id="userId" th:value="${user.user.id}"/>
<b><p th:text="${user.user.lastName} + ' ' + ${user.user.firstName} + ' ' + ${user.user.patronymic}"></p></b> <b><p th:text="${user.user.lastName} + ' ' + ${user.user.firstName} + ' ' + ${user.user.patronymic}"></p></b>
<i><p th:if="${user.conference != null}" th:text="'Сейчас на конференции ' + ${user.conference.title}"></p></i> <i><p th:if="${user.conference != null}" th:text="'Сейчас на конференции ' + ${user.conference.title}"></p></i>
<i><p th:if="${user.lesson != null}" th:text="'Сейчас на паре ' + ${user.lesson.nameOfLesson} + ' в аудитории ' + ${user.lesson.room}"></p></i> <i><p th:if="${user.lesson != null}" th:text="'Сейчас на паре ' + ${user.lesson.nameOfLesson} + ' в аудитории ' + ${user.lesson.room}"></p></i>
<p th:if="${user.isOnline()}">Онлайн</p> <p th:if="${user.isOnline()}">Онлайн</p>
<button onclick="blockUser()">Заблокировать</button>
</div> </div>
</div> </div>
</div> </div>