Updated on 2026-08-14

This commit is contained in:
Tangem 2020-04-03 18:03:21 +03:00
parent eff17d7ffc
commit ce683bac19
9 changed files with 541 additions and 494 deletions

View file

@ -0,0 +1,15 @@
package com.tangem.tangemtest._arch.structure.abstraction
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter
/**
[REDACTED_AUTHOR]
*/
interface DefaultConverter<A, B> {
fun convert(from: A, default: B): B
}
interface ItemsToModel<M> : DefaultConverter<List<Item>, M>
interface ModelToItems<M> : Converter<M, List<Item>>
interface ModelConverter<M> : DefaultConverter<List<Item>, M>, Converter<M, List<Item>>

View file

@ -0,0 +1,135 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter
import com.tangem.commands.EllipticCurve
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.impl.KeyValue
import com.tangem.tangemtest.ucase.variants.personalize.*
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder
/**
[REDACTED_AUTHOR]
*/
class PersonalizeConfigValuesHolder : BaseTypedHolder<Id, Value>() {
// All registered association values can't be objects
fun init(default: PersonalizeConfig) {
register(CardNumber.Series, Value(default.series))
register(CardNumber.Number, Value(default.startNumber))
register(CardNumber.BatchId, Value(default.batchId))
register(Common.Curve, Value(default.curveID, Helper.listOfCurves()))
register(Common.Blockchain, Value(default.blockchain, Helper.listOfBlockchain()))
register(Common.BlockchainCustom, Value(""))
register(Common.MaxSignatures, Value(default.MaxSignatures))
register(Common.CreateWallet, Value(default.createWallet))
register(SigningMethod.SignTx, Value(default.SigningMethod0))
register(SigningMethod.SignTxRaw, Value(default.SigningMethod1))
register(SigningMethod.SignValidatedTx, Value(default.SigningMethod2))
register(SigningMethod.SignValidatedTxRaw, Value(default.SigningMethod3))
register(SigningMethod.SignValidatedTxIssuer, Value(default.SigningMethod4))
register(SigningMethod.SignValidatedTxRawIssuer, Value(default.SigningMethod5))
register(SigningMethod.SignExternal, Value(default.SigningMethod6))
register(SignHashExProp.PinLessFloorLimit, Value(default.pinLessFloorLimit))
register(SignHashExProp.CryptoExKey, Value(default.hexCrExKey))
register(SignHashExProp.RequireTerminalCertSig, Value(default.requireTerminalCertSignature))
register(SignHashExProp.RequireTerminalTxSig, Value(default.requireTerminalTxSignature))
register(SignHashExProp.CheckPin3, Value(default.checkPIN3onCard))
register(Denomination.WriteOnPersonalize, Value(default.writeOnPersonalization))
register(Denomination.Denomination, Value(default.denomination))
register(Token.ItsToken, Value(default.itsToken))
register(Token.Symbol, Value(default.symbol))
register(Token.ContractAddress, Value(default.contractAddress))
register(Token.Decimal, Value(default.decimal))
register(ProductMask.Note, Value(default.cardData.product_note))
register(ProductMask.Tag, Value(default.cardData.product_tag))
register(ProductMask.CardId, Value(default.cardData.product_id_card))
register(SettingsMask.IsReusable, Value(default.isReusable))
register(SettingsMask.NeedActivation, Value(default.useActivation))
register(SettingsMask.ForbidPurge, Value(default.forbidPurgeWallet))
register(SettingsMask.AllowSelectBlockchain, Value(default.allowSelectBlockchain))
register(SettingsMask.UseBlock, Value(default.useBlock))
register(SettingsMask.OneApdu, Value(default.oneApdu))
register(SettingsMask.UseCvc, Value(default.useCVC))
register(SettingsMask.AllowSwapPin, Value(default.allowSwapPIN))
register(SettingsMask.AllowSwapPin2, Value(default.allowSwapPIN2))
register(SettingsMask.ForbidDefaultPin, Value(default.forbidDefaultPIN))
register(SettingsMask.SmartSecurityDelay, Value(default.smartSecurityDelay))
register(SettingsMask.ProtectIssuerDataAgainstReplay, Value(default.protectIssuerDataAgainstReplay))
register(SettingsMask.SkipSecurityDelayIfValidated, Value(default.skipSecurityDelayIfValidatedByIssuer))
register(SettingsMask.SkipPin2CvcIfValidated, Value(default.skipCheckPIN2andCVCIfValidatedByIssuer))
register(SettingsMask.SkipSecurityDelayOnLinkedTerminal, Value(default.skipSecurityDelayIfValidatedByLinkedTerminal))
register(SettingsMask.RestrictOverwriteExtraIssuerData, Value(default.restrictOverwriteIssuerDataEx))
register(SettingsMaskProtocolEnc.AllowUnencrypted, Value(default.protocolAllowUnencrypted))
register(SettingsMaskProtocolEnc.AllowStaticEncryption, Value(default.protocolAllowStaticEncryption))
register(SettingsMaskNdef.UseNdef, Value(default.useNDEF))
register(SettingsMaskNdef.DynamicNdef, Value(default.useDynamicNDEF))
register(SettingsMaskNdef.DisablePrecomputedNdef, Value(default.disablePrecomputedNDEF))
register(SettingsMaskNdef.Aar, Value(default.aar, Helper.aarList()))
register(SettingsMaskNdef.AarCustom, Value(default.aar))
register(Pins.Pin, Value(default.PIN))
register(Pins.Pin2, Value(default.PIN2))
register(Pins.Pin3, Value(default.PIN3))
register(Pins.Cvc, Value(default.CVC))
register(Pins.PauseBeforePin2, Value(default.pauseBeforePIN2, Helper.pauseBeforePin()))
}
}
class Value(
private var value: Any? = null,
val list: List<KeyValue>? = mutableListOf()
) {
fun get(): Any? = value
fun set(newValue: Any?) {
value = newValue
}
}
internal class Helper {
companion object {
fun listOfCurves(): List<KeyValue> {
return EllipticCurve.values().map { KeyValue(it.name, it.curve) }
}
fun listOfBlockchain(): List<KeyValue> {
return mutableListOf(
KeyValue("--- CUSTOM ---", ""),
KeyValue("BTC", "BTC"),
KeyValue("BTC/test", "BTC/test"),
KeyValue("ETH", "ETH"),
KeyValue("ETH/test", "ETH/test"),
KeyValue("BCH", "BCH"),
KeyValue("BCH/test", "BCH/test"),
KeyValue("LTC", "LTC"),
KeyValue("XLM", "XLM"),
KeyValue("XLM/test", "XLM/test"),
KeyValue("RSK", "RSK"),
KeyValue("XPR", "XPR"),
KeyValue("CARDANO", "CARDANO"),
KeyValue("BNB", "BNB"),
KeyValue("XTZ", "XTZ"),
KeyValue("DUC", "DUC")
)
}
fun aarList(): List<KeyValue> {
return mutableListOf(
KeyValue("--- CUSTOM ---", ""),
KeyValue("Release APP", "com.tangem.wallet"),
KeyValue("Debug APP", "com.tangem.wallet.debug"),
KeyValue("None", "")
)
}
fun pauseBeforePin(): List<KeyValue> {
return mutableListOf(
KeyValue("immediately", 0L),
KeyValue("2 seconds", 2000L),
KeyValue("5 seconds", 5000L),
KeyValue("15 seconds", 15000L),
KeyValue("30 seconds", 30000L),
KeyValue("1 minute", 60000L),
KeyValue("2 minute", 120000L)
)
}
}
}

View file

@ -1,135 +0,0 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter
import com.tangem.commands.EllipticCurve
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.impl.KeyValue
import com.tangem.tangemtest.ucase.variants.personalize.*
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import ru.dev.gbixahue.eu4d.lib.kotlin.common.BaseTypedHolder
/**
[REDACTED_AUTHOR]
*/
class Value(
private var value: Any? = null,
val list: List<KeyValue>? = mutableListOf()
) {
fun get(): Any? = value
fun set(newValue: Any?) {
value = newValue
}
}
class IdToValueAssociations : BaseTypedHolder<Id, Value>() {
// All registered association values can't be objects
fun init(from: PersonalizeConfig) {
register(CardNumber.Series, Value(from.series))
register(CardNumber.Number, Value(from.startNumber))
register(CardNumber.BatchId, Value(from.batchId))
register(Common.Curve, Value(from.curveID, Helper.listOfCurves()))
register(Common.Blockchain, Value(from.blockchain, Helper.listOfBlockchain()))
register(Common.BlockchainCustom, Value(""))
register(Common.MaxSignatures, Value(from.MaxSignatures))
register(Common.CreateWallet, Value(from.createWallet))
register(SigningMethod.SignTx, Value(from.SigningMethod0))
register(SigningMethod.SignTxRaw, Value(from.SigningMethod1))
register(SigningMethod.SignValidatedTx, Value(from.SigningMethod2))
register(SigningMethod.SignValidatedTxRaw, Value(from.SigningMethod3))
register(SigningMethod.SignValidatedTxIssuer, Value(from.SigningMethod4))
register(SigningMethod.SignValidatedTxRawIssuer, Value(from.SigningMethod5))
register(SigningMethod.SignExternal, Value(from.SigningMethod6))
register(SignHashExProp.PinLessFloorLimit, Value(from.pinLessFloorLimit))
register(SignHashExProp.CryptoExKey, Value(from.hexCrExKey))
register(SignHashExProp.RequireTerminalCertSig, Value(from.requireTerminalCertSignature))
register(SignHashExProp.RequireTerminalTxSig, Value(from.requireTerminalTxSignature))
register(SignHashExProp.CheckPin3, Value(from.checkPIN3onCard))
register(Denomination.WriteOnPersonalize, Value(from.writeOnPersonalization))
register(Denomination.Denomination, Value(from.denomination))
register(Token.ItsToken, Value(from.itsToken))
register(Token.Symbol, Value(from.symbol))
register(Token.ContractAddress, Value(from.contractAddress))
register(Token.Decimal, Value(from.decimal))
register(ProductMask.Note, Value(from.cardData.product_note))
register(ProductMask.Tag, Value(from.cardData.product_tag))
register(ProductMask.CardId, Value(from.cardData.product_id_card))
register(SettingsMask.IsReusable, Value(from.isReusable))
register(SettingsMask.NeedActivation, Value(from.useActivation))
register(SettingsMask.ForbidPurge, Value(from.forbidPurgeWallet))
register(SettingsMask.AllowSelectBlockchain, Value(from.allowSelectBlockchain))
register(SettingsMask.UseBlock, Value(from.useBlock))
register(SettingsMask.OneApdu, Value(from.oneApdu))
register(SettingsMask.UseCvc, Value(from.useCVC))
register(SettingsMask.AllowSwapPin, Value(from.allowSwapPIN))
register(SettingsMask.AllowSwapPin2, Value(from.allowSwapPIN2))
register(SettingsMask.ForbidDefaultPin, Value(from.forbidDefaultPIN))
register(SettingsMask.SmartSecurityDelay, Value(from.smartSecurityDelay))
register(SettingsMask.ProtectIssuerDataAgainstReplay, Value(from.protectIssuerDataAgainstReplay))
register(SettingsMask.SkipSecurityDelayIfValidated, Value(from.skipSecurityDelayIfValidatedByIssuer))
register(SettingsMask.SkipPin2CvcIfValidated, Value(from.skipCheckPIN2andCVCIfValidatedByIssuer))
register(SettingsMask.SkipSecurityDelayOnLinkedTerminal, Value(from.skipSecurityDelayIfValidatedByLinkedTerminal))
register(SettingsMask.RestrictOverwriteExtraIssuerData, Value(from.restrictOverwriteIssuerDataEx))
register(SettingsMaskProtocolEnc.AllowUnencrypted, Value(from.protocolAllowUnencrypted))
register(SettingsMaskProtocolEnc.AllowStaticEncryption, Value(from.protocolAllowStaticEncryption))
register(SettingsMaskNdef.UseNdef, Value(from.useNDEF))
register(SettingsMaskNdef.DynamicNdef, Value(from.useDynamicNDEF))
register(SettingsMaskNdef.DisablePrecomputedNdef, Value(from.disablePrecomputedNDEF))
register(SettingsMaskNdef.Aar, Value(from.aar, Helper.aarList()))
register(SettingsMaskNdef.AarCustom, Value(from.aar))
register(Pins.Pin, Value(from.PIN))
register(Pins.Pin2, Value(from.PIN2))
register(Pins.Pin3, Value(from.PIN3))
register(Pins.Cvc, Value(from.CVC))
register(Pins.PauseBeforePin2, Value(from.pauseBeforePIN2, Helper.pauseBeforePin()))
}
}
internal class Helper {
companion object {
fun listOfCurves(): List<KeyValue> {
return EllipticCurve.values().map { KeyValue(it.name, it.curve) }
}
fun listOfBlockchain(): List<KeyValue> {
return mutableListOf(
KeyValue("--- CUSTOM ---", ""),
KeyValue("BTC", "BTC"),
KeyValue("BTC/test", "BTC/test"),
KeyValue("ETH", "ETH"),
KeyValue("ETH/test", "ETH/test"),
KeyValue("BCH", "BCH"),
KeyValue("BCH/test", "BCH/test"),
KeyValue("LTC", "LTC"),
KeyValue("XLM", "XLM"),
KeyValue("XLM/test", "XLM/test"),
KeyValue("RSK", "RSK"),
KeyValue("XPR", "XPR"),
KeyValue("CARDANO", "CARDANO"),
KeyValue("BNB", "BNB"),
KeyValue("XTZ", "XTZ"),
KeyValue("DUC", "DUC")
)
}
fun aarList(): List<KeyValue> {
return mutableListOf(
KeyValue("--- CUSTOM ---", ""),
KeyValue("Release APP", "com.tangem.wallet"),
KeyValue("Debug APP", "com.tangem.wallet.debug"),
KeyValue("None", "")
)
}
fun pauseBeforePin(): List<KeyValue> {
return mutableListOf(
KeyValue("immediately", 0L),
KeyValue("2 seconds", 2000L),
KeyValue("5 seconds", 5000L),
KeyValue("15 seconds", 15000L),
KeyValue("30 seconds", 30000L),
KeyValue("1 minute", 60000L),
KeyValue("2 minute", 120000L)
)
}
}
}

View file

@ -1,338 +1,26 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter
import com.tangem.commands.CardData
import com.tangem.commands.EllipticCurve
import com.tangem.commands.ProductMaskBuilder
import com.tangem.commands.personalization.entities.CardConfig
import com.tangem.commands.personalization.entities.NdefRecord
import com.tangem.tangemtest._arch.structure.Additional
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.abstraction.Block
import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock
import com.tangem.tangemtest._arch.structure.impl.*
import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey
import com.tangem.tangemtest.ucase.variants.personalize.*
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ItemsToModel
import com.tangem.tangemtest._arch.structure.abstraction.ModelConverter
import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems
import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.ItemsToPersonalizeConfig
import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.PersonalizeConfigToItem
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import java.util.*
/**
[REDACTED_AUTHOR]
*/
class PersonalizeConfigConverter {
class PersonalizeConfigConverter : ModelConverter<PersonalizeConfig> {
private val associations: IdToValueAssociations = IdToValueAssociations()
private val valueMapper = ValueMapper()
private val toModel: ItemsToModel<PersonalizeConfig> = ItemsToPersonalizeConfig()
private val toItems: ModelToItems<PersonalizeConfig> = PersonalizeConfigToItem()
fun toBlock(from: PersonalizeConfig): List<Block> {
associations.init(from)
val blocList = mutableListOf<Block>()
blocList.add(cardNumber())
blocList.add(common())
blocList.add(signingMethod())
blocList.add(signHashExProperties())
blocList.add(denomination())
blocList.add(token())
blocList.add(productMask())
blocList.add(settingsMask())
blocList.add(settingsMaskProtocolEnc())
blocList.add(settingsMaskNdef())
blocList.add(pins())
val payloadBlock = ListItemBlock(Additional.JSON_TAILS)
addPayload(payloadBlock, from)
blocList.add(payloadBlock)
return blocList
override fun convert(from: List<Item>, default: PersonalizeConfig): PersonalizeConfig {
return toModel.convert(from, default)
}
private fun cardNumber(): Block {
val block = createBlock(BlockId.CardNumber)
mutableListOf(
CardNumber.Series,
CardNumber.Number,
CardNumber.BatchId
).forEach { createItem(block, it as Id) }
return block
override fun convert(from: PersonalizeConfig): List<Item> {
return toItems.convert(from)
}
private fun common(): Block {
val block = createBlock(BlockId.Common)
mutableListOf(
Common.Curve,
Common.Blockchain,
Common.BlockchainCustom,
Common.MaxSignatures,
Common.CreateWallet
).forEach { createItem(block, it) }
return block
}
private fun signingMethod(): Block {
val block = createBlock(BlockId.SigningMethod)
mutableListOf(
SigningMethod.SignTx,
SigningMethod.SignTxRaw,
SigningMethod.SignValidatedTx,
SigningMethod.SignValidatedTxRaw,
SigningMethod.SignValidatedTxIssuer,
SigningMethod.SignValidatedTxRawIssuer,
SigningMethod.SignExternal
).forEach { createItem(block, it) }
return block
}
private fun signHashExProperties(): Block {
val block = createBlock(BlockId.SignHashExProp)
mutableListOf(
SignHashExProp.PinLessFloorLimit,
SignHashExProp.CryptoExKey,
SignHashExProp.RequireTerminalCertSig,
SignHashExProp.RequireTerminalTxSig,
SignHashExProp.CheckPin3
).forEach { createItem(block, it) }
return block
}
private fun denomination(): Block {
val block = createBlock(BlockId.Denomination)
mutableListOf(
Denomination.WriteOnPersonalize,
Denomination.Denomination
).forEach { createItem(block, it) }
return block
}
private fun token(): Block {
val block = createBlock(BlockId.Token)
mutableListOf(
Token.ItsToken,
Token.Symbol,
Token.ContractAddress,
Token.Decimal
).forEach { createItem(block, it) }
return block
}
private fun productMask(): Block {
val block = createBlock(BlockId.ProdMask)
mutableListOf(
ProductMask.Note,
ProductMask.Tag,
ProductMask.CardId
).forEach { createItem(block, it) }
return block
}
private fun settingsMask(): Block {
val block = createBlock(BlockId.SettingsMask)
mutableListOf(
SettingsMask.IsReusable,
SettingsMask.NeedActivation,
SettingsMask.ForbidPurge,
SettingsMask.AllowSelectBlockchain,
SettingsMask.UseBlock,
SettingsMask.OneApdu,
SettingsMask.UseCvc,
SettingsMask.AllowSwapPin,
SettingsMask.AllowSwapPin2,
SettingsMask.ForbidDefaultPin,
SettingsMask.SmartSecurityDelay,
SettingsMask.ProtectIssuerDataAgainstReplay,
SettingsMask.SkipSecurityDelayIfValidated,
SettingsMask.SkipPin2CvcIfValidated,
SettingsMask.SkipSecurityDelayOnLinkedTerminal,
SettingsMask.RestrictOverwriteExtraIssuerData
).forEach { createItem(block, it) }
return block
}
private fun settingsMaskProtocolEnc(): Block {
val block = createBlock(BlockId.SettingsMaskProtocolEnc)
mutableListOf(
SettingsMaskProtocolEnc.AllowUnencrypted,
SettingsMaskProtocolEnc.AllowStaticEncryption
).forEach { createItem(block, it) }
return block
}
private fun settingsMaskNdef(): Block {
val block = createBlock(BlockId.SettingsMaskNdef)
mutableListOf(
SettingsMaskNdef.UseNdef,
SettingsMaskNdef.DynamicNdef,
SettingsMaskNdef.DisablePrecomputedNdef,
SettingsMaskNdef.Aar,
SettingsMaskNdef.AarCustom
).forEach { createItem(block, it) }
return block
}
private fun pins(): Block {
val block = createBlock(BlockId.Pins)
mutableListOf(Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, Pins.PauseBeforePin2)
.forEach { createItem(block, it) }
return block
}
private fun createBlock(id: Id): ListItemBlock {
return ListItemBlock(id).apply { addItem(TextItem(id)) }
}
private fun addPayload(block: Block, from: PersonalizeConfig) {
block.payload[PayloadKey.incomingJson] = from
}
private fun createItem(block: ListItemBlock, id: Id) {
val holder = associations.get(id) ?: return
val item = when {
IdItemHelper.blockIdList.contains(id) -> TextItem(id, holder.get() as? String)
IdItemHelper.listItemList.contains(id) -> ListItem(id, holder.list as List<KeyValue>, holder.get())
IdItemHelper.boolList.contains(id) -> BoolItem(id, holder.get() as? Boolean)
IdItemHelper.editTextList.contains(id) -> EditTextItem(id, holder.get() as? String)
IdItemHelper.numberList.contains(id) -> NumberItem(id, holder.get() as? Number)
else -> ListItemBlock(Additional.UNDEFINED)
}
block.addItem(item)
}
fun toConfig(blockList: List<Block>, defaultConfig: PersonalizeConfig): PersonalizeConfig {
return valueMapper.mapOnObject(blockList, defaultConfig)
}
fun createCardConfig(applyConfig: PersonalizeConfig): CardConfig {
val signingMethod = com.tangem.commands.SigningMethod.build(
signHash = applyConfig.SigningMethod0,
signRaw = applyConfig.SigningMethod1,
signHashValidatedByIssuer = applyConfig.SigningMethod2,
signRawValidatedByIssuer = applyConfig.SigningMethod3,
signHashValidatedByIssuerAndWriteIssuerData = applyConfig.SigningMethod4,
signRawValidatedByIssuerAndWriteIssuerData = applyConfig.SigningMethod5,
signPos = applyConfig.SigningMethod6
)
val isNote = applyConfig.cardData.product_note
val isTag = applyConfig.cardData.product_tag
val isIdCard = applyConfig.cardData.product_id_card
val productMaskBuilder = ProductMaskBuilder()
if (isNote) productMaskBuilder.add(com.tangem.commands.ProductMask.note)
if (isTag) productMaskBuilder.add(com.tangem.commands.ProductMask.tag)
if (isIdCard) productMaskBuilder.add(com.tangem.commands.ProductMask.idCard)
val productMask = productMaskBuilder.build()
var tokenSymbol: String? = null
var tokenContractAddress: String? = null
var tokenDecimal: Int? = null
if (applyConfig.itsToken) {
tokenSymbol = applyConfig.symbol
tokenContractAddress = applyConfig.contractAddress
tokenDecimal = applyConfig.decimal.toInt()
}
val blockchain = if (applyConfig.blockchain.isNotEmpty()) applyConfig.blockchain else applyConfig.blockchainCustom
val cardData = CardData(
blockchainName = blockchain,
batchId = applyConfig.batchId,
productMask = productMask,
tokenSymbol = tokenSymbol,
tokenContractAddress = tokenContractAddress,
tokenDecimal = tokenDecimal,
issuerName = null,
manufactureDateTime = Calendar.getInstance().time,
manufacturerSignature = null)
val ndefs = mutableListOf<NdefRecord>()
when (applyConfig.aar) {
"None" -> null
"--- CUSTOM ---" -> NdefRecord(NdefRecord.Type.AAR, applyConfig.aarCustom)
else -> NdefRecord(NdefRecord.Type.AAR, applyConfig.aar)
}?.let { ndefs.add(it) }
return CardConfig(
"Tangem",
"Tangem Test",
applyConfig.series,
applyConfig.startNumber,
1000,
applyConfig.PIN,
applyConfig.PIN2,
applyConfig.PIN3,
applyConfig.hexCrExKey,
applyConfig.CVC,
applyConfig.pauseBeforePIN2.toInt(),
applyConfig.smartSecurityDelay,
EllipticCurve.byName(applyConfig.curveID) ?: EllipticCurve.Secp256k1,
signingMethod,
applyConfig.MaxSignatures.toInt(),
applyConfig.isReusable,
applyConfig.allowSwapPIN,
applyConfig.allowSwapPIN2,
applyConfig.useActivation,
applyConfig.useCVC,
applyConfig.useNDEF,
applyConfig.useDynamicNDEF,
applyConfig.oneApdu,
applyConfig.useBlock,
applyConfig.allowSelectBlockchain,
applyConfig.forbidPurgeWallet,
applyConfig.protocolAllowUnencrypted,
applyConfig.protocolAllowStaticEncryption,
applyConfig.protectIssuerDataAgainstReplay,
applyConfig.forbidDefaultPIN,
applyConfig.disablePrecomputedNDEF,
applyConfig.skipSecurityDelayIfValidatedByIssuer,
applyConfig.skipCheckPIN2andCVCIfValidatedByIssuer,
applyConfig.skipSecurityDelayIfValidatedByLinkedTerminal,
applyConfig.restrictOverwriteIssuerDataEx,
applyConfig.requireTerminalTxSignature,
applyConfig.requireTerminalCertSignature,
applyConfig.checkPIN3onCard,
applyConfig.createWallet,
cardData,
ndefs
)
}
}
class IdItemHelper {
companion object {
val blockIdList = mutableListOf<com.tangem.tangemtest.ucase.variants.personalize.BlockId>(
BlockId.CardNumber, BlockId.Common, BlockId.SigningMethod, BlockId.SignHashExProp, BlockId.Denomination,
BlockId.Token, BlockId.ProdMask, BlockId.SettingsMask, BlockId.SettingsMaskProtocolEnc,
BlockId.SettingsMaskNdef, BlockId.Pins
)
val listItemList = mutableListOf(Common.Curve, Common.Blockchain, SettingsMaskNdef.Aar, Pins.PauseBeforePin2)
val boolList = mutableListOf(
Common.CreateWallet, SigningMethod.SignTx, SigningMethod.SignTxRaw, SigningMethod.SignValidatedTx,
SigningMethod.SignValidatedTxRaw, SigningMethod.SignValidatedTxIssuer,
SigningMethod.SignValidatedTxRawIssuer, SigningMethod.SignExternal, SignHashExProp.RequireTerminalCertSig,
SignHashExProp.RequireTerminalTxSig, SignHashExProp.CheckPin3, Denomination.WriteOnPersonalize, Token.ItsToken,
ProductMask.Note, ProductMask.Tag, ProductMask.CardId, SettingsMask.IsReusable, SettingsMask.NeedActivation,
SettingsMask.ForbidPurge, SettingsMask.AllowSelectBlockchain, SettingsMask.UseBlock, SettingsMask.OneApdu,
SettingsMask.UseCvc, SettingsMask.AllowSwapPin, SettingsMask.AllowSwapPin2, SettingsMask.ForbidDefaultPin,
SettingsMask.SmartSecurityDelay, SettingsMask.ProtectIssuerDataAgainstReplay,
SettingsMask.SkipSecurityDelayIfValidated, SettingsMask.SkipPin2CvcIfValidated,
SettingsMask.SkipSecurityDelayOnLinkedTerminal, SettingsMask.RestrictOverwriteExtraIssuerData,
SettingsMaskProtocolEnc.AllowUnencrypted, SettingsMaskProtocolEnc.AllowStaticEncryption,
SettingsMaskNdef.UseNdef, SettingsMaskNdef.DynamicNdef, SettingsMaskNdef.DisablePrecomputedNdef
)
val editTextList = mutableListOf(
CardNumber.Series, CardNumber.BatchId, Common.BlockchainCustom, SignHashExProp.CryptoExKey, Token.Symbol,
Token.ContractAddress, Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, SettingsMaskNdef.AarCustom
)
val numberList = mutableListOf(
CardNumber.Number, Common.MaxSignatures, SignHashExProp.PinLessFloorLimit, Denomination.Denomination, Token.Decimal
)
}
}
class JsonTails(
val count: Int,
val numberFormat: String,
val issuerData: Any?,
val releaseVersion: Boolean,
val issuerName: String
)
}

View file

@ -0,0 +1,38 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo
import com.tangem.tangemtest.ucase.variants.personalize.*
class ItemTypes {
val blockIdList = mutableListOf(
BlockId.CardNumber, BlockId.Common, BlockId.SigningMethod, BlockId.SignHashExProp, BlockId.Denomination,
BlockId.Token, BlockId.ProdMask, BlockId.SettingsMask, BlockId.SettingsMaskProtocolEnc,
BlockId.SettingsMaskNdef, BlockId.Pins
)
val listItemList = mutableListOf(Common.Curve, Common.Blockchain, SettingsMaskNdef.Aar, Pins.PauseBeforePin2)
val boolList = mutableListOf(
Common.CreateWallet, SigningMethod.SignTx, SigningMethod.SignTxRaw, SigningMethod.SignValidatedTx,
SigningMethod.SignValidatedTxRaw, SigningMethod.SignValidatedTxIssuer,
SigningMethod.SignValidatedTxRawIssuer, SigningMethod.SignExternal, SignHashExProp.RequireTerminalCertSig,
SignHashExProp.RequireTerminalTxSig, SignHashExProp.CheckPin3, Denomination.WriteOnPersonalize, Token.ItsToken,
ProductMask.Note, ProductMask.Tag, ProductMask.CardId, SettingsMask.IsReusable, SettingsMask.NeedActivation,
SettingsMask.ForbidPurge, SettingsMask.AllowSelectBlockchain, SettingsMask.UseBlock, SettingsMask.OneApdu,
SettingsMask.UseCvc, SettingsMask.AllowSwapPin, SettingsMask.AllowSwapPin2, SettingsMask.ForbidDefaultPin,
SettingsMask.SmartSecurityDelay, SettingsMask.ProtectIssuerDataAgainstReplay,
SettingsMask.SkipSecurityDelayIfValidated, SettingsMask.SkipPin2CvcIfValidated,
SettingsMask.SkipSecurityDelayOnLinkedTerminal, SettingsMask.RestrictOverwriteExtraIssuerData,
SettingsMaskProtocolEnc.AllowUnencrypted, SettingsMaskProtocolEnc.AllowStaticEncryption,
SettingsMaskNdef.UseNdef, SettingsMaskNdef.DynamicNdef, SettingsMaskNdef.DisablePrecomputedNdef
)
val editTextList = mutableListOf(
CardNumber.Series, CardNumber.BatchId, Common.BlockchainCustom, SignHashExProp.CryptoExKey, Token.Symbol,
Token.ContractAddress, Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, SettingsMaskNdef.AarCustom
)
val numberList = mutableListOf(
CardNumber.Number, Common.MaxSignatures, SignHashExProp.PinLessFloorLimit, Denomination.Denomination, Token.Decimal
)
}

View file

@ -1,45 +1,44 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter
package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.abstraction.BaseItem
import com.tangem.tangemtest._arch.structure.abstraction.Block
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ItemsToModel
import com.tangem.tangemtest._arch.structure.impl.KeyValue
import com.tangem.tangemtest._arch.structure.impl.ListValueWrapper
import com.tangem.tangemtest.ucase.variants.personalize.*
import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizeConfigValuesHolder
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import ru.dev.gbixahue.eu4d.lib.android.global.log.Log
/**
[REDACTED_AUTHOR]
*/
class ValueMapper {
private val default: IdToValueAssociations = IdToValueAssociations()
private val updatedByItemList: IdToValueAssociations = IdToValueAssociations()
class ItemsToPersonalizeConfig : ItemsToModel<PersonalizeConfig> {
protected val valuesHolder = PersonalizeConfigValuesHolder()
fun mapOnObject(itemList: List<Item>, defaultConfig: PersonalizeConfig): PersonalizeConfig {
default.init(defaultConfig)
updatedByItemList.init(defaultConfig)
startMapping(itemList)
return createConfig()
override fun convert(from: List<Item>, default: PersonalizeConfig): PersonalizeConfig {
valuesHolder.init(default)
mapListItems(from)
return createModel()
}
private fun startMapping(itemList: List<Item>) {
itemList.forEach { item -> mapItem(item) }
private fun mapListItems(itemList: List<Item>) {
itemList.forEach { item -> mapItemToHolder(item) }
}
private fun mapItem(item: Item) {
private fun mapItemToHolder(item: Item) {
when (item) {
is Block -> startMapping(item.itemList)
is Block -> mapListItems(item.itemList)
is BaseItem<*> -> {
val value = updatedByItemList.get(item.id) ?: return
value.set(item.viewModel.data)
val defValue = valuesHolder.get(item.id) ?: return
defValue.set(item.viewModel.data)
}
}
}
private fun createConfig(): PersonalizeConfig {
private fun createModel(): PersonalizeConfig {
val export = PersonalizeConfig()
export.series = getTyped(CardNumber.Series)
export.startNumber = getTyped(CardNumber.Number)
@ -101,12 +100,12 @@ class ValueMapper {
}
private inline fun <reified Type> getTyped(id: Id): Type {
return getTypedBy<Type>(updatedByItemList, id) ?: getTypedBy<Type>(default, id)!!
return getTypedBy<Type>(valuesHolder, id)!!
}
private inline fun <reified Type> getTypedBy(associations: IdToValueAssociations, id: Id): Type? {
private inline fun <reified Type> getTypedBy(holder: PersonalizeConfigValuesHolder, id: Id): Type? {
Log.d(this, "getTyped for id: $id")
var typedValue = associations.get(id)?.get()
var typedValue = holder.get(id)?.get()
typedValue = when (typedValue) {
is ListValueWrapper -> (typedValue.selectedItem as KeyValue).value as Type

View file

@ -0,0 +1,296 @@
package com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo
import com.tangem.commands.CardData
import com.tangem.commands.EllipticCurve
import com.tangem.commands.ProductMaskBuilder
import com.tangem.commands.personalization.entities.CardConfig
import com.tangem.commands.personalization.entities.NdefRecord
import com.tangem.tangemtest._arch.structure.Additional
import com.tangem.tangemtest._arch.structure.Id
import com.tangem.tangemtest._arch.structure.abstraction.Block
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._arch.structure.abstraction.ListItemBlock
import com.tangem.tangemtest._arch.structure.abstraction.ModelToItems
import com.tangem.tangemtest._arch.structure.impl.*
import com.tangem.tangemtest.ucase.domain.paramsManager.PayloadKey
import com.tangem.tangemtest.ucase.variants.personalize.*
import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizeConfigValuesHolder
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
import ru.dev.gbixahue.eu4d.lib.kotlin.common.Converter
import java.util.*
/**
[REDACTED_AUTHOR]
*/
class PersonalizeConfigToItem : ModelToItems<PersonalizeConfig> {
private val valuesHolder = PersonalizeConfigValuesHolder()
private val idIdentification = ItemTypes()
override fun convert(from: PersonalizeConfig): List<Item> {
valuesHolder.init(from)
val blocList = mutableListOf<Block>()
blocList.add(cardNumber())
blocList.add(common())
blocList.add(signingMethod())
blocList.add(signHashExProperties())
blocList.add(denomination())
blocList.add(token())
blocList.add(productMask())
blocList.add(settingsMask())
blocList.add(settingsMaskProtocolEnc())
blocList.add(settingsMaskNdef())
blocList.add(pins())
val payloadBlock = ListItemBlock(Additional.JSON_TAILS)
addPayload(payloadBlock, from)
blocList.add(payloadBlock)
return blocList
}
private fun cardNumber(): Block {
val block = createBlock(BlockId.CardNumber)
mutableListOf(
CardNumber.Series,
CardNumber.Number,
CardNumber.BatchId
).forEach { createItem(block, it as Id) }
return block
}
private fun common(): Block {
val block = createBlock(BlockId.Common)
mutableListOf(
Common.Curve,
Common.Blockchain,
Common.BlockchainCustom,
Common.MaxSignatures,
Common.CreateWallet
).forEach { createItem(block, it) }
return block
}
private fun signingMethod(): Block {
val block = createBlock(BlockId.SigningMethod)
mutableListOf(
SigningMethod.SignTx,
SigningMethod.SignTxRaw,
SigningMethod.SignValidatedTx,
SigningMethod.SignValidatedTxRaw,
SigningMethod.SignValidatedTxIssuer,
SigningMethod.SignValidatedTxRawIssuer,
SigningMethod.SignExternal
).forEach { createItem(block, it) }
return block
}
private fun signHashExProperties(): Block {
val block = createBlock(BlockId.SignHashExProp)
mutableListOf(
SignHashExProp.PinLessFloorLimit,
SignHashExProp.CryptoExKey,
SignHashExProp.RequireTerminalCertSig,
SignHashExProp.RequireTerminalTxSig,
SignHashExProp.CheckPin3
).forEach { createItem(block, it) }
return block
}
private fun denomination(): Block {
val block = createBlock(BlockId.Denomination)
mutableListOf(
Denomination.WriteOnPersonalize,
Denomination.Denomination
).forEach { createItem(block, it) }
return block
}
private fun token(): Block {
val block = createBlock(BlockId.Token)
mutableListOf(
Token.ItsToken,
Token.Symbol,
Token.ContractAddress,
Token.Decimal
).forEach { createItem(block, it) }
return block
}
private fun productMask(): Block {
val block = createBlock(BlockId.ProdMask)
mutableListOf(
ProductMask.Note,
ProductMask.Tag,
ProductMask.CardId
).forEach { createItem(block, it) }
return block
}
private fun settingsMask(): Block {
val block = createBlock(BlockId.SettingsMask)
mutableListOf(
SettingsMask.IsReusable,
SettingsMask.NeedActivation,
SettingsMask.ForbidPurge,
SettingsMask.AllowSelectBlockchain,
SettingsMask.UseBlock,
SettingsMask.OneApdu,
SettingsMask.UseCvc,
SettingsMask.AllowSwapPin,
SettingsMask.AllowSwapPin2,
SettingsMask.ForbidDefaultPin,
SettingsMask.SmartSecurityDelay,
SettingsMask.ProtectIssuerDataAgainstReplay,
SettingsMask.SkipSecurityDelayIfValidated,
SettingsMask.SkipPin2CvcIfValidated,
SettingsMask.SkipSecurityDelayOnLinkedTerminal,
SettingsMask.RestrictOverwriteExtraIssuerData
).forEach { createItem(block, it) }
return block
}
private fun settingsMaskProtocolEnc(): Block {
val block = createBlock(BlockId.SettingsMaskProtocolEnc)
mutableListOf(
SettingsMaskProtocolEnc.AllowUnencrypted,
SettingsMaskProtocolEnc.AllowStaticEncryption
).forEach { createItem(block, it) }
return block
}
private fun settingsMaskNdef(): Block {
val block = createBlock(BlockId.SettingsMaskNdef)
mutableListOf(
SettingsMaskNdef.UseNdef,
SettingsMaskNdef.DynamicNdef,
SettingsMaskNdef.DisablePrecomputedNdef,
SettingsMaskNdef.Aar,
SettingsMaskNdef.AarCustom
).forEach { createItem(block, it) }
return block
}
private fun pins(): Block {
val block = createBlock(BlockId.Pins)
mutableListOf(Pins.Pin, Pins.Pin2, Pins.Pin3, Pins.Cvc, Pins.PauseBeforePin2)
.forEach { createItem(block, it) }
return block
}
private fun createBlock(id: Id): ListItemBlock {
return ListItemBlock(id).apply { addItem(TextItem(id)) }
}
private fun addPayload(block: Block, from: PersonalizeConfig) {
block.payload[PayloadKey.incomingJson] = from
}
private fun createItem(block: ListItemBlock, id: Id) {
val holder = valuesHolder.get(id) ?: return
val item = when {
idIdentification.blockIdList.contains(id) -> TextItem(id, holder.get() as? String)
idIdentification.listItemList.contains(id) -> ListItem(id, holder.list as List<KeyValue>, holder.get())
idIdentification.boolList.contains(id) -> BoolItem(id, holder.get() as? Boolean)
idIdentification.editTextList.contains(id) -> EditTextItem(id, holder.get() as? String)
idIdentification.numberList.contains(id) -> NumberItem(id, holder.get() as? Number)
else -> ListItemBlock(Additional.UNDEFINED)
}
block.addItem(item)
}
}
class PersonalizeConfigToCardConfig : Converter<PersonalizeConfig, CardConfig> {
override fun convert(from: PersonalizeConfig): CardConfig {
val signingMethod = com.tangem.commands.SigningMethod.build(
signHash = from.SigningMethod0,
signRaw = from.SigningMethod1,
signHashValidatedByIssuer = from.SigningMethod2,
signRawValidatedByIssuer = from.SigningMethod3,
signHashValidatedByIssuerAndWriteIssuerData = from.SigningMethod4,
signRawValidatedByIssuerAndWriteIssuerData = from.SigningMethod5,
signPos = from.SigningMethod6
)
val isNote = from.cardData.product_note
val isTag = from.cardData.product_tag
val isIdCard = from.cardData.product_id_card
val productMaskBuilder = ProductMaskBuilder()
if (isNote) productMaskBuilder.add(com.tangem.commands.ProductMask.note)
if (isTag) productMaskBuilder.add(com.tangem.commands.ProductMask.tag)
if (isIdCard) productMaskBuilder.add(com.tangem.commands.ProductMask.idCard)
val productMask = productMaskBuilder.build()
var tokenSymbol: String? = null
var tokenContractAddress: String? = null
var tokenDecimal: Int? = null
if (from.itsToken) {
tokenSymbol = from.symbol
tokenContractAddress = from.contractAddress
tokenDecimal = from.decimal.toInt()
}
val blockchain = if (from.blockchain.isNotEmpty()) from.blockchain else from.blockchainCustom
val cardData = CardData(
blockchainName = blockchain,
batchId = from.batchId,
productMask = productMask,
tokenSymbol = tokenSymbol,
tokenContractAddress = tokenContractAddress,
tokenDecimal = tokenDecimal,
issuerName = null,
manufactureDateTime = Calendar.getInstance().time,
manufacturerSignature = null)
val ndefs = mutableListOf<NdefRecord>()
when (from.aar) {
"None" -> null
"--- CUSTOM ---" -> NdefRecord(NdefRecord.Type.AAR, from.aarCustom)
else -> NdefRecord(NdefRecord.Type.AAR, from.aar)
}?.let { ndefs.add(it) }
return CardConfig(
"Tangem",
"Tangem Test",
from.series,
from.startNumber,
1000,
from.PIN,
from.PIN2,
from.PIN3,
from.hexCrExKey,
from.CVC,
from.pauseBeforePIN2.toInt(),
from.smartSecurityDelay,
EllipticCurve.byName(from.curveID) ?: EllipticCurve.Secp256k1,
signingMethod,
from.MaxSignatures.toInt(),
from.isReusable,
from.allowSwapPIN,
from.allowSwapPIN2,
from.useActivation,
from.useCVC,
from.useNDEF,
from.useDynamicNDEF,
from.oneApdu,
from.useBlock,
from.allowSelectBlockchain,
from.forbidPurgeWallet,
from.protocolAllowUnencrypted,
from.protocolAllowStaticEncryption,
from.protectIssuerDataAgainstReplay,
from.forbidDefaultPIN,
from.disablePrecomputedNDEF,
from.skipSecurityDelayIfValidatedByIssuer,
from.skipCheckPIN2andCVCIfValidatedByIssuer,
from.skipSecurityDelayIfValidatedByLinkedTerminal,
from.restrictOverwriteIssuerDataEx,
from.requireTerminalTxSignature,
from.requireTerminalCertSignature,
from.checkPIN3onCard,
from.createWallet,
cardData,
ndefs
)
}
}

View file

@ -14,7 +14,7 @@ import com.google.android.material.snackbar.Snackbar
import com.tangem.CardManager
import com.tangem.tangem_sdk_new.extensions.init
import com.tangem.tangemtest.R
import com.tangem.tangemtest._arch.structure.abstraction.Block
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest._main.MainViewModel
import com.tangem.tangemtest.ucase.domain.paramsManager.ItemsManager
import com.tangem.tangemtest.ucase.domain.paramsManager.ParamsManagerFactory
@ -52,7 +52,7 @@ class PersonalizeFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val blockList = mutableListOf<Block>()
val blockList = mutableListOf<Item>()
personalizeVM.ldBlockList.observe(viewLifecycleOwner, Observer { list ->
blockList.clear()
blockList.addAll(list)

View file

@ -8,7 +8,9 @@ import com.google.gson.Gson
import com.tangem.commands.personalization.entities.CardConfig
import com.tangem.tangemtest._arch.structure.abstraction.BaseItem
import com.tangem.tangemtest._arch.structure.abstraction.Block
import com.tangem.tangemtest._arch.structure.abstraction.Item
import com.tangem.tangemtest.ucase.variants.personalize.converter.PersonalizeConfigConverter
import com.tangem.tangemtest.ucase.variants.personalize.converter.fromTo.PersonalizeConfigToCardConfig
import com.tangem.tangemtest.ucase.variants.personalize.dto.PersonalizeConfig
/**
@ -20,20 +22,21 @@ class PersonalizeViewModelFactory(private val config: PersonalizeConfig) : ViewM
class PersonalizeViewModel(private val config: PersonalizeConfig) : ViewModel() {
val ldBlockList: MutableLiveData<List<Block>> by lazy { MutableLiveData(initBlockList()) }
val ldBlockList: MutableLiveData<List<Item>> by lazy { MutableLiveData(initBlockList()) }
private val configConverter = PersonalizeConfigConverter()
private fun initBlockList(): List<Block> = createBlocksFromConfig(config)
private fun initBlockList(): List<Item> = createBlocksFromConfig(config)
fun createBlocksFromConfig(config: PersonalizeConfig): List<Block> {
return PersonalizeConfigConverter().toBlock(config)
fun createBlocksFromConfig(config: PersonalizeConfig): List<Item> {
return configConverter.convert(config)
}
fun createConfig(blocList: List<Block>): PersonalizeConfig {
return PersonalizeConfigConverter().toConfig(blocList, PersonalizeConfig())
fun createConfig(blocList: List<Item>): PersonalizeConfig {
return configConverter.convert(blocList, PersonalizeConfig())
}
fun createCardConfig(config: PersonalizeConfig): CardConfig {
return PersonalizeConfigConverter().createCardConfig(config)
return PersonalizeConfigToCardConfig().convert(config)
}
fun convertToJson(config: PersonalizeConfig): String {
@ -41,11 +44,19 @@ class PersonalizeViewModel(private val config: PersonalizeConfig) : ViewModel()
}
fun toggleDescriptionVisibility(state: Boolean) {
ldBlockList.value?.forEach { block ->
block.itemList.forEach { item ->
val vm = item as? BaseItem<*> ?: return@forEach
vm.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
ldBlockList.value?.forEach { item ->
when(item) {
is BaseItem<*> -> {
item.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
is Block -> {
item.itemList.forEach { blockItem ->
val vm = blockItem as? BaseItem<*> ?: return@forEach
vm.viewModel.viewState.descriptionVisibility = if (state) View.VISIBLE else View.GONE
}
}
}
}
}
}