use of com.auth0.android.jwt.JWT in project bank-of-anthos by GoogleCloudPlatform.
the class LedgerMonolithController method addTransaction.
// BEGIN LEDGER WRITER
/**
* Submit a new transaction to the ledger.
*
* @param bearerToken HTTP request 'Authorization' header
* @param transaction transaction to submit
*
* @return HTTP Status 200 if transaction was successfully submitted
*/
@PostMapping(value = "/transactions", consumes = "application/json")
@ResponseStatus(HttpStatus.OK)
public ResponseEntity<?> addTransaction(@RequestHeader("Authorization") String bearerToken, @RequestBody Transaction transaction) {
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
bearerToken = bearerToken.split("Bearer ")[1];
}
try {
if (bearerToken == null) {
LOGGER.error("Transaction submission failed: " + "Authorization header null");
throw new IllegalArgumentException(EXCEPTION_MESSAGE_WHEN_AUTHORIZATION_HEADER_NULL);
}
final DecodedJWT jwt = this.verifier.verify(bearerToken);
// Check against cache for duplicate transactions
if (this.ledgerWriterCache.asMap().containsKey(transaction.getRequestUuid())) {
throw new IllegalStateException(EXCEPTION_MESSAGE_DUPLICATE_TRANSACTION);
}
// validate transaction
transactionValidator.validateTransaction(localRoutingNum, jwt.getClaim(JWT_ACCOUNT_KEY).asString(), transaction);
// Ensure sender balance can cover transaction.
if (transaction.getFromRoutingNum().equals(localRoutingNum)) {
Long balance = getAvailableBalance(transaction.getFromAccountNum());
if (balance < transaction.getAmount()) {
LOGGER.error("Transaction submission failed: " + "Insufficient balance");
throw new IllegalStateException(EXCEPTION_MESSAGE_INSUFFICIENT_BALANCE);
}
}
// No exceptions thrown. Add to ledger
transactionRepository.save(transaction);
this.ledgerWriterCache.put(transaction.getRequestUuid(), transaction.getTransactionId());
LOGGER.info("Submitted transaction successfully");
return new ResponseEntity<String>(READINESS_CODE, HttpStatus.CREATED);
} catch (JWTVerificationException e) {
LOGGER.error("Failed to submit transaction: " + "not authorized");
return new ResponseEntity<String>(UNAUTHORIZED_CODE, HttpStatus.UNAUTHORIZED);
} catch (IllegalArgumentException | IllegalStateException e) {
LOGGER.error("Failed to retrieve account balance: " + "bad request");
return new ResponseEntity<String>(e.getMessage(), HttpStatus.BAD_REQUEST);
} catch (ResourceAccessException | CannotCreateTransactionException | HttpServerErrorException e) {
LOGGER.error("Failed to retrieve account balance");
return new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
use of com.auth0.android.jwt.JWT in project bank-of-anthos by GoogleCloudPlatform.
the class LedgerMonolithController method getTransactions.
// BEGIN TRANSACTION HISTORY
/**
* Return a list of transactions for the specified account.
*
* The currently authenticated user must be allowed to access the account.
* @param bearerToken HTTP request 'Authorization' header
* @param accountId the account to get transactions for.
* @return a list of transactions for this account.
*/
@GetMapping("/transactions/{accountId}")
public ResponseEntity<?> getTransactions(@RequestHeader("Authorization") String bearerToken, @PathVariable String accountId) {
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
bearerToken = bearerToken.split("Bearer ")[1];
}
try {
DecodedJWT jwt = verifier.verify(bearerToken);
// Check that the authenticated user can access this account.
if (!accountId.equals(jwt.getClaim("acct").asString())) {
LOGGER.error("Failed to retrieve account transactions: " + "not authorized");
return new ResponseEntity<String>("not authorized", HttpStatus.UNAUTHORIZED);
}
// Load from cache
AccountInfo info = ledgerReaderCache.get(accountId);
Deque<Transaction> historyList = info.getTransactions();
// Set artificial extra latency.
LOGGER.debug("Setting artificial latency");
if (extraLatencyMillis != null) {
try {
Thread.sleep(extraLatencyMillis);
} catch (InterruptedException e) {
// Fake latency interrupted. Continue.
}
}
return new ResponseEntity<Collection<Transaction>>(historyList, HttpStatus.OK);
} catch (JWTVerificationException e) {
LOGGER.error("Failed to retrieve account transactions: " + "not authorized");
return new ResponseEntity<String>("not authorized", HttpStatus.UNAUTHORIZED);
} catch (ExecutionException | UncheckedExecutionException e) {
LOGGER.error("Cache error");
return new ResponseEntity<String>("cache error", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
use of com.auth0.android.jwt.JWT in project bank-of-anthos by GoogleCloudPlatform.
the class JWTVerifierGenerator method generateJWTVerifier.
@Bean(name = "verifier")
public JWTVerifier generateJWTVerifier(@Value("${PUB_KEY_PATH}") final String publicKeyPath) {
// load public key from file
try {
LOGGER.debug("Generating JWT token verifier");
String keyStr = new String(Files.readAllBytes(Paths.get(publicKeyPath)));
keyStr = keyStr.replaceFirst("-----BEGIN PUBLIC KEY-----", "").replaceFirst("-----END PUBLIC KEY-----", "").replaceAll("\\s", "");
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(keyBytes);
RSAPublicKey publicKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
// Initialize JWT verifier.
Algorithm algorithm = Algorithm.RSA256(publicKey, null);
return JWT.require(algorithm).build();
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
LOGGER.error(String.format("Failed initializing JWT verifier: %s", e.toString()));
throw new GenerateKeyException("Cannot generate key: ", e);
}
}
use of com.auth0.android.jwt.JWT in project bank-of-anthos by GoogleCloudPlatform.
the class JWTVerifierGenerator method generateJWTVerifier.
@Bean(name = "verifier")
public JWTVerifier generateJWTVerifier(@Value("${PUB_KEY_PATH}") final String publicKeyPath) {
// load public key from file
try {
LOGGER.debug("Generating JWT token verifier");
String keyStr = new String(Files.readAllBytes(Paths.get(publicKeyPath)));
keyStr = keyStr.replaceFirst("-----BEGIN PUBLIC KEY-----", "").replaceFirst("-----END PUBLIC KEY-----", "").replaceAll("\\s", "");
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
KeyFactory kf = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(keyBytes);
RSAPublicKey publicKey = (RSAPublicKey) kf.generatePublic(keySpecX509);
// Initialize JWT verifier.
Algorithm algorithm = Algorithm.RSA256(publicKey, null);
return JWT.require(algorithm).build();
} catch (IOException | NoSuchAlgorithmException | InvalidKeySpecException e) {
LOGGER.error(String.format("Failed initializing JWT verifier: %s", e.toString()));
throw new GenerateKeyException("Cannot generate key: ", e);
}
}
use of com.auth0.android.jwt.JWT in project bank-of-anthos by GoogleCloudPlatform.
the class BalanceReaderController method getBalance.
/**
* Return the balance for the specified account.
*
* The currently authenticated user must be allowed to access the account.
*
* @param bearerToken HTTP request 'Authorization' header
* @param accountId the account to get the balance for
* @return the balance of the account
*/
@GetMapping("/balances/{accountId}")
public ResponseEntity<?> getBalance(@RequestHeader("Authorization") String bearerToken, @PathVariable String accountId) {
if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
bearerToken = bearerToken.split("Bearer ")[1];
}
try {
DecodedJWT jwt = verifier.verify(bearerToken);
// Check that the authenticated user can access this account.
if (!accountId.equals(jwt.getClaim("acct").asString())) {
LOGGER.error("Failed to retrieve account balance: " + "not authorized");
return new ResponseEntity<String>("not authorized", HttpStatus.UNAUTHORIZED);
}
// Load from cache
Long balance = cache.get(accountId);
return new ResponseEntity<Long>(balance, HttpStatus.OK);
} catch (JWTVerificationException e) {
LOGGER.error("Failed to retrieve account balance: not authorized");
return new ResponseEntity<String>("not authorized", HttpStatus.UNAUTHORIZED);
} catch (ExecutionException | UncheckedExecutionException e) {
LOGGER.error("Cache error");
return new ResponseEntity<String>("cache error", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Aggregations