diff --git a/db/1.0.0/5. createGame.sql b/db/1.0.0/5. createGame.sql index 2285216..5a5c55c 100644 --- a/db/1.0.0/5. createGame.sql +++ b/db/1.0.0/5. createGame.sql @@ -2,6 +2,8 @@ CREATE TABLE IF NOT EXISTS raid_builder.game( game_id uuid PRIMARY KEY, game_name text UNIQUE NOT NULL, game_icon text, + + --Auditing modified_by uuid, modified_date timestamptz, created_by uuid NOT NULL, diff --git a/db/1.0.0/6. createGamePermission.sql b/db/1.0.0/6. createGamePermission.sql index 298b0fe..8b203eb 100644 --- a/db/1.0.0/6. createGamePermission.sql +++ b/db/1.0.0/6. createGamePermission.sql @@ -8,9 +8,9 @@ CREATE TABLE IF NOT EXISTS raid_builder.game_permission( 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, + modified_by uuid, + modified_date timestamptz, + created_by uuid NOT NULL, created_date timestamptz NOT NULL ); diff --git a/db/1.0.0/7. createRaidGroup.sql b/db/1.0.0/7. createRaidGroup.sql new file mode 100644 index 0000000..2ab64ad --- /dev/null +++ b/db/1.0.0/7. createRaidGroup.sql @@ -0,0 +1,14 @@ +CREATE TABLE IF NOT EXISTS raid_builder.raid_group( + raid_group_id uuid PRIMARY KEY, + game_id uuid REFERENCES raid_builder.game(game_id) NOT NULL, + raid_group_name text NOT NULL, + raid_group_icon text, + + --Auditing + modified_by uuid, + modified_date timestamptz, + created_by uuid NOT NULL, + created_date timestamptz NOT NULL +); + +GRANT ALL ON TABLE raid_builder.raid_group TO raid_builder; diff --git a/db/1.0.0/8. createRaidGroupPermission.sql b/db/1.0.0/8. createRaidGroupPermission.sql new file mode 100644 index 0000000..c5e1b8d --- /dev/null +++ b/db/1.0.0/8. createRaidGroupPermission.sql @@ -0,0 +1,17 @@ +CREATE TYPE raid_builder.raid_group_permission_type AS ENUM ( 'ADMIN', 'LEADER', 'RAIDER' ); + + +CREATE TABLE IF NOT EXISTS raid_builder.raid_group_permission( + raid_group_permission_id uuid PRIMARY KEY, + account_id uuid REFERENCES raid_builder.account(account_id) NOT NULL, + raid_group_id uuid REFERENCES raid_builder.raid_group(raid_group_id) NOT NULL, + permission raid_builder.raid_group_permission_type NOT NULL, + + --Auditing + modified_by uuid NOT NULL, + modified_date timestamptz, + created_by uuid NOT NULL, + created_date timestamptz NOT NULL +); + +GRANT ALL ON TABLE raid_builder.raid_group_permission TO raid_builder; diff --git a/src/main/java/com/mattrixwv/raidbuilder/annotation/RaidGroupAuthorization.java b/src/main/java/com/mattrixwv/raidbuilder/annotation/RaidGroupAuthorization.java new file mode 100644 index 0000000..75d10a4 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/annotation/RaidGroupAuthorization.java @@ -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.RaidGroupPermissionType; + + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface RaidGroupAuthorization{ + public RaidGroupPermissionType[] permissions(); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/aspect/RaidGroupAuthorizationAspect.java b/src/main/java/com/mattrixwv/raidbuilder/aspect/RaidGroupAuthorizationAspect.java new file mode 100644 index 0000000..d1b72bf --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/aspect/RaidGroupAuthorizationAspect.java @@ -0,0 +1,105 @@ +package com.mattrixwv.raidbuilder.aspect; + + +import java.lang.reflect.Parameter; +import java.util.List; +import java.util.UUID; + +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.RaidGroupAuthorization; +import com.mattrixwv.raidbuilder.entity.Account; +import com.mattrixwv.raidbuilder.entity.AccountPermission; +import com.mattrixwv.raidbuilder.entity.RaidGroupPermission; +import com.mattrixwv.raidbuilder.service.AccountPermissionService; +import com.mattrixwv.raidbuilder.service.AccountService; +import com.mattrixwv.raidbuilder.service.RaidGroupPermissionService; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@Aspect +@Configuration +@RequiredArgsConstructor +public class RaidGroupAuthorizationAspect{ + private final AccountService accountService; + private final AccountPermissionService accountPermissionService; + private final RaidGroupPermissionService raidGroupPermissionService; + + + @Pointcut("@annotation(com.mattrixwv.raidbuilder.annotations.RaidGroupAuthorization)") + public void raidGroupAuthorization(){ + //Intentionally blank + } + + @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping) || @annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.DeleteMapping)") + public void mappedFunction(){ + //Intentionally blank + } + + + @Before("raidGroupAuthorization() && mappedFunction()") + public void authorizeRaidGroup(JoinPoint joinPoint){ + log.debug("Authorizing Raid Group"); + + + //Get the annotation + RaidGroupAuthorization raidGroupAuthorization = ((MethodSignature)joinPoint.getSignature()).getMethod().getAnnotation(RaidGroupAuthorization.class); + log.debug("Required authorizations = {}", raidGroupAuthorization); + //Return if there are no required permissions + if(raidGroupAuthorization.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); + + //Return if the user is a site admin + List accountPermissions = accountPermissionService.getByAccountId(account.getAccountId()); + for(AccountPermission permission : accountPermissions){ + if(permission.getAccountPermissionType() == AccountPermissionType.ADMIN){ + log.debug("User is a site admin"); + return; + } + } + + UUID raidGroupId = null; + Parameter[] params = ((MethodSignature)joinPoint.getSignature()).getMethod().getParameters(); + for(int cnt = 0;cnt < params.length;++cnt){ + if(params[cnt].getName().equals("raidGroupId")){ + raidGroupId = (UUID)joinPoint.getArgs()[cnt]; + break; + } + } + + //Return if the account has a matching permission + List raidGroupPermissions = raidGroupPermissionService.getByAccountId(account.getAccountId()); + for(RaidGroupPermission permission : raidGroupPermissions){ + for(RaidGroupPermissionType permissionType : raidGroupAuthorization.permissions()){ + if((permission.getRaidGroupId().equals(raidGroupId)) && (permission.getPermission() == permissionType)){ + log.debug("User is authorized"); + return; + } + } + } + + //If the user doesn't have a matching permission throw an authorization exception + throw new AuthorizationDeniedException("User is not a qualified member of the raid group", () -> false); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/GameController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/GameController.java index 30eaf5d..b93b56c 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/controller/GameController.java +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/GameController.java @@ -58,7 +58,7 @@ public class GameController{ @GetMapping("/count") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) public ObjectNode getGamesCount(@RequestParam(value = "searchTerm", required = false) String searchTerm){ - log.info("Getting games count"); + log.info("Getting games count with search term {}", searchTerm); Long gamesCount; @@ -98,6 +98,15 @@ public class GameController{ return returnNode; } + @GetMapping("/{gameId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public Game getGame(@PathVariable("gameId") UUID gameId){ + log.info("Getting game {}", gameId); + + + return gameService.getGameById(gameId); + } + @PutMapping("/{gameId}") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @GameAuthorization(permissions = {GamePermissionType.ADMIN}) diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java index 8a5683a..c5faab1 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/IconController.java @@ -27,13 +27,25 @@ public class IconController{ @GetMapping("/gameIcons/{gameIconName}") @AccountAuthorization(permissions = {}) - public ResponseEntity getGameClassIcons(@PathVariable("gameIconName") String gameIconName) throws IOException{ + public ResponseEntity getGameIcons(@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); + } + + @GetMapping("/raidGroupIcons/{raidGroupIconName}") + @AccountAuthorization(permissions = {}) + public ResponseEntity getRaidGroupIcons(@PathVariable("raidGroupIconName") String raidGroupIconName) throws IOException{ + log.info("Getting raid group icon {}", raidGroupIconName); + + + byte[] resource = Files.readAllBytes(Path.of(uploadFileDirectory + "/raidGroupIcons/" + raidGroupIconName)); + + return ResponseEntity.ok().body(resource); } } diff --git a/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupController.java b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupController.java new file mode 100644 index 0000000..9b44976 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/controller/RaidGroupController.java @@ -0,0 +1,151 @@ +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.RaidGroupAuthorization; +import com.mattrixwv.raidbuilder.entity.RaidGroup; +import com.mattrixwv.raidbuilder.service.RaidGroupService; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.AccountPermissionType; +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@RestController +@RequestMapping("/raidGroup") +@RequiredArgsConstructor +public class RaidGroupController{ + private final ObjectMapper mapper; + private final RaidGroupService raidGroupService; + + + @GetMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) + public List getRaidGroups(@RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(value = "searchTerm", required = false) String searchTerm){ + log.info("Getting raid groups page {} of size {} with search term {}", page, pageSize, searchTerm); + + + List raidGroups; + if((searchTerm == null) || (searchTerm.isBlank())){ + raidGroups = raidGroupService.getRaidGroups(page, pageSize); + } + else{ + raidGroups = raidGroupService.getRaidGroups(page, pageSize, searchTerm); + } + + + return raidGroups; + } + + @GetMapping("/count") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) + public ObjectNode getRaidGroupsCount(@RequestParam(value = "searchTerm", required = false) String searchTerm){ + log.info("Getting raid groups count with search term {}", searchTerm); + + + Long raidGroupsCount; + if((searchTerm == null) || (searchTerm.isBlank())){ + raidGroupsCount = raidGroupService.getRaidGroupsCount(); + } + else{ + raidGroupsCount = raidGroupService.getRaidGroupsCount(searchTerm); + } + + ObjectNode countNode = mapper.createObjectNode(); + countNode.put("count", raidGroupsCount); + countNode.put("status", "success"); + + + return countNode; + } + + + @PostMapping + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode createRaidGroup(@RequestParam(value = "iconFile", required = false) MultipartFile file, @RequestParam("raidGroupName") String raidGroupName, @RequestParam("gameId") UUID gameId){ + log.info("Creating raid group {}", raidGroupName); + + + //TODO: New raid group verification + ObjectNode returnNode = mapper.createObjectNode(); + RaidGroup raidGroup = new RaidGroup(); + raidGroup.setGameId(gameId); + raidGroup.setRaidGroupName(raidGroupName); + raidGroupService.createRaidGroup(raidGroup, file); + + returnNode.put("raidGroupId", raidGroup.getRaidGroupId().toString()); + returnNode.put("status", "success"); + + log.info("Successfully created raid group: {}", raidGroup.getRaidGroupId()); + + return returnNode; + } + + @GetMapping("/{raidGroupId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN, RaidGroupPermissionType.LEADER, RaidGroupPermissionType.RAIDER}) + public RaidGroup getRaidGroup(@PathVariable("raidGroupId") UUID raidGroupId){ + log.info("Getting raid group {}", raidGroupId); + + + RaidGroup raidGroup = raidGroupService.getByRaidGroupId(raidGroupId); + + + return raidGroup; + + } + + @PutMapping("/{raidGroupId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode updateRaidGroup(@RequestParam(value = "iconFile", required = false) MultipartFile file, @PathVariable("raidGroupId") UUID raidGroupId, @RequestParam("raidGroupName") String raidGroupName, @RequestParam("gameId") UUID gameId, @RequestParam(value = "raidGroupIcon", required = false) String raidGroupIcon){ + log.info("Updating raid group {}", raidGroupName); + + + ObjectNode returnNode = mapper.createObjectNode(); + RaidGroup raidGroup = new RaidGroup(); + raidGroup.setRaidGroupId(raidGroupId); + raidGroup.setGameId(gameId); + raidGroup.setRaidGroupName(raidGroupName); + raidGroup.setRaidGroupIcon(raidGroupIcon); + raidGroupService.updateRaidGroup(raidGroup, file); + + returnNode.put("raidGroupId", raidGroup.getRaidGroupId().toString()); + returnNode.put("status", "success"); + + log.info("Successfully updated raid group: {}", raidGroup.getRaidGroupId()); + + return returnNode; + } + + @DeleteMapping("/{raidGroupId}") + @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) + public ObjectNode deleteRaidGroup(@PathVariable("raidGroupId") UUID raidGroupId){ + log.info("Deleting raid group {}", raidGroupId); + + + ObjectNode returnNode = mapper.createObjectNode(); + raidGroupService.deleteById(raidGroupId); + returnNode.put("status", "success"); + + log.info("Successfully deleted raid group: {}", raidGroupId); + + return returnNode; + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java b/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java index efe925c..ddd5c7a 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/Game.java @@ -13,7 +13,6 @@ import jakarta.persistence.Table; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import lombok.ToString; @Entity @@ -21,7 +20,6 @@ import lombok.ToString; @EntityListeners(AuditableEntityListener.class) @Data @EqualsAndHashCode(callSuper = false) -@ToString(callSuper = true) @NoArgsConstructor public class Game extends AuditableEntity{ @Id diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java new file mode 100644 index 0000000..5037881 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroup.java @@ -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; + + +@Entity +@Table(name = "raid_group", schema = "raid_builder") +@EntityListeners(AuditableEntityListener.class) +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class RaidGroup extends AuditableEntity{ + @Id + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "raid_group_id") + private UUID raidGroupId; + @Column(name = "game_id") + private UUID gameId; + @Column(name = "raid_group_name") + private String raidGroupName; + @Column(name = "raid_group_icon") + private String raidGroupIcon; +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java new file mode 100644 index 0000000..b649525 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/entity/RaidGroupPermission.java @@ -0,0 +1,40 @@ +package com.mattrixwv.raidbuilder.entity; + + +import java.util.UUID; + +import com.mattrixwv.raidbuilder.util.DatabaseTypeUtil.RaidGroupPermissionType; + +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 = "raid_group_permission", schema = "raid_builder") +@EntityListeners(AuditableEntityListener.class) +@Data +@EqualsAndHashCode(callSuper = false) +@NoArgsConstructor +public class RaidGroupPermission extends AuditableEntity{ + @Id + @GeneratedValue(strategy = GenerationType.UUID) + @Column(name = "raid_group_permission_id") + private UUID raidGroupPermissionId; + @Column(name = "account_id") + private UUID accountId; + @Column(name = "raid_group_id") + private UUID raidGroupId; + @Enumerated(EnumType.STRING) + @Column(name = "permission") + private RaidGroupPermissionType permission; +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupCustomRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupCustomRepository.java new file mode 100644 index 0000000..b5c93e8 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupCustomRepository.java @@ -0,0 +1,5 @@ +package com.mattrixwv.raidbuilder.repository.raid_group; + + +public interface RaidGroupCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepository.java new file mode 100644 index 0000000..69e22da --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepository.java @@ -0,0 +1,16 @@ +package com.mattrixwv.raidbuilder.repository.raid_group; + + +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.RaidGroup; + + +public interface RaidGroupRepository extends RaidGroupCustomRepository, JpaRepository{ + public List findAllByRaidGroupNameContainingIgnoreCase(String searchTerm, PageRequest pageRequest); + public long countAllByRaidGroupNameContainingIgnoreCase(String searchTerm); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepositoryImpl.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepositoryImpl.java new file mode 100644 index 0000000..4da4efa --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group/RaidGroupRepositoryImpl.java @@ -0,0 +1,9 @@ +package com.mattrixwv.raidbuilder.repository.raid_group; + + +import org.springframework.stereotype.Repository; + + +@Repository +public class RaidGroupRepositoryImpl implements RaidGroupCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionCustomRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionCustomRepository.java new file mode 100644 index 0000000..0c7e51c --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionCustomRepository.java @@ -0,0 +1,5 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_permission; + + +public interface RaidGroupPermissionCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java new file mode 100644 index 0000000..4906e60 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepository.java @@ -0,0 +1,14 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_permission; + + +import java.util.List; +import java.util.UUID; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.mattrixwv.raidbuilder.entity.RaidGroupPermission; + + +public interface RaidGroupPermissionRepository extends RaidGroupPermissionCustomRepository, JpaRepository{ + public List findAllByAccountId(UUID accountId); +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepositoryImpl.java b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepositoryImpl.java new file mode 100644 index 0000000..034b777 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/repository/raid_group_permission/RaidGroupPermissionRepositoryImpl.java @@ -0,0 +1,9 @@ +package com.mattrixwv.raidbuilder.repository.raid_group_permission; + + +import org.springframework.stereotype.Repository; + + +@Repository +public class RaidGroupPermissionRepositoryImpl implements RaidGroupPermissionCustomRepository{ +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java b/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java index 9c5b329..0c060a6 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java +++ b/src/main/java/com/mattrixwv/raidbuilder/service/GameService.java @@ -92,6 +92,10 @@ public class GameService{ //Read + public Game getGameById(UUID gameId){ + return gameRepository.findById(gameId).orElse(null); + } + public List getGames(int page, int pageSize){ return gameRepository.findAll(PageRequest.of(page, pageSize, Sort.by("gameName").ascending())).getContent(); } diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java new file mode 100644 index 0000000..ad8416d --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupPermissionService.java @@ -0,0 +1,31 @@ +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.RaidGroupPermission; +import com.mattrixwv.raidbuilder.repository.raid_group_permission.RaidGroupPermissionRepository; + +import lombok.RequiredArgsConstructor; + + +@Service +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class RaidGroupPermissionService{ + private final RaidGroupPermissionRepository raidGroupPermissionRepository; + + + public RaidGroupPermission createRaidGroupPermission(RaidGroupPermission raidGroupPermission){ + return raidGroupPermissionRepository.save(raidGroupPermission); + } + + + public List getByAccountId(UUID accountId){ + return raidGroupPermissionRepository.findAllByAccountId(accountId); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java new file mode 100644 index 0000000..389efb9 --- /dev/null +++ b/src/main/java/com/mattrixwv/raidbuilder/service/RaidGroupService.java @@ -0,0 +1,118 @@ +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.RaidGroup; +import com.mattrixwv.raidbuilder.repository.raid_group.RaidGroupRepository; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + + +@Slf4j +@Service +@Transactional(rollbackFor = Exception.class) +@RequiredArgsConstructor +public class RaidGroupService{ + private final RaidGroupRepository raidGroupRepository; + @Value("${uploadFileDirectory}") + private String uploadFileDirectory; + + + //Write + public RaidGroup createRaidGroup(RaidGroup raidGroup, MultipartFile file){ + if(file != null){ + String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename(); + Path filePath = Paths.get(uploadFileDirectory + "/raidGroupIcons").resolve(fileName); + + try{ + file.transferTo(filePath); + raidGroup.setRaidGroupIcon(fileName); + } + catch(Exception error){ + log.error("Error uploading file: " + error.getMessage(), error); + throw new RuntimeException("Error uploading file: " + error.getMessage(), error); + } + } + return raidGroupRepository.save(raidGroup); + } + + public RaidGroup updateRaidGroup(RaidGroup raidGroup, MultipartFile file){ + RaidGroup existingRaidGroup = raidGroupRepository.findById(raidGroup.getRaidGroupId()).orElse(null); + + //Delete the old file if one exists + if((existingRaidGroup != null) && (existingRaidGroup.getRaidGroupIcon() != null) && (raidGroup.getRaidGroupIcon() == null)){ + log.debug("Deleting old file: {}", existingRaidGroup.getRaidGroupIcon()); + File existingFile = new File(uploadFileDirectory + "/raidGroupIcons/" + existingRaidGroup.getRaidGroupIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + + if(file != null){ + //Upload the new file + String fileName = UUID.randomUUID().toString() + "--" + file.getOriginalFilename(); + Path filePath = Paths.get(uploadFileDirectory + "/raidGroupIcons").resolve(fileName); + try{ + file.transferTo(filePath); + raidGroup.setRaidGroupIcon(fileName); + } + catch(Exception error){ + log.error("Error uploading file: " + error.getMessage(), error); + throw new RuntimeException("Error uploading file: " + error.getMessage(), error); + } + } + + return raidGroupRepository.save(raidGroup); + } + + public void deleteById(UUID raidGroupId){ + RaidGroup raidGroup = raidGroupRepository.findById(raidGroupId).orElse(null); + if(raidGroup != null){ + if(raidGroup.getRaidGroupIcon() != null){ + File existingFile = new File(uploadFileDirectory + "/raidGroupIcons/" + raidGroup.getRaidGroupIcon()); + if(existingFile.exists()){ + existingFile.delete(); + } + } + raidGroupRepository.deleteById(raidGroupId); + } + } + + + //Read + public RaidGroup getByRaidGroupId(UUID raidGroupId){ + return raidGroupRepository.findById(raidGroupId).orElse(null); + } + + public List getRaidGroups(int page, int pageSize){ + return raidGroupRepository.findAll(PageRequest.of(page, pageSize, Sort.by("raidGroupName").ascending())).getContent(); + } + + public List getRaidGroups(int page, int pageSize, String searchTerm){ + return raidGroupRepository.findAllByRaidGroupNameContainingIgnoreCase( + searchTerm, + PageRequest.of(page, pageSize, Sort.by("raidGroupName").ascending()) + ); + } + + public long getRaidGroupsCount(){ + return raidGroupRepository.count(); + } + + public long getRaidGroupsCount(String searchTerm){ + return raidGroupRepository.countAllByRaidGroupNameContainingIgnoreCase(searchTerm); + } +} diff --git a/src/main/java/com/mattrixwv/raidbuilder/util/DatabaseTypeUtil.java b/src/main/java/com/mattrixwv/raidbuilder/util/DatabaseTypeUtil.java index 7f8cd8b..a20942c 100644 --- a/src/main/java/com/mattrixwv/raidbuilder/util/DatabaseTypeUtil.java +++ b/src/main/java/com/mattrixwv/raidbuilder/util/DatabaseTypeUtil.java @@ -23,6 +23,12 @@ public class DatabaseTypeUtil{ ADMIN }; + public static enum RaidGroupPermissionType { + ADMIN, + LEADER, + RAIDER + }; + public static enum TutorialStatus { COMPLETED, NOT_COMPLETED diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 31128cc..653ab35 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -22,3 +22,4 @@ jwt.refreshTokenDuration=30d #Files uploadFileDirectory=../raidBuilderIcons +spring.servlet.multipart.max-file-size=10MB