Integrate rooms database to store long form id
This commit is contained in:
Родитель
3467578cb7
Коммит
a263285a0d
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.microsoft.portableIdentity.sdk
|
|||
import android.content.Context
|
||||
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.microsoft.portableIdentity.sdk.PortableIdentitySdk.identityManager
|
||||
import com.microsoft.portableIdentity.sdk.crypto.CryptoOperations
|
||||
import com.microsoft.portableIdentity.sdk.crypto.keyStore.AndroidKeyStore
|
||||
import com.microsoft.portableIdentity.sdk.crypto.models.webCryptoApi.SubtleCrypto
|
||||
|
@ -28,7 +27,6 @@ class IdentityManagerInstrumentedTest {
|
|||
private val recoveryKeyReference: String
|
||||
private val registrar: Registrar
|
||||
private val resolver: Resolver
|
||||
// private val identityManager: IdentityManager
|
||||
private val androidSubtle: SubtleCrypto
|
||||
private val ecSubtle: EllipticCurveSubtleCrypto
|
||||
private val cryptoOperations: CryptoOperations
|
||||
|
@ -49,7 +47,6 @@ class IdentityManagerInstrumentedTest {
|
|||
subtleCrypto = SubtleCryptoMapItem(ecSubtle, SubtleCryptoScope.All)
|
||||
)
|
||||
PortableIdentitySdk.init(context)
|
||||
// identityManager = IdentityManager(cryptoOperations, resolver, registrar, signatureKeyReference, encryptionKeyReference, recoveryKeyReference)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -97,7 +97,7 @@ class SidetreeRegistrarInstrumentedTest {
|
|||
}
|
||||
}*/
|
||||
|
||||
@Test
|
||||
/* @Test
|
||||
fun idCreationTest() {
|
||||
val alias = Base64Url.encode(Random.nextBytes(5))
|
||||
runBlocking {
|
||||
|
@ -112,5 +112,5 @@ class SidetreeRegistrarInstrumentedTest {
|
|||
)
|
||||
assertThat(id).isNotNull
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
|
@ -9,17 +9,20 @@ import com.microsoft.portableIdentity.sdk.crypto.CryptoOperations
|
|||
import com.microsoft.portableIdentity.sdk.crypto.keys.KeyType
|
||||
import com.microsoft.portableIdentity.sdk.crypto.keys.SecretKey
|
||||
import com.microsoft.portableIdentity.sdk.crypto.models.webCryptoApi.JsonWebKey
|
||||
//import com.microsoft.portableIdentity.sdk.identifier.response.IdentifierResponse
|
||||
import com.microsoft.portableIdentity.sdk.identifier.Identifier
|
||||
import com.microsoft.portableIdentity.sdk.identifier.IdentifierToken
|
||||
import com.microsoft.portableIdentity.sdk.identifier.LongformIdentifier
|
||||
import com.microsoft.portableIdentity.sdk.identifier.PayloadGenerator
|
||||
import com.microsoft.portableIdentity.sdk.identifier.models.PatchData
|
||||
import com.microsoft.portableIdentity.sdk.registrars.NullRegistrar
|
||||
//import com.microsoft.portableIdentity.sdk.identifier.response.IdentifierResponseToken
|
||||
import com.microsoft.portableIdentity.sdk.registrars.Registrar
|
||||
import com.microsoft.portableIdentity.sdk.registrars.RegistrationDocument
|
||||
import com.microsoft.portableIdentity.sdk.repository.PortableIdentityRepository
|
||||
import com.microsoft.portableIdentity.sdk.resolvers.Resolver
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Base64Url
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Constants.INITIAL_STATE_LONGFORM
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Constants.METHOD_NAME
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Constants.IDENTITY_SECRET_KEY_NAME
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Serializer
|
||||
import com.microsoft.portableIdentity.sdk.utilities.byteArrayToString
|
||||
import kotlinx.coroutines.*
|
||||
|
@ -45,13 +48,12 @@ class IdentityManager @Inject constructor(
|
|||
@Named("resolverUrl") resolverUrl: String
|
||||
) {
|
||||
|
||||
private val didSecretName = "did.identifier"
|
||||
private val url = resolverUrl
|
||||
|
||||
val did: Identifier by lazy { initLongFormDid() }
|
||||
// val did = initLongFormDid()
|
||||
|
||||
suspend fun registerPortableIdentity(url: String): Identifier {
|
||||
private suspend fun registerPortableIdentity(url: String): Identifier {
|
||||
val alias = Base64Url.encode(Random.nextBytes(16))
|
||||
val personaEncKeyRef = "$alias.$encryptionKeyReference"
|
||||
val personaSigKeyRef = "$alias.$signatureKeyReference"
|
||||
|
@ -65,10 +67,15 @@ class IdentityManager @Inject constructor(
|
|||
val registrationDocumentEncoded = payloadGenerator.generateCreatePayload(alias)
|
||||
val registrationDocument = Serializer.parse(RegistrationDocument.serializer(), byteArrayToString(Base64Url.decode(registrationDocumentEncoded)))
|
||||
val uniqueSuffix = payloadGenerator.computeUniqueSuffix(registrationDocument.suffixData)
|
||||
val portableIdentity = "did:ion:test:$uniqueSuffix"
|
||||
val identifier = "$portableIdentity?-ion-initial-state=$registrationDocumentEncoded"
|
||||
val portableIdentity = "did:$METHOD_NAME:test:$uniqueSuffix"
|
||||
val identifier = "$portableIdentity?$INITIAL_STATE_LONGFORM=$registrationDocumentEncoded"
|
||||
val resolveUrl = "$url/$identifier"
|
||||
val identifierDocument = identityRepository.resolveIdentifier(resolveUrl)
|
||||
val patchDataJson = byteArrayToString(Base64Url.decode(registrationDocument.patchData))
|
||||
val nextUpdateCommitmentHash =Serializer.parse(PatchData.serializer(), patchDataJson).nextUpdateCommitmentHash
|
||||
val longformIdentifier = LongformIdentifier(portableIdentity, alias, nextUpdateCommitmentHash, identifierDocument!!)
|
||||
identityRepository.insert(longformIdentifier)
|
||||
val saved = identityRepository.query(portableIdentity)
|
||||
return Identifier(
|
||||
identifierDocument!!,
|
||||
personaSigKeyRef,
|
||||
|
@ -104,22 +111,22 @@ class IdentityManager @Inject constructor(
|
|||
}*/
|
||||
|
||||
private fun initLongFormDid(): Identifier {
|
||||
val did = if (cryptoOperations.keyStore.list().containsKey(didSecretName)) {
|
||||
val did = if (cryptoOperations.keyStore.list().containsKey(IDENTITY_SECRET_KEY_NAME)) {
|
||||
println("Identifier found, deserializing")
|
||||
val keySerialized = cryptoOperations.keyStore.getSecretKey(didSecretName).getKey()
|
||||
val keySerialized = cryptoOperations.keyStore.getSecretKey(IDENTITY_SECRET_KEY_NAME).getKey()
|
||||
deserializeIdentifier(keySerialized.k!!)
|
||||
} else {
|
||||
println("No identifier found, registering new DID")
|
||||
val identifier = registerNewLongFormDid()
|
||||
val identifier = registerPortableIdentity()
|
||||
val key = SecretKey(
|
||||
JsonWebKey(
|
||||
kty = KeyType.Octets.value,
|
||||
kid = "#$didSecretName.1",
|
||||
kid = "#$IDENTITY_SECRET_KEY_NAME.1",
|
||||
//TODO: Save only signing key or recovery key as well?
|
||||
k = identifier.serialize()
|
||||
)
|
||||
)
|
||||
cryptoOperations.keyStore.save(didSecretName, key)
|
||||
cryptoOperations.keyStore.save(IDENTITY_SECRET_KEY_NAME, key)
|
||||
identifier
|
||||
}
|
||||
println("Using identifier ${did.document.id}")
|
||||
|
@ -137,13 +144,13 @@ class IdentityManager @Inject constructor(
|
|||
return did!!
|
||||
}*/
|
||||
|
||||
private fun registerNewLongFormDid(): Identifier {
|
||||
private fun registerPortableIdentity(): Identifier {
|
||||
var did: Identifier? = null
|
||||
// TODO: Verify runBlocking is proper here
|
||||
runBlocking {
|
||||
did = createLongFormIdentifier()
|
||||
did = createPortableIdentity()
|
||||
}
|
||||
println("Registered ${did!!.document.id}")
|
||||
println("Created ${did!!.document.id}")
|
||||
return did!!
|
||||
}
|
||||
|
||||
|
@ -153,9 +160,9 @@ class IdentityManager @Inject constructor(
|
|||
}
|
||||
}*/
|
||||
|
||||
fun createLongFormIdentifier(callback: (Identifier) -> Unit) {
|
||||
fun createPortableIdentity(callback: (Identifier) -> Unit) {
|
||||
GlobalScope.launch {
|
||||
callback.invoke(createLongFormIdentifier())
|
||||
callback.invoke(createPortableIdentity())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,13 +179,8 @@ class IdentityManager @Inject constructor(
|
|||
}
|
||||
}*/
|
||||
|
||||
suspend fun createLongFormIdentifier(): Identifier {
|
||||
private suspend fun createPortableIdentity(): Identifier {
|
||||
return withContext(Dispatchers.Default) {
|
||||
/* val alias = Base64Url.encode(Random.nextBytes(16))
|
||||
Identifier.createLongFormIdentifier(
|
||||
alias, cryptoOperations, signatureKeyReference,
|
||||
encryptionKeyReference, recoveryKeyReference, resolver, registrar
|
||||
)*/
|
||||
registerPortableIdentity(url)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class Identifier constructor(
|
|||
) {
|
||||
companion object {
|
||||
// TODO: needs refactoring! Dependency inject this object instead of having this companion etc.
|
||||
suspend fun createLongFormIdentifier(
|
||||
/* suspend fun createLongFormIdentifier(
|
||||
alias: String,
|
||||
cryptoOperations: CryptoOperations,
|
||||
signatureKeyReference: String,
|
||||
|
@ -70,7 +70,7 @@ class Identifier constructor(
|
|||
resolver = resolver,
|
||||
registrar = registrar
|
||||
)
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
fun serialize(): String {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package com.microsoft.portableIdentity.sdk.identifier
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.microsoft.portableIdentity.sdk.identifier.models.document.IdentifierDocument
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Data model to describe a Portable Identity Card.
|
||||
*/
|
||||
@Entity
|
||||
@Serializable
|
||||
data class LongformIdentifier (
|
||||
|
||||
@PrimaryKey
|
||||
val identifier: String,
|
||||
val alias: String,
|
||||
val nextUpdateCommitmentHash: String,
|
||||
val document: IdentifierDocument
|
||||
|
||||
)
|
|
@ -69,6 +69,7 @@ class PayloadGenerator @Inject constructor(
|
|||
return IdentifierDocumentPayload(
|
||||
publicKeys = listOf(
|
||||
IdentifierDocumentPublicKey(
|
||||
//TODO: Look into new restrictions on Sidetree api for id length(20) and characters allowed(only base64url charsets)
|
||||
id = "cIiCWr41",
|
||||
type = LinkedDataKeySpecification.EcdsaSecp256k1Signature2019.values.first(),
|
||||
publicKeyHex = convertCryptoKeyToCompressedHex(Base64.decode(signingKeyJWK.x!!), Base64.decode(signingKeyJWK.y!!))
|
||||
|
@ -76,6 +77,7 @@ class PayloadGenerator @Inject constructor(
|
|||
),
|
||||
serviceEndpoints = listOf(
|
||||
IdentityHubService(
|
||||
//TODO: What should be the default values for these while registering portable identity
|
||||
id = "test",
|
||||
serviceEndpoint = "https://beta.hub.microsoft.com"
|
||||
)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.microsoft.portableIdentity.sdk.repository
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.microsoft.portableIdentity.sdk.identifier.LongformIdentifier
|
||||
import com.microsoft.portableIdentity.sdk.repository.networking.PortableIdentityNetworkOperation
|
||||
import javax.inject.Inject
|
||||
|
||||
|
@ -7,5 +9,11 @@ class PortableIdentityRepository @Inject constructor(
|
|||
database: SdkDatabase,
|
||||
private val identityNetworkOperation: PortableIdentityNetworkOperation
|
||||
) {
|
||||
val portableIdentityDao = database.portableIdentityDao()
|
||||
|
||||
suspend fun resolveIdentifier(url: String/*, identifier: String*/) = identityNetworkOperation.resolveIdentifier(url/*, identifier*/)
|
||||
|
||||
fun insert(longformIdentifier: LongformIdentifier) = portableIdentityDao.insert(longformIdentifier)
|
||||
|
||||
fun query(identifier: String): LongformIdentifier = portableIdentityDao.queryIdentifier(identifier)
|
||||
}
|
|
@ -9,6 +9,7 @@ import androidx.room.TypeConverter
|
|||
import com.microsoft.portableIdentity.sdk.auth.models.contracts.display.DisplayContract
|
||||
import com.microsoft.portableIdentity.sdk.cards.verifiableCredential.VerifiableCredential
|
||||
import com.microsoft.portableIdentity.sdk.cards.verifiableCredential.VerifiableCredentialDescriptor
|
||||
import com.microsoft.portableIdentity.sdk.identifier.models.document.IdentifierDocument
|
||||
import com.microsoft.portableIdentity.sdk.utilities.Serializer
|
||||
|
||||
object RoomConverters {
|
||||
|
@ -28,4 +29,12 @@ object RoomConverters {
|
|||
@TypeConverter
|
||||
@JvmStatic
|
||||
fun stringToVerifiableCredential(serializedVc: String) = Serializer.parse(VerifiableCredential.serializer(), serializedVc)
|
||||
|
||||
@TypeConverter
|
||||
@JvmStatic
|
||||
fun stringToIdentifierDocument(serializedDoc: String) = Serializer.parse(IdentifierDocument.serializer(), serializedDoc)
|
||||
|
||||
@TypeConverter
|
||||
@JvmStatic
|
||||
fun identifierDocumentToString(idDocument: IdentifierDocument) = Serializer.stringify(IdentifierDocument.serializer(), idDocument)
|
||||
}
|
|
@ -11,8 +11,10 @@ import androidx.room.TypeConverters
|
|||
import com.microsoft.portableIdentity.sdk.cards.PortableIdentityCard
|
||||
import com.microsoft.portableIdentity.sdk.cards.deprecated.ClaimObject
|
||||
import com.microsoft.portableIdentity.sdk.cards.deprecated.SerialClaimObject
|
||||
import com.microsoft.portableIdentity.sdk.identifier.LongformIdentifier
|
||||
import com.microsoft.portableIdentity.sdk.repository.dao.ClaimObjectDao
|
||||
import com.microsoft.portableIdentity.sdk.repository.dao.PortableIdentityCardDao
|
||||
import com.microsoft.portableIdentity.sdk.repository.dao.PortableIdentityDao
|
||||
import com.microsoft.portableIdentity.sdk.repository.dao.SerialClaimObjectDao
|
||||
|
||||
/**
|
||||
|
@ -25,7 +27,7 @@ import com.microsoft.portableIdentity.sdk.repository.dao.SerialClaimObjectDao
|
|||
* More info:
|
||||
* https://developer.android.com/topic/libraries/architecture/room
|
||||
*/
|
||||
@Database(entities = [ClaimObject::class, SerialClaimObject::class, PortableIdentityCard::class], version = 1)
|
||||
@Database(entities = [ClaimObject::class, SerialClaimObject::class, PortableIdentityCard::class, LongformIdentifier::class], version = 1)
|
||||
@TypeConverters(RoomConverters::class)
|
||||
abstract class SdkDatabase : RoomDatabase() {
|
||||
abstract fun claimObjectDao(): ClaimObjectDao
|
||||
|
@ -33,4 +35,6 @@ abstract class SdkDatabase : RoomDatabase() {
|
|||
abstract fun serialClaimObjectDao(): SerialClaimObjectDao
|
||||
|
||||
abstract fun cardDao(): PortableIdentityCardDao
|
||||
|
||||
abstract fun portableIdentityDao(): PortableIdentityDao
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.microsoft.portableIdentity.sdk.repository.dao
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Query
|
||||
import com.microsoft.portableIdentity.sdk.identifier.LongformIdentifier
|
||||
|
||||
@Dao
|
||||
interface PortableIdentityDao {
|
||||
|
||||
@Insert
|
||||
fun insert(longformIdentifier: LongformIdentifier)
|
||||
|
||||
@Query("SELECT * FROM LongformIdentifier where identifier = :identifier")
|
||||
fun queryIdentifier(identifier: String): LongformIdentifier
|
||||
}
|
|
@ -22,4 +22,9 @@ object Constants {
|
|||
const val MILLISECONDS_IN_A_SECOND = 1000
|
||||
const val SECONDS_IN_A_MINUTE = 60
|
||||
const val RESPONSE_EXPIRATION_IN_MINUTES = 5
|
||||
|
||||
//Portable Identity Constants
|
||||
const val IDENTITY_SECRET_KEY_NAME = "did.identifier"
|
||||
const val METHOD_NAME = "ion"
|
||||
const val INITIAL_STATE_LONGFORM = "-$METHOD_NAME-initial-state"
|
||||
}
|
Загрузка…
Ссылка в новой задаче