Secured admin account

This commit is contained in:
Andrey Terentev 2024-04-25 16:31:52 +07:00 committed by Andrey Terentev
parent 426e60c716
commit 02d71c7138
5 changed files with 59 additions and 2 deletions

View File

@ -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<String, String> details) {}
}

View File

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

View File

@ -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) {}
}

View File

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

View File

@ -6,6 +6,8 @@ import org.jetbrains.annotations.NotNull;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; 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.Account;
import ru.dragonestia.picker.model.Permission; import ru.dragonestia.picker.model.Permission;
import ru.dragonestia.picker.service.AccountService; import ru.dragonestia.picker.service.AccountService;
@ -22,12 +24,13 @@ import java.util.stream.Collectors;
public class AccountServiceImpl implements AccountService { public class AccountServiceImpl implements AccountService {
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
private final RoomPickerServerConfig.AdminCredentials adminCredentials;
private final Map<String, Account> accounts = new ConcurrentHashMap<>(); private final Map<String, Account> accounts = new ConcurrentHashMap<>();
@PostConstruct @PostConstruct
void init() { void init() {
var account = createNewAccount("admin", "qwerty123"); var account = createNewAccount(adminCredentials.username(), adminCredentials.password());
account.setAuthorities(Arrays.stream(Permission.values()).collect(Collectors.toSet())); account.setAuthorities(Arrays.stream(Permission.values()).collect(Collectors.toSet()));
createNewAccount("test", "qwerty123"); createNewAccount("test", "qwerty123");
@ -46,17 +49,21 @@ public class AccountServiceImpl implements AccountService {
@Override @Override
public @NotNull Collection<Account> allAccounts() { public @NotNull Collection<Account> allAccounts() {
return accounts.values(); return accounts.values().stream()
.filter(account -> !adminCredentials.username().equals(account.getUsername()))
.toList();
} }
@Override @Override
public void removeAccount(@NotNull Account account) { public void removeAccount(@NotNull Account account) {
checkAdmin(account.getUsername());
accounts.remove(account.getUsername()); accounts.remove(account.getUsername());
account.setEnabled(false); account.setEnabled(false);
} }
@Override @Override
public void updateState(@NotNull Account account) { public void updateState(@NotNull Account account) {
checkAdmin(account.getUsername());
// TODO: save data to local storage // TODO: save data to local storage
} }
@ -69,4 +76,10 @@ public class AccountServiceImpl implements AccountService {
throw new UsernameNotFoundException("User '" + username + "' does not exists"); throw new UsernameNotFoundException("User '" + username + "' does not exists");
} }
private void checkAdmin(String accountId) {
if (adminCredentials.username().equals(accountId)) {
throw new ConstantAdminParamsException();
}
}
} }