Skip to content

Commit

Permalink
Manage admin's bank data to assign off-chain gateways (#474)
Browse files Browse the repository at this point in the history
  • Loading branch information
fatemeh-i authored Nov 3, 2024
1 parent dff6775 commit a528eab
Show file tree
Hide file tree
Showing 19 changed files with 421 additions and 62 deletions.
2 changes: 2 additions & 0 deletions common/src/main/kotlin/co/nilin/opex/common/OpexError.kt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ enum class OpexError(val code: Int, val message: String?, val status: HttpStatus
GatewayIsExist(6025, null, HttpStatus.NOT_FOUND),

InvalidDeposit(6026, "Invalid deposit", HttpStatus.BAD_REQUEST),
BankDataIsExist(6027, "This identifier is exist", HttpStatus.BAD_REQUEST),
BankDataNotFound(6027, "Object not found", HttpStatus.BAD_REQUEST),



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ class SecurityConfig(private val webClient: WebClient) {
.pathMatchers("/admin/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.PUT, "/otc/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.POST, "/otc/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.DELETE, "/otc/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.PUT, "/currency/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.POST, "/currency/**").hasRoleAndLevel("Admin")
.pathMatchers(HttpMethod.DELETE, "/currency/**").hasRoleAndLevel("Admin")
.pathMatchers("/manually/**").hasRoleAndLevel("Admin")
.pathMatchers("/deposit/**").hasRoleAndLevel("System")
.pathMatchers("/withdraw").hasRoleAndLevel("user", "Trusted")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,41 @@ package co.nilin.opex.wallet.app.controller
import co.nilin.opex.wallet.app.dto.CurrenciesDto
import co.nilin.opex.wallet.app.dto.CurrencyDto
import co.nilin.opex.wallet.app.service.CurrencyServiceV2
import co.nilin.opex.wallet.core.inout.BankDataCommand
import co.nilin.opex.wallet.core.inout.CurrencyGatewayCommand
import co.nilin.opex.wallet.core.inout.OnChainGatewayCommand
import co.nilin.opex.wallet.core.inout.GatewayType
import co.nilin.opex.wallet.core.spi.GatewayBankDataManager
import org.springframework.web.bind.annotation.*
import java.util.UUID

@RestController
@RequestMapping("/currency")
class CurrencyController(private val currencyService: CurrencyServiceV2) {
class CurrencyController(
private val currencyService: CurrencyServiceV2,
private val gatewayBankDataManager: GatewayBankDataManager
) {

@PostMapping("")
suspend fun addCurrency(@RequestBody request: CurrencyDto): CurrencyDto? {
return currencyService.createNewCurrency(request)
}

@PutMapping("/{currencySymbol}")
suspend fun updateCurrency(@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyDto): CurrencyDto? {
suspend fun updateCurrency(
@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyDto
): CurrencyDto? {
return currencyService.updateCurrency(request.apply { symbol = currencySymbol })
}


@GetMapping("/{currencySymbol}")
suspend fun getCurrency(
@PathVariable("currencySymbol") currencySymbol: String,
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
@PathVariable("currencySymbol") currencySymbol: String,
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
): CurrencyDto? {

val includeGateways = mutableListOf<GatewayType>().apply {
Expand All @@ -43,9 +50,9 @@ class CurrencyController(private val currencyService: CurrencyServiceV2) {

@GetMapping("")
suspend fun getCurrencies(
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
): CurrenciesDto? {
val includeGateways = mutableListOf<GatewayType>().apply {

Expand All @@ -58,41 +65,49 @@ class CurrencyController(private val currencyService: CurrencyServiceV2) {


@PostMapping("/{currencySymbol}/gateway")
suspend fun addGateway2Currency(@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyGatewayCommand): CurrencyGatewayCommand? {
suspend fun addGateway2Currency(
@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyGatewayCommand
): CurrencyGatewayCommand? {
return currencyService.addGateway2Currency(request.apply {
this.currencySymbol = currencySymbol
})
}

@PutMapping("{currencySymbol}/gateway/{gatewayUuid}")
suspend fun updateGateway(@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyGatewayCommand): CurrencyGatewayCommand? {
suspend fun updateGateway(
@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String,
@RequestBody request: CurrencyGatewayCommand
): CurrencyGatewayCommand? {
return currencyService.updateGateway(request.apply {
this.currencySymbol = currencySymbol
this.gatewayUuid = gatewayUuid
})
}

@GetMapping("{currencySymbol}/gateway/{gatewayUuid}")
suspend fun getGateway(@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String): CurrencyGatewayCommand? {
suspend fun getGateway(
@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String
): CurrencyGatewayCommand? {
return currencyService.fetchCurrencyGateway(gatewayUuid, currencySymbol)
}

@DeleteMapping("{currencySymbol}/gateway/{gatewayUuid}")
suspend fun deleteGateway(@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String) {
suspend fun deleteGateway(
@PathVariable("gatewayUuid") gatewayUuid: String,
@PathVariable("currencySymbol") currencySymbol: String
) {
currencyService.deleteGateway(gatewayUuid, currencySymbol)
}


@GetMapping("/gateways")
suspend fun getGateways(
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
@RequestParam includeManualGateways: Boolean? = false,
@RequestParam includeOffChainGateways: Boolean? = false,
@RequestParam includeOnChainGateways: Boolean? = false,
): List<CurrencyGatewayCommand>? {
val includeGateways = mutableListOf<GatewayType>().apply {
if (includeManualGateways == true) add(GatewayType.Manually)
Expand All @@ -102,4 +117,29 @@ class CurrencyController(private val currencyService: CurrencyServiceV2) {
return currencyService.fetchGateways(includeGateways)
}


@PostMapping("/gateway/{gatewayUuid}/bank-data")
suspend fun assignBankDataToGateway(
@PathVariable("gatewayUuid") gatewayUuid: String,
@RequestBody bankData: List<String>
) {
return gatewayBankDataManager.assignBankDataToGateway(gatewayUuid, bankData)
}


@GetMapping("/gateway/{gatewayUuid}/bank-data")
suspend fun getGatewayBankData(
@PathVariable("gatewayUuid") gatewayUuid: String
): List<BankDataCommand>? {
return gatewayBankDataManager.getAssignedBankDataToGateway(gatewayUuid)
}

@DeleteMapping("/gateway/{gatewayUuid}/bank-data")
suspend fun revokeBankDataFromGateway(
@PathVariable("gatewayUuid") gatewayUuid: String,
@RequestBody bankData: List<String>
) {
return gatewayBankDataManager.revokeBankDataToGateway(gatewayUuid, bankData)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,115 @@ import co.nilin.opex.wallet.core.inout.DepositResponse
import co.nilin.opex.wallet.app.dto.ManualTransferRequest
import co.nilin.opex.wallet.core.inout.*
import co.nilin.opex.wallet.app.service.DepositService
import co.nilin.opex.wallet.core.spi.BankDataManager
import io.swagger.annotations.ApiResponse
import io.swagger.annotations.Example
import io.swagger.annotations.ExampleProperty
import org.springframework.http.ResponseEntity
import org.springframework.security.core.annotation.CurrentSecurityContext
import org.springframework.security.core.context.SecurityContext
import org.springframework.web.bind.annotation.*
import java.math.BigDecimal
import java.time.Instant
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.UUID

@RestController
@RequestMapping("/admin")
@RequestMapping("/admin/deposit")

class DepositAdminController(private val depositService: DepositService) {
class DepositAdminController(
private val depositService: DepositService,
private val bankDataManager: BankDataManager
) {


@PostMapping("/deposit/manually/{amount}_{symbol}/{receiverUuid}")


@PostMapping("/manually/{amount}_{symbol}/{receiverUuid}")
@ApiResponse(
message = "OK",
code = 200,
examples = Example(
ExampleProperty(
value = "{ }",
mediaType = "application/json"
message = "OK",
code = 200,
examples = Example(
ExampleProperty(
value = "{ }",
mediaType = "application/json"
)
)
)
)
suspend fun depositManually(
@PathVariable("symbol") symbol: String,
@PathVariable("receiverUuid") receiverUuid: String,
@PathVariable("amount") amount: BigDecimal,
@RequestBody request: ManualTransferRequest,
@CurrentSecurityContext securityContext: SecurityContext
@PathVariable("symbol") symbol: String,
@PathVariable("receiverUuid") receiverUuid: String,
@PathVariable("amount") amount: BigDecimal,
@RequestBody request: ManualTransferRequest,
@CurrentSecurityContext securityContext: SecurityContext
): TransferResult? {
return depositService.depositManually(
symbol, receiverUuid,
securityContext.authentication.name, amount, request
symbol, receiverUuid,
securityContext.authentication.name, amount, request
)
}

@PostMapping("/deposit/search")
@PostMapping("/search")
suspend fun search(
@RequestParam offset: Int,
@RequestParam size: Int,
@RequestBody body: AdminSearchDepositRequest
@RequestParam offset: Int,
@RequestParam size: Int,
@RequestBody body: AdminSearchDepositRequest
): List<DepositResponse> {
return depositService.searchDeposit(
body.uuid,
body.currency,
body.sourceAddress,
body.transactionRef,
body.startTime?.let {
LocalDateTime.ofInstant(Instant.ofEpochMilli(body.startTime), ZoneId.systemDefault())
},
body.endTime?.let {
LocalDateTime.ofInstant(Instant.ofEpochMilli(body.endTime), ZoneId.systemDefault())
},
offset,
size,
body.ascendingByTime,
body.uuid,
body.currency,
body.sourceAddress,
body.transactionRef,
body.startTime?.let {
LocalDateTime.ofInstant(Instant.ofEpochMilli(body.startTime), ZoneId.systemDefault())
},
body.endTime?.let {
LocalDateTime.ofInstant(Instant.ofEpochMilli(body.endTime), ZoneId.systemDefault())
},
offset,
size,
body.ascendingByTime,
)
}


@PostMapping("/bank-data")
suspend fun registerAdminBankData(
@RequestBody body: BankDataCommand
): BankDataCommand? {
return bankDataManager.save(body.apply { uuid = UUID.randomUUID().toString() })
}


@PutMapping("/bank-data/{uuid}")
suspend fun updateBankData(
@PathVariable("uuid") bankDataUuid: String,
@RequestBody body: BankDataCommand
): BankDataCommand? {
return bankDataManager.update(body.apply { uuid = bankDataUuid })
}


@DeleteMapping("/bank-data/{uuid}")
suspend fun deleteBankData(
@PathVariable("uuid") bankDataUuid: String,
) {
bankDataManager.delete(bankDataUuid)
}

@GetMapping("/bank-data")
suspend fun getBankData(
): List<BankDataCommand>? {
return bankDataManager.fetchBankData()
}
@GetMapping("/bank-data/{uuid}")
suspend fun getBankData(
@PathVariable("uuid") bankDataUuid: String,
) {
bankDataManager.fetchBankData(bankDataUuid)
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class PaymentGatewayController(
receiverWalletType
)

val command = transferManager.transfer(
transferManager.transfer(
TransferCommand(
sourceWallet,
receiverWallet,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package co.nilin.opex.wallet.app.service

import org.springframework.stereotype.Service

@Service
class BankDataService {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package co.nilin.opex.wallet.core.inout

import java.util.*

data class BankDataCommand(
var uuid: String?,
var owner: String,
var identifier: String,
var active: Boolean? = true,
var type: TransferMethod,
var bankSwiftCode: String
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ package co.nilin.opex.wallet.core.inout

enum class TransferMethod {
Card2card, Sheba, IPG
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package co.nilin.opex.wallet.core.spi

import co.nilin.opex.wallet.core.inout.BankDataCommand

interface BankDataManager {

suspend fun save(bankDataCommand: BankDataCommand):BankDataCommand?
suspend fun update(bankDataCommand: BankDataCommand): BankDataCommand?
suspend fun delete(uuid: String)
suspend fun fetchBankData(): List<BankDataCommand>?
suspend fun fetchBankData(uuid: String): BankDataCommand?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package co.nilin.opex.wallet.core.spi

import co.nilin.opex.wallet.core.inout.BankDataCommand

interface GatewayBankDataManager {
suspend fun assignBankDataToGateway(gatewayUuid:String, bankData:List<String>)

suspend fun getAssignedBankDataToGateway(gatewayUuid: String):List<BankDataCommand>?

suspend fun revokeBankDataToGateway(gatewayUuid:String, bankData:List<String>)

}
Loading

0 comments on commit a528eab

Please sign in to comment.