Implemented account management controller

This commit is contained in:
Andrey Terentev 2024-04-25 16:18:31 +07:00 committed by Andrey Terentev
parent d0199bb8f0
commit 426e60c716
7 changed files with 101 additions and 6 deletions

View File

@ -26,6 +26,7 @@ public class ExceptionFactory {
factory.put(RoomNotFoundException.ERROR_ID, RoomNotFoundException::new);
factory.put(NotPersistedNodeException.ERROR_ID, NotPersistedNodeException::new);
factory.put(AccountDoesNotExistsException.ERROR_ID, AccountDoesNotExistsException::new);
factory.put(PermissionNotFoundException.ERROR_ID, PermissionNotFoundException::new);
return factory;
}

View File

@ -0,0 +1,34 @@
package ru.dragonestia.picker.api.exception;
import ru.dragonestia.picker.api.repository.response.ErrorResponse;
import java.util.Map;
public final class PermissionNotFoundException extends ApiException {
public static final String ERROR_ID = "err.permission.not_found";
private final String permissionId;
public PermissionNotFoundException(String permissionId) {
this.permissionId = permissionId;
}
public PermissionNotFoundException(ErrorResponse errorResponse) {
this(errorResponse.details().get("permissionId"));
}
public String getPermissionId() {
return permissionId;
}
@Override
public String getErrorId() {
return ERROR_ID;
}
@Override
public void appendDetailsToErrorResponse(Map<String, String> details) {
details.put("permissionId", permissionId);
}
}

View File

@ -0,0 +1,7 @@
package ru.dragonestia.picker.api.repository.response;
import ru.dragonestia.picker.api.model.account.ResponseAccount;
import java.util.List;
public record AllAccountsResponse(List<ResponseAccount> accounts) {}

View File

@ -6,11 +6,15 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.*;
import ru.dragonestia.picker.api.exception.AccountDoesNotExistsException;
import ru.dragonestia.picker.api.exception.PermissionNotFoundException;
import ru.dragonestia.picker.api.model.account.ResponseAccount;
import ru.dragonestia.picker.api.repository.response.AllAccountsResponse;
import ru.dragonestia.picker.model.Account;
import ru.dragonestia.picker.model.Permission;
import ru.dragonestia.picker.service.AccountService;
import java.util.List;
import java.util.HashSet;
@RestController
@RequestMapping("/accounts")
@ -36,22 +40,57 @@ public class AccountsController {
}
@GetMapping
List<ResponseAccount> allAccounts() {
throw new UnsupportedOperationException("Not implemented");
AllAccountsResponse allAccounts() {
return new AllAccountsResponse(accountService.allAccounts().stream()
.map(Account::toResponseObject)
.toList());
}
@PostMapping
ResponseAccount registerAccount(@RequestParam String username, @RequestParam String password, @RequestParam String permissions) {
throw new UnsupportedOperationException("Not implemented");
var account = accountService.createNewAccount(username, password);
var authorities = new HashSet<Permission>();
for (var permStr : permissions.split(",")) {
try {
var perm = Permission.valueOf(permStr);
authorities.add(perm);
} catch (IllegalArgumentException ex) {
throw new PermissionNotFoundException(permStr);
}
}
account.setAuthorities(authorities);
accountService.updateState(account);
return account.toResponseObject();
}
@PutMapping("/{accountId}")
ResponseEntity<?> updatePermissions(@PathVariable String accountId, @RequestParam String permissions) {
throw new UnsupportedOperationException("Not implemented");
var account = accountService.findAccount(accountId).orElseThrow(() -> new AccountDoesNotExistsException(accountId));
var authorities = new HashSet<Permission>();
for (var permStr : permissions.split(",")) {
try {
var perm = Permission.valueOf(permStr);
authorities.add(perm);
} catch (IllegalArgumentException ex) {
throw new PermissionNotFoundException(permStr);
}
}
account.setAuthorities(authorities);
accountService.updateState(account);
return ResponseEntity.ok().build();
}
@DeleteMapping("/{accountId}")
ResponseEntity<?> removeAccount(@PathVariable String accountId) {
throw new UnsupportedOperationException("Not implemented");
var account = accountService.findAccount(accountId).orElseThrow(() -> new AccountDoesNotExistsException(accountId));
accountService.removeAccount(account);
return ResponseEntity.ok().build();
}
}

View File

@ -66,6 +66,11 @@ public class ExceptionHandlerController {
return create(404, ex);
}
@ExceptionHandler({PermissionNotFoundException.class})
ResponseEntity<?> permissionNotFound(PermissionNotFoundException ex) {
return create(400, ex);
}
private ResponseEntity<ErrorResponse> create(int code, ApiException ex) {
var details = new HashMap<String, String>();
ex.appendDetailsToErrorResponse(details);

View File

@ -7,12 +7,15 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
import ru.dragonestia.picker.model.Account;
import java.util.Collection;
import java.util.Optional;
public interface AccountService extends UserDetailsService {
@PreAuthorize("hasRole('ADMIN')")
@NotNull Account createNewAccount(@NotNull String username, @NotNull String password);
@NotNull Optional<Account> findAccount(@NotNull String accountId);
@PreAuthorize("hasRole('ADMIN')")
@NotNull Collection<Account> allAccounts();

View File

@ -13,6 +13,7 @@ import ru.dragonestia.picker.service.AccountService;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@ -38,6 +39,11 @@ public class AccountServiceImpl implements AccountService {
return account;
}
@Override
public @NotNull Optional<Account> findAccount(@NotNull String accountId) {
return Optional.ofNullable(accounts.getOrDefault(accountId, null));
}
@Override
public @NotNull Collection<Account> allAccounts() {
return accounts.values();