From 02d71c7138524edb62157ba02b2b3c008ee11284 Mon Sep 17 00:00:00 2001 From: ScarletRedMan Date: Thu, 25 Apr 2024 16:31:52 +0700 Subject: [PATCH] Secured admin account --- .../ConstantAdminParamsException.java | 16 ++++++++++++++ .../api/exception/ExceptionFactory.java | 1 + .../picker/config/RoomPickerServerConfig.java | 22 +++++++++++++++++++ .../ExceptionHandlerController.java | 5 +++++ .../service/impl/AccountServiceImpl.java | 17 ++++++++++++-- 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 client-api/src/main/java/ru/dragonestia/picker/api/exception/ConstantAdminParamsException.java create mode 100644 server/src/main/java/ru/dragonestia/picker/config/RoomPickerServerConfig.java diff --git a/client-api/src/main/java/ru/dragonestia/picker/api/exception/ConstantAdminParamsException.java b/client-api/src/main/java/ru/dragonestia/picker/api/exception/ConstantAdminParamsException.java new file mode 100644 index 0000000..a32b782 --- /dev/null +++ b/client-api/src/main/java/ru/dragonestia/picker/api/exception/ConstantAdminParamsException.java @@ -0,0 +1,16 @@ +package ru.dragonestia.picker.api.exception; + +import java.util.Map; + +public class ConstantAdminParamsException extends ApiException { + + public static final String ERROR_ID = "err.account.admin.modification"; + + @Override + public String getErrorId() { + return ERROR_ID; + } + + @Override + public void appendDetailsToErrorResponse(Map details) {} +} diff --git a/client-api/src/main/java/ru/dragonestia/picker/api/exception/ExceptionFactory.java b/client-api/src/main/java/ru/dragonestia/picker/api/exception/ExceptionFactory.java index 1d9712a..ec0c0d9 100644 --- a/client-api/src/main/java/ru/dragonestia/picker/api/exception/ExceptionFactory.java +++ b/client-api/src/main/java/ru/dragonestia/picker/api/exception/ExceptionFactory.java @@ -27,6 +27,7 @@ public class ExceptionFactory { factory.put(NotPersistedNodeException.ERROR_ID, NotPersistedNodeException::new); factory.put(AccountDoesNotExistsException.ERROR_ID, AccountDoesNotExistsException::new); factory.put(PermissionNotFoundException.ERROR_ID, PermissionNotFoundException::new); + factory.put(ConstantAdminParamsException.ERROR_ID, err -> new ConstantAdminParamsException()); return factory; } diff --git a/server/src/main/java/ru/dragonestia/picker/config/RoomPickerServerConfig.java b/server/src/main/java/ru/dragonestia/picker/config/RoomPickerServerConfig.java new file mode 100644 index 0000000..d12c9cb --- /dev/null +++ b/server/src/main/java/ru/dragonestia/picker/config/RoomPickerServerConfig.java @@ -0,0 +1,22 @@ +package ru.dragonestia.picker.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class RoomPickerServerConfig { + + @Value("${ROOMPICKER_ADMIN_USERNAME:admin}") + private String adminUsername; + + @Value("${ROOMPICKER_ADMIN_PASSWORD:qwerty123}") + private String adminPassword; + + @Bean + AdminCredentials adminCredentials() { + return new AdminCredentials(adminUsername, adminPassword); + } + + public record AdminCredentials(String username, String password) {} +} diff --git a/server/src/main/java/ru/dragonestia/picker/controller/ExceptionHandlerController.java b/server/src/main/java/ru/dragonestia/picker/controller/ExceptionHandlerController.java index 51f6f74..a59b3a7 100644 --- a/server/src/main/java/ru/dragonestia/picker/controller/ExceptionHandlerController.java +++ b/server/src/main/java/ru/dragonestia/picker/controller/ExceptionHandlerController.java @@ -71,6 +71,11 @@ public class ExceptionHandlerController { return create(400, ex); } + @ExceptionHandler({ConstantAdminParamsException.class}) + ResponseEntity constantAdminParams(ConstantAdminParamsException ex) { + return create(401, ex); + } + private ResponseEntity create(int code, ApiException ex) { var details = new HashMap(); ex.appendDetailsToErrorResponse(details); diff --git a/server/src/main/java/ru/dragonestia/picker/service/impl/AccountServiceImpl.java b/server/src/main/java/ru/dragonestia/picker/service/impl/AccountServiceImpl.java index 8f1bf1d..43d4106 100644 --- a/server/src/main/java/ru/dragonestia/picker/service/impl/AccountServiceImpl.java +++ b/server/src/main/java/ru/dragonestia/picker/service/impl/AccountServiceImpl.java @@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import ru.dragonestia.picker.api.exception.ConstantAdminParamsException; +import ru.dragonestia.picker.config.RoomPickerServerConfig; import ru.dragonestia.picker.model.Account; import ru.dragonestia.picker.model.Permission; import ru.dragonestia.picker.service.AccountService; @@ -22,12 +24,13 @@ import java.util.stream.Collectors; public class AccountServiceImpl implements AccountService { private final PasswordEncoder passwordEncoder; + private final RoomPickerServerConfig.AdminCredentials adminCredentials; private final Map accounts = new ConcurrentHashMap<>(); @PostConstruct void init() { - var account = createNewAccount("admin", "qwerty123"); + var account = createNewAccount(adminCredentials.username(), adminCredentials.password()); account.setAuthorities(Arrays.stream(Permission.values()).collect(Collectors.toSet())); createNewAccount("test", "qwerty123"); @@ -46,17 +49,21 @@ public class AccountServiceImpl implements AccountService { @Override public @NotNull Collection allAccounts() { - return accounts.values(); + return accounts.values().stream() + .filter(account -> !adminCredentials.username().equals(account.getUsername())) + .toList(); } @Override public void removeAccount(@NotNull Account account) { + checkAdmin(account.getUsername()); accounts.remove(account.getUsername()); account.setEnabled(false); } @Override public void updateState(@NotNull Account account) { + checkAdmin(account.getUsername()); // TODO: save data to local storage } @@ -69,4 +76,10 @@ public class AccountServiceImpl implements AccountService { throw new UsernameNotFoundException("User '" + username + "' does not exists"); } + + private void checkAdmin(String accountId) { + if (adminCredentials.username().equals(accountId)) { + throw new ConstantAdminParamsException(); + } + } }