Compare commits

..

7 Commits

10 changed files with 156 additions and 18 deletions

View File

@ -1,13 +1,30 @@
package com.gipro.giprolab; package com.gipro.giprolab;
import com.gipro.giprolab.models.UserDto;
import com.gipro.giprolab.services.UserService;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
@SpringBootApplication @SpringBootApplication
public class GiprolabApplication { public class GiprolabApplication {
private final UserService userService;
public GiprolabApplication(UserService userService) {
this.userService = userService;
}
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(GiprolabApplication.class, args); SpringApplication.run(GiprolabApplication.class, args);
} }
@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
if (userService.getUserByLogin("user@user.ru") == null) {
userService.createDefaultRoles();
userService.createUser(new UserDto("user@user.ru", "user"));
}
}
} }

View File

@ -10,7 +10,7 @@ public class Constants {
public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$"; public static final String LOGIN_REGEX = "^[_'.@A-Za-z0-9-]*$";
public static final String COOKIES_NAME = "JSESSIONID"; public static final String COOKIES_NAME = "JSESSIONID";
public static final String LOGOUT_URL = "/login?logout"; public static final String LOGOUT_URL = "/logform?logout";
public static final String SESSION_ID_ATTR = "sessionId"; public static final String SESSION_ID_ATTR = "sessionId";
public static final int SESSION_TIMEOUT_SECONDS = 30 * 60; public static final int SESSION_TIMEOUT_SECONDS = 30 * 60;
@ -18,4 +18,5 @@ public class Constants {
public static final String PASSWORD_RESET_PAGE = "/reset"; public static final String PASSWORD_RESET_PAGE = "/reset";
public static final String SYSTEM_ENDPOINT_URL = "/metrics"; public static final String SYSTEM_ENDPOINT_URL = "/metrics";
public static final String CONTACTS_PAGE = "/contacts.html";
} }

View File

@ -0,0 +1,22 @@
package com.gipro.giprolab.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/{articlename:\\w+}");
registry.addRedirectViewController("/", "/home");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/");
}
}

View File

@ -16,6 +16,7 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
@ -24,11 +25,16 @@ public class SecurityConfiguration {
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class); private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
private final UserService userService; private final UserService userService;
private final BCryptPasswordEncoder bCryptPasswordEncoder; private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final AuthenticationSuccessHandler authenticationSuccessHandler;
//private final LogoutSuccessHandler logoutSuccessHandler;
public SecurityConfiguration(UserService userService, public SecurityConfiguration(UserService userService,
BCryptPasswordEncoder bCryptPasswordEncoder) { BCryptPasswordEncoder bCryptPasswordEncoder,
AuthenticationSuccessHandler authenticationSuccessHandler) {
this.userService = userService; this.userService = userService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder; this.bCryptPasswordEncoder = bCryptPasswordEncoder;
this.authenticationSuccessHandler = authenticationSuccessHandler;
} }
@Bean @Bean
@ -39,6 +45,7 @@ public class SecurityConfiguration {
//.requestMatchers(UserController.ACTIVATE_URL).permitAll() //.requestMatchers(UserController.ACTIVATE_URL).permitAll()
.requestMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll() .requestMatchers(Constants.PASSWORD_RESET_REQUEST_PAGE).permitAll()
.requestMatchers(Constants.PASSWORD_RESET_PAGE).permitAll() .requestMatchers(Constants.PASSWORD_RESET_PAGE).permitAll()
.requestMatchers(Constants.CONTACTS_PAGE).permitAll()
//.requestMatchers(UserController.URL + UserController.REGISTER_URL).permitAll() //.requestMatchers(UserController.URL + UserController.REGISTER_URL).permitAll()
//.requestMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll() //.requestMatchers(UserController.URL + UserController.ACTIVATE_URL).permitAll()
//.requestMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll() //.requestMatchers(UserController.URL + UserController.PASSWORD_RESET_REQUEST_URL).permitAll()
@ -46,8 +53,9 @@ public class SecurityConfiguration {
.requestMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN) .requestMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN)
.anyRequest().authenticated()) .anyRequest().authenticated())
.formLogin(fl -> fl .formLogin(fl -> fl
.loginPage("/login") .loginPage("/logform")
//.successHandler(authenticationSuccessHandler) .successHandler(authenticationSuccessHandler)
.defaultSuccessUrl("/", true)
.permitAll()) .permitAll())
.csrf(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable)
.logout(l -> l .logout(l -> l
@ -62,7 +70,7 @@ public class SecurityConfiguration {
@Bean @Bean
public WebSecurityCustomizer webSecurityCustomizer() { public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring().requestMatchers("/css/**", "/js/**", "/templates/**", "/webjars/**"); return (web) -> web.ignoring().requestMatchers("/assets.js/**", "/bootstrap_theme/**", "/bootstrap/**", "/css/**", "/js/**", "/templates/**", "/webjars/**");
} }
@Autowired @Autowired

View File

@ -51,6 +51,16 @@ public class UserDto {
roles = new LinkedHashSet<>(); roles = new LinkedHashSet<>();
} }
public UserDto(String login, String password) {
this();
this.login = login;
this.password = password;
this.passwordConfirm = password;
this.email = "email@email.ru";
this.firstName = "user";
this.lastName = "user";
}
public UserDto(User user) { public UserDto(User user) {
this(); this();
this.id = user.getId(); this.id = user.getId();

View File

@ -0,0 +1,22 @@
package com.gipro.giprolab.services;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
public final class IpAddressResolver {
private static final String CLIENT_IP_HEADER = "Client-IP";
private static final String FORWARDED_FOR_HEADER = "X-Forwarded-For";
public static String getRemoteAddr(HttpServletRequest request) {
String headerClientIp = request.getHeader("");
String headerXForwardedFor = request.getHeader(HttpServletRequest.FORM_AUTH);
if (StringUtils.isEmpty(request.getRemoteAddr()) && !StringUtils.isEmpty(headerClientIp)) {
return headerClientIp;
}
if (!StringUtils.isEmpty(headerXForwardedFor)) {
return headerXForwardedFor;
}
return request.getRemoteAddr();
}
}

View File

@ -82,11 +82,14 @@ public class UserService implements UserDetailsService {
throw new UserPasswordsNotValidOrNotMatchException(); throw new UserPasswordsNotValidOrNotMatchException();
} }
User user = userMapper.userDtoToUserEntity(userDto); User user = userMapper.userDtoToUserEntity(userDto);
user.setActivated(false); user.setActivated(true);
user.setActivationKey(UserUtils.generateActivationKey());
user.setRoles(Collections.singleton(new UserRole(UserRoleConstants.USER)));
user.setPassword(passwordEncoder.encode(userDto.getPassword())); user.setPassword(passwordEncoder.encode(userDto.getPassword()));
user = userRepository.save(user); user = userRepository.save(user);
//user.setActivationKey(UserUtils.generateActivationKey());
Set<UserRole> set = new HashSet<>();
set.add(new UserRole(UserRoleConstants.USER));
user.setRoles(set);
user = userRepository.save(user);
//TODO: mailService.sendActivationEmail(user); //TODO: mailService.sendActivationEmail(user);
log.debug("Created Information for User: {}", user.getLogin()); log.debug("Created Information for User: {}", user.getLogin());
return userMapper.userEntityToUserDto(user); return userMapper.userEntityToUserDto(user);
@ -259,4 +262,9 @@ public class UserService implements UserDetailsService {
.map(role -> new SimpleGrantedAuthority(role.getName())) .map(role -> new SimpleGrantedAuthority(role.getName()))
.collect(Collectors.toList())); .collect(Collectors.toList()));
} }
public void createDefaultRoles() {
userRoleRepository.save(new UserRole(UserRoleConstants.USER));
userRoleRepository.save(new UserRole(UserRoleConstants.ADMIN));
}
} }

View File

@ -0,0 +1,41 @@
package com.gipro.giprolab.services;
import com.gipro.giprolab.config.Constants;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class UserSessionLoginHandler extends SavedRequestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
private final Logger log = LoggerFactory.getLogger(UserSessionLoginHandler.class);
public UserSessionLoginHandler() {
super();
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
super.onAuthenticationSuccess(request, response, authentication);
final String login = authentication.getName();
final String ipAddress = IpAddressResolver.getRemoteAddr(request);
final String host = request.getRemoteHost();
log.debug("Authentication Success for {}@{} ({})", login, ipAddress, host);
HttpSession session = request.getSession(false);
if (session != null) {
final String sessionId = session.getId();
session.setAttribute(Constants.SESSION_ID_ATTR, sessionId);
session.setMaxInactiveInterval(Constants.SESSION_TIMEOUT_SECONDS);
}
}
}

View File

@ -8,29 +8,30 @@
<meta name="author" content=""> <meta name="author" content="">
<title>Вход</title> <title>Вход</title>
<!-- Bootstrap core CSS --> <!-- Bootstrap core CSS -->
<link href="bootstrap_theme/bootstrap.css" rel="stylesheet" type="text/css"> <link href="/bootstrap_theme/bootstrap.css" rel="stylesheet" type="text/css">
<!-- Custom styles for this template --> <!-- Custom styles for this template -->
<link href="css/style.css" rel="stylesheet"> <link href="/css/style.css" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Allerta&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Allerta&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abel&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Abel&display=swap">
</head> </head>
<body class="bg-gradient bg-success-subtle bg-white border mt-0" <body class="bg-gradient bg-success-subtle bg-white border mt-0"
style="position: relative; height: 900px; font-family: 'Allerta', sans-serif; background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 67%, rgba(0, 0, 0, 0.33) 99%) !important;"> style="position: relative; height: 900px; font-family: 'Allerta', sans-serif; background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0) 67%, rgba(0, 0, 0, 0.33) 99%) !important;">
<script src="assets/js/popper.min.js"></script> <script src="/assets.js/popper.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script> <script src="/bootstrap/js/bootstrap.min.js"></script>
<div class="row" <div class="row"
style="justify-content: space-between; display: flex; align-items: stretch; flex-wrap: nowrap; align-content: stretch; max-width: 100%;"> style="justify-content: space-between; display: flex; align-items: stretch; flex-wrap: nowrap; align-content: stretch; max-width: 100%;">
<img src="css\Index_img\2033603791.gif" <img src="/css\Index_img\2033603791.gif"
style="width: 27.867%; display: inline-block; padding-right: 0%; margin-right: 0%;"> style="width: 27.867%; display: inline-block; padding-right: 0%; margin-right: 0%;">
<img src="css\Index_img\ремонт.jpg" <img src="/css\Index_img\ремонт.jpg"
style="width: 21.167%; display: inline-block; padding-right: 0%; padding-left: 0%; margin-right: -1.5%;" style="width: 21.167%; display: inline-block; padding-right: 0%; padding-left: 0%; margin-right: -1.5%;"
class="border-secondary border-start"> class="border-secondary border-start">
<img src="css\Index_img\1492683.jpg" style="width: 18%; margin-right: -1.404%; padding-right: 0%; padding-left: 0%;" <img src="/css\Index_img\1492683.jpg"
style="width: 18%; margin-right: -1.404%; padding-right: 0%; padding-left: 0%;"
class="border-secondary border-start"> class="border-secondary border-start">
<img src="css\Index_img\d0_b1_d0_b51.jpg" <img src="/css\Index_img\d0_b1_d0_b51.jpg"
style="width: 21.1%; margin-right: 0%; padding-left: 0%; padding-right: 0%;" style="width: 21.1%; margin-right: 0%; padding-left: 0%; padding-right: 0%;"
class="border-secondary border-start"> class="border-secondary border-start">
<img src="css\Index_img\8qii3srewyar9x9bd5r019kyadwaxiwx.png" <img src="/css\Index_img\8qii3srewyar9x9bd5r019kyadwaxiwx.png"
style="width: 17%; padding-left: 0%; padding-right: 0%; margin-right: 0%; margin-left: 0%;" style="width: 17%; padding-left: 0%; padding-right: 0%; margin-right: 0%; margin-left: 0%;"
class="border-secondary border-start"> class="border-secondary border-start">
</div> </div>
@ -75,7 +76,8 @@
<div class="form-group" style="margin-top: -1.953vw;"> <div class="form-group" style="margin-top: -1.953vw;">
<label for="exampleInputEmail1" <label for="exampleInputEmail1"
style="margin-top: 1.918vw; margin-bottom: 0.595vw; position: relative; left: 31%;">Логин</label> style="margin-top: 1.918vw; margin-bottom: 0.595vw; position: relative; left: 31%;">Логин</label>
<input type="email" name="login" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" <input type="email" name="username" class="form-control" id="exampleInputEmail1"
aria-describedby="emailHelp"
placeholder="Введите логин" placeholder="Введите логин"
style="width: 23.577vw; font-family: 'Abel', sans-serif; position: relative; left: 31%;"> style="width: 23.577vw; font-family: 'Abel', sans-serif; position: relative; left: 31%;">
</div> </div>

View File

@ -65,6 +65,13 @@
<li class="nav-item"><a class="border-end border-secondary border-start nav-link" href="contacts.html" <li class="nav-item"><a class="border-end border-secondary border-start nav-link" href="contacts.html"
style="font-family: 'Allerta', sans-serif;">Связаться с нами</a> style="font-family: 'Allerta', sans-serif;">Связаться с нами</a>
</li> </li>
<li class="nav-item">
<a class="nav-item nav-link" href="/logout">
<i class="fa fa-sign-out" aria-hidden="true"></i>
Выход
</a>
</li>
</ul> </ul>
</div> </div>
</div> </div>