Remove artificial restriction that account keys need to start with 'accounts.'

Rework URL decoding into own util method because the previously used method
is only available since Java 10 (current runtime is 1.9 however).
Further adjust unit tests and test data to reflect the change.
Also add a migration script for already installed instances.
This commit is contained in:
2019-05-12 00:43:28 +02:00
parent 4e29ecff6a
commit c96a36f325
12 changed files with 136 additions and 63 deletions

View File

@@ -7,7 +7,6 @@ public enum ResponseReason {
OK(HttpStatus.OK),
UNKNOWN_ERROR(HttpStatus.INTERNAL_SERVER_ERROR),
INVALID_ACCOUNT_TYPE(HttpStatus.INTERNAL_SERVER_ERROR),
INVALID_ACCOUNT_KEY(HttpStatus.INTERNAL_SERVER_ERROR),
FROM_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR),
TO_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR),
FROM_AND_TO_ACCOUNT_NOT_FOUND(HttpStatus.INTERNAL_SERVER_ERROR),

View File

@@ -10,9 +10,6 @@ import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
@RestController
@RequestMapping("accounts")
public class AccountController {
@@ -24,7 +21,7 @@ public class AccountController {
@RequestMapping("getByKey")
public Account getAccountByKey(String key) {
final String decoded = URLDecoder.decode(key, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(key);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/accounts/getAccountByKey got parameter: %s", decoded));
@@ -40,7 +37,7 @@ public class AccountController {
@RequestMapping("createAccount")
public ResponseEntity createAccount(String key, String type) {
final String decoded = URLDecoder.decode(key, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(key);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/accounts/createAccount got parameters: %s, %s", decoded, type));
@@ -57,7 +54,7 @@ public class AccountController {
@RequestMapping("closeAccount")
public ResponseEntity closeAccount(String key) {
final String decoded = URLDecoder.decode(key, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(key);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/accounts/closeAccount got parameters: %s", decoded));
@@ -74,7 +71,7 @@ public class AccountController {
@RequestMapping("openAccount")
public ResponseEntity openAccount(String key) {
final String decoded = URLDecoder.decode(key, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(key);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/accounts/openAccount got parameters: %s", decoded));

View File

@@ -0,0 +1,22 @@
package de.financer.controller;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
public class ControllerUtil {
/**
* This method decodes the given URL encoded string, e.g. replaces <code>%20</code> with a space.
*
* @param toDecode the string to decode
* @return the decoded string in UTF-8 or, if UTF-8 is not available for whatever reason, the encoded string
*/
public static final String urlDecode(String toDecode) {
try {
return URLDecoder.decode(toDecode, StandardCharsets.UTF_8.name());
}
catch (UnsupportedEncodingException e) {
return toDecode;
}
}
}

View File

@@ -35,7 +35,7 @@ public class RecurringTransactionController {
@RequestMapping("getAllForAccount")
public Iterable<RecurringTransaction> getAllForAccount(String accountKey) {
final String decoded = URLDecoder.decode(accountKey, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(accountKey);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/recurringTransactions/getAllForAccount got parameter: %s", decoded));
@@ -55,8 +55,8 @@ public class RecurringTransactionController {
String intervalType, String firstOccurrence,
String lastOccurrence
) {
final String decodedFrom = URLDecoder.decode(fromAccountKey, StandardCharsets.UTF_8);
final String decodedTo = URLDecoder.decode(toAccountKey, StandardCharsets.UTF_8);
final String decodedFrom = ControllerUtil.urlDecode(fromAccountKey);
final String decodedTo = ControllerUtil.urlDecode(toAccountKey);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String

View File

@@ -28,7 +28,7 @@ public class TransactionController {
@RequestMapping("getAllForAccount")
public Iterable<Transaction> getAllForAccount(String accountKey) {
final String decoded = URLDecoder.decode(accountKey, StandardCharsets.UTF_8);
final String decoded = ControllerUtil.urlDecode(accountKey);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("/transactions/getAllForAccount got parameter: %s", decoded));
@@ -41,8 +41,8 @@ public class TransactionController {
public ResponseEntity createTransaction(String fromAccountKey, String toAccountKey, Long amount, String date,
String description
) {
final String decodedFrom = URLDecoder.decode(fromAccountKey, StandardCharsets.UTF_8);
final String decodedTo = URLDecoder.decode(toAccountKey, StandardCharsets.UTF_8);
final String decodedFrom = ControllerUtil.urlDecode(fromAccountKey);
final String decodedTo = ControllerUtil.urlDecode(toAccountKey);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(String

View File

@@ -55,10 +55,9 @@ public class AccountService {
* This method creates new account with the given key and type. The account has status {@link AccountStatus#OPEN OPEN}
* and a current balance of <code>0</code>.
*
* @param key the key of the new account. Must begin with <b>account.</b>
* @param key the key of the new account
* @param type the type of the new account. Must be one of {@link AccountType}.
* @return {@link ResponseReason#INVALID_ACCOUNT_TYPE} if the given type is not a valid {@link AccountType},
* {@link ResponseReason#INVALID_ACCOUNT_KEY} if the given key does not conform to the format specification,
* {@link ResponseReason#UNKNOWN_ERROR} if an unexpected error occurs and
* {@link ResponseReason#OK} if the operation completed successfully. Never returns <code>null</code>.
*/
@@ -68,10 +67,6 @@ public class AccountService {
return ResponseReason.INVALID_ACCOUNT_TYPE;
}
if (!StringUtils.startsWith(key, "accounts.")) {
return ResponseReason.INVALID_ACCOUNT_KEY;
}
final Account account = new Account();
account.setKey(key);
@@ -105,10 +100,6 @@ public class AccountService {
// Visible for unit tests
/* package */ ResponseReason setAccountStatus(String key, AccountStatus accountStatus) {
if (!StringUtils.startsWith(key, "accounts.")) {
return ResponseReason.INVALID_ACCOUNT_KEY;
}
final Account account = this.accountRepository.findByKey(key);
if (account == null) {

View File

@@ -0,0 +1,88 @@
-- Rename all accounts to proper names instead of the artificial 'accounts.' names
UPDATE account
SET "key" = 'Check account'
WHERE "key" = 'accounts.checkaccount';
UPDATE account
SET "key" = 'Income'
WHERE "key" = 'accounts.income'
UPDATE account
SET "key" = 'Cash'
WHERE "key" = 'accounts.cash';
UPDATE account
SET "key" = 'Start'
WHERE "key" = 'accounts.start';
UPDATE account
SET "key" = 'Rent'
WHERE "key" = 'accounts.rent';
UPDATE account
SET "key" = 'FVS'
WHERE "key" = 'accounts.fvs';
UPDATE account
SET "key" = 'Car'
WHERE "key" = 'accounts.car';
UPDATE account
SET "key" = 'Gas'
WHERE "key" = 'accounts.gas';
UPDATE account
SET "key" = 'Alimony'
WHERE "key" = 'accounts.alimony';
UPDATE account
SET "key" = 'Electricity/Water'
WHERE "key" = 'accounts.electricitywater';
UPDATE account
SET "key" = 'Mobile'
WHERE "key" = 'accounts.mobile';
UPDATE account
SET "key" = 'Internet'
WHERE "key" = 'accounts.internet';
UPDATE account
SET "key" = 'Legal insurance'
WHERE "key" = 'accounts.legalinsurance';
UPDATE account
SET "key" = 'Netflix'
WHERE "key" = 'accounts.netflix';
UPDATE account
SET "key" = 'Hetzner'
WHERE "key" = 'accounts.hetzner';
UPDATE account
SET "key" = 'Fees'
WHERE "key" = 'accounts.fees';
UPDATE account
SET "key" = 'Food'
WHERE "key" = 'accounts.food';
UPDATE account
SET "key" = 'Food (external)'
WHERE "key" = 'accounts.foodexternal';
UPDATE account
SET "key" = 'Child'
WHERE "key" = 'accounts.child';
UPDATE account
SET "key" = 'Credit card'
WHERE "key" = 'accounts.creditcard';
UPDATE account
SET "key" = 'Student loan'
WHERE "key" = 'accounts.studentloan';
UPDATE account
SET "key" = 'Bed'
WHERE "key" = 'accounts.bed';