Games tab on admin page working
This commit is contained in:
11
db/1.0.0/5. createGame.sql
Normal file
11
db/1.0.0/5. createGame.sql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS raid_builder.game(
|
||||||
|
game_id uuid PRIMARY KEY,
|
||||||
|
game_name text UNIQUE NOT NULL,
|
||||||
|
game_icon text,
|
||||||
|
modified_by uuid,
|
||||||
|
modified_date timestamptz,
|
||||||
|
created_by uuid NOT NULL,
|
||||||
|
created_date timestamptz NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
GRANT ALL ON TABLE raid_builder.game TO raid_builder;
|
||||||
17
db/1.0.0/6. createGamePermission.sql
Normal file
17
db/1.0.0/6. createGamePermission.sql
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
CREATE TYPE raid_builder.game_permission_type AS ENUM ( 'ADMIN' );
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS raid_builder.game_permission(
|
||||||
|
game_permission_id uuid PRIMARY KEY,
|
||||||
|
account_id uuid REFERENCES raid_builder.account(account_id) NOT NULL,
|
||||||
|
game_id uuid REFERENCES raid_builder.game(game_id) NOT NULL,
|
||||||
|
game_permission_type raid_builder.game_permission_type NOT NULL,
|
||||||
|
|
||||||
|
--Auditing
|
||||||
|
modified_by uuid REFERENCES raid_builder.account(account_id) NOT NULL,
|
||||||
|
modified_date timestamptz NOT NULL,
|
||||||
|
created_by uuid REFERENCES raid_builder.account(account_id) NOT NULL,
|
||||||
|
created_date timestamptz NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
GRANT ALL ON TABLE raid_builder.game_permission TO raid_builder;
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.annotation;
|
||||||
|
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType;
|
||||||
|
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface GameAuthorization{
|
||||||
|
public GamePermissionType[] permissions();
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.aspect;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.authorization.AuthorizationDeniedException;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.annotation.GameAuthorization;
|
||||||
|
import com.mattrixwv.raidbuilder.entity.Account;
|
||||||
|
import com.mattrixwv.raidbuilder.entity.AccountPermission;
|
||||||
|
import com.mattrixwv.raidbuilder.entity.GamePermission;
|
||||||
|
import com.mattrixwv.raidbuilder.service.AccountPermissionService;
|
||||||
|
import com.mattrixwv.raidbuilder.service.AccountService;
|
||||||
|
import com.mattrixwv.raidbuilder.service.GamePermissionService;
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType;
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountStatus;
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Aspect
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GameAuthorizationAspect{
|
||||||
|
private final AccountService accountService;
|
||||||
|
private final AccountPermissionService accountPermissionService;
|
||||||
|
private final GamePermissionService gamePermissionService;
|
||||||
|
|
||||||
|
|
||||||
|
@Pointcut("@annotation(com.mattrixwv.raidbuilder.annotation.GameAuthorizationAspect)")
|
||||||
|
public void gameAuthorizationAnnotation(){
|
||||||
|
//Intentionally blank
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Before("gameAuthorizationAnnotation()")
|
||||||
|
public void authorizeGame(JoinPoint joinPoint){
|
||||||
|
log.debug("Authorizing game");
|
||||||
|
|
||||||
|
|
||||||
|
//Get the annotation
|
||||||
|
GameAuthorization gameAuthorization = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(GameAuthorization.class);
|
||||||
|
//Return if there are no required permissions
|
||||||
|
if(gameAuthorization.permissions().length == 0){
|
||||||
|
log.debug("No required permissions");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get the account
|
||||||
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
String username = ((Jwt)auth.getPrincipal()).getClaimAsString("sub");
|
||||||
|
Account account = accountService.getByUsername(username);
|
||||||
|
if(account.getAccountStatus() != AccountStatus.ACTIVE){
|
||||||
|
throw new AuthorizationDeniedException("Account is not active", () -> false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return if the user is a site admin
|
||||||
|
List<AccountPermission> accountPermissions = accountPermissionService.getByAccountId(account.getAccountId());
|
||||||
|
for(AccountPermission permission : accountPermissions){
|
||||||
|
if(permission.getAccountPermissionType() == AccountPermissionType.ADMIN){
|
||||||
|
log.debug("User is a site admin");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return if the account has a matching permission
|
||||||
|
List<GamePermission> gamePermissions = gamePermissionService.getByAccountId(account.getAccountId());
|
||||||
|
for(GamePermission permission : gamePermissions){
|
||||||
|
for(GamePermissionType permissionType : gameAuthorization.permissions()){
|
||||||
|
if(permission.getGamePermissionType() == permissionType){
|
||||||
|
log.debug("User is authorized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
log.debug("User is not authorized");
|
||||||
|
|
||||||
|
//If the user doesn't have a matching permission, throw an authorization exception
|
||||||
|
throw new AuthorizationDeniedException("User is not authorized to perform this action", () -> false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,7 @@ public class SecurityConfig{
|
|||||||
.csrf(csrf -> csrf.disable())
|
.csrf(csrf -> csrf.disable())
|
||||||
.authorizeHttpRequests(auth -> {
|
.authorizeHttpRequests(auth -> {
|
||||||
auth.requestMatchers(HttpMethod.OPTIONS).permitAll()
|
auth.requestMatchers(HttpMethod.OPTIONS).permitAll()
|
||||||
|
.requestMatchers("/icons/**").permitAll()
|
||||||
.requestMatchers("/auth/refresh", "/auth/test").permitAll() //Permit refresh tokens
|
.requestMatchers("/auth/refresh", "/auth/test").permitAll() //Permit refresh tokens
|
||||||
.requestMatchers(HttpMethod.POST, "/auth/signup", "/auth/confirm").permitAll() //Permit signup operations
|
.requestMatchers(HttpMethod.POST, "/auth/signup", "/auth/confirm").permitAll() //Permit signup operations
|
||||||
.requestMatchers("/auth/forgot", "/auth/forgot/*").permitAll() //Permit forgot password operations
|
.requestMatchers("/auth/forgot", "/auth/forgot/*").permitAll() //Permit forgot password operations
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ public class TokenService{
|
|||||||
.expiresAt(now.plus(accessTokenDuration))
|
.expiresAt(now.plus(accessTokenDuration))
|
||||||
.subject(account.getUsername())
|
.subject(account.getUsername())
|
||||||
.claim("scope", scope)
|
.claim("scope", scope)
|
||||||
|
.claim("accountId", account.getAccountId().toString())
|
||||||
|
//Game Permissions
|
||||||
|
//Raid Group Permissions
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
return encoder.encode(JwtEncoderParameters.from(claims)).getTokenValue();
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ public class AccountController{
|
|||||||
log.info("Updating account {}", accountId);
|
log.info("Updating account {}", accountId);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: Existing account verification
|
||||||
Account oldAccount = accountService.getByAccountId(accountId);
|
Account oldAccount = accountService.getByAccountId(accountId);
|
||||||
ObjectNode returnNode = mapper.createObjectNode();
|
ObjectNode returnNode = mapper.createObjectNode();
|
||||||
if(oldAccount == null){
|
if(oldAccount == null){
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PutMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
import com.mattrixwv.raidbuilder.annotation.AccountAuthorization;
|
||||||
|
import com.mattrixwv.raidbuilder.annotation.GameAuthorization;
|
||||||
|
import com.mattrixwv.raidbuilder.entity.Game;
|
||||||
|
import com.mattrixwv.raidbuilder.service.GameService;
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType;
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/game")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GameController{
|
||||||
|
private final ObjectMapper mapper;
|
||||||
|
private final GameService gameService;
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
@AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER})
|
||||||
|
public List<Game> getGames(@RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(value = "searchTerm", required = false) String searchTerm){
|
||||||
|
log.info("Getting games page {} of size {} with search term {}", page, pageSize, searchTerm);
|
||||||
|
|
||||||
|
|
||||||
|
List<Game> games;
|
||||||
|
if((searchTerm == null) || (searchTerm.isBlank())){
|
||||||
|
games = gameService.getGames(page, pageSize);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
games = gameService.getGames(page, pageSize, searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return games;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/count")
|
||||||
|
@AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER})
|
||||||
|
public ObjectNode getGamesCount(@RequestParam(value = "searchTerm", required = false) String searchTerm){
|
||||||
|
log.info("Getting games count");
|
||||||
|
|
||||||
|
|
||||||
|
Long gamesCount;
|
||||||
|
if((searchTerm == null) || (searchTerm.isBlank())){
|
||||||
|
gamesCount = gameService.getGamesCount();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
gamesCount = gameService.getGamesCount(searchTerm);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectNode countNode = mapper.createObjectNode();
|
||||||
|
countNode.put("count", gamesCount);
|
||||||
|
countNode.put("status", "success");
|
||||||
|
|
||||||
|
|
||||||
|
return countNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
@AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER})
|
||||||
|
@GameAuthorization(permissions = {GamePermissionType.ADMIN})
|
||||||
|
public ObjectNode createGame(@RequestParam(value = "iconFile", required = false) MultipartFile file, @RequestParam("gameName") String gameName){
|
||||||
|
log.info("Creating game {}", gameName);
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: New game verification
|
||||||
|
ObjectNode returnNode = mapper.createObjectNode();
|
||||||
|
Game game = new Game();
|
||||||
|
game.setGameName(gameName);
|
||||||
|
game = gameService.createGame(game, file);
|
||||||
|
returnNode.put("gameId", game.getGameId().toString());
|
||||||
|
returnNode.put("status", "success");
|
||||||
|
|
||||||
|
log.info("Successfully created game: {}", game.getGameId());
|
||||||
|
|
||||||
|
return returnNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{gameId}")
|
||||||
|
@AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER})
|
||||||
|
@GameAuthorization(permissions = {GamePermissionType.ADMIN})
|
||||||
|
public ObjectNode updateGame(@PathVariable("gameId") UUID gameId, @RequestParam(value = "iconFile", required = false) MultipartFile file, @RequestParam("gameName") String gameName, @RequestParam(name = "gameIcon", required = false) String gameIcon){
|
||||||
|
log.info("Updating game {}", gameName);
|
||||||
|
|
||||||
|
|
||||||
|
ObjectNode returnNode = mapper.createObjectNode();
|
||||||
|
Game game = new Game();
|
||||||
|
game.setGameId(gameId);
|
||||||
|
game.setGameName(gameName);
|
||||||
|
game.setGameIcon(gameIcon);
|
||||||
|
game = gameService.updateGame(game, file);
|
||||||
|
returnNode.put("gameId", game.getGameId().toString());
|
||||||
|
returnNode.put("status", "success");
|
||||||
|
|
||||||
|
log.info("Successfully updated game: {}", game.getGameId());
|
||||||
|
|
||||||
|
return returnNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{gameId}")
|
||||||
|
@AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER})
|
||||||
|
@GameAuthorization(permissions = {GamePermissionType.ADMIN})
|
||||||
|
public ObjectNode deleteGame(@PathVariable("gameId") UUID gameId){
|
||||||
|
log.info("Deleting game {}", gameId);
|
||||||
|
|
||||||
|
|
||||||
|
ObjectNode returnNode = mapper.createObjectNode();
|
||||||
|
gameService.deleteById(gameId);
|
||||||
|
returnNode.put("status", "success");
|
||||||
|
|
||||||
|
log.info("Successfully deleted game: {}", gameId);
|
||||||
|
|
||||||
|
return returnNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.annotation.AccountAuthorization;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/icons")
|
||||||
|
public class IconController{
|
||||||
|
@Value("${uploadFileDirectory}")
|
||||||
|
private String uploadFileDirectory;
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/gameIcons/{gameIconName}")
|
||||||
|
@AccountAuthorization(permissions = {})
|
||||||
|
public ResponseEntity<byte[]> getGameClassIcons(@PathVariable("gameIconName") String gameIconName) throws IOException{
|
||||||
|
log.info("Getting game icon {}", gameIconName);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] resource = Files.readAllBytes(Path.of(uploadFileDirectory + "/gameIcons/" + gameIconName));
|
||||||
|
|
||||||
|
|
||||||
|
return ResponseEntity.ok().body(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,33 +4,26 @@ package com.mattrixwv.raidbuilder.entity;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.springframework.data.annotation.CreatedBy;
|
|
||||||
import org.springframework.data.annotation.CreatedDate;
|
|
||||||
import org.springframework.data.annotation.LastModifiedBy;
|
|
||||||
import org.springframework.data.annotation.LastModifiedDate;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.MappedSuperclass;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@MappedSuperclass
|
||||||
public abstract class AuditableEntity{
|
public abstract class AuditableEntity{
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@LastModifiedBy
|
|
||||||
@Column(name = "modified_by")
|
@Column(name = "modified_by")
|
||||||
protected UUID modifiedBy;
|
protected UUID modifiedBy;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@LastModifiedDate
|
|
||||||
@Column(name = "modified_date")
|
@Column(name = "modified_date")
|
||||||
protected ZonedDateTime modifiedDate;
|
protected ZonedDateTime modifiedDate;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@CreatedBy
|
|
||||||
@Column(name = "created_by", updatable = false)
|
@Column(name = "created_by", updatable = false)
|
||||||
protected UUID createdBy;
|
protected UUID createdBy;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
@CreatedDate
|
|
||||||
@Column(name = "created_date", updatable = false)
|
@Column(name = "created_date", updatable = false)
|
||||||
protected ZonedDateTime createdDate;
|
protected ZonedDateTime createdDate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,11 @@ package com.mattrixwv.raidbuilder.entity;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.oauth2.jwt.Jwt;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import com.mattrixwv.raidbuilder.service.AccountService;
|
|
||||||
|
|
||||||
import jakarta.persistence.PrePersist;
|
import jakarta.persistence.PrePersist;
|
||||||
import jakarta.persistence.PreUpdate;
|
import jakarta.persistence.PreUpdate;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
@@ -20,19 +19,16 @@ import lombok.extern.slf4j.Slf4j;
|
|||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AuditableEntityListener{
|
public class AuditableEntityListener{
|
||||||
private final AccountService accountService;
|
|
||||||
|
|
||||||
|
|
||||||
@PrePersist
|
@PrePersist
|
||||||
public void prePersist(AuditableEntity entity){
|
public void prePersist(AuditableEntity entity) throws NoSuchFieldException, IllegalAccessException{
|
||||||
entity.setCreatedBy(getCurrentUserId());
|
entity.createdBy = getCurrentUserId();
|
||||||
entity.setCreatedDate(ZonedDateTime.now());
|
entity.createdDate = ZonedDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreUpdate
|
@PreUpdate
|
||||||
public void preUpdate(AuditableEntity entity){
|
public void preUpdate(AuditableEntity entity){
|
||||||
entity.setModifiedBy(getCurrentUserId());
|
entity.modifiedBy = getCurrentUserId();
|
||||||
entity.setModifiedDate(ZonedDateTime.now());
|
entity.modifiedDate = ZonedDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -43,11 +39,11 @@ public class AuditableEntityListener{
|
|||||||
UUID returnUUID;
|
UUID returnUUID;
|
||||||
|
|
||||||
try{
|
try{
|
||||||
UserDetails userDetails = (UserDetails)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
|
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||||
returnUUID = accountService.getByUsername(userDetails.getUsername()).getAccountId();
|
returnUUID = UUID.fromString(((Jwt)auth.getPrincipal()).getClaimAsString("accountId"));
|
||||||
}
|
}
|
||||||
catch(Exception e){
|
catch(Exception e){
|
||||||
returnUUID = UUID.fromString("382b1ed8-7d5a-4683-a25d-1f462e9cd921");
|
returnUUID = new UUID(0, 0);
|
||||||
log.debug("No user logged in: {}", returnUUID);
|
log.debug("No user logged in: {}", returnUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
35
src/main/java/com/mattrixwv/raidbuilder/entity/Game.java
Normal file
35
src/main/java/com/mattrixwv/raidbuilder/entity/Game.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EntityListeners;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "game", schema = "raid_builder")
|
||||||
|
@EntityListeners(AuditableEntityListener.class)
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Game extends AuditableEntity{
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
@Column(name = "game_id")
|
||||||
|
private UUID gameId;
|
||||||
|
@Column(name = "game_name")
|
||||||
|
private String gameName;
|
||||||
|
@Column(name = "game_icon")
|
||||||
|
private String gameIcon;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.entity;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.GamePermissionType;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EntityListeners;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "game_permission", schema = "raid_builder")
|
||||||
|
@EntityListeners(AuditableEntityListener.class)
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = false)
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class GamePermission extends AuditableEntity{
|
||||||
|
@Id
|
||||||
|
@Column(name = "game_permission_id")
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
private UUID gamePermissionId;
|
||||||
|
@Column(name = "account_id")
|
||||||
|
private UUID accountId;
|
||||||
|
@Column(name = "game_id")
|
||||||
|
private UUID gameId;
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
@Column(name = "game_permission_type")
|
||||||
|
private GamePermissionType gamePermissionType;
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game;
|
||||||
|
|
||||||
|
|
||||||
|
public interface GameCustomRepository{
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.entity.Game;
|
||||||
|
|
||||||
|
|
||||||
|
public interface GameRepository extends GameCustomRepository, JpaRepository<Game, UUID>{
|
||||||
|
public List<Game> findAllByGameNameContainingIgnoreCase(String searchTerm, PageRequest pageRequest);
|
||||||
|
public long countAllByGameNameContainingIgnoreCase(String searchTerm);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class GameRepositoryImpl implements GameCustomRepository{
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game_permission;
|
||||||
|
|
||||||
|
|
||||||
|
public interface GamePermissionCustomRepository{
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game_permission;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.entity.GamePermission;
|
||||||
|
|
||||||
|
|
||||||
|
public interface GamePermissionRepository extends GamePermissionCustomRepository, JpaRepository<GamePermission, UUID>{
|
||||||
|
public List<GamePermission> findAllByAccountId(UUID accountId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.repository.game_permission;
|
||||||
|
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public class GamePermissionRepositoryImpl implements GamePermissionCustomRepository{
|
||||||
|
}
|
||||||
@@ -127,7 +127,10 @@ public class AccountService implements UserDetailsService{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Account> getAccounts(int page, int pageSize, String searchTerm){
|
public List<Account> getAccounts(int page, int pageSize, String searchTerm){
|
||||||
return accountRepository.findAllByUsernameContainingIgnoreCase(searchTerm, PageRequest.of(page, pageSize, Sort.by("username").ascending()));
|
return accountRepository.findAllByUsernameContainingIgnoreCase(
|
||||||
|
searchTerm,
|
||||||
|
PageRequest.of(page, pageSize, Sort.by("username").ascending())
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getAccountsCount(){
|
public long getAccountsCount(){
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.entity.GamePermission;
|
||||||
|
import com.mattrixwv.raidbuilder.repository.game_permission.GamePermissionRepository;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GamePermissionService{
|
||||||
|
private final GamePermissionRepository gamePermissionRepository;
|
||||||
|
|
||||||
|
|
||||||
|
//Write
|
||||||
|
public GamePermission createGamePermission(GamePermission gamePermission){
|
||||||
|
return gamePermissionRepository.save(gamePermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GamePermission updateGamePermission(GamePermission gamePermission){
|
||||||
|
return gamePermissionRepository.save(gamePermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteGamePermission(GamePermission gamePermission){
|
||||||
|
gamePermissionRepository.delete(gamePermission);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Read
|
||||||
|
public List<GamePermission> getByAccountId(UUID accountId){
|
||||||
|
return gamePermissionRepository.findAllByAccountId(accountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
113
src/main/java/com/mattrixwv/raidbuilder/service/GameService.java
Normal file
113
src/main/java/com/mattrixwv/raidbuilder/service/GameService.java
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package com.mattrixwv.raidbuilder.service;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.data.domain.PageRequest;
|
||||||
|
import org.springframework.data.domain.Sort;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.mattrixwv.raidbuilder.entity.Game;
|
||||||
|
import com.mattrixwv.raidbuilder.repository.game.GameRepository;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class GameService{
|
||||||
|
private final GameRepository gameRepository;
|
||||||
|
@Value("${uploadFileDirectory}")
|
||||||
|
private String uploadFileDirectory;
|
||||||
|
|
||||||
|
|
||||||
|
//Write
|
||||||
|
public Game createGame(Game game, MultipartFile file){
|
||||||
|
if(file != null){
|
||||||
|
String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename();
|
||||||
|
Path filePath = Paths.get(uploadFileDirectory + "/gameIcons").resolve(fileName);
|
||||||
|
try{
|
||||||
|
file.transferTo(filePath);
|
||||||
|
game.setGameIcon(fileName);
|
||||||
|
}
|
||||||
|
catch(Exception error){
|
||||||
|
log.error("Error uploading file: " + error.getMessage(), error);
|
||||||
|
throw new RuntimeException("Error uploading file: " + error.getMessage(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return gameRepository.save(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game updateGame(Game game, MultipartFile file){
|
||||||
|
Game existingGame = gameRepository.findById(game.getGameId()).orElse(null);
|
||||||
|
|
||||||
|
//Delete the old file if one exists
|
||||||
|
if((existingGame != null) && (existingGame.getGameIcon() != null) && (game.getGameIcon() == null)){
|
||||||
|
log.debug("Deleting old file: {}", existingGame.getGameIcon());
|
||||||
|
File existingFile = new File(uploadFileDirectory + "/gameIcons/" + existingGame.getGameIcon());
|
||||||
|
if(existingFile.exists()){
|
||||||
|
existingFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(file != null){
|
||||||
|
//Upload the new file
|
||||||
|
String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename();
|
||||||
|
Path filePath = Paths.get(uploadFileDirectory + "/gameIcons").resolve(fileName);
|
||||||
|
try{
|
||||||
|
file.transferTo(filePath);
|
||||||
|
game.setGameIcon(fileName);
|
||||||
|
}
|
||||||
|
catch(Exception error){
|
||||||
|
log.error("Error uploading file: " + error.getMessage(), error);
|
||||||
|
throw new RuntimeException("Error uploading file: " + error.getMessage(), error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameRepository.save(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteById(UUID gameId){
|
||||||
|
Game game = gameRepository.findById(gameId).orElse(null);
|
||||||
|
if(game != null){
|
||||||
|
if(game.getGameIcon() != null){
|
||||||
|
File existingFile = new File(uploadFileDirectory + "/gameIcons/" + game.getGameIcon());
|
||||||
|
if(existingFile.exists()){
|
||||||
|
existingFile.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gameRepository.deleteById(gameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Read
|
||||||
|
public List<Game> getGames(int page, int pageSize){
|
||||||
|
return gameRepository.findAll(PageRequest.of(page, pageSize, Sort.by("gameName").ascending())).getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Game> getGames(int page, int pageSize, String searchTerm){
|
||||||
|
return gameRepository.findAllByGameNameContainingIgnoreCase(
|
||||||
|
searchTerm,
|
||||||
|
PageRequest.of(page, pageSize, Sort.by("gameName").ascending())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getGamesCount(){
|
||||||
|
return gameRepository.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getGamesCount(String searchTerm){
|
||||||
|
return gameRepository.countAllByGameNameContainingIgnoreCase(searchTerm);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,11 @@ public class DatabaseTypeUtil{
|
|||||||
public static enum AccountPermissionType {
|
public static enum AccountPermissionType {
|
||||||
ADMIN,
|
ADMIN,
|
||||||
USER
|
USER
|
||||||
}
|
};
|
||||||
|
|
||||||
|
public static enum GamePermissionType {
|
||||||
|
ADMIN
|
||||||
|
};
|
||||||
|
|
||||||
public static enum TutorialStatus {
|
public static enum TutorialStatus {
|
||||||
COMPLETED,
|
COMPLETED,
|
||||||
|
|||||||
@@ -19,3 +19,6 @@ rsa.privateKey=classpath:certs/private.pem
|
|||||||
rsa.publicKey=classpath:certs/public.pem
|
rsa.publicKey=classpath:certs/public.pem
|
||||||
jwt.accessTokenDuration=15m
|
jwt.accessTokenDuration=15m
|
||||||
jwt.refreshTokenDuration=30d
|
jwt.refreshTokenDuration=30d
|
||||||
|
|
||||||
|
#Files
|
||||||
|
uploadFileDirectory=../raidBuilderIcons
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Reference in New Issue
Block a user