blob: 44a0938ce5bd1966cbc8ca230c87071f5bd2cc07 [file] [log] [blame]
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../jacoco-resources/report.css" type="text/css"/><link rel="shortcut icon" href="../jacoco-resources/report.gif" type="image/gif"/><title>SecureBankService.java</title><link rel="stylesheet" href="../jacoco-resources/prettify.css" type="text/css"/><script type="text/javascript" src="../jacoco-resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="info"><a href="../jacoco-sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Apache Shiro :: Samples :: AspectJ</a> &gt; <a href="index.source.html" class="el_package">org.apache.shiro.samples.aspectj.bank</a> &gt; <span class="el_source">SecureBankService.java</span></div><h1>SecureBankService.java</h1><pre class="source lang-java linenums">/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* &quot;License&quot;); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* &quot;AS IS&quot; BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.shiro.samples.aspectj.bank;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.samples.aspectj.bank.AccountTransaction.TransactionType;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SecureBankService implements BankService {
<span class="fc" id="L35"> private static final Logger log = LoggerFactory.getLogger(SecureBankService.class);</span>
private volatile boolean _isRunning;
private final List&lt;Account&gt; _accounts;
private Map&lt;Long, Account&gt; _accountsById;
/**
* Creates a new {@link SecureBankService} instance.
*/
<span class="fc" id="L43"> public SecureBankService() {</span>
<span class="fc" id="L44"> _accounts = new ArrayList&lt;Account&gt;();</span>
<span class="fc" id="L45"> _accountsById = new HashMap&lt;Long, Account&gt;();</span>
<span class="fc" id="L46"> }</span>
/**
* Starts this service
*/
public void start() throws Exception {
<span class="fc" id="L52"> _isRunning = true;</span>
<span class="fc" id="L53"> log.info(&quot;Bank service started&quot;);</span>
<span class="fc" id="L54"> }</span>
/**
* Stop this service
*/
public void dispose() {
<span class="fc" id="L60"> log.info(&quot;Stopping bank service...&quot;);</span>
<span class="fc" id="L61"> _isRunning = false;</span>
<span class="fc" id="L63"> synchronized (_accounts) {</span>
<span class="fc" id="L64"> _accountsById.clear();</span>
<span class="fc" id="L65"> _accounts.clear();</span>
}
<span class="fc" id="L68"> log.info(&quot;Bank service stopped&quot;);</span>
<span class="fc" id="L69"> }</span>
/**
* Internal utility method that validate the internal state of this service.
*/
protected void assertServiceState() {
<span class="pc bpc" id="L75" title="1 of 2 branches missed."> if (!_isRunning) {</span>
<span class="nc" id="L76"> throw new IllegalStateException(&quot;This bank service is not running&quot;);</span>
}
<span class="fc" id="L78"> }</span>
public int getAccountCount() {
<span class="nc" id="L81"> return _accounts.size();</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#createNewAccount(java.lang.String)
*/
@RequiresPermissions(&quot;bankAccount:create&quot;)
public long createNewAccount(String anOwnerName) {
<span class="fc" id="L90"> assertServiceState();</span>
<span class="fc" id="L91"> log.info(&quot;Creating new account for &quot; + anOwnerName);</span>
<span class="fc" id="L93"> synchronized (_accounts) {</span>
<span class="fc" id="L94"> Account account = new Account(anOwnerName);</span>
<span class="fc" id="L95"> account.setCreatedBy(getCurrentUsername());</span>
<span class="fc" id="L96"> _accounts.add(account);</span>
<span class="fc" id="L97"> _accountsById.put(account.getId(), account);</span>
<span class="fc" id="L99"> log.debug(&quot;Created new account: &quot; + account);</span>
<span class="fc" id="L100"> return account.getId();</span>
}
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#searchAccountIdsByOwner(java.lang.String)
*/
public long[] searchAccountIdsByOwner(String anOwnerName) {
<span class="nc" id="L109"> assertServiceState();</span>
<span class="nc" id="L110"> log.info(&quot;Searching existing accounts for &quot; + anOwnerName);</span>
<span class="nc" id="L112"> ArrayList&lt;Account&gt; matchAccounts = new ArrayList&lt;Account&gt;();</span>
<span class="nc" id="L113"> synchronized (_accounts) {</span>
<span class="nc bnc" id="L114" title="All 2 branches missed."> for (Account a : _accounts) {</span>
<span class="nc bnc" id="L115" title="All 2 branches missed."> if (a.getOwnerName().toLowerCase().contains(anOwnerName.toLowerCase())) {</span>
<span class="nc" id="L116"> matchAccounts.add(a);</span>
}
}
}
<span class="nc" id="L121"> long[] accountIds = new long[matchAccounts.size()];</span>
<span class="nc" id="L122"> int index = 0;</span>
<span class="nc bnc" id="L123" title="All 2 branches missed."> for (Account a : matchAccounts) {</span>
<span class="nc" id="L124"> accountIds[index++] = a.getId();</span>
}
<span class="nc" id="L127"> log.debug(&quot;Found &quot; + accountIds.length + &quot; account(s) matching the name &quot; + anOwnerName);</span>
<span class="nc" id="L128"> return accountIds;</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#getOwnerOf(long)
*/
@RequiresPermissions(&quot;bankAccount:read&quot;)
public String getOwnerOf(long anAccountId) throws AccountNotFoundException {
<span class="fc" id="L137"> assertServiceState();</span>
<span class="fc" id="L138"> log.info(&quot;Getting owner of account &quot; + anAccountId);</span>
<span class="fc" id="L140"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L141"> return a.getOwnerName();</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#getBalanceOf(long)
*/
@RequiresPermissions(&quot;bankAccount:read&quot;)
public double getBalanceOf(long anAccountId) throws AccountNotFoundException {
<span class="fc" id="L150"> assertServiceState();</span>
<span class="fc" id="L151"> log.info(&quot;Getting balance of account &quot; + anAccountId);</span>
<span class="fc" id="L153"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L154"> return a.getBalance();</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#depositInto(long, double)
*/
@RequiresPermissions(&quot;bankAccount:operate&quot;)
public double depositInto(long anAccountId, double anAmount) throws AccountNotFoundException, InactiveAccountException {
<span class="fc" id="L163"> assertServiceState();</span>
<span class="fc" id="L164"> log.info(&quot;Making deposit of &quot; + anAmount + &quot; into account &quot; + anAccountId);</span>
try {
<span class="fc" id="L167"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L168"> AccountTransaction tx = AccountTransaction.createDepositTx(anAccountId, anAmount);</span>
<span class="fc" id="L169"> tx.setCreatedBy(getCurrentUsername());</span>
<span class="fc" id="L170"> log.debug(&quot;Created a new transaction &quot; + tx);</span>
<span class="fc" id="L172"> a.applyTransaction(tx);</span>
<span class="fc" id="L173"> log.debug(&quot;New balance of account &quot; + a.getId() + &quot; after deposit is &quot; + a.getBalance());</span>
<span class="fc" id="L175"> return a.getBalance();</span>
<span class="nc" id="L177"> } catch (NotEnoughFundsException nefe) {</span>
<span class="nc" id="L178"> throw new IllegalStateException(&quot;Should never happen&quot;, nefe);</span>
}
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#withdrawFrom(long, double)
*/
@RequiresPermissions(&quot;bankAccount:operate&quot;)
public double withdrawFrom(long anAccountId, double anAmount) throws AccountNotFoundException, NotEnoughFundsException, InactiveAccountException {
<span class="fc" id="L188"> assertServiceState();</span>
<span class="fc" id="L189"> log.info(&quot;Making withdrawal of &quot; + anAmount + &quot; from account &quot; + anAccountId);</span>
<span class="fc" id="L191"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L192"> AccountTransaction tx = AccountTransaction.createWithdrawalTx(anAccountId, anAmount);</span>
<span class="fc" id="L193"> tx.setCreatedBy(getCurrentUsername());</span>
<span class="fc" id="L194"> log.debug(&quot;Created a new transaction &quot; + tx);</span>
<span class="fc" id="L196"> a.applyTransaction(tx);</span>
<span class="fc" id="L197"> log.debug(&quot;New balance of account &quot; + a.getId() + &quot; after withdrawal is &quot; + a.getBalance());</span>
<span class="fc" id="L199"> return a.getBalance();</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#getTxHistoryFor(long)
*/
@RequiresPermissions(&quot;bankAccount:read&quot;)
public TxLog[] getTxHistoryFor(long anAccountId) throws AccountNotFoundException {
<span class="fc" id="L208"> assertServiceState();</span>
<span class="fc" id="L209"> log.info(&quot;Getting transactions of account &quot; + anAccountId);</span>
<span class="fc" id="L211"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L213"> TxLog[] txs = new TxLog[a.getTransactions().size()];</span>
<span class="fc" id="L214"> int index = 0;</span>
<span class="fc bfc" id="L215" title="All 2 branches covered."> for (AccountTransaction tx : a.getTransactions()) {</span>
<span class="fc" id="L216"> log.debug(&quot;Retrieved transaction &quot; + tx);</span>
<span class="fc bfc" id="L218" title="All 2 branches covered."> if (TransactionType.DEPOSIT == tx.getType()) {</span>
<span class="fc" id="L219"> txs[index++] = new TxLog(tx.getCreationDate(), tx.getAmount(), tx.getCreatedBy());</span>
<span class="fc" id="L220"> } else {</span>
<span class="fc" id="L221"> txs[index++] = new TxLog(tx.getCreationDate(), -1.0d * tx.getAmount(), tx.getCreatedBy());</span>
}
}
<span class="fc" id="L225"> return txs;</span>
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#closeAccount(long)
*/
@RequiresPermissions(&quot;bankAccount:close&quot;)
public double closeAccount(long anAccountId) throws AccountNotFoundException, InactiveAccountException {
<span class="fc" id="L234"> assertServiceState();</span>
<span class="fc" id="L235"> log.info(&quot;Closing account &quot; + anAccountId);</span>
<span class="fc" id="L237"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc bfc" id="L238" title="All 2 branches covered."> if (!a.isActive()) {</span>
<span class="fc" id="L239"> throw new InactiveAccountException(&quot;The account &quot; + anAccountId + &quot; is already closed&quot;);</span>
}
try {
<span class="fc" id="L243"> AccountTransaction tx = AccountTransaction.createWithdrawalTx(a.getId(), a.getBalance());</span>
<span class="fc" id="L244"> tx.setCreatedBy(getCurrentUsername());</span>
<span class="fc" id="L245"> log.debug(&quot;Created a new transaction &quot; + tx);</span>
<span class="fc" id="L246"> a.applyTransaction(tx);</span>
<span class="fc" id="L247"> a.setActive(false);</span>
<span class="fc" id="L249"> log.debug(&quot;Account &quot; + a.getId() + &quot; is now closed and an amount of &quot; + tx.getAmount() + &quot; is given to the owner&quot;);</span>
<span class="fc" id="L250"> return tx.getAmount();</span>
<span class="nc" id="L252"> } catch (NotEnoughFundsException nefe) {</span>
<span class="nc" id="L253"> throw new IllegalStateException(&quot;Should never happen&quot;, nefe);</span>
}
}
/* (non-Javadoc)
* @see com.connectif.trilogy.root.security.BankService#isAccountActive(long)
*/
@RequiresPermissions(&quot;bankAccount:read&quot;)
public boolean isAccountActive(long anAccountId) throws AccountNotFoundException {
<span class="fc" id="L263"> assertServiceState();</span>
<span class="fc" id="L264"> log.info(&quot;Getting active status of account &quot; + anAccountId);</span>
<span class="fc" id="L266"> Account a = safellyRetrieveAccountForId(anAccountId);</span>
<span class="fc" id="L267"> return a.isActive();</span>
}
/**
* Internal method that safelly (concurrency-wise) retrieves an account from the id passed in.
*
* @param anAccountId The identifier of the account to retrieve.
* @return The account instance retrieved.
* @throws AccountNotFoundException If no account is found for the provided identifier.
*/
protected Account safellyRetrieveAccountForId(long anAccountId) throws AccountNotFoundException {
<span class="fc" id="L279"> Account account = null;</span>
<span class="fc" id="L280"> synchronized (_accounts) {</span>
<span class="fc" id="L281"> account = _accountsById.get(anAccountId);</span>
}
<span class="pc bpc" id="L284" title="1 of 2 branches missed."> if (account == null) {</span>
<span class="nc" id="L285"> throw new AccountNotFoundException(&quot;No account found for the id &quot; + anAccountId);</span>
}
<span class="fc" id="L288"> log.info(&quot;Retrieved account &quot; + account);</span>
<span class="fc" id="L289"> return account;</span>
}
/**
* Internal utility method to retrieve the username of the current authenticated user.
*
* @return The name.
*/
protected String getCurrentUsername() {
<span class="fc" id="L298"> Subject subject = SecurityUtils.getSubject();</span>
<span class="pc bpc" id="L299" title="3 of 6 branches missed."> if (subject == null || subject.getPrincipal() == null || !subject.isAuthenticated()) {</span>
<span class="nc" id="L300"> throw new IllegalStateException(&quot;Unable to retrieve the current authenticated subject&quot;);</span>
}
<span class="fc" id="L302"> return SecurityUtils.getSubject().getPrincipal().toString();</span>
}
}
</pre><div class="footer"><span class="right">Created with <a href="http://www.jacoco.org/jacoco">JaCoCo</a> 0.8.3.201901230119</span></div></body></html>