Compare commits
6 Commits
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;
|
||||
|
||||
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 com.webproglabs.lab1.lab34.model.enums.UserRole;
|
||||
import com.webproglabs.lab1.lab34.mvc.UserSignUpMvcController;
|
||||
import com.webproglabs.lab1.lab34.services.UserService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.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;
|
||||
|
||||
@ -36,18 +32,16 @@ public class SecurityConfiguration 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;
|
||||
private final UserService userService;
|
||||
|
||||
public SecurityConfiguration(ProfileService userService) {
|
||||
public SecurityConfiguration(UserService userService) {
|
||||
this.userService = userService;
|
||||
this.jwtFilter = new JwtFilter(userService);
|
||||
createAdminOnStartup();
|
||||
}
|
||||
|
||||
private void createAdminOnStartup() {
|
||||
final String admin = "admin";
|
||||
if (userService.findByLogin(admin) == null) {
|
||||
if (userService.findUserByLogin(admin) == null) {
|
||||
log.info("Admin user successfully created");
|
||||
try {
|
||||
userService.createUser(admin, admin, admin, UserRole.ADMIN);
|
||||
@ -59,13 +53,12 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
|
||||
http.exceptionHandling().authenticationEntryPoint(delegatingEntryPoint());
|
||||
http.headers().frameOptions().sameOrigin().and()
|
||||
.cors().and()
|
||||
.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers(UserSignupMvcController.SIGNUP_URL).permitAll()
|
||||
.antMatchers(UserSignUpMvcController.SIGNUP_URL).permitAll()
|
||||
.antMatchers(HttpMethod.GET, LOGIN_URL).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.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;
|
||||
|
||||
import com.webproglabs.lab1.lab34.OpenAPI30Configuration;
|
||||
import org.springframework.boot.web.server.ErrorPage;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
@ -13,7 +12,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
public static final String REST_API = OpenAPI30Configuration.API_PREFIX;
|
||||
public static final String REST_API = "/api";
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry 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.Size;
|
||||
|
||||
public class UserSignupDto {
|
||||
public class UserSignUpDto {
|
||||
@NotBlank
|
||||
@Size(min = 3, max = 64)
|
||||
private String login;
|
||||
@NotBlank
|
||||
@Size(min = 6, max = 64)
|
||||
@Size(min = 4, max = 64)
|
||||
private String password;
|
||||
@NotBlank
|
||||
@Size(min = 6, max = 64)
|
||||
@Size(min = 4, max = 64)
|
||||
private String passwordConfirm;
|
||||
|
||||
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;
|
||||
|
||||
public enum UserRole implements GrantedAuthority {
|
||||
ADMIN,
|
||||
USER;
|
||||
USER,
|
||||
;
|
||||
|
||||
private static final String PREFIX = "ROLE_";
|
||||
|
||||
@ -18,3 +19,5 @@ public enum UserRole implements GrantedAuthority {
|
||||
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.services.ProfileService;
|
||||
import com.webproglabs.lab1.lab34.dto.UserSignUpDto;
|
||||
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.ui.Model;
|
||||
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.RequestMapping;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(UserSignupMvcController.SIGNUP_URL)
|
||||
public class UserSignupMvcController {
|
||||
@RequestMapping(UserSignUpMvcController.SIGNUP_URL)
|
||||
public class UserSignUpMvcController {
|
||||
public static final String SIGNUP_URL = "/signup";
|
||||
|
||||
private final ProfileService userService;
|
||||
private final UserService UserService;
|
||||
|
||||
public UserSignupMvcController(ProfileService userService) {
|
||||
this.userService = userService;
|
||||
public UserSignUpMvcController(UserService userService) {
|
||||
UserService = userService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String showSignupForm(Model model) {
|
||||
model.addAttribute("userDto", new UserSignupDto());
|
||||
model.addAttribute("userDto", new UserSignUpDto());
|
||||
return "signup";
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public String signup(@ModelAttribute("userDto") @Valid UserSignupDto userSignupDto,
|
||||
public String signup(@ModelAttribute("userDto") @Valid UserSignUpDto userSignupDto,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
@ -38,9 +38,8 @@ public class UserSignupMvcController {
|
||||
return "signup";
|
||||
}
|
||||
try {
|
||||
final Profile user = userService.createUser(
|
||||
userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
||||
return "redirect:/login?created=" + user.getLogin();
|
||||
final User NewUser = UserService.createUser(userSignupDto.getLogin(), userSignupDto.getPassword(), userSignupDto.getPasswordConfirm());
|
||||
return "redirect:/login?created=" + NewUser.getLogin();
|
||||
} catch (Exception e) {
|
||||
model.addAttribute("errors", e.getMessage());
|
||||
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,44 +3,33 @@
|
||||
xmlns:th="http://www.thymeleaf.org"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
|
||||
>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Лабораторная работа 5</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<link rel="icon" href="/favicon.svg">
|
||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
<meta charset="UTF-8"/>
|
||||
<title>Магазин</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<link rel="icon" href="/favicon.svg">
|
||||
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
|
||||
<link rel="stylesheet" href="/css/style.css"/>
|
||||
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
|
||||
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
|
||||
<link rel="stylesheet" href="/css/style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<p class='text-center m-3 h3'> Лабораторная работа 5</p>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p class='text-center m-3 h3'>Магазин</p>
|
||||
</div>
|
||||
<div>
|
||||
<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>
|
||||
<a sec:authorize="isAuthenticated()" href="/logout" class="text-decoration-none m-3">
|
||||
Выход
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div >
|
||||
<div >
|
||||
<div layout:fragment="content"></div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
window.onload = () => {
|
||||
$('#postEdit').modal('show');
|
||||
$('#commentCreate').modal('show');
|
||||
$('#commentEdit').modal('show');
|
||||
}
|
||||
</div>
|
||||
|
||||
</script>
|
||||
</html>
|
||||
</body>
|
@ -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>
|
@ -4,10 +4,10 @@
|
||||
layout:decorate="~{default}">
|
||||
<body>
|
||||
<div class="container" layout:fragment="content">
|
||||
<div class="alert alert-danger">
|
||||
<span th:text="${error}"></span>
|
||||
</div>
|
||||
<a href="/">На главную</a>
|
||||
<div class="alert alert-danger">
|
||||
<span th:text="${error}"></span>
|
||||
</div>
|
||||
<a href="/">На главную</a>
|
||||
</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>
|
@ -4,27 +4,27 @@
|
||||
layout:decorate="~{default}">
|
||||
<body>
|
||||
<div class="container" layout:fragment="content">
|
||||
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
|
||||
Пользователь не найден или пароль указан не верно
|
||||
<div th:if="${param.error}" class="alert alert-danger margin-bottom">
|
||||
Пользователь не найден или пароль указан не верно
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
|
||||
Выход успешно произведен
|
||||
</div>
|
||||
<div th:if="${param.created}" class="alert alert-success margin-bottom">
|
||||
Пользователь '<span th:text="${param.created}"></span>' успешно создан
|
||||
</div>
|
||||
<form th:action="@{/login}" method="post" class="container-padding">
|
||||
<div class="mb-3">
|
||||
<input type="text" name="username" id="username" class="form-control"
|
||||
placeholder="Логин" required="true" autofocus="true"/>
|
||||
</div>
|
||||
<div th:if="${param.logout}" class="alert alert-success margin-bottom">
|
||||
Выход успешно произведен
|
||||
<div class="mb-3">
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Пароль" required="true"/>
|
||||
</div>
|
||||
<div th:if="${param.created}" class="alert alert-success margin-bottom">
|
||||
Пользователь '<span th:text="${param.created}"></span>' успешно создан
|
||||
</div>
|
||||
<form th:action="@{/login}" method="post" class="container-padding">
|
||||
<div class="mb-3">
|
||||
<input type="text" name="username" id="username" class="form-control"
|
||||
placeholder="Логин" required="true" autofocus="true"/>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<input type="password" name="password" id="password" class="form-control"
|
||||
placeholder="Пароль" required="true"/>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success button-fixed">Войти</button>
|
||||
<a class="btn btn-primary button-fixed" href="/signup">Регистрация</a>
|
||||
</form>
|
||||
<button type="submit" class="btn btn-success button-fixed">Войти</button>
|
||||
<a class="btn btn-primary button-fixed" href="/signup">Регистрация</a>
|
||||
</form>
|
||||
</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>
|
||||
<html lang="en"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{default}">
|
||||
layout:decorate="~{default}"
|
||||
>
|
||||
<body>
|
||||
<div class="container container-padding" layout:fragment="content">
|
||||
<div th:if="${errors}" th:text="${errors}" class="margin-bottom alert alert-danger"></div>
|
||||
@ -12,11 +13,11 @@
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<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 class="mb-3">
|
||||
<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 class="mb-3">
|
||||
<button type="submit" class="btn btn-success button-fixed">Создать</button>
|
||||
|
Loading…
Reference in New Issue
Block a user