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.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.mattrixwv.raidbuilder.annotation.AccountAuthorization; import com.mattrixwv.raidbuilder.annotation.RaidGroupAuthorization; import com.mattrixwv.raidbuilder.entity.Account; import com.mattrixwv.raidbuilder.entity.RaidGroupPermission; 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 @RestController @RequestMapping("/account") @RequiredArgsConstructor public class AccountController{ private final ObjectMapper mapper; private final AccountService accountService; private final RaidGroupPermissionService rgpService; @GetMapping @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public List getAccounts(@RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(value = "searchTerm", required = false) String searchTerm){ log.info("Getting accounts page {} of size {} with search term {}", page, pageSize, searchTerm); List accounts; if((searchTerm == null) || (searchTerm.isEmpty())){ accounts = accountService.getAccounts(page, pageSize); } else{ accounts = accountService.getAccounts(page, pageSize, searchTerm); } return accounts; } @GetMapping("/raidGroup/{raidGroupId}") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) public List getAccountsByRaidGroup(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam("page") int page, @RequestParam("pageSize") int pageSize, @RequestParam(value = "searchTerm", required = false) String searchTerm){ log.info("Getting accounts by raid group {}", raidGroupId); List accounts; if(searchTerm == null){ accounts = accountService.getAccountsByRaidGroupId(raidGroupId, page, pageSize); } else{ accounts = accountService.getAccountsByRaidGroupId(raidGroupId, page, pageSize, searchTerm); } return accounts; } @GetMapping("/{accountId}/raidGroup/{raidGroupId}/permission") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) public ObjectNode getAccountPermission(@PathVariable("accountId") UUID accountId, @PathVariable("raidGroupId") UUID raidGroupId){ log.info("Getting account permission for account {} and raid group {}", accountId, raidGroupId); RaidGroupPermission permission = rgpService.getByAccountIdAndRaidGroupId(accountId, raidGroupId); ObjectNode returnNode = mapper.createObjectNode(); returnNode.put("status", "success"); returnNode.put("permission", permission.getPermission().name()); return returnNode; } @PutMapping("/{accountId}/raidGroup/{raidGroupId}/permission") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) public ObjectNode updateAccountPermission(@PathVariable("accountId") UUID accountId, @PathVariable("raidGroupId") UUID raidGroupId, @RequestBody ObjectNode permissionNode){ log.info("Updating account permission for account {} and raid group {}", accountId, raidGroupId); RaidGroupPermission existingPermission = rgpService.getByAccountIdAndRaidGroupId(accountId, raidGroupId); ObjectNode returnNode = mapper.createObjectNode(); if(existingPermission == null){ returnNode.put("status", "error"); ArrayNode arrayNode = mapper.createArrayNode(); arrayNode.add("Account does not have permission to raid group"); returnNode.set("errors", arrayNode); } else{ RaidGroupPermissionType permission = RaidGroupPermissionType.valueOf(permissionNode.get("permission").asText()); existingPermission.setPermission(permission); rgpService.createRaidGroupPermission(existingPermission); returnNode.put("status", "success"); } return returnNode; } @DeleteMapping("/{accountId}/raidGroup/{raidGroupId}/permission") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) public ObjectNode deleteAccountPermission(@PathVariable("accountId") UUID accountId, @PathVariable("raidGroupId") UUID raidGroupId){ log.info("Deleting account permission for account {} and raid group {}", accountId, raidGroupId); rgpService.deleteByAccountIdAndRaidGroupId(accountId, raidGroupId); ObjectNode returnNode = mapper.createObjectNode(); returnNode.put("status", "success"); return returnNode; } @PostMapping @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode createAccount(@RequestBody Account account){ log.info("Creating account {}", account.getUsername()); ObjectNode returnNode = mapper.createObjectNode(); Account existingAccount = accountService.getByUsername(account.getUsername()); if(existingAccount != null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Username already exists"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ account = accountService.createAccount(account); returnNode.put("status", "success"); returnNode.put("accountId", account.getAccountId().toString()); } return returnNode; } @GetMapping("/count") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode getAccountsCount(@RequestParam(value = "searchTerm", required = false) String searchTerm){ log.info("Getting accounts count"); Long accountsCount; if((searchTerm == null) || (searchTerm.isBlank())){ accountsCount = accountService.getAccountsCount(); } else{ accountsCount = accountService.getAccountsCount(searchTerm); } ObjectNode countNode = mapper.createObjectNode(); countNode.put("count", accountsCount); countNode.put("status", "success"); return countNode; } @GetMapping("/raidGroup/{raidGroupId}/count") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN, AccountPermissionType.USER}) @RaidGroupAuthorization(permissions = {RaidGroupPermissionType.ADMIN}) public ObjectNode getAccountsCountByRaidGroup(@PathVariable("raidGroupId") UUID raidGroupId, @RequestParam(name = "searchTerm", required = false) String searchTerm){ log.info("Getting accounts count by raid group {}", raidGroupId); Long accountsCount; if(searchTerm == null){ accountsCount = accountService.getAccountsByRaidGroupIdCount(raidGroupId); } else{ accountsCount = accountService.getAccountsByRaidGroupIdCount(raidGroupId, searchTerm); } ObjectNode countNode = mapper.createObjectNode(); countNode.put("count", accountsCount); countNode.put("status", "success"); return countNode; } @PutMapping("/{accountId}/forcePasswordReset") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode forcePasswordReset(@PathVariable("accountId") UUID accountId){ log.info("Forcing password reset for account {}", accountId); Account account = accountService.getByAccountId(accountId); ObjectNode returnNode = mapper.createObjectNode(); if(account == null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Account not found"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ account.setRefreshToken(null); account.setRefreshTokenExpiration(null); account.setForceReset(true); accountService.updateAccount(account); returnNode.put("status", "success"); } return returnNode; } @PutMapping("/{accountId}/resetPassword") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode resetPassword(@PathVariable("accountId") UUID accountId, @RequestBody ObjectNode passwordNode){ log.info("Resetting password for account {}", accountId); Account account = accountService.getByAccountId(accountId); ObjectNode returnNode = mapper.createObjectNode(); if(account == null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Account not found"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ account.setRefreshToken(null); account.setRefreshTokenExpiration(null); account.setForceReset(false); accountService.updateAccount(account); accountService.updatePassword(accountId, passwordNode.get("password").asText()); returnNode.put("status", "success"); } return returnNode; } @PutMapping("/{accountId}/revokeRefreshToken") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode revokeRefreshToken(@PathVariable("accountId") UUID accountId){ log.info("Revoking refresh token for account {}", accountId); Account account = accountService.getByAccountId(accountId); ObjectNode returnNode = mapper.createObjectNode(); if(account == null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Account not found"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ account.setRefreshToken(null); account.setRefreshTokenExpiration(null); accountService.updateAccount(account); returnNode.put("status", "success"); } return returnNode; } @PutMapping("/{accountId}") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode updateAccount(@PathVariable("accountId") UUID accountId, @RequestBody Account account){ log.info("Updating account {}", accountId); //TODO: Existing account verification Account oldAccount = accountService.getByAccountId(accountId); ObjectNode returnNode = mapper.createObjectNode(); if(oldAccount == null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Account not found"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ oldAccount.setUsername(account.getUsername()); oldAccount.setEmail(account.getEmail()); oldAccount.setAccountStatus(account.getAccountStatus()); accountService.updateAccount(oldAccount); returnNode.put("status", "success"); } return returnNode; } @DeleteMapping("/{accountId}") @AccountAuthorization(permissions = {AccountPermissionType.ADMIN}) public ObjectNode deleteAccount(@PathVariable("accountId") UUID accountId){ log.info("Deleting account {}", accountId); Account account = accountService.getByAccountId(accountId); ObjectNode returnNode = mapper.createObjectNode(); if(account == null){ ArrayNode errorsNode = mapper.createArrayNode(); errorsNode.add("Account not found"); returnNode.set("errors", errorsNode); returnNode.put("status", "error"); } else{ accountService.deleteAccount(accountId); returnNode.put("status", "success"); } return returnNode; } }