1
0
Форкнуть 0

Integrate rooms database to store long form id

This commit is contained in:
nithyaganeshng 2020-04-04 15:27:53 -07:00
Родитель 3467578cb7
Коммит a263285a0d
12 изменённых файлов: 96 добавлений и 31 удалений

Просмотреть файл

@ -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"
}