diff --git a/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java b/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java index 894cf39..5eb7220 100644 --- a/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java +++ b/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java @@ -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.WebSecurityConfigurerAdapter; 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.logout.LogoutSuccessHandler; +import ru.ulstu.core.model.AuthFailureHandler; import ru.ulstu.user.controller.UserController; import ru.ulstu.user.model.UserRoleConstants; import ru.ulstu.user.service.UserService; @@ -35,17 +37,20 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { private final AuthenticationSuccessHandler authenticationSuccessHandler; private final LogoutSuccessHandler logoutSuccessHandler; private final ApplicationProperties applicationProperties; + private final AuthenticationFailureHandler authenticationFailureHandler; public SecurityConfiguration(UserService userService, BCryptPasswordEncoder bCryptPasswordEncoder, AuthenticationSuccessHandler authenticationSuccessHandler, LogoutSuccessHandler logoutSuccessHandler, - ApplicationProperties applicationProperties) { + ApplicationProperties applicationProperties, + AuthFailureHandler authenticationFailureHandler) { this.userService = userService; this.bCryptPasswordEncoder = bCryptPasswordEncoder; this.authenticationSuccessHandler = authenticationSuccessHandler; this.logoutSuccessHandler = logoutSuccessHandler; this.applicationProperties = applicationProperties; + this.authenticationFailureHandler = authenticationFailureHandler; } @Override @@ -66,6 +71,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .antMatchers(UserController.ACTIVATE_URL).permitAll() .antMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll() .antMatchers(Constants.PASSWORD_RESET_PAGE).permitAll() + .antMatchers("/users/block").permitAll() .antMatchers(UserController.URL + UserController.REGISTER_URL).permitAll() .antMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll() .antMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll() @@ -76,6 +82,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .formLogin() .loginPage("/login") .successHandler(authenticationSuccessHandler) + .failureHandler(authenticationFailureHandler) .permitAll() .and() .logout() diff --git a/src/main/java/ru/ulstu/core/model/AuthFailureHandler.java b/src/main/java/ru/ulstu/core/model/AuthFailureHandler.java new file mode 100644 index 0000000..8b6bd9d --- /dev/null +++ b/src/main/java/ru/ulstu/core/model/AuthFailureHandler.java @@ -0,0 +1,21 @@ +package ru.ulstu.core.model; + +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.AuthenticationFailureHandler; +import org.springframework.stereotype.Component; +import ru.ulstu.user.error.UserBlockedException; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@Component +public class AuthFailureHandler implements AuthenticationFailureHandler { + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException ex) throws IOException { + if (ex.getClass() == UserBlockedException.class) { + response.sendRedirect("/users/block"); + } + } +} \ No newline at end of file diff --git a/src/main/java/ru/ulstu/grant/controller/GrantController.java b/src/main/java/ru/ulstu/grant/controller/GrantController.java index 1e28a33..48dee8e 100644 --- a/src/main/java/ru/ulstu/grant/controller/GrantController.java +++ b/src/main/java/ru/ulstu/grant/controller/GrantController.java @@ -50,7 +50,7 @@ public class GrantController { @GetMapping("/grant") public void getGrant(ModelMap modelMap, @RequestParam(value = "id") Integer id) { if (id != null && id > 0) { - GrantDto grantDto = grantService.findOneDto(id); + GrantDto grantDto = grantService.getExistGrantById(id); attachPaper(grantDto); modelMap.put("grantDto", grantDto); } else { diff --git a/src/main/java/ru/ulstu/grant/service/GrantService.java b/src/main/java/ru/ulstu/grant/service/GrantService.java index 03ae07f..99387c7 100644 --- a/src/main/java/ru/ulstu/grant/service/GrantService.java +++ b/src/main/java/ru/ulstu/grant/service/GrantService.java @@ -1,5 +1,6 @@ package ru.ulstu.grant.service; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -17,7 +18,6 @@ import ru.ulstu.paper.model.Paper; import ru.ulstu.paper.model.PaperDto; import ru.ulstu.paper.service.PaperService; import ru.ulstu.ping.service.PingService; -import ru.ulstu.project.model.Project; import ru.ulstu.project.model.ProjectDto; import ru.ulstu.project.service.ProjectService; import ru.ulstu.timeline.service.EventService; @@ -77,6 +77,11 @@ public class GrantService extends BaseService { this.pingService = pingService; } + public GrantDto getExistGrantById(Integer id) { + GrantDto grantDto = new GrantDto(findById(id)); + return grantDto; + } + public List findAll() { return grantRepository.findAll(); } @@ -85,17 +90,13 @@ public class GrantService extends BaseService { return convert(findAll(), GrantDto::new); } - public GrantDto findOneDto(Integer id) { - return new GrantDto(grantRepository.findOne(id)); - } - @Transactional - public Integer create(GrantDto grantDto) throws IOException { + public Grant create(GrantDto grantDto) throws IOException { Grant newGrant = copyFromDto(new Grant(), grantDto); newGrant = grantRepository.save(newGrant); eventService.createFromObject(newGrant, Collections.emptyList(), false, "гранта"); grantNotificationService.sendCreateNotification(newGrant); - return newGrant.getId(); + return newGrant; } private Grant copyFromDto(Grant grant, GrantDto grantDto) throws IOException { @@ -106,9 +107,11 @@ public class GrantService extends BaseService { grant.setProject(projectService.findById(grantDto.getProject().getId())); } grant.setDeadlines(deadlineService.saveOrCreate(grantDto.getDeadlines())); - grant.setFiles(fileService.saveOrCreate(grantDto.getFiles().stream() - .filter(f -> !f.isDeleted()) - .collect(toList()))); + if (!grant.getFiles().isEmpty()) { + grant.setFiles(fileService.saveOrCreate(grantDto.getFiles().stream() + .filter(f -> !f.isDeleted()) + .collect(toList()))); + } grant.getAuthors().clear(); if (grantDto.getAuthorIds() != null && !grantDto.getAuthorIds().isEmpty()) { grantDto.getAuthorIds().forEach(authorIds -> grant.getAuthors().add(userService.findById(authorIds))); @@ -123,6 +126,7 @@ public class GrantService extends BaseService { return grant; } + public void createProject(GrantDto grantDto) throws IOException { grantDto.setProject( new ProjectDto(projectService.save(new ProjectDto(grantDto.getTitle())))); @@ -130,7 +134,7 @@ public class GrantService extends BaseService { @Transactional public Integer update(GrantDto grantDto) throws IOException { - Grant grant = grantRepository.findOne(grantDto.getId()); + Grant grant = findById(grantDto.getId()); Set oldAuthors = new HashSet<>(grant.getAuthors()); User oldLeader = grant.getLeader(); for (FileDataDto file : grantDto.getFiles().stream() @@ -159,34 +163,19 @@ public class GrantService extends BaseService { } @Transactional - public void delete(Integer grantId) throws IOException { - Grant grant = grantRepository.findOne(grantId); - grantRepository.delete(grant); + public boolean delete(Integer grantId) throws IOException { + Grant grant = findById(grantId); + if (grant != null) { + grantRepository.delete(grant); + return true; + } + return false; } public List getGrantStatuses() { return Arrays.asList(Grant.GrantStatus.values()); } - @Transactional - public Grant create(String title, Project projectId, Date deadlineDate, User user, Paper paper) { - Grant grant = new Grant(); - grant.setTitle(title); - grant.setComment("Комментарий к гранту 1"); - grant.setProject(projectId); - grant.setStatus(APPLICATION); - grant.getDeadlines().add(new Deadline(deadlineDate, "первый дедлайн")); - grant.getAuthors().add(user); - grant.setLeader(user); - grant.getPapers().add(paper); - grant = grantRepository.save(grant); - - eventService.createFromObject(grant, Collections.emptyList(), false, "гранта"); - grantNotificationService.sendCreateNotification(grant); - - return grant; - } - public boolean save(GrantDto grantDto, Errors errors) throws IOException { grantDto.setName(grantDto.getTitle()); filterEmptyDeadlines(grantDto); @@ -274,20 +263,22 @@ public class GrantService extends BaseService { return paperService.findAllNotCompleted(); } - public void attachPaper(GrantDto grantDto) { + public List attachPaper(GrantDto grantDto) { if (!grantDto.getPaperIds().isEmpty()) { grantDto.getPapers().clear(); grantDto.setPapers(getGrantPapers(grantDto.getPaperIds())); } else { grantDto.getPapers().clear(); } + return grantDto.getPapers(); } - public void removeDeadline(GrantDto grantDto, Integer deadlineId) { + public GrantDto removeDeadline(GrantDto grantDto, Integer deadlineId) { if (grantDto.getDeadlines().get(deadlineId).getId() != null) { grantDto.getRemovedDeadlineIds().add(grantDto.getDeadlines().get(deadlineId).getId()); } grantDto.getDeadlines().remove((int) deadlineId); + return grantDto; } private List getCompletedPapersAuthors(Paper.PaperType type) { @@ -313,10 +304,11 @@ public class GrantService extends BaseService { .collect(toList()); } - public void filterEmptyDeadlines(GrantDto grantDto) { + public List filterEmptyDeadlines(GrantDto grantDto) { grantDto.setDeadlines(grantDto.getDeadlines().stream() - .filter(dto -> dto.getDate() != null || !org.springframework.util.StringUtils.isEmpty(dto.getDescription())) + .filter(dto -> dto.getDate() != null || !StringUtils.isEmpty(dto.getDescription())) .collect(Collectors.toList())); + return grantDto.getDeadlines(); } @Transactional @@ -346,8 +338,4 @@ public class GrantService extends BaseService { public void ping(int grantId) throws IOException { pingService.addPing(findById(grantId)); } - - public Grant findGrantById(Integer grantId) { - return grantRepository.findOne(grantId); - } } diff --git a/src/main/java/ru/ulstu/user/controller/UserController.java b/src/main/java/ru/ulstu/user/controller/UserController.java index 3c4556d..d080d54 100644 --- a/src/main/java/ru/ulstu/user/controller/UserController.java +++ b/src/main/java/ru/ulstu/user/controller/UserController.java @@ -175,4 +175,9 @@ public class UserController extends OdinController { @RequestParam(value = "activity", required = false) String activity) { return new Response<>(userService.getActivitiesPings(userId, activity)); } + + @PostMapping("/block") + public void blockUser(@RequestParam("userId") Integer userId) { + userService.blockUser(userId); + } } diff --git a/src/main/java/ru/ulstu/user/controller/UserMvcController.java b/src/main/java/ru/ulstu/user/controller/UserMvcController.java index f0a28d8..bf84176 100644 --- a/src/main/java/ru/ulstu/user/controller/UserMvcController.java +++ b/src/main/java/ru/ulstu/user/controller/UserMvcController.java @@ -74,4 +74,8 @@ public class UserMvcController extends OdinController { @GetMapping("/pings") public void getPings() { } + + @GetMapping("/block") + public void getBlock() { + } } diff --git a/src/main/java/ru/ulstu/user/error/UserBlockedException.java b/src/main/java/ru/ulstu/user/error/UserBlockedException.java new file mode 100644 index 0000000..23b9b3a --- /dev/null +++ b/src/main/java/ru/ulstu/user/error/UserBlockedException.java @@ -0,0 +1,9 @@ +package ru.ulstu.user.error; + +import org.springframework.security.core.AuthenticationException; + +public class UserBlockedException extends AuthenticationException { + public UserBlockedException(String message) { + super(message); + } +} diff --git a/src/main/java/ru/ulstu/user/model/User.java b/src/main/java/ru/ulstu/user/model/User.java index 520b439..bb76618 100644 --- a/src/main/java/ru/ulstu/user/model/User.java +++ b/src/main/java/ru/ulstu/user/model/User.java @@ -12,6 +12,7 @@ import javax.persistence.Enumerated; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; @@ -91,6 +92,10 @@ public class User extends BaseEntity { @Temporal(TemporalType.TIMESTAMP) private Date birthDate; + @ManyToOne() + @JoinColumn(name = "blocker_id") + private User blocker; + public enum UserDegree { CANDIDATE("Кандидат технических наук"), DOCTOR("Доктор технических наук"); @@ -229,6 +234,14 @@ public class User extends BaseEntity { this.degree = degree; } + public User getBlocker() { + return blocker; + } + + public void setBlocker(User blocker) { + this.blocker = blocker; + } + public String getUserAbbreviate() { return String.format(USER_ABBREVIATE_TEMPLATE, lastName == null ? "" : lastName, diff --git a/src/main/java/ru/ulstu/user/service/UserService.java b/src/main/java/ru/ulstu/user/service/UserService.java index b4f8f28..bbac124 100644 --- a/src/main/java/ru/ulstu/user/service/UserService.java +++ b/src/main/java/ru/ulstu/user/service/UserService.java @@ -21,12 +21,10 @@ import ru.ulstu.core.jpa.OffsetablePageRequest; import ru.ulstu.core.model.BaseEntity; import ru.ulstu.core.model.UserActivity; import ru.ulstu.core.model.response.PageableItems; -import ru.ulstu.grant.service.GrantService; -import ru.ulstu.paper.service.PaperService; import ru.ulstu.ping.model.Ping; import ru.ulstu.ping.service.PingService; -import ru.ulstu.project.service.ProjectService; import ru.ulstu.user.error.UserActivationError; +import ru.ulstu.user.error.UserBlockedException; import ru.ulstu.user.error.UserEmailExistsException; import ru.ulstu.user.error.UserIdExistsException; import ru.ulstu.user.error.UserIsUndeadException; @@ -323,6 +321,9 @@ public class UserService implements UserDetailsService { if (!user.getActivated()) { 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(), user.getPassword(), Optional.ofNullable(user.getRoles()).orElse(Collections.emptySet()).stream() @@ -424,4 +425,10 @@ public class UserService implements UserDetailsService { } return activitiesPings; } + + public void blockUser(int userId) { + User userToBlock = findById(userId); + userToBlock.setBlocker(getCurrentUser()); + userRepository.save(userToBlock); + } } diff --git a/src/main/resources/db/changelog-20190607_000002-schema.xml b/src/main/resources/db/changelog-20190607_000002-schema.xml new file mode 100644 index 0000000..9531c87 --- /dev/null +++ b/src/main/resources/db/changelog-20190607_000002-schema.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/src/main/resources/db/changelog-master.xml b/src/main/resources/db/changelog-master.xml index 3c79c6d..afcf8c9 100644 --- a/src/main/resources/db/changelog-master.xml +++ b/src/main/resources/db/changelog-master.xml @@ -53,4 +53,5 @@ + \ No newline at end of file diff --git a/src/main/resources/public/js/users.js b/src/main/resources/public/js/users.js index 0de86d6..0f8d1c0 100644 --- a/src/main/resources/public/js/users.js +++ b/src/main/resources/public/js/users.js @@ -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) { re = /\S+@\S+\.\S+/; diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 32939e7..d3c49dd 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -109,6 +109,7 @@ +