initial commit
This commit is contained in:
116
pom.xml
Normal file
116
pom.xml
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.4</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<groupId>ru.kayashov</groupId>
|
||||||
|
<artifactId>karthall</artifactId>
|
||||||
|
<version>4.3.0</version>
|
||||||
|
<name>KartHall</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate.orm</groupId>
|
||||||
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
<version>6.5.2.Final</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.12.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.12.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.12.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.telegram</groupId>
|
||||||
|
<artifactId>telegrambots</artifactId>
|
||||||
|
<version>6.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.module</groupId>
|
||||||
|
<artifactId>jackson-module-jakarta-xmlbind-annotations</artifactId>
|
||||||
|
<version>2.18.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>org.springframework.kafka</groupId>-->
|
||||||
|
<!-- <artifactId>spring-kafka</artifactId>-->
|
||||||
|
<!-- <version>3.2.4</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>${lombok.version}</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
13
src/main/java/ru/kayashov/karthall/KartHallApplication.java
Normal file
13
src/main/java/ru/kayashov/karthall/KartHallApplication.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package ru.kayashov.karthall;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class KartHallApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(KartHallApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.kayashov.karthall.model.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.OneToMany;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Championship {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
@OneToMany(mappedBy = "championship")
|
||||||
|
private List<Event> events;
|
||||||
|
}
|
||||||
31
src/main/java/ru/kayashov/karthall/model/entity/Event.java
Normal file
31
src/main/java/ru/kayashov/karthall/model/entity/Event.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package ru.kayashov.karthall.model.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.ManyToMany;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Event {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private LocalDate date;
|
||||||
|
private LocalTime startTime;
|
||||||
|
private LocalTime endTime;
|
||||||
|
@ManyToOne
|
||||||
|
private Championship championship;
|
||||||
|
}
|
||||||
20
src/main/java/ru/kayashov/karthall/model/entity/Place.java
Normal file
20
src/main/java/ru/kayashov/karthall/model/entity/Place.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package ru.kayashov.karthall.model.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Place {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private String address;
|
||||||
|
private String photo;
|
||||||
|
}
|
||||||
65
src/main/java/ru/kayashov/karthall/model/entity/Player.java
Normal file
65
src/main/java/ru/kayashov/karthall/model/entity/Player.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package ru.kayashov.karthall.model.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class Player implements UserDetails {
|
||||||
|
@Id
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private String lastName;
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private UserRole role;
|
||||||
|
private Integer age;
|
||||||
|
private String email;
|
||||||
|
private String phone;
|
||||||
|
private String image;
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return role.getAuthorities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername() {
|
||||||
|
return id.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package ru.kayashov.karthall.model.entity;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public enum UserRole {
|
||||||
|
|
||||||
|
RACER(Set.of("racer")), //стандартный участник
|
||||||
|
MODERATOR(Set.of("racer", "event_admin")), //модератор события
|
||||||
|
ADMIN(Set.of("racer", "event_admin", "championship_admin")), //модератор чемпионата
|
||||||
|
OWNER(Set.of("racer", "event_admin", "championship_admin", "place_admin")), //модератор места проведения
|
||||||
|
SUPERADMIN(Set.of("racer", "event_admin", "championship_admin", "place_admin", "admin")); //супер админ
|
||||||
|
|
||||||
|
private final Set<String> authorities;
|
||||||
|
|
||||||
|
public Set<GrantedAuthority> getAuthorities() {
|
||||||
|
return authorities.stream()
|
||||||
|
.map(SimpleGrantedAuthority::new)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.kayashov.karthall.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.kayashov.karthall.model.entity.Championship;
|
||||||
|
|
||||||
|
public interface ChampionshipRepository extends JpaRepository<Championship, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.kayashov.karthall.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.kayashov.karthall.model.entity.Event;
|
||||||
|
|
||||||
|
public interface EventRepository extends JpaRepository<Event, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package ru.kayashov.karthall.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.kayashov.karthall.model.entity.Place;
|
||||||
|
|
||||||
|
public interface PlaceRepository extends JpaRepository<Place, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package ru.kayashov.karthall.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import ru.kayashov.karthall.model.entity.Player;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public interface PlayerRepository extends JpaRepository<Player, Long> {
|
||||||
|
Optional<Player> findByPhoneOrderByEmail(String login);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package ru.kayashov.karthall.security;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import ru.kayashov.karthall.model.entity.UserRole;
|
||||||
|
import ru.kayashov.karthall.repository.PlayerRepository;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class CustomUserDetailService implements UserDetailsService {
|
||||||
|
|
||||||
|
private final PlayerRepository repository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
return repository.findById(Long.parseLong(username)).orElseThrow(() -> new RuntimeException("Пользователь с email " + username + " не найден!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Set<GrantedAuthority> getAuthorities(long userId) {
|
||||||
|
// Visitor visitor = repository.findById(userId).orElseThrow(RuntimeException::new);
|
||||||
|
return UserRole.ADMIN.getAuthorities();
|
||||||
|
// return visitor.getResidents().stream()
|
||||||
|
// .filter(BarResident::getActive)
|
||||||
|
// .map(BarResident::getRole)
|
||||||
|
// .map(UserRole::getAuthorities)
|
||||||
|
// .flatMap(Collection::stream)
|
||||||
|
// .collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package ru.kayashov.karthall.security;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.context.SecurityContext;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
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 java.io.IOException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class JwtTokenFilter extends GenericFilterBean {
|
||||||
|
|
||||||
|
public static final String BEARER_PREFIX = "Bearer ";
|
||||||
|
public static final String HEADER_NAME = "Authorization";
|
||||||
|
private final JwtTokenProvider jwtTokenProvider;
|
||||||
|
private final CustomUserDetailService detailService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doFilter(ServletRequest request,
|
||||||
|
ServletResponse response,
|
||||||
|
FilterChain filterChain) throws IOException, ServletException {
|
||||||
|
var authHeader = ((HttpServletRequest) request).getHeader(HEADER_NAME);
|
||||||
|
if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обрезаем префикс и получаем имя пользователя из токена
|
||||||
|
var jwt = authHeader.substring(BEARER_PREFIX.length());
|
||||||
|
var username = jwtTokenProvider.extractUserName(jwt);
|
||||||
|
|
||||||
|
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||||
|
UserDetails userDetails = detailService.loadUserByUsername(username);
|
||||||
|
|
||||||
|
// Если токен валиден, то аутентифицируем пользователя
|
||||||
|
if (jwtTokenProvider.isTokenValid(jwt, userDetails)) {
|
||||||
|
SecurityContext context = SecurityContextHolder.createEmptyContext();
|
||||||
|
|
||||||
|
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(
|
||||||
|
userDetails,
|
||||||
|
null,
|
||||||
|
detailService.getAuthorities(Long.parseLong(username))
|
||||||
|
);
|
||||||
|
|
||||||
|
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails((HttpServletRequest) request));
|
||||||
|
context.setAuthentication(authToken);
|
||||||
|
SecurityContextHolder.setContext(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
package ru.kayashov.karthall.security;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Claims;
|
||||||
|
import io.jsonwebtoken.Jwts;
|
||||||
|
import io.jsonwebtoken.io.Decoders;
|
||||||
|
import io.jsonwebtoken.security.Keys;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import ru.kayashov.karthall.model.entity.Player;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtTokenProvider {
|
||||||
|
|
||||||
|
@Value("${token.signing.key}")
|
||||||
|
private String jwtSecretKey;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
protected void init() {
|
||||||
|
jwtSecretKey = Base64.getEncoder().encodeToString(jwtSecretKey.getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String extractUserName(String token) {
|
||||||
|
return extractClaim(token, Claims::getSubject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String generateToken(UserDetails userDetails) {
|
||||||
|
Map<String, Object> claims = new HashMap<>();
|
||||||
|
if (userDetails instanceof Player customUserDetails) {
|
||||||
|
claims.put("id", customUserDetails.getId());
|
||||||
|
// claims.put("role", customUserDetails.getRole());
|
||||||
|
}
|
||||||
|
return generateToken(claims, userDetails);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTokenValid(String token, UserDetails userDetails) {
|
||||||
|
final String userName = extractUserName(token);
|
||||||
|
return (userName.equals(userDetails.getUsername())) && !isTokenExpired(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T extractClaim(String token, Function<Claims, T> claimsResolvers) {
|
||||||
|
final Claims claims = extractAllClaims(token);
|
||||||
|
return claimsResolvers.apply(claims);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String generateToken(Map<String, Object> extraClaims, UserDetails userDetails) {
|
||||||
|
return Jwts.builder()
|
||||||
|
.claims(extraClaims)
|
||||||
|
.subject(userDetails.getUsername())
|
||||||
|
.issuedAt(new Date())
|
||||||
|
.expiration(new Date(Instant.now().plus(24, ChronoUnit.HOURS).toEpochMilli()))
|
||||||
|
.signWith(getSigningKey())
|
||||||
|
.compact();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isTokenExpired(String token) {
|
||||||
|
return extractExpiration(token).before(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date extractExpiration(String token) {
|
||||||
|
return extractClaim(token, Claims::getExpiration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Claims extractAllClaims(String token) {
|
||||||
|
return Jwts.parser()
|
||||||
|
.verifyWith((SecretKey) getSigningKey())
|
||||||
|
.build()
|
||||||
|
.parseSignedClaims(token)
|
||||||
|
.getPayload();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Key getSigningKey() {
|
||||||
|
String keyForSigning = jwtSecretKey;
|
||||||
|
byte[] bytes = Decoders.BASE64.decode(keyForSigning);
|
||||||
|
return Keys.hmacShaKeyFor(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package ru.kayashov.karthall.security;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.CorsConfigurer;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
|
@EnableMethodSecurity
|
||||||
|
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SecurityConfig {
|
||||||
|
|
||||||
|
private final JwtTokenFilter jwtTokenFilter;
|
||||||
|
private final CustomUserDetailService userDetailsService;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PasswordEncoder passwordEncoder() {
|
||||||
|
return new BCryptPasswordEncoder(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
http.csrf(AbstractHttpConfigurer::disable)
|
||||||
|
.cors(this::corsConfiguration)
|
||||||
|
.authorizeHttpRequests(this::authorizeConfiguration)
|
||||||
|
.sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
|
||||||
|
.authenticationProvider(authenticationProvider())
|
||||||
|
.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
|
||||||
|
return http.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void authorizeConfiguration(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry request) {
|
||||||
|
request
|
||||||
|
.antMatchers()
|
||||||
|
.permitAll();
|
||||||
|
// Можно указать конкретный путь, * - 1 уровень вложенности, ** - любое количество уровней вложенности
|
||||||
|
// .antMatchers("/api/auth/**").permitAll()
|
||||||
|
// .antMatchers("/api/cocktail/menu").permitAll()
|
||||||
|
// .antMatchers("/api/cocktail/drink/**").permitAll()
|
||||||
|
// .antMatchers("/api/cocktail/modal").permitAll()
|
||||||
|
// .antMatchers("/api/category").permitAll()
|
||||||
|
// .antMatchers("/api/glass").permitAll()
|
||||||
|
// .antMatchers("/api/ingredient/simple").permitAll()
|
||||||
|
// .anyRequest()
|
||||||
|
// .authenticated();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void corsConfiguration(CorsConfigurer<HttpSecurity> cors) {
|
||||||
|
cors.configurationSource(request -> {
|
||||||
|
var corsConfiguration = new CorsConfiguration();
|
||||||
|
corsConfiguration.setAllowedOriginPatterns(List.of("*"));
|
||||||
|
corsConfiguration.setAllowedMethods(List.of("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
|
||||||
|
corsConfiguration.setAllowedHeaders(List.of("*"));
|
||||||
|
corsConfiguration.setAllowCredentials(true);
|
||||||
|
return corsConfiguration;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationProvider authenticationProvider() {
|
||||||
|
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
|
||||||
|
authProvider.setUserDetailsService(userDetailsService);
|
||||||
|
authProvider.setPasswordEncoder(passwordEncoder());
|
||||||
|
return authProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
|
||||||
|
return config.getAuthenticationManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
21
src/main/java/ru/kayashov/karthall/service/EventService.java
Normal file
21
src/main/java/ru/kayashov/karthall/service/EventService.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package ru.kayashov.karthall.service;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.kayashov.karthall.model.entity.Event;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class EventService {
|
||||||
|
|
||||||
|
private final ExecutorService executorService;
|
||||||
|
|
||||||
|
// public void createEvent(Event event) {
|
||||||
|
// executorService.submit(() -> {eventRepository.save(event);});
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package ru.kayashov.karthall.service;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.kayashov.karthall.model.entity.Player;
|
||||||
|
import ru.kayashov.karthall.repository.PlayerRepository;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class PlayerService {
|
||||||
|
|
||||||
|
private final PlayerRepository playerRepository;
|
||||||
|
|
||||||
|
public Player getCurrentVisitor() {
|
||||||
|
Long id = ((Player) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
|
||||||
|
return findById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player findById(Long id) {
|
||||||
|
return playerRepository.findById(id).orElseThrow(() -> new RuntimeException("пользователь не найден. id: " + id));
|
||||||
|
}
|
||||||
|
}
|
||||||
18
src/main/resources/application.properties
Normal file
18
src/main/resources/application.properties
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
spring.application.name=myBar
|
||||||
|
|
||||||
|
spring.datasource.driver-class-name=org.postgresql.Driver
|
||||||
|
spring.datasource.url=${DB_URL:jdbc:postgresql://localhost:5433/kart_hall}
|
||||||
|
spring.datasource.username=${DB_NAME:kart_hall}
|
||||||
|
spring.datasource.password=${DB_PASSWORD:pgkarthallpass}
|
||||||
|
spring.datasource.hikari.minimum-idle=15
|
||||||
|
spring.datasource.hikari.maximum-pool-size=50
|
||||||
|
spring.datasource.hikari.idle-timeout=30000
|
||||||
|
spring.datasource.hikari.max-lifetime=600000
|
||||||
|
|
||||||
|
spring.jpa.generate-ddl=true
|
||||||
|
|
||||||
|
token.signing.key=${SIGNING_KEY:ThisIsKartHallSecretKey-1.0.0Version}
|
||||||
|
|
||||||
|
spring.jpa.show-sql=false
|
||||||
|
|
||||||
|
#server.port=8081
|
||||||
Reference in New Issue
Block a user