Compare commits
6 Commits
aefeeeee48
...
048a00a4a4
Author | SHA1 | Date | |
---|---|---|---|
048a00a4a4 | |||
fcf22c2a4d | |||
4a64a94660 | |||
1c8d6ccfd0 | |||
0fb27f8d13 | |||
8ae10007bb |
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
3828
data.trace.db
3828
data.trace.db
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,8 @@
|
|||||||
package com.webproglabs.lab1;
|
package com.webproglabs.lab1;
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileController;
|
import com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||||
import com.webproglabs.lab1.lab34.controller.mvc_controllers.UserSignupMvcController;
|
import com.webproglabs.lab1.lab34.mvc.UserSignUpMvcController;
|
||||||
import com.webproglabs.lab1.lab34.jwt.JwtFilter;
|
import com.webproglabs.lab1.lab34.services.UserService;
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
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;
|
||||||
@ -17,12 +15,10 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
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.config.http.SessionCreationPolicy;
|
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
|
||||||
@ -36,18 +32,16 @@ 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;
|
||||||
private final JwtFilter jwtFilter;
|
|
||||||
|
|
||||||
public SecurityConfiguration(ProfileService userService) {
|
public SecurityConfiguration(UserService userService) {
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.jwtFilter = new JwtFilter(userService);
|
|
||||||
createAdminOnStartup();
|
createAdminOnStartup();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAdminOnStartup() {
|
private void createAdminOnStartup() {
|
||||||
final String admin = "admin";
|
final String admin = "admin";
|
||||||
if (userService.findByLogin(admin) == null) {
|
if (userService.findUserByLogin(admin) == null) {
|
||||||
log.info("Admin user successfully created");
|
log.info("Admin user successfully created");
|
||||||
try {
|
try {
|
||||||
userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
||||||
@ -59,13 +53,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
protected void configure(HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
|
http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
|
||||||
http.headers().frameOptions().sameOrigin().and()
|
http.headers().frameOptions().sameOrigin().and()
|
||||||
.cors().and()
|
.cors().and()
|
||||||
.csrf().disable()
|
.csrf().disable()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
.antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
|
.antMatchers(UserSignUpMvcController.SIGNUP_URL).permitAll()
|
||||||
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
||||||
.anyRequest().authenticated()
|
.anyRequest().authenticated()
|
||||||
.and()
|
.and()
|
||||||
|
@ -1,105 +0,0 @@
|
|||||||
package com.webproglabs.lab1;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileController;
|
|
||||||
import com.webproglabs.lab1.lab34.controller.mvc_controllers.UserSignupMvcController;
|
|
||||||
import com.webproglabs.lab1.lab34.jwt.JwtFilter;
|
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Profile;
|
|
||||||
import org.springframework.http.HttpMethod;
|
|
||||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
|
||||||
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.config.http.SessionCreationPolicy;
|
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
|
||||||
import org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint;
|
|
||||||
import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
|
|
||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@EnableWebSecurity
|
|
||||||
@EnableGlobalMethodSecurity(securedEnabled = true)
|
|
||||||
@Profile("spa")
|
|
||||||
public class SecurityConfigurationSPA extends WebSecurityConfigurerAdapter {
|
|
||||||
private final Logger log = LoggerFactory.getLogger(SecurityConfiguration.class);
|
|
||||||
private static final String LOGIN_URL = "/login";
|
|
||||||
public static final String SPA_URL_MASK = "/{path:[^\\.]*}";
|
|
||||||
private final ProfileService userService;
|
|
||||||
private final JwtFilter jwtFilter;
|
|
||||||
|
|
||||||
public SecurityConfigurationSPA(ProfileService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
this.jwtFilter = new JwtFilter(userService);
|
|
||||||
createAdminOnStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createAdminOnStartup() {
|
|
||||||
final String admin = "admin";
|
|
||||||
if (userService.findByLogin(admin) == null) {
|
|
||||||
log.info("Admin user successfully created");
|
|
||||||
try {
|
|
||||||
userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(HttpSecurity http) throws Exception {
|
|
||||||
log.info("Creating security configuration");
|
|
||||||
http.cors()
|
|
||||||
.and()
|
|
||||||
.csrf().disable()
|
|
||||||
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
|
||||||
.and()
|
|
||||||
.authorizeRequests()
|
|
||||||
.antMatchers("/", SPA_URL_MASK).permitAll()
|
|
||||||
.antMatchers(HttpMethod.POST, WebConfiguration.REST_API + "/profile" + ProfileController.URL_LOGIN).permitAll()
|
|
||||||
.anyRequest()
|
|
||||||
.authenticated()
|
|
||||||
.and()
|
|
||||||
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
|
|
||||||
.anonymous();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
|
|
||||||
auth.userDetailsService(userService);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void configure(WebSecurity web) {
|
|
||||||
web.ignoring()
|
|
||||||
.antMatchers("/css/**")
|
|
||||||
.antMatchers("/js/**")
|
|
||||||
.antMatchers("/templates/**")
|
|
||||||
.antMatchers("/webjars/**")
|
|
||||||
.antMatchers("/swagger-resources/**")
|
|
||||||
.antMatchers("/v3/api-docs/**");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public AuthenticationEntryPoint delegatingEntryPoint() {
|
|
||||||
final LinkedHashMap<RequestMatcher, AuthenticationEntryPoint> map = new LinkedHashMap();
|
|
||||||
map.put(new AntPathRequestMatcher("/"), new LoginUrlAuthenticationEntryPoint("/login"));
|
|
||||||
map.put(new AntPathRequestMatcher("/api/1.0/**"), new Http403ForbiddenEntryPoint());
|
|
||||||
|
|
||||||
final DelegatingAuthenticationEntryPoint entryPoint = new DelegatingAuthenticationEntryPoint(map);
|
|
||||||
entryPoint.setDefaultEntryPoint(new LoginUrlAuthenticationEntryPoint("/login"));
|
|
||||||
|
|
||||||
return entryPoint;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,5 @@
|
|||||||
package com.webproglabs.lab1;
|
package com.webproglabs.lab1;
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.OpenAPI30Configuration;
|
|
||||||
import org.springframework.boot.web.server.ErrorPage;
|
import org.springframework.boot.web.server.ErrorPage;
|
||||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||||
@ -13,7 +12,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebConfiguration implements WebMvcConfigurer {
|
public class WebConfiguration implements WebMvcConfigurer {
|
||||||
public static final String REST_API = OpenAPI30Configuration.API_PREFIX;
|
public static final String REST_API = "/api";
|
||||||
@Override
|
@Override
|
||||||
public void addViewControllers(ViewControllerRegistry registry) {
|
public void addViewControllers(ViewControllerRegistry registry) {
|
||||||
WebMvcConfigurer.super.addViewControllers(registry);
|
WebMvcConfigurer.super.addViewControllers(registry);
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab1;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class Lab1Controller {
|
|
||||||
@GetMapping("/ilove")
|
|
||||||
public String ilove(@RequestParam(value = "thing", defaultValue = "cookies") String thing) {
|
|
||||||
return String.format("I love %s!", thing);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/ask")
|
|
||||||
public String question(@RequestParam(value = "question", defaultValue = "Задайте вопрос") String question) {
|
|
||||||
if (question.contains("Задайте вопрос")) return question;
|
|
||||||
String[] answers = new String[] {
|
|
||||||
"Не знаю",
|
|
||||||
"Да",
|
|
||||||
"Нет",
|
|
||||||
"Спросите у мамы"
|
|
||||||
};
|
|
||||||
Random random = new Random();
|
|
||||||
return answers[random.nextInt(4)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/touppercase")
|
|
||||||
public String tuupper(@RequestParam(value = "content", defaultValue = "Введите строку") String content) {
|
|
||||||
return content.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/date")
|
|
||||||
public String date () {
|
|
||||||
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
|
|
||||||
LocalDateTime now = LocalDateTime.now();
|
|
||||||
return dtf.format(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2.config;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab2.domain.Lab2Int;
|
|
||||||
import com.webproglabs.lab1.lab2.domain.Lab2String;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class Lab2Config {
|
|
||||||
|
|
||||||
@Bean(value="int")
|
|
||||||
public Lab2Int createLab2Int() {
|
|
||||||
return new Lab2Int();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean(value="String")
|
|
||||||
public Lab2String createLab2String() {
|
|
||||||
return new Lab2String();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//фронт на жсон сервер был когда то
|
|
||||||
//сделать на основе старых сущностей сущности в жпа
|
|
||||||
//делаем сущности, зависимость для жпа, сервис для круд операций,
|
|
||||||
//тесты
|
|
||||||
//фронт не нужно
|
|
||||||
//двунправленная связь один ко многим
|
|
@ -1,35 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2.controllers;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab2.Lab2Service;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
public class Lab2Controller {
|
|
||||||
private final Lab2Service lab2Service;
|
|
||||||
|
|
||||||
public Lab2Controller(Lab2Service lab2Service) {this.lab2Service = lab2Service;}
|
|
||||||
|
|
||||||
@GetMapping("/lab2/sum")
|
|
||||||
public Object sum(@RequestParam (value = "first", defaultValue = "hello") String first,
|
|
||||||
@RequestParam (value = "second", defaultValue = "world") String second,
|
|
||||||
@RequestParam (value = "type") String type) {
|
|
||||||
return lab2Service.sum(first, second, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/lab2/makeitbigger")
|
|
||||||
public Object makeItBigger(@RequestParam (value = "small") String small, @RequestParam (value = "type") String type) {
|
|
||||||
return lab2Service.makeItBigger(small, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/lab2/reverse")
|
|
||||||
public Object reverse(@RequestParam(value="value")String value, @RequestParam (value = "type") String type) {
|
|
||||||
return lab2Service.reverse(value, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("lab2/lenght")
|
|
||||||
public Object lenght(@RequestParam(value = "value") String value, @RequestParam (value = "type") String type) {
|
|
||||||
return lab2Service.lenght(value, type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab2.domain.Lab2Interface;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class Lab2Service {
|
|
||||||
private final ApplicationContext applicationContext;
|
|
||||||
|
|
||||||
public Lab2Service(ApplicationContext applicationContext) {
|
|
||||||
this.applicationContext = applicationContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object sum(Object first, Object second, String type) {
|
|
||||||
if (type.equals("int")) {
|
|
||||||
first = Integer.parseInt(first.toString());
|
|
||||||
second = Integer.parseInt(second.toString());
|
|
||||||
}
|
|
||||||
final Lab2Interface summator =(Lab2Interface)applicationContext.getBean(type);
|
|
||||||
return summator.sum(first, second);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object makeItBigger(Object small, String type) {
|
|
||||||
if (type.equals("int")) {
|
|
||||||
small = Integer.parseInt(small.toString());
|
|
||||||
}
|
|
||||||
final Lab2Interface biggernator = (Lab2Interface)applicationContext.getBean(type);
|
|
||||||
return biggernator.makeItBigger(small);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object reverse (Object value, String type) {
|
|
||||||
if (type.equals("int")) {
|
|
||||||
value = Integer.parseInt(value.toString());
|
|
||||||
}
|
|
||||||
final Lab2Interface reversenator = (Lab2Interface) applicationContext.getBean(type);
|
|
||||||
return reversenator.reverse(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object lenght (Object value, String type) {
|
|
||||||
if (type.equals("int")) {
|
|
||||||
value = Integer.parseInt(value.toString());
|
|
||||||
}
|
|
||||||
final Lab2Interface leghtgetter = (Lab2Interface) applicationContext.getBean(type);
|
|
||||||
return leghtgetter.lenght(value);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2.domain;
|
|
||||||
|
|
||||||
public class Lab2Int implements Lab2Interface<Integer>{
|
|
||||||
// @Override
|
|
||||||
// public Object sum(Object first, Object second) {
|
|
||||||
// if (!(first instanceof Integer && second instanceof Integer)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return (Integer)first + (Integer)second;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object makeItBigger(Object small) {
|
|
||||||
// if (!(small instanceof Integer)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return (Integer)small * (Integer)small;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object reverse(Object value) {
|
|
||||||
// if (!(value instanceof Integer)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return (Integer)value * (-1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object lenght(Object value) {
|
|
||||||
// if (!(value instanceof Integer)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// int newvalue = (Integer)value;
|
|
||||||
// if (newvalue < 0) newvalue = newvalue * (-1);
|
|
||||||
// return newvalue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer sum(Integer first, Integer second) {
|
|
||||||
return first + second;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer makeItBigger(Integer small) {
|
|
||||||
return small*small;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer reverse(Integer value) {
|
|
||||||
return value*(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer lenght(Integer value) {
|
|
||||||
if (value < 0) return value *(-1);
|
|
||||||
else return value;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2.domain;
|
|
||||||
|
|
||||||
public interface Lab2Interface<T> {
|
|
||||||
T sum(T first, T second);
|
|
||||||
|
|
||||||
T makeItBigger (T small);
|
|
||||||
|
|
||||||
T reverse (T value);
|
|
||||||
|
|
||||||
T lenght (T value);
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab2.domain;
|
|
||||||
|
|
||||||
public class Lab2String implements Lab2Interface<String>{
|
|
||||||
// @Override
|
|
||||||
// public Object sum(Object first, Object second) {
|
|
||||||
// if (!(first instanceof String && second instanceof String)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return ((String) first).concat((String)second);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object makeItBigger(Object small) {
|
|
||||||
// if (!(small instanceof String)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return ((String) small).toUpperCase();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object reverse(Object value) {
|
|
||||||
// if (!(value instanceof String)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// StringBuilder sb = new StringBuilder((String)value);
|
|
||||||
// sb.reverse();
|
|
||||||
// return sb.toString();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Object lenght(Object value) {
|
|
||||||
// if (!(value instanceof String)) {
|
|
||||||
// throw new IllegalArgumentException();
|
|
||||||
// }
|
|
||||||
// return ((String) value).length();
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String sum(String first, String second) {
|
|
||||||
return first.concat(second);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String makeItBigger(String small) {
|
|
||||||
return small.toUpperCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String reverse(String value) {
|
|
||||||
StringBuilder sb = new StringBuilder(value);
|
|
||||||
sb.reverse();
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String lenght(String value) {
|
|
||||||
int len = value.length();
|
|
||||||
return Integer.toString(len);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.jwt.JwtFilter;
|
|
||||||
import io.swagger.v3.oas.models.Components;
|
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class OpenAPI30Configuration {
|
|
||||||
public static final String API_PREFIX = "/api/1.0";
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public OpenAPI customizeOpenAPI() {
|
|
||||||
final String securitySchemeName = JwtFilter.TOKEN_BEGIN_STR;
|
|
||||||
return new OpenAPI()
|
|
||||||
.addSecurityItem(new SecurityRequirement()
|
|
||||||
.addList(securitySchemeName))
|
|
||||||
.components(new Components()
|
|
||||||
.addSecuritySchemes(securitySchemeName, new SecurityScheme()
|
|
||||||
.name(securitySchemeName)
|
|
||||||
.type(SecurityScheme.Type.HTTP)
|
|
||||||
.scheme("bearer")
|
|
||||||
.bearerFormat("JWT")));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.WebConfiguration;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.services.CommentService;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/comment")
|
|
||||||
public class CommentController {
|
|
||||||
private final CommentService commentService;
|
|
||||||
|
|
||||||
public CommentController(CommentService commentService) {
|
|
||||||
this.commentService = commentService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public CommentDto getComment(@PathVariable Long id) {
|
|
||||||
return new CommentDto(commentService.findComment(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public List<CommentDto> getComments() {
|
|
||||||
return commentService.findAllComments().stream()
|
|
||||||
.map(CommentDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
@GetMapping("/find")
|
|
||||||
public List<PostDto> getFilteredComments(@RequestParam("text") String text) {
|
|
||||||
return commentService.findFilteredComments(text).stream()
|
|
||||||
.map(PostDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@PostMapping
|
|
||||||
public CommentDto createComment(@RequestParam("text") String text, @RequestParam("ownerId") Long id, @RequestParam("postId") Long postId){
|
|
||||||
final Comment comment = commentService.addComment(text, id, postId);
|
|
||||||
return new CommentDto(comment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public CommentDto updateComment(@RequestParam("text") String text, @PathVariable Long id) {
|
|
||||||
return new CommentDto(commentService.updateComment(id, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public CommentDto deleteComment(@PathVariable Long id) {
|
|
||||||
return new CommentDto(commentService.deleteComment(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping
|
|
||||||
public void deleteAllComments(){
|
|
||||||
commentService.deleteAllComments();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
|
|
||||||
public class CommentDto {
|
|
||||||
private Long id;
|
|
||||||
private String text;
|
|
||||||
private String authorLogin;
|
|
||||||
|
|
||||||
public CommentDto(Comment comment) {
|
|
||||||
this.id = comment.getId();
|
|
||||||
this.text = comment.getText();
|
|
||||||
this.authorLogin = comment.getOwner().getLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getText() {return text;}
|
|
||||||
public String getAuthor() {return authorLogin;}
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.WebConfiguration;
|
|
||||||
import com.webproglabs.lab1.lab34.services.PostService;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/post")
|
|
||||||
public class PostController {
|
|
||||||
private final PostService postService;
|
|
||||||
|
|
||||||
public PostController(PostService postService) {
|
|
||||||
this.postService = postService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public PostDto getPost(@PathVariable Long id) {
|
|
||||||
return new PostDto(postService.findPost(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public List<PostDto> getPosts() {
|
|
||||||
return postService.findAllPosts().stream()
|
|
||||||
.map(PostDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/find")
|
|
||||||
public List<PostDto> getFilteredPosts(@RequestParam("text") String text) {
|
|
||||||
return postService.findFilteredPosts(text).stream()
|
|
||||||
.map(PostDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping
|
|
||||||
public PostDto createPost(
|
|
||||||
@RequestParam("text") String text,
|
|
||||||
@RequestParam("authorId") Long authorId
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return new PostDto(postService.addPost(text, new ArrayList<>(),authorId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public PostDto updatePost(
|
|
||||||
@PathVariable Long id,
|
|
||||||
@RequestParam("text") String text
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return new PostDto(postService.updatePost(id, text));
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public PostDto deletePost (@PathVariable Long id) {
|
|
||||||
return new PostDto(postService.deletePost(id));
|
|
||||||
}
|
|
||||||
@DeleteMapping
|
|
||||||
public void deleteAllPosts() {
|
|
||||||
postService.deleteAllPosts();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PostDto {
|
|
||||||
private Long id;
|
|
||||||
private String text;
|
|
||||||
private List<CommentDto> comments = new ArrayList<>();
|
|
||||||
|
|
||||||
private String authorLogin;
|
|
||||||
|
|
||||||
public PostDto(Post post){
|
|
||||||
this.id = post.getId();
|
|
||||||
this.text = post.getText();
|
|
||||||
for(Comment comment: post.getComments()){
|
|
||||||
comments.add(new CommentDto(comment));
|
|
||||||
}
|
|
||||||
this.authorLogin = post.getAuthor().getLogin();
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getText() {return text;}
|
|
||||||
public List<CommentDto> getComments() {return comments;}
|
|
||||||
public String getAuthor() {return authorLogin;}
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.WebConfiguration;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RestController
|
|
||||||
@RequestMapping(WebConfiguration.REST_API + "/profile")
|
|
||||||
public class ProfileController {
|
|
||||||
|
|
||||||
public static final String URL_LOGIN = "/jwt/login";
|
|
||||||
|
|
||||||
private final ProfileService profileService;
|
|
||||||
|
|
||||||
public ProfileController(ProfileService profileService) {
|
|
||||||
this.profileService = profileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public ProfileDto getProfile(@PathVariable Long id) {
|
|
||||||
return new ProfileDto(profileService.findUser(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/find/{login}")
|
|
||||||
public ProfileDto getProfileByLogin(@PathVariable String login) {
|
|
||||||
return new ProfileDto(profileService.findByLogin(login));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public List<ProfileDto> getProfiles() {
|
|
||||||
return profileService.findAllUsers().stream()
|
|
||||||
.map(ProfileDto::new)
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping
|
|
||||||
public ProfileDto createProfile(
|
|
||||||
@RequestParam("login") String login,
|
|
||||||
@RequestParam("password") String password
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return new ProfileDto(profileService.addUser(login, password, new ArrayList<>(),new ArrayList<>() ));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
|
||||||
public ProfileDto updateProfile(
|
|
||||||
@PathVariable Long id,
|
|
||||||
@RequestParam("login") String login,
|
|
||||||
@RequestParam("password") String password
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return new ProfileDto(profileService.updateUser(id, login, password));
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/{id}")
|
|
||||||
public ProfileDto deleteProfile (@PathVariable Long id) {
|
|
||||||
return new ProfileDto(profileService.deleteUser(id));
|
|
||||||
}
|
|
||||||
@DeleteMapping
|
|
||||||
public void deleteAllProfiles() {
|
|
||||||
profileService.deleteAllUsers();
|
|
||||||
}
|
|
||||||
@PostMapping(URL_LOGIN)
|
|
||||||
public String login(@RequestBody @Valid ProfileDto userDto) {
|
|
||||||
return profileService.loginAndGetToken(userDto);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// этот метод юзать для проверки на администраторсткую роль вместо старой проверки по логину админа ЛОЛ
|
|
||||||
//
|
|
||||||
@GetMapping("role/{token}")
|
|
||||||
public String getRoleByToken(@PathVariable String token) {
|
|
||||||
var userDetails = profileService.loadUserByToken(token);
|
|
||||||
Profile user = profileService.findByLogin(userDetails.getUsername());
|
|
||||||
if (user != null) {
|
|
||||||
return user.getRole().toString();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ProfileDto {
|
|
||||||
private Long id;
|
|
||||||
private String login;
|
|
||||||
private String password;
|
|
||||||
private List<CommentDto> comments = new ArrayList<>();
|
|
||||||
|
|
||||||
private List<PostDto> posts = new ArrayList<>();
|
|
||||||
|
|
||||||
private UserRole role;
|
|
||||||
|
|
||||||
public ProfileDto(){}
|
|
||||||
|
|
||||||
public ProfileDto(Profile profile){
|
|
||||||
this.id = profile.getId();
|
|
||||||
this.login = profile.getLogin();
|
|
||||||
this.password = profile.getPassword();
|
|
||||||
this.role = profile.getRole();
|
|
||||||
for(Comment comment: profile.getComments()){
|
|
||||||
comments.add(new CommentDto(comment));
|
|
||||||
}
|
|
||||||
for (Post post: profile.getPosts()) {
|
|
||||||
posts.add(new PostDto(post));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
|
||||||
public long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
public String getLogin() {return login;}
|
|
||||||
public void setLogin(String login) {this.login = login;}
|
|
||||||
public String getPassword() {return password;}
|
|
||||||
|
|
||||||
public UserRole getRole() {return role;}
|
|
||||||
|
|
||||||
public void setPassword(String password) {this.password = password;}
|
|
||||||
public List<CommentDto> getComments() {return comments;}
|
|
||||||
public List<PostDto> getPosts() {return posts;}
|
|
||||||
}
|
|
@ -1,121 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.controller.CommentDto;
|
|
||||||
import com.webproglabs.lab1.lab34.controller.PostDto;
|
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.services.CommentService;
|
|
||||||
import com.webproglabs.lab1.lab34.services.PostService;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/feed")
|
|
||||||
public class FeedMvcController {
|
|
||||||
private final ProfileService profileService;
|
|
||||||
private final PostService postService;
|
|
||||||
private final CommentService commentService;
|
|
||||||
public FeedMvcController(ProfileService profileService, PostService postService, CommentService commentService) {
|
|
||||||
this.profileService = profileService;
|
|
||||||
this.postService = postService;
|
|
||||||
this.commentService = commentService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public String getFeedPage(Model model) {
|
|
||||||
UserDetails principal = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
|
||||||
var user = profileService.findByLogin(principal.getUsername());
|
|
||||||
if (user != null) {
|
|
||||||
return "redirect:/feed/" + user.getId().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
return "feed";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"/{id}"})
|
|
||||||
public String getFeedPageAuthorized(@PathVariable Long id, Model model) {
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(id)));
|
|
||||||
|
|
||||||
return "feedPosts";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value= {"/filter/{id}/"})
|
|
||||||
public String getFeedPageFiltered(@PathVariable Long id, @RequestParam(value="searchField") String searchField, Model model) {
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("posts", postService.findFilteredPosts(searchField).stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(id)));
|
|
||||||
return "feedPosts";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value={"/post/{id}/"})
|
|
||||||
public String createPost(@PathVariable Long id, @RequestParam(value="postInputField") String postInputField) {
|
|
||||||
postService.addPost(postInputField, new ArrayList<>(), id);
|
|
||||||
return "redirect:/feed/" + id.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/deletePost/{id}/{authorId}"})
|
|
||||||
public String deletePost(@PathVariable Long id, @PathVariable Long authorId) {
|
|
||||||
postService.deletePost(id);
|
|
||||||
return "redirect:/feed/" + authorId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"postModal/{id}/{authorId}"})
|
|
||||||
public String getPostEditModal(@PathVariable Long id,@PathVariable Long authorId, Model model) {
|
|
||||||
model.addAttribute("selectedPost", new PostDto(postService.findPost(id)));
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(authorId)));
|
|
||||||
return "editPostModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"editPost/{id}/{authorId}/"})
|
|
||||||
public String editPost(@PathVariable Long id, @PathVariable Long authorId, @RequestParam(value="postEditField") String postEditField) {
|
|
||||||
postService.updatePost(id, postEditField);
|
|
||||||
return "redirect:/feed/" + authorId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"commentModal/{authorId}/{postId}"})
|
|
||||||
public String getCommentModal(@PathVariable Long authorId,@PathVariable Long postId, Model model) {
|
|
||||||
model.addAttribute("selectedPost", new PostDto(postService.findPost(postId)));
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(authorId)));
|
|
||||||
return "commentModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"comment/{authorId}/{postId}/"})
|
|
||||||
public String createComment(@PathVariable Long authorId,@PathVariable Long postId, @RequestParam(value="commentInputField") String commentInputField) {
|
|
||||||
commentService.addComment(commentInputField, authorId, postId);
|
|
||||||
return "redirect:/feed/" + authorId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"/deleteComment/{id}/{authorId}"})
|
|
||||||
public String deleteComment(@PathVariable Long id, @PathVariable Long authorId) {
|
|
||||||
commentService.deleteComment(id);
|
|
||||||
return "redirect:/feed/" + authorId.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"commentEditModal/{id}/{authorId}"})
|
|
||||||
public String getCommentEditModal(@PathVariable Long id,@PathVariable Long authorId, Model model) {
|
|
||||||
model.addAttribute("selectedComment", new CommentDto(commentService.findComment(id)));
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("posts", postService.findAllPosts().stream().map(PostDto::new).toList());
|
|
||||||
model.addAttribute("selectedProfile", new ProfileDto(profileService.findUser(authorId)));
|
|
||||||
return "editCommentModal";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"editComment/{authorId}/{commentId}/"})
|
|
||||||
public String editComment(@PathVariable Long authorId,@PathVariable Long commentId, @RequestParam(value="commentEditField") String commentEditField) {
|
|
||||||
commentService.updateComment(commentId, commentEditField);
|
|
||||||
return "redirect:/feed/" + authorId.toString();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
import org.springframework.security.access.annotation.Secured;
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/")
|
|
||||||
public class ProfileMvcController {
|
|
||||||
private final ProfileService profileService;
|
|
||||||
|
|
||||||
public ProfileMvcController(ProfileService profileService) {
|
|
||||||
this.profileService = profileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping
|
|
||||||
public String index() {
|
|
||||||
return "default";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value={"profiles"})
|
|
||||||
@Secured({UserRole.AsString.ADMIN})
|
|
||||||
public String getProfiles(Model model) {
|
|
||||||
model.addAttribute("profiles", profileService.findAllUsers().stream().map(ProfileDto::new).toList());
|
|
||||||
model.addAttribute("profileDto", new ProfileDto());
|
|
||||||
return "profiles";
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = {"profile/{login}"})
|
|
||||||
public String getProfile(@PathVariable String login, Model model) {
|
|
||||||
model.addAttribute("profile", new ProfileDto(profileService.findUserByLogin(login)));
|
|
||||||
return "profilePage";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"profile/{id}"})
|
|
||||||
public String deleteProfile(@PathVariable Long id) {
|
|
||||||
profileService.deleteUser(id);
|
|
||||||
return "redirect:/profiles";
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping(value = {"profile/create/"})
|
|
||||||
public String createProfile(@ModelAttribute ProfileDto profileDto) {
|
|
||||||
profileService.addUser(profileDto.getLogin(), profileDto.getPassword(), new ArrayList<>(), new ArrayList<>());
|
|
||||||
return "redirect:/profiles";
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Category;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CategoryDto {
|
||||||
|
private Long Id;
|
||||||
|
@NotNull
|
||||||
|
private String Name;
|
||||||
|
@NotNull
|
||||||
|
private List<ProductDto> Products;
|
||||||
|
|
||||||
|
public CategoryDto(Category Category) {
|
||||||
|
this.Id = Category.getId();
|
||||||
|
this.Name = Category.getName();
|
||||||
|
this.Products = Category.getProducts().stream().map(ProductDto::new).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryDto(){}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductDto> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
}
|
33
src/main/java/com/webproglabs/lab1/lab34/dto/ProductDto.java
Normal file
33
src/main/java/com/webproglabs/lab1/lab34/dto/ProductDto.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
public class ProductDto {
|
||||||
|
private Long Id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String Name;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Double Cost;
|
||||||
|
|
||||||
|
public ProductDto(Product Product) {
|
||||||
|
this.Id = Product.getId();
|
||||||
|
this.Name = Product.getName();
|
||||||
|
this.Cost = Product.getCost();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCost() { return Cost; }
|
||||||
|
}
|
38
src/main/java/com/webproglabs/lab1/lab34/dto/ShopDto.java
Normal file
38
src/main/java/com/webproglabs/lab1/lab34/dto/ShopDto.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Shop;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ShopDto {
|
||||||
|
private Long Id;
|
||||||
|
@NotNull
|
||||||
|
private String Name;
|
||||||
|
@NotNull
|
||||||
|
private List<ProductDto> Products;
|
||||||
|
|
||||||
|
public ShopDto(Shop Shop) {
|
||||||
|
this.Id = Shop.getId();
|
||||||
|
this.Name = Shop.getName();
|
||||||
|
this.Products = Shop.getProducts().stream().map(ProductDto::new).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShopDto() {}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
public void setName(String name) {
|
||||||
|
this.Name = name;
|
||||||
|
}
|
||||||
|
public List<ProductDto> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
}
|
52
src/main/java/com/webproglabs/lab1/lab34/dto/UserDto.java
Normal file
52
src/main/java/com/webproglabs/lab1/lab34/dto/UserDto.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.webproglabs.lab1.lab34.model.User;
|
||||||
|
import com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UserDto {
|
||||||
|
private Long Id;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String Login;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private String Password;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private List<ProductDto> Products;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private UserRole Role;
|
||||||
|
|
||||||
|
public UserDto(User User) {
|
||||||
|
this.Id = User.getId();
|
||||||
|
this.Login = User.getLogin();
|
||||||
|
this.Password = User.getPassword();
|
||||||
|
this.Role = User.getRole();
|
||||||
|
this.Products = User.getProducts().stream().map(ProductDto::new).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLogin() {
|
||||||
|
return Login;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return Password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ProductDto> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
public UserRole getRole() {
|
||||||
|
return Role;
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,17 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
package com.webproglabs.lab1.lab34.dto;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.Size;
|
import javax.validation.constraints.Size;
|
||||||
|
|
||||||
public class UserSignupDto {
|
public class UserSignUpDto {
|
||||||
@NotBlank
|
@NotBlank
|
||||||
@Size(min = 3, max = 64)
|
@Size(min = 3, max = 64)
|
||||||
private String login;
|
private String login;
|
||||||
@NotBlank
|
@NotBlank
|
||||||
@Size(min = 6, max = 64)
|
@Size(min = 4, max = 64)
|
||||||
private String password;
|
private String password;
|
||||||
@NotBlank
|
@NotBlank
|
||||||
@Size(min = 6, max = 64)
|
@Size(min = 4, max = 64)
|
||||||
private String passwordConfirm;
|
private String passwordConfirm;
|
||||||
|
|
||||||
public String getLogin() {
|
public String getLogin() {
|
@ -1,11 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.jwt;
|
|
||||||
|
|
||||||
public class JwtException extends RuntimeException {
|
|
||||||
public JwtException(Throwable throwable) {
|
|
||||||
super(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public JwtException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.jwt;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
|
||||||
import org.springframework.http.MediaType;
|
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.filter.GenericFilterBean;
|
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.ServletRequest;
|
|
||||||
import javax.servlet.ServletResponse;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class JwtFilter extends GenericFilterBean {
|
|
||||||
private static final String AUTHORIZATION = "Authorization";
|
|
||||||
public static final String TOKEN_BEGIN_STR = "Bearer ";
|
|
||||||
|
|
||||||
private final ProfileService userService;
|
|
||||||
|
|
||||||
public JwtFilter(ProfileService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTokenFromRequest(HttpServletRequest request) {
|
|
||||||
String bearer = request.getHeader(AUTHORIZATION);
|
|
||||||
if (StringUtils.hasText(bearer) && bearer.startsWith(TOKEN_BEGIN_STR)) {
|
|
||||||
return bearer.substring(TOKEN_BEGIN_STR.length());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void raiseException(ServletResponse response, int status, String message) throws IOException {
|
|
||||||
if (response instanceof final HttpServletResponse httpResponse) {
|
|
||||||
httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
||||||
httpResponse.setStatus(status);
|
|
||||||
final byte[] body = new ObjectMapper().writeValueAsBytes(message);
|
|
||||||
response.getOutputStream().write(body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doFilter(ServletRequest request,
|
|
||||||
ServletResponse response,
|
|
||||||
FilterChain chain) throws IOException, ServletException {
|
|
||||||
if (request instanceof final HttpServletRequest httpRequest) {
|
|
||||||
final String token = getTokenFromRequest(httpRequest);
|
|
||||||
if (StringUtils.hasText(token)) {
|
|
||||||
try {
|
|
||||||
final UserDetails user = userService.loadUserByToken(token);
|
|
||||||
final UsernamePasswordAuthenticationToken auth =
|
|
||||||
new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
|
|
||||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
|
||||||
} catch (JwtException e) {
|
|
||||||
raiseException(response, HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
|
|
||||||
return;
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
raiseException(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
|
|
||||||
String.format("Internal error: %s", e.getMessage()));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chain.doFilter(request, response);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.jwt;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
@ConfigurationProperties(prefix = "jwt", ignoreInvalidFields = true)
|
|
||||||
public class JwtProperties {
|
|
||||||
private String devToken = "";
|
|
||||||
private Boolean isDev = true;
|
|
||||||
|
|
||||||
public String getDevToken() {
|
|
||||||
return devToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDevToken(String devToken) {
|
|
||||||
this.devToken = devToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isDev() {
|
|
||||||
return isDev;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDev(Boolean dev) {
|
|
||||||
isDev = dev;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,107 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.jwt;
|
|
||||||
|
|
||||||
import com.auth0.jwt.JWT;
|
|
||||||
import com.auth0.jwt.algorithms.Algorithm;
|
|
||||||
import com.auth0.jwt.exceptions.JWTVerificationException;
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
|
||||||
import com.auth0.jwt.interfaces.JWTVerifier;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class JwtProvider {
|
|
||||||
private final static Logger LOG = LoggerFactory.getLogger(JwtProvider.class);
|
|
||||||
|
|
||||||
private final static byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);
|
|
||||||
private final static String ISSUER = "auth0";
|
|
||||||
|
|
||||||
private final Algorithm algorithm;
|
|
||||||
private final JWTVerifier verifier;
|
|
||||||
|
|
||||||
public JwtProvider(JwtProperties jwtProperties) {
|
|
||||||
if (!jwtProperties.isDev()) {
|
|
||||||
LOG.info("Generate new JWT key for prod");
|
|
||||||
try {
|
|
||||||
final MessageDigest salt = MessageDigest.getInstance("SHA-256");
|
|
||||||
salt.update(UUID.randomUUID().toString().getBytes(StandardCharsets.UTF_8));
|
|
||||||
LOG.info("Use generated JWT key for prod \n{}", bytesToHex(salt.digest()));
|
|
||||||
algorithm = Algorithm.HMAC256(bytesToHex(salt.digest()));
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new JwtException(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG.info("Use default JWT key for dev \n{}", jwtProperties.getDevToken());
|
|
||||||
algorithm = Algorithm.HMAC256(jwtProperties.getDevToken());
|
|
||||||
}
|
|
||||||
verifier = JWT.require(algorithm)
|
|
||||||
.withIssuer(ISSUER)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String bytesToHex(byte[] bytes) {
|
|
||||||
byte[] hexChars = new byte[bytes.length * 2];
|
|
||||||
for (int j = 0; j < bytes.length; j++) {
|
|
||||||
int v = bytes[j] & 0xFF;
|
|
||||||
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
|
|
||||||
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
|
|
||||||
}
|
|
||||||
return new String(hexChars, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String generateToken(String login) {
|
|
||||||
final Date issueDate = Date.from(LocalDate.now()
|
|
||||||
.atStartOfDay(ZoneId.systemDefault())
|
|
||||||
.toInstant());
|
|
||||||
final Date expireDate = Date.from(LocalDate.now()
|
|
||||||
.plusDays(15)
|
|
||||||
.atStartOfDay(ZoneId.systemDefault())
|
|
||||||
.toInstant());
|
|
||||||
return JWT.create()
|
|
||||||
.withIssuer(ISSUER)
|
|
||||||
.withIssuedAt(issueDate)
|
|
||||||
.withExpiresAt(expireDate)
|
|
||||||
.withSubject(login)
|
|
||||||
.sign(algorithm);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DecodedJWT validateToken(String token) {
|
|
||||||
try {
|
|
||||||
return verifier.verify(token);
|
|
||||||
} catch (JWTVerificationException e) {
|
|
||||||
throw new JwtException(String.format("Token verification error: %s", e.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTokenValid(String token) {
|
|
||||||
if (!StringUtils.hasText(token)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
validateToken(token);
|
|
||||||
return true;
|
|
||||||
} catch (JwtException e) {
|
|
||||||
LOG.error(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<String> getLoginFromToken(String token) {
|
|
||||||
try {
|
|
||||||
return Optional.ofNullable(validateToken(token).getSubject());
|
|
||||||
} catch (JwtException e) {
|
|
||||||
LOG.error(e.getMessage());
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
77
src/main/java/com/webproglabs/lab1/lab34/model/Category.java
Normal file
77
src/main/java/com/webproglabs/lab1/lab34/model/Category.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Category {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long Id;
|
||||||
|
|
||||||
|
@Column(unique = true)
|
||||||
|
private String Name;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "Category")
|
||||||
|
private List<Product> Products = new ArrayList<>();
|
||||||
|
|
||||||
|
public Category(String Name) {
|
||||||
|
this.Name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category(){}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Product> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String Name) {
|
||||||
|
this.Name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProduct(Product Product) {
|
||||||
|
this.Products.add(Product);
|
||||||
|
Product.setCategory(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeProduct(Product Product) {
|
||||||
|
this.Products.remove(Product);
|
||||||
|
Product.setCategory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProducts (List<Product> Products) {
|
||||||
|
this.Products = Products;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Category category = (Category) o;
|
||||||
|
return Objects.equals(Id, category.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Category{" +
|
||||||
|
"Id=" + Id +
|
||||||
|
", Name='" + Name +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -1,81 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.model;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Comment {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private Profile owner;
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private Post post;
|
|
||||||
|
|
||||||
public Comment(){};
|
|
||||||
public Comment(String text, Profile owner, Post post) {
|
|
||||||
this.text = text;
|
|
||||||
this.owner = owner;
|
|
||||||
this.post = post;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Profile getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
public void setOwner(Profile owner) {
|
|
||||||
this.owner.getComments().remove(this);
|
|
||||||
this.owner = owner;
|
|
||||||
if (!owner.getComments().contains(this)) {
|
|
||||||
owner.getComments().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Post getPost() {return post; }
|
|
||||||
|
|
||||||
public void setPost(Post post) {
|
|
||||||
this.post.getComments().remove(this);
|
|
||||||
this.post = post;
|
|
||||||
if (!post.getComments().contains(this)) {
|
|
||||||
post.getComments().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Comment comment = (Comment) o;
|
|
||||||
return Objects.equals(id, comment.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "Comment{" +
|
|
||||||
"id=" + id +
|
|
||||||
", text='" + text + '\'' +
|
|
||||||
", owner='" + owner.ToString() + '\'' +
|
|
||||||
", post='" + post.ToString() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.model;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
public class Post {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
private String text;
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "post", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Comment> comments = new ArrayList<Comment>();
|
|
||||||
|
|
||||||
@ManyToOne()
|
|
||||||
private Profile author;
|
|
||||||
|
|
||||||
public Post(){}
|
|
||||||
public Post(String text, Profile author, List<Comment> comments) {
|
|
||||||
this.text = text;
|
|
||||||
this.author = author;
|
|
||||||
for (int i = 0; i < comments.size(); i++) {
|
|
||||||
addComment(comments.get(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getText() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Profile getAuthor() {
|
|
||||||
return author;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthor(Profile author) {
|
|
||||||
this.author.getPosts().remove(this);
|
|
||||||
this.author = author;
|
|
||||||
if (!author.getPosts().contains(this)) {
|
|
||||||
author.getPosts().add(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Comment> getComments() { return comments; }
|
|
||||||
public int getCommentsSize() {
|
|
||||||
if (comments == null) return 0;
|
|
||||||
else return comments.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addComment(Comment comment) {
|
|
||||||
this.comments.add(comment);
|
|
||||||
if (comment.getPost() != this) {
|
|
||||||
comment.setPost(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Post post = (Post) o;
|
|
||||||
return Objects.equals(id, post.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "Post{" +
|
|
||||||
"id=" + id +
|
|
||||||
", text='" + text + '\'' +
|
|
||||||
", author='" + author.ToString() + '\'' +
|
|
||||||
", comments='" + getCommentsSize() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
103
src/main/java/com/webproglabs/lab1/lab34/model/Product.java
Normal file
103
src/main/java/com/webproglabs/lab1/lab34/model/Product.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Product {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long Id;
|
||||||
|
|
||||||
|
private String Name;
|
||||||
|
|
||||||
|
public Double Cost;
|
||||||
|
|
||||||
|
@ManyToOne()
|
||||||
|
private Shop Shop;
|
||||||
|
|
||||||
|
@ManyToOne()
|
||||||
|
private Category Category;
|
||||||
|
|
||||||
|
@ManyToMany()
|
||||||
|
private List<User> Users = new ArrayList<>();
|
||||||
|
|
||||||
|
public Product (String Name, Double Cost, Shop Shop, Category Category) {
|
||||||
|
this.Name = Name;
|
||||||
|
this.Shop = Shop;
|
||||||
|
this.Cost = Cost;
|
||||||
|
this.Category = Category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Product(){}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCost(){ return Cost; }
|
||||||
|
|
||||||
|
public Shop getShop() {
|
||||||
|
return Shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Category getCategory() {
|
||||||
|
return Category;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<User> getUsers() {
|
||||||
|
return Users;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String Name) {
|
||||||
|
this.Name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCost(Double Cost) { this.Cost = Cost; }
|
||||||
|
|
||||||
|
public void setShop(Shop Shop) {
|
||||||
|
this.Shop.removeProduct(this);
|
||||||
|
Shop.addProduct(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategory(Category Category) {
|
||||||
|
this.Category.removeProduct(this);
|
||||||
|
Category.addProduct(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUser(User User) {
|
||||||
|
Users.add(User);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeUser(User User) {
|
||||||
|
Users.remove(User);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Product product = (Product) o;
|
||||||
|
return Objects.equals(Id, product.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Product{" +
|
||||||
|
"Id=" + Id +
|
||||||
|
", name='" + Name +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,133 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.model;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import javax.validation.constraints.NotBlank;
|
|
||||||
import javax.validation.constraints.Size;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name="tab_user")
|
|
||||||
public class Profile {
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@Column(nullable = false, unique = true, length = 64)
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 3, max = 64)
|
|
||||||
private String login;
|
|
||||||
|
|
||||||
@Column(nullable = false, length = 64)
|
|
||||||
@NotBlank
|
|
||||||
@Size(min = 6, max = 64)
|
|
||||||
private String password;
|
|
||||||
|
|
||||||
private UserRole role;
|
|
||||||
|
|
||||||
public UserRole getRole() {
|
|
||||||
return role;
|
|
||||||
}
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "owner", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Comment> comments = new ArrayList<Comment>();
|
|
||||||
|
|
||||||
@OneToMany(mappedBy = "author", orphanRemoval = true, fetch = FetchType.EAGER)
|
|
||||||
private List<Post> posts = new ArrayList<Post>();
|
|
||||||
|
|
||||||
public Profile(){}
|
|
||||||
public Profile(String login, String password, List<Comment> comments, List<Post> posts) {
|
|
||||||
this.login = login;
|
|
||||||
this.password=password;
|
|
||||||
this.role = UserRole.USER;
|
|
||||||
for (int i = 0; i < comments.size(); i++) {
|
|
||||||
addComment(comments.get(i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < posts.size(); i++) {
|
|
||||||
addPost(posts.get(i));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
public Profile(String login, String password, List<Comment> comments, List<Post> posts, UserRole role) {
|
|
||||||
this.login = login;
|
|
||||||
this.password=password;
|
|
||||||
this.role = role;
|
|
||||||
for (int i = 0; i < comments.size(); i++) {
|
|
||||||
addComment(comments.get(i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < posts.size(); i++) {
|
|
||||||
addPost(posts.get(i));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Long getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 List<Comment> getComments() { return comments; }
|
|
||||||
|
|
||||||
public List<Post> getPosts() {return posts; }
|
|
||||||
|
|
||||||
public int getCommentsSize() {
|
|
||||||
if (comments == null) return 0;
|
|
||||||
else return comments.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPostsSize() {
|
|
||||||
if (posts == null) return 0;
|
|
||||||
else return posts.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addComment(Comment comment) {
|
|
||||||
this.comments.add(comment);
|
|
||||||
if (comment.getOwner() != this) {
|
|
||||||
comment.setOwner(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addPost(Post post) {
|
|
||||||
this.posts.add(post);
|
|
||||||
if (post.getAuthor() != this) {
|
|
||||||
post.setAuthor(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
Profile user = (Profile) o;
|
|
||||||
return Objects.equals(id, user.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String ToString() {
|
|
||||||
return "User{" +
|
|
||||||
"id=" + id +
|
|
||||||
", login='" + login + '\'' +
|
|
||||||
", password='" + password + '\'' +
|
|
||||||
", comments='" + getCommentsSize() + '\'' +
|
|
||||||
", comments='" + getPostsSize() + '\'' +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
}
|
|
75
src/main/java/com/webproglabs/lab1/lab34/model/Shop.java
Normal file
75
src/main/java/com/webproglabs/lab1/lab34/model/Shop.java
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.model;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Shop {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long Id;
|
||||||
|
@Column(unique = true)
|
||||||
|
private String Name;
|
||||||
|
@OneToMany(mappedBy = "Shop")
|
||||||
|
private List<Product> Products = new ArrayList<>();
|
||||||
|
|
||||||
|
public Shop(String Name) {
|
||||||
|
this.Name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Shop(){}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Product> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String Name) {
|
||||||
|
this.Name = Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProduct(Product Product) {
|
||||||
|
this.Products.add(Product);
|
||||||
|
Product.setShop(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeProduct(Product Product) {
|
||||||
|
this.Products.remove(Product);
|
||||||
|
Product.setShop(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProducts (List<Product> Products) {
|
||||||
|
this.Products = Products;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
Shop shop = (Shop) o;
|
||||||
|
return Objects.equals(Id, shop.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Shop{" +
|
||||||
|
"Id=" + Id +
|
||||||
|
", Name='" + Name +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
src/main/java/com/webproglabs/lab1/lab34/model/User.java
Normal file
100
src/main/java/com/webproglabs/lab1/lab34/model/User.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.model;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Size;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "users")
|
||||||
|
public class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long Id;
|
||||||
|
|
||||||
|
@Column(nullable = false, unique = true, length = 1024)
|
||||||
|
@NotBlank
|
||||||
|
@Size(min = 4, max = 64)
|
||||||
|
private String login;
|
||||||
|
|
||||||
|
@Column(nullable = false, length = 1024)
|
||||||
|
@NotBlank
|
||||||
|
@Size(min = 4, max = 64)
|
||||||
|
private String Password;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "Users")
|
||||||
|
private List<Product> Products = new ArrayList<>();
|
||||||
|
|
||||||
|
private UserRole Role;
|
||||||
|
|
||||||
|
public User(String login, String password, UserRole role) {
|
||||||
|
this.login = login;
|
||||||
|
this.Password = password;
|
||||||
|
this.Role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User(String Login, String Password) {
|
||||||
|
this(Login, Password, UserRole.USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public User() {}
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 List<Product> getProducts() {
|
||||||
|
return Products;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addProduct(Product Product) {
|
||||||
|
this.Products.add(Product);
|
||||||
|
Product.addUser(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeProduct(Product Product) {
|
||||||
|
this.Products.remove(Product);
|
||||||
|
Product.removeUser(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserRole getRole() {
|
||||||
|
return Role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(UserRole Role) {
|
||||||
|
this.Role = Role;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
User user = (User) o;
|
||||||
|
return Objects.equals(Id, user.Id) && Objects.equals(login, user.login);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(Id, login);
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,11 @@
|
|||||||
package com.webproglabs.lab1.lab34.model;
|
package com.webproglabs.lab1.lab34.model.enums;
|
||||||
|
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
public enum UserRole implements GrantedAuthority {
|
public enum UserRole implements GrantedAuthority {
|
||||||
ADMIN,
|
ADMIN,
|
||||||
USER;
|
USER,
|
||||||
|
;
|
||||||
|
|
||||||
private static final String PREFIX = "ROLE_";
|
private static final String PREFIX = "ROLE_";
|
||||||
|
|
||||||
@ -18,3 +19,5 @@ public enum UserRole implements GrantedAuthority {
|
|||||||
public static final String USER = PREFIX + "USER";
|
public static final String USER = PREFIX + "USER";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.mvc;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.dto.ShopDto;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Shop;
|
||||||
|
import com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||||
|
import com.webproglabs.lab1.lab34.services.ShopService;
|
||||||
|
import org.springframework.security.access.annotation.Secured;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/shops")
|
||||||
|
public class ShopMvcController {
|
||||||
|
private final ShopService shopService;
|
||||||
|
|
||||||
|
public ShopMvcController(ShopService shopService) {
|
||||||
|
this.shopService = shopService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public String getShops(Model model) {
|
||||||
|
model.addAttribute("shops", shopService.findAllShops().stream().map(ShopDto::new).toList());
|
||||||
|
model.addAttribute("shopDto", new ShopDto());
|
||||||
|
return "shops";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(value = {"/edit/{Id}"})
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public String getShopEdit(@PathVariable Long Id, Model model) {
|
||||||
|
model.addAttribute("shop", shopService.findShopById(Id));
|
||||||
|
model.addAttribute("shopDto", new ShopDto());
|
||||||
|
return "shopEdit";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"/edit/{Id}"})
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public String editShop(@PathVariable Long Id, @ModelAttribute ShopDto shopDto) {
|
||||||
|
shopService.updateShop(Id, shopDto.getName());
|
||||||
|
return "redirect:/shops";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"/create"})
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public String createShop(@ModelAttribute ShopDto shopDto) {
|
||||||
|
shopService.addShop(shopDto.getName());
|
||||||
|
return "redirect:/shops";
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping(value = {"/delete/{Id}"})
|
||||||
|
@Secured({UserRole.AsString.ADMIN})
|
||||||
|
public String deleteShop(@PathVariable Long Id) {
|
||||||
|
shopService.deleteShop(Id);
|
||||||
|
return "redirect:/shops";
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,9 @@
|
|||||||
package com.webproglabs.lab1.lab34.controller.mvc_controllers;
|
package com.webproglabs.lab1.lab34.mvc;
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
import com.webproglabs.lab1.lab34.dto.UserSignUpDto;
|
||||||
import com.webproglabs.lab1.lab34.services.ProfileService;
|
import com.webproglabs.lab1.lab34.model.User;
|
||||||
|
import com.webproglabs.lab1.lab34.services.UserService;
|
||||||
|
import javax.validation.Valid;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
@ -10,27 +12,25 @@ import org.springframework.web.bind.annotation.ModelAttribute;
|
|||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping(UserSignupMvcController.SIGNUP_URL)
|
@RequestMapping(UserSignUpMvcController.SIGNUP_URL)
|
||||||
public class UserSignupMvcController {
|
public class UserSignUpMvcController {
|
||||||
public static final String SIGNUP_URL = "/signup";
|
public static final String SIGNUP_URL = "/signup";
|
||||||
|
|
||||||
private final ProfileService userService;
|
private final UserService UserService;
|
||||||
|
|
||||||
public UserSignupMvcController(ProfileService userService) {
|
public UserSignUpMvcController(UserService userService) {
|
||||||
this.userService = userService;
|
UserService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public String showSignupForm(Model model) {
|
public String showSignupForm(Model model) {
|
||||||
model.addAttribute("userDto", new UserSignupDto());
|
model.addAttribute("userDto", new UserSignUpDto());
|
||||||
return "signup";
|
return "signup";
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public String signup(@ModelAttribute("userDto") @Valid UserSignupDto userSignupDto,
|
public String signup(@ModelAttribute("userDto") @Valid UserSignUpDto userSignupDto,
|
||||||
BindingResult bindingResult,
|
BindingResult bindingResult,
|
||||||
Model model) {
|
Model model) {
|
||||||
if (bindingResult.hasErrors()) {
|
if (bindingResult.hasErrors()) {
|
||||||
@ -38,9 +38,8 @@ public class UserSignupMvcController {
|
|||||||
return "signup";
|
return "signup";
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final Profile user = userService.createUser(
|
final User NewUser = UserService.createUser(userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
||||||
userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
return "redirect:/login?created=" + NewUser.getLogin();
|
||||||
return "redirect:/login?created=" + user.getLogin();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
model.addAttribute("errors", e.getMessage());
|
model.addAttribute("errors", e.getMessage());
|
||||||
return "signup";
|
return "signup";
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.repository;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Category;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface CategoryRepository extends JpaRepository<Category, Long> {
|
||||||
|
Optional<Category> findById(Long Id);
|
||||||
|
}
|
@ -1,10 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.repository;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface CommentRepository extends JpaRepository<Comment, Long> {
|
|
||||||
List<Comment> findByTextLike(String text);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.repository;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface PostRepository extends JpaRepository<Post, Long> {
|
|
||||||
List<Post> findByTextLike(String text);
|
|
||||||
}
|
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.repository;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface ProductRepository extends JpaRepository<Product, Long> {
|
||||||
|
Optional<Product> findById(Long Id);
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.repository;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public interface ProfileRepository extends JpaRepository<Profile, Long> {
|
|
||||||
List<Profile> findByLoginLike(String login);
|
|
||||||
Profile findOneByLoginIgnoreCase(String login);
|
|
||||||
}
|
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.repository;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Shop;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface ShopRepository extends JpaRepository<Shop, Long> {
|
||||||
|
Optional<Shop> findById(Long Id);
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.repository;
|
||||||
|
import com.webproglabs.lab1.lab34.model.User;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
Optional<User> findById(Long Id);
|
||||||
|
Optional<User> findOneByLoginIgnoreCase(String Login);
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.services;
|
||||||
|
|
||||||
|
import javax.persistence.EntityNotFoundException;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Category;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
import com.webproglabs.lab1.lab34.repository.CategoryRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CategoryService {
|
||||||
|
private final CategoryRepository CategoryRepository;
|
||||||
|
|
||||||
|
public CategoryService(CategoryRepository CategoryRepository) {
|
||||||
|
this.CategoryRepository = CategoryRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Category addCategory(String Name) {
|
||||||
|
if (!StringUtils.hasText(Name)) {
|
||||||
|
throw new IllegalArgumentException("Name is null or empty");
|
||||||
|
}
|
||||||
|
final Category Category = new Category(Name);
|
||||||
|
CategoryRepository.save(Category);
|
||||||
|
return Category;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Category findCategoryById(Long Id) {
|
||||||
|
final Category Category = CategoryRepository.findById(Id).orElse(null);
|
||||||
|
if (Category == null) {
|
||||||
|
throw new EntityNotFoundException(String.format(" Category with id [%s] is not found", Id));
|
||||||
|
}
|
||||||
|
return Category;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<Category> findAllCategories(){
|
||||||
|
return CategoryRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Category updateCategory(Long Id, String Name) {
|
||||||
|
if (!StringUtils.hasText(Name)) {
|
||||||
|
throw new IllegalArgumentException("Name is null or empty");
|
||||||
|
}
|
||||||
|
final Category CurrentCategory = findCategoryById(Id);
|
||||||
|
CurrentCategory.setName(Name);
|
||||||
|
return CategoryRepository.save(CurrentCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Category deleteCategory(Long Id) {
|
||||||
|
final Category CurrentCategory = findCategoryById(Id);
|
||||||
|
CategoryRepository.delete(CurrentCategory);
|
||||||
|
return CurrentCategory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllCategories() {
|
||||||
|
CategoryRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product addProductToCategory(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final Category CurrentCategory = findCategoryById(Id);
|
||||||
|
CurrentCategory.addProduct(Product);
|
||||||
|
CategoryRepository.save(CurrentCategory);
|
||||||
|
return Product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void removeProductFromCategory(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final Category CurrentCategory = findCategoryById(Id);
|
||||||
|
CurrentCategory.removeProduct(Product);
|
||||||
|
CategoryRepository.save(CurrentCategory);
|
||||||
|
}
|
||||||
|
}
|
@ -1,102 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.CommentRepository;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.PostRepository;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.ProfileRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class CommentService {
|
|
||||||
|
|
||||||
private final ProfileRepository profileRepository;
|
|
||||||
private final CommentRepository commentRepository;
|
|
||||||
|
|
||||||
private final PostRepository postRepository;
|
|
||||||
|
|
||||||
public CommentService(ProfileRepository profileRepository, CommentRepository commentRepository, PostRepository postRepository) {
|
|
||||||
this.profileRepository = profileRepository;
|
|
||||||
this.commentRepository = commentRepository;
|
|
||||||
this.postRepository = postRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment findComment(Long id) {
|
|
||||||
final Optional<Comment> comment = commentRepository.findById(id);
|
|
||||||
return comment.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Comment> findAllComments() {
|
|
||||||
return commentRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Post> findFilteredComments(String filter) {
|
|
||||||
List<Post> postList = postRepository.findByTextLike("%" + filter + "%");
|
|
||||||
List<Comment> commentList = commentRepository.findByTextLike("%" + filter + "%");
|
|
||||||
List<Post> allPosts = postRepository.findAll();
|
|
||||||
for(Post post : allPosts) {
|
|
||||||
for (Comment comm : commentList) {
|
|
||||||
if (post.getComments().contains(comm) && !(postList.contains(post))) {
|
|
||||||
postList.add(post);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return postList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment addComment(String text, Long profileId, Long postId) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Comment data is null or empty");
|
|
||||||
}
|
|
||||||
try{
|
|
||||||
Profile user = profileRepository.findById(profileId).get();
|
|
||||||
Post post = postRepository.findById(postId).get();
|
|
||||||
Comment comment = new Comment(text, user, post);
|
|
||||||
user.addComment(comment);
|
|
||||||
post.addComment(comment);
|
|
||||||
profileRepository.save(user);
|
|
||||||
postRepository.save(post);
|
|
||||||
return commentRepository.save(comment);
|
|
||||||
}
|
|
||||||
catch (Exception exception) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment updateComment(Long id, String text) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Comment data is null or empty");
|
|
||||||
}
|
|
||||||
Comment currentComment = findComment(id);
|
|
||||||
currentComment.setText(text);
|
|
||||||
final Profile owner = currentComment.getOwner();
|
|
||||||
profileRepository.save(owner);
|
|
||||||
final Post post = currentComment.getPost();
|
|
||||||
postRepository.save(post);
|
|
||||||
return commentRepository.save(currentComment);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Comment deleteComment(Long id) {
|
|
||||||
final Comment currentComment = findComment(id);
|
|
||||||
commentRepository.delete(currentComment);
|
|
||||||
return currentComment;
|
|
||||||
}
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllComments() {
|
|
||||||
commentRepository.deleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,90 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.CommentRepository;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.PostRepository;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.ProfileRepository;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class PostService {
|
|
||||||
private final PostRepository postRepository;
|
|
||||||
private final CommentRepository commentRepository;
|
|
||||||
private final ProfileRepository profileRepository;
|
|
||||||
|
|
||||||
public PostService(PostRepository postRepository, CommentRepository commentRepository, ProfileRepository profileRepository) {
|
|
||||||
this.postRepository = postRepository;
|
|
||||||
this.commentRepository = commentRepository;
|
|
||||||
this.profileRepository = profileRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post findPost(Long id) {
|
|
||||||
final Optional<Post> post = postRepository.findById(id);
|
|
||||||
return post.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Post> findAllPosts() {
|
|
||||||
return postRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Post> findFilteredPosts(String filter) {
|
|
||||||
List<Post> postList = postRepository.findByTextLike("%" + filter + "%");
|
|
||||||
List<Comment> commentList = commentRepository.findByTextLike("%" + filter + "%");
|
|
||||||
List<Post> allPosts = postRepository.findAll();
|
|
||||||
for(Post post : allPosts) {
|
|
||||||
for (Comment comm : commentList) {
|
|
||||||
if (post.getComments().contains(comm) && !(postList.contains(post))) {
|
|
||||||
postList.add(post);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return postList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post addPost (String text, List<Comment> comments, Long authorId) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Post data is null or empty");
|
|
||||||
}
|
|
||||||
Profile author = profileRepository.findById(authorId).get();
|
|
||||||
Post post = new Post(text, author, comments);
|
|
||||||
author.addPost(post);
|
|
||||||
profileRepository.save(author);
|
|
||||||
return postRepository.save(post);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post updatePost(Long id, String text) {
|
|
||||||
if (!StringUtils.hasText(text)) {
|
|
||||||
throw new IllegalArgumentException("Post data is null or empty");
|
|
||||||
}
|
|
||||||
final Post currentPost = findPost(id);
|
|
||||||
currentPost.setText(text);
|
|
||||||
final Profile author = currentPost.getAuthor();
|
|
||||||
profileRepository.save(author);
|
|
||||||
return postRepository.save(currentPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Post deletePost(Long id) {
|
|
||||||
final Post currentPost = findPost(id);
|
|
||||||
postRepository.delete(currentPost);
|
|
||||||
return currentPost;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllPosts() {
|
|
||||||
postRepository.deleteAll();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.services;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.persistence.EntityNotFoundException;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Category;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Shop;
|
||||||
|
import com.webproglabs.lab1.lab34.repository.ProductRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ProductService {
|
||||||
|
private final ProductRepository ProductRepository;
|
||||||
|
|
||||||
|
public ProductService(ProductRepository productRepository) {
|
||||||
|
ProductRepository = productRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product addProduct(String Name, Double Cost, Shop Shop, Category Category) {
|
||||||
|
if (!StringUtils.hasText(Name) || Cost == null || Cost < 0 || Shop == null || Category == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
final Product NewProduct = new Product(Name, Cost, Shop, Category);
|
||||||
|
return ProductRepository.save(NewProduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product findProductById(Long Id) {
|
||||||
|
final Product CurrentProduct = ProductRepository.findById(Id).orElse(null);
|
||||||
|
if (CurrentProduct == null) {
|
||||||
|
throw new EntityNotFoundException(String.format(" Product with id [%s] is not found", Id));
|
||||||
|
}
|
||||||
|
return CurrentProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<Product> findAllProducts() {
|
||||||
|
return ProductRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product updateProduct(Long Id, String Name, Double Cost, Shop Shop, Category Category) {
|
||||||
|
final Product CurrentProduct = findProductById(Id);
|
||||||
|
if (!StringUtils.hasText(Name) || Cost == null || Cost < 0 || Shop == null || Category == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
CurrentProduct.setName(Name);
|
||||||
|
CurrentProduct.setCost(Cost);
|
||||||
|
CurrentProduct.setShop(Shop);
|
||||||
|
CurrentProduct.setCategory(Category);
|
||||||
|
return ProductRepository.save(CurrentProduct);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product deleteProduct(Long Id) {
|
||||||
|
final Product CurrentProduct = findProductById(Id);
|
||||||
|
ProductRepository.delete(CurrentProduct);
|
||||||
|
return CurrentProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllProducts() {
|
||||||
|
ProductRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,158 +0,0 @@
|
|||||||
package com.webproglabs.lab1.lab34.services;
|
|
||||||
|
|
||||||
import com.webproglabs.lab1.lab34.controller.ProfileDto;
|
|
||||||
import com.webproglabs.lab1.lab34.jwt.JwtException;
|
|
||||||
import com.webproglabs.lab1.lab34.jwt.JwtProvider;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Comment;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Post;
|
|
||||||
import com.webproglabs.lab1.lab34.model.Profile;
|
|
||||||
import com.webproglabs.lab1.lab34.model.UserRole;
|
|
||||||
import com.webproglabs.lab1.lab34.repository.ProfileRepository;
|
|
||||||
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.util.StringUtils;
|
|
||||||
|
|
||||||
import javax.persistence.EntityNotFoundException;
|
|
||||||
import javax.transaction.Transactional;
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
@Service
|
|
||||||
public class ProfileService implements UserDetailsService {
|
|
||||||
|
|
||||||
private final ProfileRepository profileRepository;
|
|
||||||
private final PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
private final JwtProvider jwtProvider;
|
|
||||||
|
|
||||||
public ProfileService(ProfileRepository profileRepository, PasswordEncoder passwordEncoder, JwtProvider jwtProvider) {
|
|
||||||
this.profileRepository = profileRepository;
|
|
||||||
this.passwordEncoder = passwordEncoder;
|
|
||||||
this.jwtProvider = jwtProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile findUser(Long id) {
|
|
||||||
final Optional<Profile> profile = profileRepository.findById(id);
|
|
||||||
return profile.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile findUserByLogin(String login) {
|
|
||||||
final Optional<Profile> profile = profileRepository.findByLoginLike(login).stream().findFirst();
|
|
||||||
return profile.orElseThrow(EntityNotFoundException::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public List<Profile> findAllUsers() {
|
|
||||||
return profileRepository.findAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile addUser(String login, String password, List<Comment> comments, List<Post> posts) {
|
|
||||||
if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
|
|
||||||
throw new IllegalArgumentException("User data is null or empty");
|
|
||||||
}
|
|
||||||
final Profile user = new Profile(login, password, comments, posts, UserRole.USER);
|
|
||||||
return profileRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile addUser(String login, String password, List<Comment> comments, List<Post> posts, UserRole role) {
|
|
||||||
if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
|
|
||||||
throw new IllegalArgumentException("User data is null or empty");
|
|
||||||
}
|
|
||||||
final Profile user = new Profile(login, password, comments, posts, role);
|
|
||||||
return profileRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile createUser(String login, String password, String passwordConfirm) throws Exception {
|
|
||||||
if (findByLogin(login) != null) {
|
|
||||||
throw new Exception("User " + login + " already exists");
|
|
||||||
}
|
|
||||||
final Profile user = new Profile(login, passwordEncoder.encode(password), new ArrayList<>(), new ArrayList<>(), UserRole.USER);
|
|
||||||
if (!Objects.equals(password, passwordConfirm)) {
|
|
||||||
throw new Exception("Passwords not equals");
|
|
||||||
}
|
|
||||||
return profileRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile createUser(String login, String password, String passwordConfirm, UserRole role) throws Exception {
|
|
||||||
if (findByLogin(login) != null) {
|
|
||||||
throw new Exception("User " + login + " already exists");
|
|
||||||
}
|
|
||||||
final Profile user = new Profile(login, passwordEncoder.encode(password), new ArrayList<>(), new ArrayList<>(), role);
|
|
||||||
if (!Objects.equals(password, passwordConfirm)) {
|
|
||||||
throw new Exception("Passwords not equals");
|
|
||||||
}
|
|
||||||
return profileRepository.save(user);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile updateUser(Long id, String login, String password) {
|
|
||||||
if (!StringUtils.hasText(login) || !StringUtils.hasText(password)) {
|
|
||||||
throw new IllegalArgumentException("User data is null or empty");
|
|
||||||
}
|
|
||||||
final Profile currentUser = findUser(id);
|
|
||||||
currentUser.setLogin(login);
|
|
||||||
currentUser.setPassword(password);
|
|
||||||
return profileRepository.save(currentUser);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public Profile deleteUser(Long id) {
|
|
||||||
final Profile currentUser = findUser(id);
|
|
||||||
profileRepository.delete(currentUser);
|
|
||||||
return currentUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Transactional
|
|
||||||
public void deleteAllUsers() {
|
|
||||||
profileRepository.deleteAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Profile findByLogin(String login) {
|
|
||||||
return profileRepository.findOneByLoginIgnoreCase(login);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
|
||||||
final Profile userEntity = findByLogin(username);
|
|
||||||
if (userEntity == null) {
|
|
||||||
throw new UsernameNotFoundException(username);
|
|
||||||
}
|
|
||||||
return new org.springframework.security.core.userdetails.User(
|
|
||||||
userEntity.getLogin(), userEntity.getPassword(), Collections.singleton(userEntity.getRole()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String loginAndGetToken(ProfileDto userDto) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
final Profile user = findByLogin(userDto.getLogin());
|
|
||||||
if (user == null) {
|
|
||||||
throw new Exception("Login not found" + userDto.getLogin());
|
|
||||||
}
|
|
||||||
if (!passwordEncoder.matches(userDto.getPassword(), user.getPassword())) {
|
|
||||||
throw new Exception("User not found" + user.getLogin());
|
|
||||||
}
|
|
||||||
return jwtProvider.generateToken(user.getLogin());
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
var ex = e;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserDetails loadUserByToken(String token) throws UsernameNotFoundException {
|
|
||||||
if (!jwtProvider.isTokenValid(token)) {
|
|
||||||
throw new JwtException("Bad token");
|
|
||||||
}
|
|
||||||
final String userLogin = jwtProvider.getLoginFromToken(token)
|
|
||||||
.orElseThrow(() -> new JwtException("Token is not contain Login"));
|
|
||||||
return loadUserByUsername(userLogin);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,85 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.services;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
import com.webproglabs.lab1.lab34.model.Shop;
|
||||||
|
import com.webproglabs.lab1.lab34.repository.ShopRepository;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.persistence.EntityNotFoundException;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ShopService {
|
||||||
|
private final ShopRepository ShopRepository;
|
||||||
|
|
||||||
|
public ShopService(ShopRepository ShopRepository) {
|
||||||
|
this.ShopRepository = ShopRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Shop addShop(String Name) {
|
||||||
|
if (!StringUtils.hasText(Name)) {
|
||||||
|
throw new IllegalArgumentException("Name is null or empty");
|
||||||
|
}
|
||||||
|
final Shop Shop = new Shop(Name);
|
||||||
|
ShopRepository.save(Shop);
|
||||||
|
return Shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Shop findShopById(Long Id) {
|
||||||
|
final Shop Shop = ShopRepository.findById(Id).orElse(null);
|
||||||
|
if (Shop == null) {
|
||||||
|
throw new EntityNotFoundException(String.format(" Shop with id [%s] is not found", Id));
|
||||||
|
}
|
||||||
|
return Shop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<Shop> findAllShops(){
|
||||||
|
return ShopRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Shop updateShop(Long Id, String Name) {
|
||||||
|
if (!StringUtils.hasText(Name)) {
|
||||||
|
throw new IllegalArgumentException("Name is null or empty");
|
||||||
|
}
|
||||||
|
final Shop CurrentShop = findShopById(Id);
|
||||||
|
CurrentShop.setName(Name);
|
||||||
|
return ShopRepository.save(CurrentShop);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Shop deleteShop(Long Id) {
|
||||||
|
final Shop CurrentShop = findShopById(Id);
|
||||||
|
ShopRepository.delete(CurrentShop);
|
||||||
|
return CurrentShop;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllShops() {
|
||||||
|
ShopRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Product addProductToShop(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final Shop CurrentShop = findShopById(Id);
|
||||||
|
CurrentShop.addProduct(Product);
|
||||||
|
ShopRepository.save(CurrentShop);
|
||||||
|
return Product;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void removeProductFromShop(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final Shop CurrentShop = findShopById(Id);
|
||||||
|
CurrentShop.removeProduct(Product);
|
||||||
|
ShopRepository.save(CurrentShop);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,117 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.services;
|
||||||
|
|
||||||
|
import com.webproglabs.lab1.lab34.model.Product;
|
||||||
|
import com.webproglabs.lab1.lab34.model.User;
|
||||||
|
import com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||||
|
import com.webproglabs.lab1.lab34.repository.UserRepository;
|
||||||
|
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.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.persistence.EntityNotFoundException;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class UserService implements UserDetailsService {
|
||||||
|
private final UserRepository UserRepository;
|
||||||
|
private final PasswordEncoder PasswordEncoder;
|
||||||
|
|
||||||
|
public UserService(UserRepository UserRepository, PasswordEncoder PasswordEncoder) {
|
||||||
|
this.UserRepository = UserRepository;
|
||||||
|
this.PasswordEncoder = PasswordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User findUserById(Long Id) {
|
||||||
|
User CurrentUser = UserRepository.findById(Id).orElse(null);
|
||||||
|
if (CurrentUser == null) {
|
||||||
|
throw new EntityNotFoundException(String.format(" User with id [%s] is not found", Id));
|
||||||
|
}
|
||||||
|
return CurrentUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User findUserByLogin(String Login) {
|
||||||
|
if (!StringUtils.hasText(Login)) {
|
||||||
|
throw new IllegalArgumentException("Login is null or empty");
|
||||||
|
}
|
||||||
|
User CurrentUser = UserRepository.findOneByLoginIgnoreCase(Login).orElse(null);
|
||||||
|
return CurrentUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<User> findAllUsers() {
|
||||||
|
return UserRepository.findAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User createUser(String Login, String Password, String PasswordConfirm) {
|
||||||
|
return createUser(Login, Password, PasswordConfirm, UserRole.USER);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User createUser(String Login, String Password, String PasswordConfirm, UserRole Role) {
|
||||||
|
if (findUserByLogin(Login) != null) {
|
||||||
|
throw new IllegalArgumentException("User " + Login + " already exists");
|
||||||
|
}
|
||||||
|
if (!Objects.equals(Password, PasswordConfirm)) {
|
||||||
|
throw new IllegalArgumentException("Passwords not equals");
|
||||||
|
}
|
||||||
|
final User NewUser = new User(Login, PasswordEncoder.encode(Password), Role);
|
||||||
|
return UserRepository.save(NewUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User updateUser(Long Id, String Login, String Password, UserRole Role) {
|
||||||
|
if (!StringUtils.hasText(Login) || !StringUtils.hasText(Password)) {
|
||||||
|
throw new IllegalArgumentException("User data is null or empty");
|
||||||
|
}
|
||||||
|
final User CurrentUser = findUserById(Id);
|
||||||
|
CurrentUser.setLogin(Login);
|
||||||
|
CurrentUser.setPassword(Password);
|
||||||
|
CurrentUser.setRole(Role);
|
||||||
|
return UserRepository.save(CurrentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public User deleteUser(Long Id) {
|
||||||
|
final User CurrentUser = findUserById(Id);
|
||||||
|
UserRepository.delete(CurrentUser);
|
||||||
|
return CurrentUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void deleteAllUsers(){
|
||||||
|
UserRepository.deleteAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void addProductToUser(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final User CurrentUser = findUserById(Id);
|
||||||
|
CurrentUser.addProduct(Product);
|
||||||
|
UserRepository.save(CurrentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public void removeProductFromUser(Long Id, Product Product) {
|
||||||
|
// TODO возможно придется подключать репозиторий продуктов и там тоже сохранять
|
||||||
|
|
||||||
|
final User CurrentUser = findUserById(Id);
|
||||||
|
CurrentUser.removeProduct(Product);
|
||||||
|
UserRepository.save(CurrentUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String Login) throws UsernameNotFoundException {
|
||||||
|
final User UserEntity = findUserByLogin(Login);
|
||||||
|
return new org.springframework.security.core.userdetails.User(UserEntity.getLogin(), UserEntity.getPassword(), Collections.singleton(UserEntity.getRole()));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.validation;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class ValidationException extends RuntimeException {
|
||||||
|
public <T> ValidationException(Set<String> errors) {
|
||||||
|
super(String.join("\n", errors));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> ValidationException(String error) {
|
||||||
|
super(error);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.webproglabs.lab1.lab34.validation;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.Validation;
|
||||||
|
import javax.validation.Validator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ValidatorUtil {
|
||||||
|
private final Validator validator;
|
||||||
|
|
||||||
|
public ValidatorUtil() {
|
||||||
|
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void validate(T object) {
|
||||||
|
final Set<ConstraintViolation<T>> errors = validator.validate(object);
|
||||||
|
if (!errors.isEmpty()) {
|
||||||
|
throw new ValidationException(errors.stream()
|
||||||
|
.map(ConstraintViolation::getMessage)
|
||||||
|
.collect(Collectors.toSet()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="commentCreate" tabindex="-1" role="dialog" aria-labelledby="commentCreateLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="commentCreateLabel">Создать комментарий</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/comment/{id}/{postId}/{text} (id=${selectedProfile.id}, postId=${selectedPost.id}, text=${commentInputField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст комментария:</p>
|
|
||||||
<input th:value="${commentInputField}" id="commentInputField" name="commentInputField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -3,10 +3,9 @@
|
|||||||
xmlns:th="http://www.thymeleaf.org"
|
xmlns:th="http://www.thymeleaf.org"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||||
>
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="UTF-8"/>
|
||||||
<title>Лабораторная работа 5</title>
|
<title>Магазин</title>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<link rel="icon" href="/favicon.svg">
|
<link rel="icon" href="/favicon.svg">
|
||||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||||
@ -19,12 +18,10 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p class='text-center m-3 h3'> Лабораторная работа 5</p>
|
<p class='text-center m-3 h3'>Магазин</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p class='h4 text-center'>
|
<p class='h4 text-center'>
|
||||||
<a sec:authorize="hasRole('ROLE_ADMIN')" href="/profiles" 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 sec:authorize="isAuthenticated()" href="/logout" class="text-decoration-none m-3">
|
||||||
Выход
|
Выход
|
||||||
</a>
|
</a>
|
||||||
@ -34,13 +31,5 @@
|
|||||||
<div >
|
<div >
|
||||||
<div layout:fragment="content"></div>
|
<div layout:fragment="content"></div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
|
||||||
<script type="text/javascript">
|
|
||||||
window.onload = () => {
|
|
||||||
$('#postEdit').modal('show');
|
|
||||||
$('#commentCreate').modal('show');
|
|
||||||
$('#commentEdit').modal('show');
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</body>
|
||||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="commentEdit" tabindex="-1" role="dialog" aria-labelledby="commentEditLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="commentEditLabel">Редактировать комментарий</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/editComment/{id}/{commentId}/{text} (id=${selectedProfile.id}, commentId=${selectedComment.id}, text=${commentEditField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Новый текст комментария:</p>
|
|
||||||
<input th:attr="value = ${selectedComment.text}" id="commentEditField" name="commentEditField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Изменить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feedPosts}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div layout:fragment="modalFeed">
|
|
||||||
|
|
||||||
<div class="modal fade" id="postEdit" tabindex="-1" role="dialog" aria-labelledby="postEditLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="postEditLabel">Редактировать пост</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/editPost/{id}/{authorId}/{text} (id=${selectedPost.id}, authorId=${selectedProfile.id}, text=${postEditField} ) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст поста:</p>
|
|
||||||
<input th:attr="value = ${selectedPost.text}" id="postEditField" name="postEditField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
<div class="text-center">
|
|
||||||
|
|
||||||
<!-- <div class="dropdown text-center mx-auto w-25 ">-->
|
|
||||||
<!-- <div class="text-end mt-3">-->
|
|
||||||
<!-- <button class="btn btn-secondary dropdown-toggle ms-3 mb-3 " type="button" data-bs-toggle="dropdown" aria-expanded="false">-->
|
|
||||||
<!-- Выбор пользователя-->
|
|
||||||
<!-- </button>-->
|
|
||||||
<!-- <ul class="dropdown-menu " >-->
|
|
||||||
<!-- <li th:each="profile: ${profiles}">-->
|
|
||||||
<!-- <a class="dropdown-item" th:href="@{/feed/{id}(id=${profile.id})}" th:text="${profile.login}">-->
|
|
||||||
<!-- </a>-->
|
|
||||||
<!-- </li>-->
|
|
||||||
<!-- </ul>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<div layout:fragment="contentFeed"></div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,106 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{feed}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="contentFeed">
|
|
||||||
|
|
||||||
<div class='h3 mb-3 mx-auto w-25'>
|
|
||||||
<p class="text-end" th:text="${selectedProfile.login}"></p>
|
|
||||||
</div>
|
|
||||||
<div class='h3 m-3 d-flex justify-content-between text-center mx-auto w-25'>
|
|
||||||
|
|
||||||
Лента
|
|
||||||
<button type='button' class="btn btn-primary ms-5 mb-3 " data-bs-toggle="modal" data-bs-target="#postCreate">
|
|
||||||
Добавить новый пост
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form th:action="@{/feed/filter/{id}/{text} (id=${selectedProfile.id}, text=${searchField}) }" method="get">
|
|
||||||
<input th:value="${searchField}" id="searchField" name="searchField" type="text" class="mb-2" style="width: 20%" placeholder="Поиск...">
|
|
||||||
<button type='submit' class="btn btn-primary mb-2" style="width: 5%">
|
|
||||||
Найти
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
|
|
||||||
<div th:each="post: ${posts}" class="text-center mx-auto w-25 mb-3 ">
|
|
||||||
<div class="border p-2">
|
|
||||||
<p th:text="${post.text}" class="h4 text-start"></p>
|
|
||||||
<div class="d-flex justify-content-between fst-italic">
|
|
||||||
<div>
|
|
||||||
Автор:
|
|
||||||
<a th:text="${post.getAuthor()}" class="text-start fst-italic" th:href="@{/profile/{login}(login=${post.getAuthor()})}"></a>
|
|
||||||
</div>
|
|
||||||
<div th:if="${selectedProfile.getLogin() == post.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
|
||||||
<form th:action="@{/feed/deletePost/{id}/{authorId} (id=${post.id}, authorId=${selectedProfile.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger me-1 mb-1 ms-2" >
|
|
||||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
<form th:action="@{/feed/postModal/{id}/{authorId} (id=${post.id}, authorId=${selectedProfile.id})}" method="get">
|
|
||||||
<button type="submit" class="btn btn-warning mb-1" data-bs-toggle="modal" data-bs-target="#postEdit" >
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="border p-2" th:if="${post.comments.size() > 0}" >
|
|
||||||
<div class="text-start">
|
|
||||||
<p class="text-start h5">Комментарии:</p>
|
|
||||||
<div th:each="comment: ${post.comments}" >
|
|
||||||
<p class="fst-italic" th:text="${comment.getAuthor() + ':'}"> </p>
|
|
||||||
<div class="d-flex justify-content-between fst-italic">
|
|
||||||
<p class="ms-3" th:text="${comment.text}"></p>
|
|
||||||
|
|
||||||
<div th:if="${selectedProfile.getLogin() == comment.getAuthor()}" class="d-flex justify-content-between fst-italic">
|
|
||||||
<form th:action="@{/feed/deleteComment/{id}/{authorId} (id=${comment.id}, authorId=${selectedProfile.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger me-1 mb-1"> <i class="fa fa-trash" aria-hidden="true"> </i> </button>
|
|
||||||
</form>
|
|
||||||
<form th:action="@{/feed/commentEditModal/{id}/{authorId} (id=${comment.id}, authorId=${selectedProfile.id})}" method="get">
|
|
||||||
<button type="submit" class="btn btn-warning mb-1" data-bs-toggle="modal" data-bs-target="#postEdit" >
|
|
||||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/commentModal/{authorId}/{postId}/ ( authorId=${selectedProfile.id}, postId=${post.id} ) }" method="get" class="text-end">
|
|
||||||
<button type="submit" class="btn btn-info mb-3" data-bs-toggle="modal" data-bs-target="#commentCreate">Добавить комментарий</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="postCreate" tabindex="-1" role="dialog" aria-labelledby="postCreateLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="postCreateLabel">Создать пост</h5>
|
|
||||||
</div>
|
|
||||||
<form th:action="@{/feed/post/{id}/{text} (id=${selectedProfile.id}, text=${postInputField}) }" method="post" class="modal-body text-center">
|
|
||||||
<p>Текст поста:</p>
|
|
||||||
<input th:value="${postInputField}" id="postInputField" name="postInputField" type="text" class="mb-2">
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Сохранить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div layout:fragment="modalFeed"></div>
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content">
|
|
||||||
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-start mx-auto w-25 border p-5">
|
|
||||||
<p class='h5'>Профиль</p>
|
|
||||||
<p th:text="${'Логин: ' + profile.login}"></p>
|
|
||||||
<p class='h6 '>Список постов пользователя: </p>
|
|
||||||
|
|
||||||
<div th:if="${profile.posts.size()>0}">
|
|
||||||
<div th:each="post: ${profile.posts}">
|
|
||||||
<p th:text="${post.text}" class="mb-3 ms-2 border p-2"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p th:unless="${profile.posts.size()>0}">
|
|
||||||
Нет постов
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,56 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
|
|
||||||
<head>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div layout:fragment="content" class="text-center">
|
|
||||||
|
|
||||||
<div th:each="profile: ${profiles}" class="mb-2">
|
|
||||||
<div class="text-center">
|
|
||||||
<div class="text-start mx-auto w-25 border p-3">
|
|
||||||
<p class='h5'>Профиль</p>
|
|
||||||
<p th:text="${'Логин: ' + profile.login}"></p>
|
|
||||||
<p class='h6 '>Список постов пользователя: </p>
|
|
||||||
|
|
||||||
<div th:if="${profile.posts.size()>0}">
|
|
||||||
<div th:each="post: ${profile.posts}">
|
|
||||||
<p th:text="${post.text}" class="mb-3 ms-2 border p-2"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p th:unless="${profile.posts.size()>0}">
|
|
||||||
Нет постов
|
|
||||||
</p>
|
|
||||||
<div class="text-end">
|
|
||||||
<form action="#" th:action="@{/profile/{id} (id=${profile.id})}" method="post" >
|
|
||||||
<button type="submit" class="btn btn-danger">Удалить</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="modal fade" id="profileCreate" tabindex="-1" role="dialog" aria-labelledby="profileCreateLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<h5 class="modal-title" id="profileCreateLabel">Регистрация профиля</h5>
|
|
||||||
</div>
|
|
||||||
<form action="#" th:action="@{/profile/create/}" th:object="${profileDto}" method="post" class="modal-body text-center">
|
|
||||||
<p>Логин: </p>
|
|
||||||
<input th:field="${profileDto.login}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<br>
|
|
||||||
<p>Пароль: </p>
|
|
||||||
<input th:field="${profileDto.password}" type="text" class="mb-2 form-control" required="true" />
|
|
||||||
<br>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
|
|
||||||
<button type="submit" class="btn btn-primary" >Регистрация</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
21
src/main/resources/templates/shopEdit.html
Normal file
21
src/main/resources/templates/shopEdit.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}"
|
||||||
|
xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
<body>
|
||||||
|
<div class="container container-padding" layout:fragment="content">
|
||||||
|
<div>Name</div>
|
||||||
|
<div th:text="${shop.name}"></div>
|
||||||
|
<form action="#" th:action="@{/shops/edit/{id} (id=${shop.id})}" th:object="${shopDto}" method="post">
|
||||||
|
<p>New Name:</p>
|
||||||
|
<input th:field="${shopDto.name}" type="text" class="mb-2 form-control" required="true" />
|
||||||
|
<button type="submit" class="" >Edit</button>
|
||||||
|
</form>
|
||||||
|
<div th:each="product: ${shop.products}">
|
||||||
|
<p th:text="${product.name}"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
27
src/main/resources/templates/shops.html
Normal file
27
src/main/resources/templates/shops.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorate="~{default}"
|
||||||
|
xmlns:th="http://www.w3.org/1999/xhtml">
|
||||||
|
<body>
|
||||||
|
<div class="container container-padding" layout:fragment="content">
|
||||||
|
|
||||||
|
<div th:each="shop: ${shops}">
|
||||||
|
<div th:text="${'Name: ' + shop.name}" class="m-3"></div>
|
||||||
|
<form action="#" th:action="@{/shops/delete/{id} (id=${shop.id})}" method="post">
|
||||||
|
<button type="submit" class="" >Delete</button>
|
||||||
|
</form>
|
||||||
|
<form action="#" th:action="@{/shops/edit/{id} (id=${shop.id})}" method="get">
|
||||||
|
<button type="submit" class="">Edit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<form action="#" th:action="@{/shops/create}" th:object="${shopDto}" method="post">
|
||||||
|
<p>Name:</p>
|
||||||
|
<input th:field="${shopDto.name}" type="text" class="mb-2 form-control" required="true" />
|
||||||
|
<button type="submit" class="" >Add</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,7 +1,8 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en"
|
<html lang="en"
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
layout:decorate="~{default}">
|
layout:decorate="~{default}"
|
||||||
|
>
|
||||||
<body>
|
<body>
|
||||||
<div class="container container-padding" layout:fragment="content">
|
<div class="container container-padding" layout:fragment="content">
|
||||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
||||||
@ -12,11 +13,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<input type="password" class="form-control" th:field="${userDto.password}"
|
<input type="password" class="form-control" th:field="${userDto.password}"
|
||||||
placeholder="Пароль" required="true" minlength="6" maxlength="64"/>
|
placeholder="Пароль" required="true" minlength="4" maxlength="64"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<input type="password" class="form-control" th:field="${userDto.passwordConfirm}"
|
<input type="password" class="form-control" th:field="${userDto.passwordConfirm}"
|
||||||
placeholder="Пароль (подтверждение)" required="true" minlength="6" maxlength="64"/>
|
placeholder="Пароль (подтверждение)" required="true" minlength="4" maxlength="64"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<button type="submit" class="btn btn-success button-fixed">Создать</button>
|
<button type="submit" class="btn btn-success button-fixed">Создать</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user