Skip to content

Commit

Permalink
patch for security with different roles.
Browse files Browse the repository at this point in the history
  • Loading branch information
Hryhorii Hevorkian committed Oct 30, 2023
1 parent 81404be commit 31f5006
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 85 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1 +1 @@
LEDGERS_VERSION=develop
LEDGERS_VERSION=5.0
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.mapping.SimpleAuthorityMapper;
import org.springframework.security.core.context.SecurityContextHolder;
Expand All @@ -31,6 +31,7 @@
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.web.context.annotation.RequestScope;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
Expand All @@ -51,6 +52,7 @@
public class WebSecurityConfigKeycloak {

private final KeycloakAuthMapper authMapper;
private final Environment environment;

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
Expand All @@ -63,11 +65,6 @@ public void configureGlobal(AuthenticationManagerBuilder auth) {
@Bean
@SuppressWarnings("PMD.SignatureDeclareThrowsException")
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {

http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);

http
.authorizeHttpRequests()
.requestMatchers(INDEX_WHITELIST).permitAll()
Expand All @@ -77,13 +74,15 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
.requestMatchers(APP_WHITELIST).permitAll()
.anyRequest()
.authenticated()
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().oauth2ResourceServer()
.and()
.oauth2ResourceServer()
.jwt().jwtAuthenticationConverter(new KeycloakJwtAuthenticationConverter()).and()
.and().cors().disable() // by default uses a Bean by the name of corsConfigurationSource
.and()
.cors().disable() // by default uses a Bean by the name of corsConfigurationSource
.csrf().disable()
.formLogin().disable()
.httpBasic().disable();
.httpBasic().disable()
.addFilterBefore(new DisableEndpointFilter(environment), BasicAuthenticationFilter.class);

return http.build();
}
Expand Down
3 changes: 3 additions & 0 deletions ledgers-app/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ springdoc:
swagger-ui:
path: /swagger-ui.html


spring:
main:
allow-bean-definition-overriding: true
security:
oauth2:
resourceserver:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,47 +35,47 @@ public class AccountMgmStaffResource implements AccountMgmStaffResourceAPI {
private final ScaInfoHolder scaInfoHolder;

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountIban(#iban)")
@PreAuthorize("hasManagerAccessToAccountIban(#iban)")
public ResponseEntity<List<AccountDetailsTO>> getAccountsByIbanAndCurrency(String iban, String currency) {
return ResponseEntity.ok(middlewareAccountService.getAccountsByIbanAndCurrency(iban, currency));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToUser(#userId)")
@PreAuthorize("hasManagerAccessToUser(#userId)")
public ResponseEntity<Boolean> createDepositAccountForUser(String userId, AccountDetailsTO accountDetailsTO) {
boolean created = middlewareAccountService.createDepositAccount(userId, scaInfoHolder.getScaInfo(), accountDetailsTO);
return ResponseEntity.ok(created);
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<List<AccountDetailsTO>> getListOfAccounts() {
return ResponseEntity.ok(middlewareAccountService.listDepositAccountsByBranch(scaInfoHolder.getUserId()));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<CustomPageImpl<AccountDetailsTO>> getListOfAccountsPaged(String queryParam, int page, int size, boolean withBalance) {
CustomPageableImpl pageable = new CustomPageableImpl(page, size);
CustomPageImpl<AccountDetailsTO> details = middlewareAccountService.listDepositAccountsByBranchPaged(scaInfoHolder.getUserId(), queryParam, withBalance, pageable);
return ResponseEntity.ok(details);
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<AccountDetailsTO> getAccountDetailsById(String accountId) {
return ResponseEntity.ok(middlewareAccountService.getDepositAccountById(accountId, LocalDateTime.now(), true));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId) && @accountAccessSecurityFilter.isEnabledAccount(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId) && isEnabledAccount(#accountId)")
public ResponseEntity<Void> depositCash(String accountId, AmountTO amount) {
middlewareAccountService.depositCash(scaInfoHolder.getScaInfo(), accountId, amount);
return ResponseEntity.accepted().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<AccountReportTO> getExtendedAccountDetailsById(String accountId) {
long start = System.nanoTime();
AccountReportTO accountReport = middlewareAccountService.getAccountReport(accountId);
Expand All @@ -84,13 +84,13 @@ public ResponseEntity<AccountReportTO> getExtendedAccountDetailsById(String acco
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<Boolean> changeStatus(String accountId) {
return ResponseEntity.ok(middlewareAccountService.changeStatus(accountId, false));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<Void> changeCreditLimit(String accountId, BigDecimal creditLimit) {
middlewareAccountService.changeCreditLimit(accountId, creditLimit);
return ResponseEntity.accepted().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,34 @@ public class AccountResource implements AccountRestAPI {
* @return : the list of accounts linked with the current customer.
*/
@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('CUSTOMER','SYSTEM')")
@PreAuthorize("hasAnyRole('CUSTOMER','SYSTEM')")
public ResponseEntity<List<AccountDetailsTO>> getListOfAccounts() {
return ResponseEntity.ok(middlewareAccountService.listDepositAccounts(scaInfoHolder.getUserId()));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccount(#accountId)")
@PreAuthorize("hasAccessToAccount(#accountId)")
public ResponseEntity<AccountDetailsTO> getAccountDetailsById(String accountId) {
return ResponseEntity.ok(middlewareAccountService.getDepositAccountById(accountId, LocalDateTime.now(), true));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccount(#accountId)")
@PreAuthorize("hasAccessToAccount(#accountId)")
public ResponseEntity<List<AccountBalanceTO>> getBalances(String accountId) {
AccountDetailsTO accountDetails = middlewareAccountService.getDepositAccountById(accountId, LocalDateTime.now(), true);
return ResponseEntity.ok(accountDetails.getBalances());
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccount(#accountId)")
@PreAuthorize("hasAccessToAccount(#accountId)")
public ResponseEntity<List<TransactionTO>> getTransactionByDates(String accountId, LocalDate dateFrom, LocalDate dateTo) {
dateChecker(dateFrom, dateTo);
List<TransactionTO> transactions = middlewareAccountService.getTransactionsByDates(accountId, validDate(dateFrom), validDate(dateTo));
return ResponseEntity.ok(transactions);
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccount(#accountId)")
@PreAuthorize("hasAccessToAccount(#accountId)")
public ResponseEntity<CustomPageImpl<TransactionTO>> getTransactionByDatesPaged(String accountId, LocalDate dateFrom, LocalDate dateTo, int page, int size) {
dateChecker(dateFrom, dateTo);
CustomPageableImpl pageable = new CustomPageableImpl(page, size);
Expand All @@ -80,13 +80,13 @@ public ResponseEntity<CustomPageImpl<TransactionTO>> getTransactionByDatesPaged(
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccount(#accountId)")
@PreAuthorize("hasAccessToAccount(#accountId)")
public ResponseEntity<TransactionTO> getTransactionById(String accountId, String transactionId) {
return ResponseEntity.ok(middlewareAccountService.getTransactionById(accountId, transactionId));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAccessToAccountWithIban(#request.psuAccount.iban)")
@PreAuthorize("hasAccessToAccountWithIban(#request.psuAccount.iban)")
public ResponseEntity<Boolean> fundsConfirmation(FundsConfirmationRequestTO request) {
if (request.getInstructedAmount().getAmount().compareTo(BigDecimal.ZERO) <= 0) { //TODO move to validation filter
throw MiddlewareModuleException.builder()
Expand All @@ -99,7 +99,7 @@ public ResponseEntity<Boolean> fundsConfirmation(FundsConfirmationRequestTO requ
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.accountInfoByIdentifier(#accountIdentifierType, #accountIdentifier)")
@PreAuthorize("accountInfoByIdentifier(#accountIdentifierType, #accountIdentifier)")
public ResponseEntity<List<AdditionalAccountInformationTO>> getAdditionalAccountInfo(AccountIdentifierTypeTO accountIdentifierType, String accountIdentifier) {
return ResponseEntity.ok(userManagementService.getAdditionalInformation(scaInfoHolder.getScaInfo(), accountIdentifierType, accountIdentifier));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,56 +47,56 @@ public class AdminResource implements AdminResourceAPI {
private final UserMapper userMapper;

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('SYSTEM')")
@PreAuthorize("hasAnyRole('SYSTEM')")
public ResponseEntity<List<UserTO>> getAllUsers() {
return ResponseEntity.ok(middlewareUserService.listUsers(0, Integer.MAX_VALUE));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<CustomPageImpl<UserExtendedTO>> users(String countryCode, String branchId, String branchLogin, String userLogin, UserRoleTO role, Boolean blocked, int page, int size) {
CustomPageableImpl pageable = new CustomPageableImpl(page, size);
List<UserRoleTO> roles = Optional.ofNullable(role).map(Collections::singletonList).orElseGet(() -> Arrays.asList(STAFF, CUSTOMER));
return ResponseEntity.ok(middlewareUserService.getUsersByBranchAndRolesExtended(countryCode, branchId, branchLogin, userLogin, roles, blocked, pageable));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<CustomPageImpl<UserTO>> admins(int page, int size) {
CustomPageableImpl pageable = new CustomPageableImpl(page, size);
return ResponseEntity.ok(middlewareUserService.getUsersByRoles(Collections.singletonList(SYSTEM), pageable));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<CustomPageImpl<AccountDetailsExtendedTO>> accounts(String countryCode, String branchId, String branchLogin, String iban, Boolean blocked, int page, int size) {
CustomPageableImpl pageable = new CustomPageableImpl(page, size);
return ResponseEntity.ok(accountManagementService.getAccountsByBranchAndMultipleParams(countryCode, branchId, branchLogin, iban, blocked, pageable));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<Void> updatePassword(String branchId, String password) {
middlewareUserService.updatePasswordById(branchId, password);
return ResponseEntity.accepted().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<Boolean> changeStatus(String userId) {
return ResponseEntity.ok(appManagementService.changeBlockedStatus(userId, false));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<UserTO> register(UserTO user) {
UserTO createdUser = middlewareUserService.create(user);
createdUser.setPin(null);
return ResponseEntity.ok(createdUser);
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM') and @accountAccessSecurityFilter.isEnabledUser(#user.id)")
@PreAuthorize("hasRole('SYSTEM') and isEnabledUser(#user.id)")
public ResponseEntity<Void> user(UserTO user) {
checkUpdateData(user);
middlewareUserService.updateUser(user.getBranch(), user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public ResponseEntity<String> ping() {
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('SYSTEM')")
@PreAuthorize("hasRole('SYSTEM')")
public ResponseEntity<Void> initApp() {
appManagementService.initApp();
return ResponseEntity.ok().build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ public class ConsentResource implements ConsentRestAPI {
private final MiddlewareAccountManagementService middlewareAccountService;

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('STAFF','CUSTOMER') and @accountAccessSecurityFilter.hasAccessToAccountsWithIbans(#aisConsent.access.listedAccountsIbans)")
@PreAuthorize("hasAnyRole('STAFF','CUSTOMER') and hasAccessToAccountsWithIbans(#aisConsent.access.listedAccountsIbans)")
public ResponseEntity<SCAConsentResponseTO> initiateAisConsent(String consentId, AisConsentTO aisConsent) {
return ResponseEntity.ok(middlewareAccountService.startAisConsent(scaInfoHolder.getScaInfo(), consentId, aisConsent));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('STAFF','CUSTOMER') and @accountAccessSecurityFilter.hasAccessToAccountsWithIbans(#aisConsent.access.listedAccountsIbans)")
@PreAuthorize("hasAnyRole('STAFF','CUSTOMER') and hasAccessToAccountsWithIbans(#aisConsent.access.listedAccountsIbans)")
public ResponseEntity<SCAConsentResponseTO> initiatePiisConsent(AisConsentTO aisConsent) {
return ResponseEntity.ok(middlewareAccountService.startPiisConsent(scaInfoHolder.getScaInfo(), aisConsent));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,42 +34,42 @@ public class DataMgmtStaffResource implements DataMgmtStaffAPI {
private final MiddlewareRecoveryService recoveryService;

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<Void> account(String accountId) {
cleanupService.deleteTransactions(scaInfoHolder.getUserId(), scaInfoHolder.getScaInfo().getUserRole(), accountId);
return ResponseEntity.ok().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToAccountId(#accountId)")
@PreAuthorize("hasManagerAccessToAccountId(#accountId)")
public ResponseEntity<Void> depositAccount(String accountId) {
cleanupService.deleteAccount(scaInfoHolder.getUserId(), scaInfoHolder.getScaInfo().getUserRole(), accountId);
return ResponseEntity.ok().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToUser(#userId)")
@PreAuthorize("hasManagerAccessToUser(#userId)")
public ResponseEntity<Void> user(String userId) {
cleanupService.deleteUser(scaInfoHolder.getUserId(), scaInfoHolder.getScaInfo().getUserRole(), userId);
return ResponseEntity.ok().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasManagerAccessToUser(#branchId)")
@PreAuthorize("hasManagerAccessToUser(#branchId)")
public ResponseEntity<Void> branch(String branchId) {
cleanupService.removeBranch(scaInfoHolder.getUserId(), scaInfoHolder.getScaInfo().getUserRole(), branchId);
return ResponseEntity.ok().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('STAFF','SYSTEM')")
@PreAuthorize("hasAnyRole('STAFF','SYSTEM')")
public ResponseEntity<Void> uploadData(UploadedDataTO data) {
appManagementService.uploadData(data, scaInfoHolder.getScaInfo());
return ResponseEntity.ok().build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasAnyRole('STAFF','SYSTEM')")
@PreAuthorize("hasAnyRole('STAFF','SYSTEM')")
public ResponseEntity<Set<Currency>> currencies() {
return ResponseEntity.ok(currencyService.getSupportedCurrencies());
}
Expand All @@ -80,26 +80,26 @@ public ResponseEntity<String> branchId(BbanStructure bbanStructure) {
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<Void> createPoint(RecoveryPointTO recoveryPoint) {
recoveryService.createRecoveryPoint(scaInfoHolder.getUserId(), recoveryPoint);
return ResponseEntity.status(HttpStatus.CREATED).build();
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<List<RecoveryPointTO>> getAllPoints() {
return ResponseEntity.ok(recoveryService.getAll(scaInfoHolder.getUserId()));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<RecoveryPointTO> getPoint(Long id) {
return ResponseEntity.ok(recoveryService.getPointById(scaInfoHolder.getUserId(), id));
}

@Override
@PreAuthorize("@accountAccessSecurityFilter.hasRole('STAFF')")
@PreAuthorize("hasRole('STAFF')")
public ResponseEntity<Void> deletePoint(Long id) {
recoveryService.deleteById(scaInfoHolder.getUserId(), id);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
Expand Down
Loading

0 comments on commit 31f5006

Please sign in to comment.