From 1b1a76d4a6f7aafb37539ec3c75041f0ac1fadeb Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:04:06 +0100 Subject: [PATCH 1/7] refactor: remove deprecated JWTTools verify method Please use the variant that requires a resolver param --- .../main/java/me/uport/sdk/jwt/JWTTools.kt | 32 -- .../java/me/uport/sdk/jwt/JWTToolsJVMTest.kt | 301 +----------------- .../java/me/uport/sdk/jwt/TimestampTests.kt | 19 -- 3 files changed, 1 insertion(+), 351 deletions(-) diff --git a/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt b/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt index ef1f43f..6de0cbe 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt @@ -1,7 +1,6 @@ @file:Suppress( "KDocUnresolvedReference", "EXPERIMENTAL_API_USAGE", - "DEPRECATION", "ThrowsCount", "MagicNumber" ) @@ -36,7 +35,6 @@ import me.uport.sdk.universaldid.PublicKeyEntry import me.uport.sdk.universaldid.PublicKeyType.Companion.EcdsaPublicKeySecp256k1 import me.uport.sdk.universaldid.PublicKeyType.Companion.Secp256k1SignatureVerificationKey2018 import me.uport.sdk.universaldid.PublicKeyType.Companion.Secp256k1VerificationKey2018 -import me.uport.sdk.universaldid.UniversalDID import org.kethereum.crypto.toAddress import org.kethereum.extensions.toBigInteger import org.kethereum.model.PUBLIC_KEY_SIZE @@ -207,36 +205,6 @@ class JWTTools( } } - - /** - * Verifies a jwt [token] - * @param token the jwt token to be verified - * @param auth if this param is `true` the public key list that this token is checked against is filtered to the - * entries in the `authentication` entries in the DID document of the issuer of the token. - * @param audience the audience that should be able to verify this token. This is usually a DID but can also be a - * callback URL for situations where the token represents a response or a bearer token. - * @throws InvalidJWTException when the current time is not within the time range of payload `iat` and `exp` - * , when no public key matches are found in the DID document - * , when the `audience` does not match the intended audience (`aud` field) - * @return a [JwtPayload] if the verification is successful and `null` if it fails - */ - @Suppress("DEPRECATION") - @Deprecated( - "Verifying a jwt token using the Universal Resolver is deprecated " + - "in favor of using a local resolver passed in as a method parameter." + - "This will be removed in the next major release.", - ReplaceWith( - """verify(token: String, auth: Boolean = false, audience: String? = null, resolver: DIDResolver)""" - ) - ) - suspend fun verify( - token: String, - auth: Boolean = false, - audience: String? = null - ): JwtPayload { - return verify(token, UniversalDID, auth, audience) - } - /** * Verifies a jwt [token] * @param token the jwt token to be verified diff --git a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt index 617369e..7365215 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt @@ -11,7 +11,6 @@ import assertk.assertions.isInstanceOf import assertk.assertions.isNotNull import assertk.assertions.isTrue import io.mockk.coEvery -import io.mockk.mockkObject import io.mockk.spyk import kotlinx.coroutines.runBlocking import me.uport.sdk.ethrdid.EthrDIDDocument @@ -19,14 +18,10 @@ import me.uport.sdk.ethrdid.EthrDIDNetwork import me.uport.sdk.ethrdid.EthrDIDResolver import me.uport.sdk.jsonrpc.JsonRPC import me.uport.sdk.jwt.JWTUtils.normalizeKnownDID -import me.uport.sdk.jwt.model.JwtPayload import me.uport.sdk.jwt.test.EthrDIDTestHelpers import me.uport.sdk.signer.KPSigner import me.uport.sdk.testhelpers.TestTimeProvider import me.uport.sdk.testhelpers.coAssert -import me.uport.sdk.universaldid.UniversalDID -import me.uport.sdk.uportdid.UportDIDDocument -import me.uport.sdk.uportdid.UportDIDResolver import org.junit.Test class JWTToolsJVMTest { @@ -36,34 +31,6 @@ class JWTToolsJVMTest { "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1MzUwMTY1OTcsImV4cCI6MTUzNTEwMjk5NywiYXVkIjoiZGlkOmV0aHI6MHhhOWUzMjMyYjYxYmRiNjcyNzEyYjlhZTMzMTk1MDY5ZDhkNjUxYzFhIiwidHlwZSI6InNoYXJlUmVzcCIsIm5hZCI6IjJvd2hGdGRtc0VVNVVWMVNCbld0RnZZcHlUcjNqNHd5TmR2Iiwib3duIjp7Im5hbWUiOiJ1UG9ydCBVc2VyIn0sInJlcSI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSkZVekkxTmtzdFVpSjkuZXlKcFlYUWlPakUxTXpVd01UWTFPRGdzSW1WNGNDSTZNVFV6TlRBeE56RTRPQ3dpY21WeGRXVnpkR1ZrSWpwYkltNWhiV1VpTENKd2FHOXVaU0lzSW1OdmRXNTBjbmtpWFN3aWNHVnliV2x6YzJsdmJuTWlPbHNpYm05MGFXWnBZMkYwYVc5dWN5SmRMQ0pqWVd4c1ltRmpheUk2SW1oMGRIQnpPaTh2WTJoaGMzRjFhUzUxY0c5eWRDNXRaUzloY0drdmRqRXZkRzl3YVdNdldtMXNOa2xuUWsxYU9XUXhWbGgwV0ZsYVJUTlBkeUlzSW1GamRDSTZJbXRsZVhCaGFYSWlMQ0owZVhCbElqb2ljMmhoY21WU1pYRWlMQ0pwYzNNaU9pSmthV1E2WlhSb2Nqb3dlR0U1WlRNeU16SmlOakZpWkdJMk56STNNVEppT1dGbE16TXhPVFV3Tmpsa09HUTJOVEZqTVdFaWZRLnRNbWh6cjFkbER0YUhUeWUtVDAxOGp2N0NUYlRhVWY4ZzlhbHNxVWJ6VGpGUkFsbV9qZ2RaR3pVVEVzeGtBY0ZmVy1ZSmpIVGtwSmtjNFNWREc3REJBQSIsImlzcyI6ImRpZDpldGhyOjB4ZThjOTFiZGU3NjI1YWIyYzBlZDlmMjE0ZGViMzk0NDBkYTdlMDNjNCJ9.-04Z_m2kgFBwF1Elh3jmv1_44jdGjEczf4x3c5Z4TxwiMP8nXZsIDVgsp3PS34DPGfpR4OkZ6LBozBBER3TABAA" ) - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `verifies simple tokens (deprecated)`() = runBlocking { - mockkObject(UniversalDID) - - coEvery { UniversalDID.resolve("did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154") }.returns( - EthrDIDDocument.fromJson( - """{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKey":[{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner","type":"Secp256k1VerificationKey2018","owner":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","ethereumAddress":"0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKeyHex":null,"publicKeyBase64":null,"publicKeyBase58":null,"value":null}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner"}],"service":[],"@context":"https://w3id.org/did/v1"}""" - ) - ) - coEvery { UniversalDID.resolve("did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4") }.returns( - EthrDIDDocument.fromJson( - """{"id":"did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4","publicKey":[{"id":"did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4#owner","type":"Secp256k1VerificationKey2018","owner":"did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4","ethereumAddress":"0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4","publicKeyHex":null,"publicKeyBase64":null,"publicKeyBase58":null,"value":null}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4#owner"}],"service":[],"@context":"https://w3id.org/did/v1"}""" - ) - ) - - tokens.forEach { token -> - val payload = JWTTools(TestTimeProvider(1535102500000L)).verify( - token = token, - audience = "did:ethr:0xa9e3232b61bdb672712b9ae33195069d8d651c1a" - ) - assertThat(payload).isNotNull() - } - } - @Test fun `verifies simple tokens`() = runBlocking { @@ -94,110 +61,6 @@ class JWTToolsJVMTest { } } - private val validShareReqToken1 = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpc3MiOiIyb2VYdWZIR0RwVTUxYmZLQnNaRGR1N0plOXdlSjNyN3NWRyIsImlhdCI6MTUyMDM2NjQzMiwicmVxdWVzdGVkIjpbIm5hbWUiLCJwaG9uZSIsImNvdW50cnkiLCJhdmF0YXIiXSwicGVybWlzc2lvbnMiOlsibm90aWZpY2F0aW9ucyJdLCJjYWxsYmFjayI6Imh0dHBzOi8vY2hhc3F1aS51cG9ydC5tZS9hcGkvdjEvdG9waWMvWG5IZnlldjUxeHNka0R0dSIsIm5ldCI6IjB4NCIsImV4cCI6MTUyMDM2NzAzMiwidHlwZSI6InNoYXJlUmVxIn0.C8mPCCtWlYAnroduqysXYRl5xvrOdx1r4iq3A3SmGDGZu47UGTnjiZCOrOQ8A5lZ0M9JfDpZDETCKGdJ7KUeWQ" - private val expectedShareReqPayload1 = JwtPayload( - iss = "2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG", - iat = 1520366432, - sub = null, - aud = null, - exp = 1520367032, - callback = "https://chasqui.uport.me/api/v1/topic/XnHfyev51xsdkDtu", - type = "shareReq", - net = "0x4", - act = null, - requested = listOf("name", "phone", "country", "avatar"), - verified = null, - permissions = listOf("notifications"), - req = null, - nad = null, - dad = null, - own = null, - capabilities = null, - claims = null, - ctl = null, - reg = null, - rel = null, - fct = null, - acc = null - ) - - private val incomingJwt = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpc3MiOiIyb21SSlpMMjNaQ1lnYzFyWnJGVnBGWEpwV29hRUV1SlVjZiIsImlhdCI6MTUxOTM1MDI1NiwicGVybWlzc2lvbnMiOlsibm90aWZpY2F0aW9ucyJdLCJjYWxsYmFjayI6Imh0dHBzOi8vYXBpLnVwb3J0LnNwYWNlL29sb3J1bi9jcmVhdGVJZGVudGl0eSIsIm5ldCI6IjB4MzAzOSIsImFjdCI6ImRldmljZWtleSIsImV4cCI6MTUyMjU0MDgwMCwidHlwZSI6InNoYXJlUmVxIn0.EkqNUyrZhcDbTQl73XpL2tp470lCo2saMXzuOZ91UI2y-XzpcBMzhhSeUORnoJXJhHnkGGpshZlESWUgrbuiVQ" - private val expectedJwtPayload = JwtPayload( - iss = "2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf", - iat = 1519350256, - sub = null, - aud = null, - exp = 1522540800, - callback = "https://api.uport.space/olorun/createIdentity", - type = "shareReq", - net = "0x3039", - act = "devicekey", - requested = null, - verified = null, - permissions = listOf("notifications"), - req = null, - nad = null, - dad = null, - own = null, - capabilities = null, - claims = null, - ctl = null, - reg = null, - rel = null, - fct = null, - acc = null - ) - - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `returns correct payload after successful verification (deprecated)`() = runBlocking { - mockkObject(UniversalDID) - - coEvery { UniversalDID.resolve("2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG") }.returns( - UportDIDDocument.fromJson("""{"id":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG","publicKey":[{"id":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG#keys-1","type":"Secp256k1VerificationKey2018","owner":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG","publicKeyHex":"04171fcc7654cad14745b9835bc534d8e59038ae6929c793d7f8dd2c934580ca39ff1e2de3d7ef69a8daba5e5590d3ec80486a273cbe2bd1b76ebd01f949b41463"}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG#keys-1"}],"service":[],"@context":"https://w3id.org/did/v1","uportProfile":{"@type":"App","image":{"@type":"ImageObject","name":"avatar","contentUrl":"/ipfs/Qmez4bdFmxPknbAoGzHmpjpLjQFChq39h5UMPGiwUHgt8f"},"name":"uPort Demo","description":"Demo App"}}""") - ) - coEvery { UniversalDID.resolve("2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf") }.returns( - UportDIDDocument.fromJson("""{"id":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf","publicKey":[{"id":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf#keys-1","type":"Secp256k1VerificationKey2018","owner":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf","publicKeyHex":"0422d2edad30d8588c0661e032f37af8177cfa0a056ee9b8ca953b07c6600a637c002ed22fe6612e28e558aee130d399ba97f89e25c16661a99c8af8c832b88568"}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf#keys-1"}],"service":[],"@context":"https://w3id.org/did/v1","uportProfile":{"@type":"App","image":{"@type":"ImageObject","name":"avatar","contentUrl":"/ipfs/QmdznPoNSnc6RawSzzvNFX5HerF62Vu7sbP3vSur9gDFGb"},"name":"Olorun","description":"Private network configuration service"}}""") - ) - - val shareReqPayload = JWTTools(TestTimeProvider(1520366666000L)).verify(validShareReqToken1) - assertThat(shareReqPayload).isEqualTo(expectedShareReqPayload1) - - val incomingJwtPayload = JWTTools(TestTimeProvider(1522540300000L)).verify(incomingJwt) - assertThat(incomingJwtPayload).isEqualTo(expectedJwtPayload) - } - - @Test - fun `returns correct payload after successful verification`() = runBlocking { - - val resolver = spyk(UportDIDResolver(JsonRPC(""))) - - coEvery { - resolver.resolve("2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG") - }.returns( - UportDIDDocument.fromJson("""{"id":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG","publicKey":[{"id":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG#keys-1","type":"Secp256k1VerificationKey2018","owner":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG","publicKeyHex":"04171fcc7654cad14745b9835bc534d8e59038ae6929c793d7f8dd2c934580ca39ff1e2de3d7ef69a8daba5e5590d3ec80486a273cbe2bd1b76ebd01f949b41463"}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG#keys-1"}],"service":[],"@context":"https://w3id.org/did/v1","uportProfile":{"@type":"App","image":{"@type":"ImageObject","name":"avatar","contentUrl":"/ipfs/Qmez4bdFmxPknbAoGzHmpjpLjQFChq39h5UMPGiwUHgt8f"},"name":"uPort Demo","description":"Demo App"}}""") - ) - - coEvery { - resolver.resolve("2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf") - }.returns( - UportDIDDocument.fromJson("""{"id":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf","publicKey":[{"id":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf#keys-1","type":"Secp256k1VerificationKey2018","owner":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf","publicKeyHex":"0422d2edad30d8588c0661e032f37af8177cfa0a056ee9b8ca953b07c6600a637c002ed22fe6612e28e558aee130d399ba97f89e25c16661a99c8af8c832b88568"}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:uport:2omRJZL23ZCYgc1rZrFVpFXJpWoaEEuJUcf#keys-1"}],"service":[],"@context":"https://w3id.org/did/v1","uportProfile":{"@type":"App","image":{"@type":"ImageObject","name":"avatar","contentUrl":"/ipfs/QmdznPoNSnc6RawSzzvNFX5HerF62Vu7sbP3vSur9gDFGb"},"name":"Olorun","description":"Private network configuration service"}}""") - ) - - val shareReqPayload = - JWTTools(TestTimeProvider(1520366666000L)).verify(validShareReqToken1, resolver) - assertThat(shareReqPayload).isEqualTo(expectedShareReqPayload1) - - val incomingJwtPayload = - JWTTools(TestTimeProvider(1522540300000L)).verify(incomingJwt, resolver) - assertThat(incomingJwtPayload).isEqualTo(expectedJwtPayload) - } - @Test fun `throws when given an unknown algorithm to create tokens`() { val tested = JWTTools() @@ -218,32 +81,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `throws error when aud is not available (deprecated)`() = runBlocking { - mockkObject(UniversalDID) - - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1MzUwMTY3MDIsImV4cCI6MTUzNTEwMzEwMiwiYXVkIjoiZGlkOmV0aHI6MHhhOWUzMjMyYjYxYmRiNjcyNzEyYjlhZTMzMTk1MDY5ZDhkNjUxYzFhIiwidHlwZSI6InNoYXJlUmVzcCIsIm5hZCI6IjJvZHpqVGFpOFJvNFYzS3hrbTNTblppdjlXU1l1Tm9aNEFoIiwib3duIjp7Im5hbWUiOiJ1UG9ydCBVc2VyIn0sInJlcSI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSkZVekkxTmtzdFVpSjkuZXlKcFlYUWlPakUxTXpVd01UWTJPREVzSW1WNGNDSTZNVFV6TlRBeE56STRNU3dpY21WeGRXVnpkR1ZrSWpwYkltNWhiV1VpTENKd2FHOXVaU0lzSW1OdmRXNTBjbmtpWFN3aWNHVnliV2x6YzJsdmJuTWlPbHNpYm05MGFXWnBZMkYwYVc5dWN5SmRMQ0pqWVd4c1ltRmpheUk2SW1oMGRIQnpPaTh2WTJoaGMzRjFhUzUxY0c5eWRDNXRaUzloY0drdmRqRXZkRzl3YVdNdmJVVXpTbVpXZWxOMFNuUnFhbnBvWWpSYVRFRnhkeUlzSW1GamRDSTZJbXRsZVhCaGFYSWlMQ0owZVhCbElqb2ljMmhoY21WU1pYRWlMQ0pwYzNNaU9pSmthV1E2WlhSb2Nqb3dlR0U1WlRNeU16SmlOakZpWkdJMk56STNNVEppT1dGbE16TXhPVFV3Tmpsa09HUTJOVEZqTVdFaWZRLnVScUdGd01XNnpWSDR4OWFmTDAtS29qSEYwVF9GbW9QWnR6OG5uSjRFXzhNY2cxejBBZ21aMnplOE5iS05wVUNnRHRwTU9RNzVGSjU4WmhzbWFxQUxBRSIsImNhcGFiaWxpdGllcyI6WyJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpGVXpJMU5rc3RVaUo5LmV5SnBZWFFpT2pFMU16VXdNVFkzTURFc0ltVjRjQ0k2TVRVek5qTXhNamN3TVN3aVlYVmtJam9pWkdsa09tVjBhSEk2TUhoaE9XVXpNak15WWpZeFltUmlOamN5TnpFeVlqbGhaVE16TVRrMU1EWTVaRGhrTmpVeFl6RmhJaXdpZEhsd1pTSTZJbTV2ZEdsbWFXTmhkR2x2Ym5NaUxDSjJZV3gxWlNJNkltRnlianBoZDNNNmMyNXpPblZ6TFhkbGMzUXRNam94TVRNeE9UWXlNVFkxTlRnNlpXNWtjRzlwYm5RdlIwTk5MM1ZRYjNKMEx6UXpNRGsxTWpZMkxUSmhPR1F0TTJFMFpTMWlaRFV3TFRka01USm1ZVE00TWpRNFlpSXNJbWx6Y3lJNkltUnBaRHBsZEdoeU9qQjRNVEE0TWpBNVpqUXlORGRpTjJabE5qWXdOV0l3WmpVNFpqa3hORFZsWXpNeU5qbGtNREUxTkNKOS5Lc0F6TmVDeHFDaF9rMkt4aTYtWHFveFNXZjBCLWFFR0xXdi1ldHVXQlF2QU5neDFTMG5oZ0ppRkllUnRXakw4ekdnVVV3MUlsSWJtYUZrOEo5aGdhd0UiXSwiYm94UHViIjoiY2g3aGI2S3hsakJ2bXh5UDJXZENWTFNTLzQ2S1hCcmdkWG1Mcm03VEpIST0iLCJpc3MiOiJkaWQ6ZXRocjoweDEwODIwOWY0MjQ3YjdmZTY2MDViMGY1OGY5MTQ1ZWMzMjY5ZDAxNTQifQ.Ncf8B_y0Ha8gdaYyCaL5jLX2RsKTMwxTQ8KlybXFygsxKUUQm9OXo4lU65fduIaFvVyPOP6Oe2adar8m0m2aiwA" - - coEvery { UniversalDID.resolve("did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154") }.returns( - EthrDIDDocument.fromJson( - """{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKey":[{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner","type":"Secp256k1VerificationKey2018","owner":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","ethereumAddress":"0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKeyHex":null,"publicKeyBase64":null,"publicKeyBase58":null,"value":null}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner"}],"service":[],"@context":"https://w3id.org/did/v1"}""" - ) - ) - - coAssert { - JWTTools(TestTimeProvider(1535102500000L)).verify( - token = token - ) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - } - } - @Test fun `throws error when aud is not available`() = runBlocking { @@ -272,33 +109,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `throws error when aud and payload aud do not match (deprecated)`() = runBlocking { - mockkObject(UniversalDID) - - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1MzUwMTY3MDIsImV4cCI6MTUzNTEwMzEwMiwiYXVkIjoiZGlkOmV0aHI6MHhhOWUzMjMyYjYxYmRiNjcyNzEyYjlhZTMzMTk1MDY5ZDhkNjUxYzFhIiwidHlwZSI6InNoYXJlUmVzcCIsIm5hZCI6IjJvZHpqVGFpOFJvNFYzS3hrbTNTblppdjlXU1l1Tm9aNEFoIiwib3duIjp7Im5hbWUiOiJ1UG9ydCBVc2VyIn0sInJlcSI6ImV5SjBlWEFpT2lKS1YxUWlMQ0poYkdjaU9pSkZVekkxTmtzdFVpSjkuZXlKcFlYUWlPakUxTXpVd01UWTJPREVzSW1WNGNDSTZNVFV6TlRBeE56STRNU3dpY21WeGRXVnpkR1ZrSWpwYkltNWhiV1VpTENKd2FHOXVaU0lzSW1OdmRXNTBjbmtpWFN3aWNHVnliV2x6YzJsdmJuTWlPbHNpYm05MGFXWnBZMkYwYVc5dWN5SmRMQ0pqWVd4c1ltRmpheUk2SW1oMGRIQnpPaTh2WTJoaGMzRjFhUzUxY0c5eWRDNXRaUzloY0drdmRqRXZkRzl3YVdNdmJVVXpTbVpXZWxOMFNuUnFhbnBvWWpSYVRFRnhkeUlzSW1GamRDSTZJbXRsZVhCaGFYSWlMQ0owZVhCbElqb2ljMmhoY21WU1pYRWlMQ0pwYzNNaU9pSmthV1E2WlhSb2Nqb3dlR0U1WlRNeU16SmlOakZpWkdJMk56STNNVEppT1dGbE16TXhPVFV3Tmpsa09HUTJOVEZqTVdFaWZRLnVScUdGd01XNnpWSDR4OWFmTDAtS29qSEYwVF9GbW9QWnR6OG5uSjRFXzhNY2cxejBBZ21aMnplOE5iS05wVUNnRHRwTU9RNzVGSjU4WmhzbWFxQUxBRSIsImNhcGFiaWxpdGllcyI6WyJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpGVXpJMU5rc3RVaUo5LmV5SnBZWFFpT2pFMU16VXdNVFkzTURFc0ltVjRjQ0k2TVRVek5qTXhNamN3TVN3aVlYVmtJam9pWkdsa09tVjBhSEk2TUhoaE9XVXpNak15WWpZeFltUmlOamN5TnpFeVlqbGhaVE16TVRrMU1EWTVaRGhrTmpVeFl6RmhJaXdpZEhsd1pTSTZJbTV2ZEdsbWFXTmhkR2x2Ym5NaUxDSjJZV3gxWlNJNkltRnlianBoZDNNNmMyNXpPblZ6TFhkbGMzUXRNam94TVRNeE9UWXlNVFkxTlRnNlpXNWtjRzlwYm5RdlIwTk5MM1ZRYjNKMEx6UXpNRGsxTWpZMkxUSmhPR1F0TTJFMFpTMWlaRFV3TFRka01USm1ZVE00TWpRNFlpSXNJbWx6Y3lJNkltUnBaRHBsZEdoeU9qQjRNVEE0TWpBNVpqUXlORGRpTjJabE5qWXdOV0l3WmpVNFpqa3hORFZsWXpNeU5qbGtNREUxTkNKOS5Lc0F6TmVDeHFDaF9rMkt4aTYtWHFveFNXZjBCLWFFR0xXdi1ldHVXQlF2QU5neDFTMG5oZ0ppRkllUnRXakw4ekdnVVV3MUlsSWJtYUZrOEo5aGdhd0UiXSwiYm94UHViIjoiY2g3aGI2S3hsakJ2bXh5UDJXZENWTFNTLzQ2S1hCcmdkWG1Mcm03VEpIST0iLCJpc3MiOiJkaWQ6ZXRocjoweDEwODIwOWY0MjQ3YjdmZTY2MDViMGY1OGY5MTQ1ZWMzMjY5ZDAxNTQifQ.Ncf8B_y0Ha8gdaYyCaL5jLX2RsKTMwxTQ8KlybXFygsxKUUQm9OXo4lU65fduIaFvVyPOP6Oe2adar8m0m2aiwA" - - coEvery { UniversalDID.resolve("did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154") }.returns( - EthrDIDDocument.fromJson( - """{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKey":[{"id":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner","type":"Secp256k1VerificationKey2018","owner":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154","ethereumAddress":"0x108209f4247b7fe6605b0f58f9145ec3269d0154","publicKeyHex":null,"publicKeyBase64":null,"publicKeyBase58":null,"value":null}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154#owner"}],"service":[],"@context":"https://w3id.org/did/v1"}""" - ) - ) - - coAssert { - JWTTools(TestTimeProvider(1535102500000L)).verify( - token = token, - audience = "did:ethr:0x108209f4247b7fe6605b0f58f9145ec3269d0154" - ) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - } - } - @Test fun `throws error when aud and payload aud do not match`() = runBlocking { @@ -328,22 +138,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `throws when a token is issued in the future (deprecated)`() { - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXRocjoweGE5ZTMyMzJiNjFiZGI2NzI3MTJiOWFlMzMxOTUwNjlkOGQ2NTFjMWEiLCJpYXQiOjE1NDU1Njk1NDEsImV4cCI6MTU0NjA4Nzk0MSwiYXVkIjoiZGlkOmV0aHI6MHgxMDgyMDlmNDI0N2I3ZmU2NjA1YjBmNThmOTE0NWVjMzI2OWQwMTU0Iiwic3ViIjoiIn0.Bt9Frc1QabJfpXYBoU4sns8WPeRLdKU87FncgMFq1lY" - - coAssert { - JWTTools(TestTimeProvider(977317692000L)).verify(token) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - } - } - @Test fun `throws when a token is issued in the future`() { val token = @@ -362,22 +156,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `throws when a token is expired (deprecated)`() { - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkaWQ6ZXRocjoweGE5ZTMyMzJiNjFiZGI2NzI3MTJiOWFlMzMxOTUwNjlkOGQ2NTFjMWEiLCJpYXQiOjE1NDU1Njk1NDEsImV4cCI6MTU0NjA4Nzk0MSwiYXVkIjoiZGlkOmV0aHI6MHgxMDgyMDlmNDI0N2I3ZmU2NjA1YjBmNThmOTE0NWVjMzI2OWQwMTU0Iiwic3ViIjoiIn0.Bt9Frc1QabJfpXYBoU4sns8WPeRLdKU87FncgMFq1lY" - - coAssert { - JWTTools(TestTimeProvider(1576847292000L)).verify(token) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - } - } - @Test fun `throws when a token is expired`() { val token = @@ -396,31 +174,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `throws when the signature does not match any public keys belonging to the issuer (deprecated)`() { - - mockkObject(UniversalDID) - coEvery { UniversalDID.resolve("did:ethr:0x6985a110df37555235d7d0de0a0fb28c9848dfa9") }.returns( - EthrDIDDocument.fromJson( - """{"id":"did:ethr:0x6985a110df37555235d7d0de0a0fb28c9848dfa9","publicKey":[{"id":"did:ethr:0x6985a110df37555235d7d0de0a0fb28c9848dfa9#owner","type":"Secp256k1VerificationKey2018","owner":"did:ethr:0x6985a110df37555235d7d0de0a0fb28c9848dfa9","ethereumAddress":"0x6985a110df37555235d7d0de0a0fb28c9848dfa9","publicKeyHex":null,"publicKeyBase64":null,"publicKeyBase58":null,"value":null}],"authentication":[{"type":"Secp256k1SignatureAuthentication2018","publicKey":"did:ethr:0x6985a110df37555235d7d0de0a0fb28c9848dfa9#owner"}],"service":[],"@context":"https://w3id.org/did/v1"}""" - ) - ) - - // JWT token with a Signer that doesn't have anything to do with the issuerDID. - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9.eyJpYXQiOjE1NDY4NTkxNTksImV4cCI6MTg2MjIxOTE1OSwiaXNzIjoiZGlkOmV0aHI6MHg2OTg1YTExMGRmMzc1NTUyMzVkN2QwZGUwYTBmYjI4Yzk4NDhkZmE5In0.fe1rvAHsoJsJzwSFAmVFTz9uxhncNY65jpbb2cS9jcY08xphpU3rOy1N85_IbEjhIZw-FrPeFgxJLoDLw6itcgE" - - coAssert { - JWTTools(TestTimeProvider(1547818630000L)).verify(token) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - } - } - @Test fun `throws when the signature does not match any public keys belonging to the issuer`() { @@ -651,7 +404,7 @@ class JWTToolsJVMTest { .build() ) - coEvery { UniversalDID.resolve(issuer) }.returns(doc) + coEvery { resolver.resolve(issuer) }.returns(doc) coAssert { JWTTools().resolveAuthenticator(alg, issuer, auth, resolver) @@ -660,32 +413,6 @@ class JWTToolsJVMTest { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `can verify a freshly minted token (deprecated)`() = runBlocking { - val signer = KPSigner("0x1234") - val did = "did:ethr:${signer.getAddress()}" - - val resolver = spyk( - EthrDIDResolver.Builder() - .addNetwork(EthrDIDNetwork("", "0xregistry", JsonRPC(""))) - .build() - ) - - coEvery { resolver.resolve(eq(did)) } returns - EthrDIDTestHelpers.mockDocForAddress(signer.getAddress()) - - UniversalDID.registerResolver(resolver) - - val token = JWTTools().createJWT(emptyMap(), did, signer) - val payload = JWTTools().verify(token) - assertThat(payload).isNotNull() - Unit - } - @Test fun `can verify a freshly minted token`() = runBlocking { val signer = KPSigner("0x1234") @@ -706,32 +433,6 @@ class JWTToolsJVMTest { Unit } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `can verify a ES256K signature with only ethereumAddress in the DID doc (deprecated)`() = - runBlocking { - val address = "0xcf03dd0a894ef79cb5b601a43c4b25e3ae4c67ed" - - val resolver = spyk( - EthrDIDResolver.Builder() - .addNetwork(EthrDIDNetwork("", "0xregistry", JsonRPC(""))) - .build() - ) - - coEvery { resolver.resolve(eq("did:ethr:$address")) } returns - EthrDIDTestHelpers.mockDocForAddress(address) - - UniversalDID.registerResolver(resolver) - - val token = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJoZWxsbyI6IndvcmxkIiwiaWF0IjoxNTYxOTcxMTE5LCJpc3MiOiJkaWQ6ZXRocjoweGNmMDNkZDBhODk0ZWY3OWNiNWI2MDFhNDNjNGIyNWUzYWU0YzY3ZWQifQ.t5o1vzZExArlrrTVHmwtti7fnicXqvWrX6SS3F-Lu3budH7p6zQHjG8X7EvUTRUxhvr-eENCbXeteSE4rgF7MA" - val payload = JWTTools().verify(token) - assertThat(payload.iss).isEqualTo("did:ethr:$address") - } - @Test fun `can verify a ES256K signature with only ethereumAddress in the DID doc`() = runBlocking { val address = "0xcf03dd0a894ef79cb5b601a43c4b25e3ae4c67ed" diff --git a/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt b/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt index 3c6a096..3606a5f 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt @@ -294,25 +294,6 @@ class TimestampTests { Unit } - @Suppress("DEPRECATION") - @Test - fun `fail when nbf missing and iat in the future (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - val jwt = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjE5MDAsImlzcyI6IjB4Y2YwM2RkMGE4OTRlZjc5Y2I1YjYwMWE0M2M0YjI1ZTNhZTRjNjdlZCJ9.PJ9wHrlcL_ScDretwS8q5izSmi4CZXRTyXyuhmlbVLGI0v2bioqMYLJZS6aMMEN1A6s7HT10BPFFt8XxLdZuvw" - - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded.containsKey("nbf")).isEqualTo(false) - assertThat(decoded["iat"]).isEqualTo(FUTURE) - - coAssert { - tested.verify(jwt) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - hasMessage("Jwt not valid yet (issued in the future) iat: $FUTURE") - } - } - @Test fun `fail when nbf missing and iat in the future`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) From c953cc4c276a741e3825b059b5799eb754005d51 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:22:29 +0100 Subject: [PATCH 2/7] refactor: remove support for the deprecated did:uport method please use a more scalable method such as did:ethr --- .gitignore | 2 - README.md | 4 - build.gradle | 1 - .../uport/credentialstatus/StatusResolver.kt | 2 - .../UniversalStatusResolver.kt | 4 - .../main/java/me/uport/sdk/ethrdid/EthrDID.kt | 2 - .../me/uport/sdk/ethrdid/EthrDIDDocument.kt | 1 - .../me/uport/sdk/ethrdid/EthrDIDResolver.kt | 1 - .../uport/sdk/ethrdid/EthrDIDResolverTest.kt | 6 - ethr-status/build.gradle | 1 - .../sdk/ethrstatus/EthrStatusResolver.kt | 1 - jwt/build.gradle | 2 - jwt/src/main/java/me/uport/sdk/jwt/ECUtils.kt | 1 - .../main/java/me/uport/sdk/jwt/JWTUtils.kt | 23 +- .../java/me/uport/sdk/jwt/JWTDecodeTest.kt | 1 - .../java/me/uport/sdk/jwt/JWTToolsJVMTest.kt | 10 - .../java/me/uport/sdk/jwt/JwtUtilsKtTest.kt | 4 - settings.gradle | 1 - .../me/uport/sdk/universaldid/DIDDocument.kt | 1 - uport-defaults/build.gradle | 2 - .../sdk/uportdefaults/DIDResolverTest.kt | 14 +- uport-did/Readme.md | 41 --- uport-did/abi/UportRegistry.json | 282 ------------------ uport-did/build.gradle | 29 -- .../me/uport/sdk/uportdid/UportDIDDocument.kt | 44 --- .../me/uport/sdk/uportdid/UportDIDResolver.kt | 155 ---------- .../sdk/uportdid/UportIdentityDocument.kt | 128 -------- .../me/uport/sdk/uportdid/UportRegistry.kt | 33 -- .../sdk/uportdid/UportDIDResolverTest.kt | 157 ---------- .../sdk/uportdid/UportIdentityDocumentTest.kt | 18 -- .../uport/sdk/httpsdid/WebDIDResolverTest.kt | 4 - 31 files changed, 7 insertions(+), 968 deletions(-) delete mode 100644 uport-did/Readme.md delete mode 100644 uport-did/abi/UportRegistry.json delete mode 100644 uport-did/build.gradle delete mode 100644 uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDDocument.kt delete mode 100644 uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDResolver.kt delete mode 100644 uport-did/src/main/java/me/uport/sdk/uportdid/UportIdentityDocument.kt delete mode 100644 uport-did/src/main/java/me/uport/sdk/uportdid/UportRegistry.kt delete mode 100644 uport-did/src/test/java/me/uport/sdk/uportdid/UportDIDResolverTest.kt delete mode 100644 uport-did/src/test/java/me/uport/sdk/uportdid/UportIdentityDocumentTest.kt diff --git a/.gitignore b/.gitignore index 9ed8b80..b58e1fe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ # repo-specific config publish.properties - # Created by https://www.gitignore.io/api/linux,macos,gradle,windows,android,androidstudio ### Android ### @@ -238,5 +237,4 @@ gradle-app.setting # # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 # gradle/wrapper/gradle-wrapper.properties - # End of https://www.gitignore.io/api/linux,macos,gradle,windows,android,androidstudio \ No newline at end of file diff --git a/README.md b/README.md index 3459584..2ad37e0 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,6 @@ We currently support the following DID methods: - [`web`](https://github.com/uport-project/https-did-resolver) - [`https`](https://github.com/uport-project/https-did-resolver) *DEPRECATED* - Defaults are automatically installed but you can customize to fit your needs. Support for other DID methods should be simple. @@ -90,7 +89,6 @@ val issuerDID = "did:ethr:${signer.getAddress()}" val token = jwt.createJWT(payload, issuerDID, signer) ``` - ### 2. Decode a did-JWT Try decoding the JWT. You can also do this using [jwt.io](https://jwt.io) @@ -116,7 +114,6 @@ but that is a more rigid structure and will be phased away in future releases. ### 3. Verify a did-JWT - ```kotlin val resolver = EthrDIDResolver.Builder() .addNetwork(EthrDIDNetwork("", "", "")) @@ -146,7 +143,6 @@ This same `aud` DID must be supplied to the `verify()` method for the token to b Generally your app will have its own DID which should always be passed to the `verify` method so that only tokens intended for your app are considered valid. - ## CHANGELOG * 0.3.6 diff --git a/build.gradle b/build.gradle index e45061e..b6380ef 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,6 @@ buildscript { jacoco_version = "0.8.4" bivrost_version = "v0.7.1" - kmnid_version = "0.4.4" kethereum_version = "0.81.4" khex_version = "1.0.0-RC6" khash_version = "1.0.0-RC5" diff --git a/credential-status/src/main/java/me/uport/credentialstatus/StatusResolver.kt b/credential-status/src/main/java/me/uport/credentialstatus/StatusResolver.kt index 5f3fadc..315c139 100644 --- a/credential-status/src/main/java/me/uport/credentialstatus/StatusResolver.kt +++ b/credential-status/src/main/java/me/uport/credentialstatus/StatusResolver.kt @@ -7,7 +7,6 @@ import me.uport.sdk.universaldid.DIDDocument **/ interface CredentialStatus - /** * Represents a status method entry that could be embedded in a W3C Verifiable Credential. * Normally, only credentials that list a status method would need to be verified by it. @@ -20,7 +19,6 @@ interface CredentialStatus */ data class StatusEntry(val type: String, val id: String) - /** * * The interface expected for status resolvers. diff --git a/credential-status/src/main/java/me/uport/credentialstatus/UniversalStatusResolver.kt b/credential-status/src/main/java/me/uport/credentialstatus/UniversalStatusResolver.kt index 577a2df..901cba3 100644 --- a/credential-status/src/main/java/me/uport/credentialstatus/UniversalStatusResolver.kt +++ b/credential-status/src/main/java/me/uport/credentialstatus/UniversalStatusResolver.kt @@ -14,17 +14,14 @@ import me.uport.sdk.universaldid.DIDDocument */ class UniversalStatusResolver : StatusResolver { - private val resolvers = mapOf().toMutableMap() - /** * This universal resolver can't be used for any one particular resolver but for all [StatusResolver]s * that have been added using [registerResolver] */ override val method: String = "" - /** * Looks for a [StatusResolver] that can check status using the provided [method] * @@ -43,7 +40,6 @@ class UniversalStatusResolver : StatusResolver { return resolver.checkStatus(credential, didDoc) } - /** * Register a resolver for a particular [method] */ diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt index 7ff0e1d..fa7dc16 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt @@ -49,7 +49,6 @@ class EthrDID( private val owner: String? = null - class DelegateOptions( val delegateType: PublicKeyType = PublicKeyType.veriKey, val expiresIn: Long = 86400L @@ -74,7 +73,6 @@ class EthrDID( return signAndSendContractCall(owner, encodedCall, txOptions) } - suspend fun addDelegate( delegate: String, options: DelegateOptions = DelegateOptions(), diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDDocument.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDDocument.kt index f07e5fa..9c018fb 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDDocument.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDDocument.kt @@ -53,4 +53,3 @@ data class EthrDIDDocument( } } - diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt index 988e15b..1335fc8 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt @@ -190,7 +190,6 @@ open class EthrDIDResolver : DIDResolver { } - } while (lastChange != BigInteger.ZERO) return events diff --git a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt index f679a70..45bc3e7 100644 --- a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt +++ b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt @@ -90,7 +90,6 @@ class EthrDIDResolverTest { assertThat(lastChanged.hexToBigInteger()).isNotEqualTo(BigInteger.ZERO) } - @Test fun `can parse getLogs response`() = runBlocking { val http = mockk() @@ -470,7 +469,6 @@ class EthrDIDResolverTest { "did:ethr:0x01:0xB9C5714089478a327F09197987f16f9E5d936E8a#owner" ) - val invalidDids = listOf( "0xb9c5714089478a327f09197987f16f9e5d936e", "B9C5714089478a327F09197987f16f9E5d936E8a", @@ -601,7 +599,6 @@ class EthrDIDResolverTest { ) } returns """{"jsonrpc":"2.0","id":1,"result":[]}""" - val resolver = EthrDIDResolver.Builder() .addNetwork(EthrDIDNetwork("mainnet", "mockregistry", rpc, "0x1")) .build() @@ -642,7 +639,6 @@ class EthrDIDResolverTest { ) } returns """{"jsonrpc":"2.0","id":1,"result":[]}""" - val resolver = EthrDIDResolver.Builder() .addNetwork(EthrDIDNetwork("mainnet", "0xregistry", rpc, "0x1")) .addNetwork(EthrDIDNetwork("rinkeby", "0xregistry", rpc, "0x4")) @@ -701,7 +697,6 @@ class EthrDIDResolverTest { ) } returns """{"jsonrpc":"2.0","id":1,"result":[]}""" - val resolver = EthrDIDResolver.Builder() .addNetwork(EthrDIDNetwork("__default__", "0xregistry", rpc, "0x01")) .build() @@ -807,7 +802,6 @@ class EthrDIDResolverTest { } } - @Test fun `throws when registry is not configured`() { val rpc = mockk() diff --git a/ethr-status/build.gradle b/ethr-status/build.gradle index d7f873b..4c1aa74 100644 --- a/ethr-status/build.gradle +++ b/ethr-status/build.gradle @@ -6,7 +6,6 @@ apply plugin: "com.jfrog.bintray" project.ext.description = "Ethr implementation of credential-status" - dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" api "com.github.uport-project.kotlin-common:jsonrpc:$uport_kotlin_common_version" diff --git a/ethr-status/src/main/java/me/uport/sdk/ethrstatus/EthrStatusResolver.kt b/ethr-status/src/main/java/me/uport/sdk/ethrstatus/EthrStatusResolver.kt index cc633ca..de0deeb 100644 --- a/ethr-status/src/main/java/me/uport/sdk/ethrstatus/EthrStatusResolver.kt +++ b/ethr-status/src/main/java/me/uport/sdk/ethrstatus/EthrStatusResolver.kt @@ -12,7 +12,6 @@ import org.kethereum.keccakshortcut.keccak import pm.gnosis.model.Solidity import java.math.BigInteger - /** * Ethr Implementation of the [StatusResolver] * This class enables users check the revocation status of a credential diff --git a/jwt/build.gradle b/jwt/build.gradle index 66c82d6..32e2df0 100644 --- a/jwt/build.gradle +++ b/jwt/build.gradle @@ -21,10 +21,8 @@ dependencies { api "com.github.uport-project.kotlin-common:jsonrpc:$uport_kotlin_common_version" api "com.github.uport-project.kotlin-common:core:$uport_kotlin_common_version" api "com.github.uport-project.kotlin-common:signer-common:$uport_kotlin_common_version" - implementation "com.github.uport-project:kmnid:$kmnid_version" api project(":universal-did") - api project(":uport-did") api project(":ethr-did") api project(":web-did") implementation "com.madgag.spongycastle:core:$spongycastle_version" diff --git a/jwt/src/main/java/me/uport/sdk/jwt/ECUtils.kt b/jwt/src/main/java/me/uport/sdk/jwt/ECUtils.kt index 5cb4611..cc57c69 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/ECUtils.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/ECUtils.kt @@ -22,7 +22,6 @@ import java.security.SignatureException internal val CURVE by lazy { CustomNamedCurves.getByName("secp256k1")!! } internal val DOMAIN_PARAMS = CURVE.run { ECDomainParameters(curve, g, n, h) } - internal data class ECDSASignature internal constructor(val r: BigInteger, val s: BigInteger) /** diff --git a/jwt/src/main/java/me/uport/sdk/jwt/JWTUtils.kt b/jwt/src/main/java/me/uport/sdk/jwt/JWTUtils.kt index b786a68..d350e25 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/JWTUtils.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/JWTUtils.kt @@ -1,7 +1,5 @@ package me.uport.sdk.jwt -import me.uport.mnid.MNID - /** * Utilities for dealing with known JWT and DID types and formats */ @@ -26,27 +24,18 @@ object JWTUtils { * Attempts to normalize a [potentialDID] to a known format. * * @return This will transform an ethereum address into an ethr-did - * and an MNID string into a uport-did * Other cases return the original string */ fun normalizeKnownDID(potentialDID: String): String { val ethPattern = "^(0[xX])*([0-9a-fA-F]{40})".toRegex() - return when { - potentialDID.matches("^did:(.*)?:.*".toRegex()) -> - potentialDID - - potentialDID.matches(ethPattern) -> { - val it = ethPattern.matchEntire(potentialDID)!! - val (_, hexDigits) = it.destructured - return "did:ethr:0x$hexDigits" - } - - MNID.isMNID(potentialDID) -> - "did:uport:$potentialDID" - - else -> potentialDID + val matchResult = ethPattern.matchEntire(potentialDID) + if (matchResult != null) { + val (_, hexDigits) = matchResult.destructured + return "did:ethr:0x$hexDigits" } + + return potentialDID } } diff --git a/jwt/src/test/java/me/uport/sdk/jwt/JWTDecodeTest.kt b/jwt/src/test/java/me/uport/sdk/jwt/JWTDecodeTest.kt index 40a9d23..df77dbf 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/JWTDecodeTest.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/JWTDecodeTest.kt @@ -9,7 +9,6 @@ import assertk.assertions.isInstanceOf import me.uport.sdk.jwt.JWTUtils.splitToken import org.junit.Test - class JWTDecodeTest { private val validShareReqToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpc3MiOiIyb2VYdWZIR0RwVTUxYmZLQnNaRGR1N0plOXdlSjNyN3NWRyIsImlhdCI6MTUyMDM2NjQzMiwicmVxdWVzdGVkIjpbIm5hbWUiLCJwaG9uZSIsImNvdW50cnkiLCJhdmF0YXIiXSwicGVybWlzc2lvbnMiOlsibm90aWZpY2F0aW9ucyJdLCJjYWxsYmFjayI6Imh0dHBzOi8vY2hhc3F1aS51cG9ydC5tZS9hcGkvdjEvdG9waWMvWG5IZnlldjUxeHNka0R0dSIsIm5ldCI6IjB4NCIsImV4cCI6MTUyMDM2NzAzMiwidHlwZSI6InNoYXJlUmVxIn0.C8mPCCtWlYAnroduqysXYRl5xvrOdx1r4iq3A3SmGDGZu47UGTnjiZCOrOQ8A5lZ0M9JfDpZDETCKGdJ7KUeWQ" diff --git a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt index 7365215..4888ab3 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt @@ -200,7 +200,6 @@ class JWTToolsJVMTest { } } - @Test fun `finds public key`() = runBlocking { @@ -236,7 +235,6 @@ class JWTToolsJVMTest { assertThat(authenticators).isEqualTo(doc.publicKey) } - @Test fun `only list authenticators able to authenticate a user`() = runBlocking { @@ -294,7 +292,6 @@ class JWTToolsJVMTest { assertThat(authenticators).isEqualTo(listOf(doc.publicKey[0], doc.publicKey[1])) } - @Test fun `errors if no suitable public keys exist for authentication`() = runBlocking { @@ -339,7 +336,6 @@ class JWTToolsJVMTest { } } - @Test fun `errors if no public keys exist`() = runBlocking { @@ -379,7 +375,6 @@ class JWTToolsJVMTest { } } - @Test fun `errors if no supported signature types exist`() = runBlocking { @@ -471,14 +466,10 @@ class JWTToolsJVMTest { @Test fun `can normalize dids`() { - val uportDID = "did:uport:2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG" - val mnid = "2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG" val ethrDID = "did:ethr:0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4" val ethrAddress = "0xe8c91bde7625ab2c0ed9f214deb39440da7e03c4" val invalidDID = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NkstUiJ9" - assertThat(normalizeKnownDID(uportDID)).isEqualTo(uportDID) - assertThat(normalizeKnownDID(mnid)).isEqualTo(uportDID) assertThat(normalizeKnownDID(ethrDID)).isEqualTo(ethrDID) assertThat(normalizeKnownDID(ethrAddress)).isEqualTo(ethrDID) assertThat(normalizeKnownDID(invalidDID)).isEqualTo(invalidDID) @@ -606,4 +597,3 @@ class JWTToolsJVMTest { } } - diff --git a/jwt/src/test/java/me/uport/sdk/jwt/JwtUtilsKtTest.kt b/jwt/src/test/java/me/uport/sdk/jwt/JwtUtilsKtTest.kt index 01b3591..1df40fd 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/JwtUtilsKtTest.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/JwtUtilsKtTest.kt @@ -21,10 +21,6 @@ class JwtUtilsKtTest { "0XF3BEAC30c498d9e26865f34fcaa57dbb935b0d74" to "did:ethr:0xF3BEAC30c498d9e26865f34fcaa57dbb935b0d74", "f3beac30c498d9e26865f34fcaa57dbb935b0d74" to "did:ethr:0xf3beac30c498d9e26865f34fcaa57dbb935b0d74", - //mnid to uport did - "2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX" to "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", - "5A8bRWU3F7j3REx3vkJWxdjQPp4tqmxFPmab1Tr" to "did:uport:5A8bRWU3F7j3REx3vkJWxdjQPp4tqmxFPmab1Tr", - //unknown is left intact "0x1234" to "0x1234", "2nQtiQG6Cgm1GYTBaaK" to "2nQtiQG6Cgm1GYTBaaK" diff --git a/settings.gradle b/settings.gradle index 4f2a850..80c5b17 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,4 @@ include ':web-did' -include ':uport-did' include ':ethr-did' include ':universal-did' include ':jwt' diff --git a/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt b/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt index a7c2add..31ab91e 100644 --- a/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt +++ b/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt @@ -128,7 +128,6 @@ data class PublicKeyType(val name: String) { override fun deserialize(decoder: Decoder): PublicKeyType = PublicKeyType(decoder.decodeString()) - ////////////////////////////// //some known key types ////////////////////////////// diff --git a/uport-defaults/build.gradle b/uport-defaults/build.gradle index a9ed448..f1f0ec3 100644 --- a/uport-defaults/build.gradle +++ b/uport-defaults/build.gradle @@ -5,14 +5,12 @@ apply plugin: "com.jfrog.bintray" project.ext.description = "Default values and configuration for DIDResolver" - dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" api "com.github.uport-project.kotlin-common:jsonrpc:$uport_kotlin_common_version" api "com.github.uport-project.kotlin-common:signer-common:$uport_kotlin_common_version" api project(":universal-did") - api project(":uport-did") api project(":ethr-did") api project(":web-did") diff --git a/uport-defaults/src/test/java/me/uport/sdk/uportdefaults/DIDResolverTest.kt b/uport-defaults/src/test/java/me/uport/sdk/uportdefaults/DIDResolverTest.kt index 57fdce5..72ead95 100644 --- a/uport-defaults/src/test/java/me/uport/sdk/uportdefaults/DIDResolverTest.kt +++ b/uport-defaults/src/test/java/me/uport/sdk/uportdefaults/DIDResolverTest.kt @@ -3,19 +3,15 @@ package me.uport.sdk.uportdefaults import assertk.assertThat import assertk.assertions.isFalse import assertk.assertions.isTrue -import me.uport.sdk.core.Networks import me.uport.sdk.ethrdid.EthrDIDNetwork import me.uport.sdk.ethrdid.EthrDIDResolver import me.uport.sdk.httpsdid.WebDIDResolver import me.uport.sdk.jsonrpc.JsonRPC import me.uport.sdk.universaldid.DIDResolver -import me.uport.sdk.uportdid.UportDIDResolver import org.junit.Test - class DIDResolverTest { - @Test fun `can resolve valid dids after adding resolvers`() { val resolver = DIDResolver.Builder() @@ -23,8 +19,6 @@ class DIDResolverTest { EthrDIDResolver.Builder() .addNetwork(EthrDIDNetwork("", "0xregistry", JsonRPC(""))) .build() - ).addResolver( - UportDIDResolver(JsonRPC(Networks.rinkeby.rpcUrl)) ) .addResolver( WebDIDResolver() @@ -37,11 +31,7 @@ class DIDResolverTest { "did:https:example.com", "did:https:example.ngrok.com#owner", "did:web:example.com", - "did:web:example.com#owner", - "2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", - "5A8bRWU3F7j3REx3vkJWxdjQPp4tqmxFPmab1Tr", - "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", - "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX#owner" + "did:web:example.com#owner" ) dids.forEach { @@ -49,7 +39,6 @@ class DIDResolverTest { } } - @Test fun `fails to resolve valid dids without adding resolvers`() { @@ -93,7 +82,6 @@ class DIDResolverTest { } } - @Test fun `fails on invalid dids`() { diff --git a/uport-did/Readme.md b/uport-did/Readme.md deleted file mode 100644 index 98d0d7b..0000000 --- a/uport-did/Readme.md +++ /dev/null @@ -1,41 +0,0 @@ -DID resolver - rough alpha -========================== - -This library provides a way to lookup a DID document for a given MNID - -The basic steps to resolve a DID are: -* decodes the MNID to get the `network` and `address` -* obtains the (hardcoded) registry contract_address by `network` -* `eth_call`s the registry contract with the `address` to get the IPFS hash -* gets the Document from IPFS and tries to decode it into a `DDO` object - -The document it obtains is described [here](https://github.com/uport-project/specs/blob/develop/pki/identitydocument.md) - -TL;DR it looks like this: -```json -{ - "@context":"http://schema.org", - "@type":"Person", - "publicKey":"0x04613bb3a4874d2703...", - "publicEncKey":"QCFPBLm..." -} -``` - -### Usage - -```kotlin -val mnid = "2ozs2ntCXceKkAQKX4c9xp2zPS8pvkJhVqC" -[...] -//in a background thread: -document = DIDResolver().getProfileDocumentSync(mnid) - -// on main thread: -DIDResolver().getProfileDocument(mnid, { err, document -> -//do something with document -}) -``` - -### NOTE - -This work is very early and about to be changed a lot. -Expect breaking changes between releases. \ No newline at end of file diff --git a/uport-did/abi/UportRegistry.json b/uport-did/abi/UportRegistry.json deleted file mode 100644 index c4de49f..0000000 --- a/uport-did/abi/UportRegistry.json +++ /dev/null @@ -1,282 +0,0 @@ -{ - "contractName": "UportRegistry", - "abi": [ - { - "constant": true, - "inputs": [ - { - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "name": "issuer", - "type": "address" - }, - { - "name": "subject", - "type": "address" - } - ], - "name": "get", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "version", - "outputs": [ - { - "name": "", - "type": "uint256" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "previousPublishedVersion", - "outputs": [ - { - "name": "", - "type": "address" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": true, - "inputs": [ - { - "name": "", - "type": "bytes32" - }, - { - "name": "", - "type": "address" - }, - { - "name": "", - "type": "address" - } - ], - "name": "registry", - "outputs": [ - { - "name": "", - "type": "bytes32" - } - ], - "payable": false, - "type": "function" - }, - { - "constant": false, - "inputs": [ - { - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "name": "subject", - "type": "address" - }, - { - "name": "value", - "type": "bytes32" - } - ], - "name": "set", - "outputs": [], - "payable": false, - "type": "function" - }, - { - "inputs": [ - { - "name": "_previousPublishedVersion", - "type": "address" - } - ], - "payable": false, - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "indexed": true, - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "name": "subject", - "type": "address" - }, - { - "indexed": false, - "name": "updatedAt", - "type": "uint256" - } - ], - "name": "Set", - "type": "event" - } - ], - "unlinked_binary": "0x6060604052346100005760405160208061029083398101604052515b600360005560018054600160a060020a031916600160a060020a0383161790555b505b6102438061004d6000396000f300606060405263ffffffff60e060020a600035041663447885f0811461005057806354fd4d50146100845780636104464f146100a357806381895b73146100cc578063d79d8e6c14610100575b610000565b3461000057610072600435600160a060020a0360243581169060443516610121565b60408051918252519081900360200190f35b3461000057610072610158565b60408051918252519081900360200190f35b34610000576100b061015e565b60408051600160a060020a039092168252519081900360200190f35b3461000057610072600435600160a060020a036024358116906044351661016d565b60408051918252519081900360200190f35b346100005761011f600435600160a060020a0360243516604435610190565b005b6000838152600260209081526040808320600160a060020a03808716855290835281842090851684529091529020545b9392505050565b60005481565b600154600160a060020a031681565b600260209081526000938452604080852082529284528284209052825290205481565b81600160a060020a031633600160a060020a031684600019167feaf626c2c2ec7b7bd4328ffad20cd8bf2e631858020a5a4a0b4ea02276af3e91426040518082815260200191505060405180910390a46000838152600260209081526040808320600160a060020a033381168552908352818420908616845290915290208190555b5050505600a165627a7a72305820e14a52c32bfcadedc74efd8012b8c1be95769eb900e095f25cce78b62c8973720029", - "networks": { - "1": { - "links": {}, - "events": { - "0xeaf626c2c2ec7b7bd4328ffad20cd8bf2e631858020a5a4a0b4ea02276af3e91": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "indexed": true, - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "name": "subject", - "type": "address" - }, - { - "indexed": false, - "name": "updatedAt", - "type": "uint256" - } - ], - "name": "Set", - "type": "event" - } - }, - "address": "0xab5c8051b9a1df1aab0149f8b0630848b7ecabf6", - "updated_at": 1487624027710 - }, - "3": { - "links": {}, - "events": { - "0xeaf626c2c2ec7b7bd4328ffad20cd8bf2e631858020a5a4a0b4ea02276af3e91": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "indexed": true, - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "name": "subject", - "type": "address" - }, - { - "indexed": false, - "name": "updatedAt", - "type": "uint256" - } - ], - "name": "Set", - "type": "event" - } - }, - "address": "0x41566e3a081f5032bdcad470adb797635ddfe1f0", - "updated_at": 1487622652023 - }, - "4": { - "links": {}, - "events": { - "0xeaf626c2c2ec7b7bd4328ffad20cd8bf2e631858020a5a4a0b4ea02276af3e91": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "indexed": true, - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "name": "subject", - "type": "address" - }, - { - "indexed": false, - "name": "updatedAt", - "type": "uint256" - } - ], - "name": "Set", - "type": "event" - } - }, - "address": "0x2cc31912b2b0f3075a87b3640923d45a26cef3ee", - "updated_at": 1498319686024 - }, - "42": { - "links": {}, - "events": { - "0xeaf626c2c2ec7b7bd4328ffad20cd8bf2e631858020a5a4a0b4ea02276af3e91": { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "name": "registrationIdentifier", - "type": "bytes32" - }, - { - "indexed": true, - "name": "issuer", - "type": "address" - }, - { - "indexed": true, - "name": "subject", - "type": "address" - }, - { - "indexed": false, - "name": "updatedAt", - "type": "uint256" - } - ], - "name": "Set", - "type": "event" - } - }, - "address": "0x5f8e9351dc2d238fb878b6ae43aa740d62fc9758", - "updated_at": 1487622652023 - } - }, - "schema_version": "0.0.5", - "updated_at": 1491317100592 -} \ No newline at end of file diff --git a/uport-did/build.gradle b/uport-did/build.gradle deleted file mode 100644 index a122e0a..0000000 --- a/uport-did/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -apply plugin: "java-library" -apply plugin: "kotlin" -apply plugin: "kotlinx-serialization" -apply plugin: "maven" -apply plugin: "com.jfrog.bintray" -apply plugin: "bivrost" - -project.ext.description = "DID resolver for the uport-did standard" - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialization_version" - implementation "com.github.gnosis.bivrost-kotlin:bivrost-solidity-types:$bivrost_version" - - api "com.github.komputing.khex:extensions:$khex_version" - api "com.github.komputing.kethereum:extensions_kotlin:$kethereum_version" - api "com.github.komputing:kbase58:$kbase58_version" - - api "com.github.uport-project.kotlin-common:jsonrpc:$uport_kotlin_common_version" - api "com.github.uport-project.kotlin-common:core:$uport_kotlin_common_version" - implementation "com.github.uport-project:kmnid:$kmnid_version" - - api project(":universal-did") - - testImplementation "junit:junit:$junit_version" - testImplementation "io.mockk:mockk:$mockk_version" - testImplementation "com.willowtreeapps.assertk:assertk-jvm:$assertk_version" -} diff --git a/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDDocument.kt b/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDDocument.kt deleted file mode 100644 index a678767..0000000 --- a/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDDocument.kt +++ /dev/null @@ -1,44 +0,0 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE", "unused") - -package me.uport.sdk.uportdid - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import me.uport.sdk.universaldid.AuthenticationEntry -import me.uport.sdk.universaldid.DIDDocument -import me.uport.sdk.universaldid.PublicKeyEntry -import me.uport.sdk.universaldid.ServiceEntry - -/** - * The [DIDDocument] implementation specific to uport-did resolver. - * This contains an extra [uportProfile] field that encapsulates the legacy profile document. - */ -@Serializable -data class UportDIDDocument( - override val id: String, - override val publicKey: List, - override val authentication: List, - override val service: List = emptyList(), - - @SerialName("@context") - override val context: String = "https://w3id.org/did/v1", - - @Suppress("DEPRECATION") - val uportProfile: UportIdentityDocument - -) : DIDDocument { - - /** - * Serializes this DID document to a JSON string - */ - fun toJson(): String = Json.stringify(serializer(), this) - - companion object { - - /** - * Attempts to deserialize a given [json] string into a [UportDIDDocument] - */ - fun fromJson(json: String) = Json.nonstrict.parse(serializer(), json) - } -} diff --git a/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDResolver.kt b/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDResolver.kt deleted file mode 100644 index 407dfdd..0000000 --- a/uport-did/src/main/java/me/uport/sdk/uportdid/UportDIDResolver.kt +++ /dev/null @@ -1,155 +0,0 @@ -package me.uport.sdk.uportdid - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import me.uport.mnid.Account -import me.uport.mnid.MNID -import me.uport.sdk.core.HttpClient -import me.uport.sdk.core.Networks -import me.uport.sdk.core.clean0xPrefix -import me.uport.sdk.core.hexToBigInteger -import me.uport.sdk.core.hexToByteArray -import me.uport.sdk.jsonrpc.JsonRPC -import me.uport.sdk.jsonrpc.model.exceptions.JsonRpcException -import me.uport.sdk.universaldid.BlankDocumentError -import me.uport.sdk.universaldid.DIDDocument -import me.uport.sdk.universaldid.DIDResolver -import me.uport.sdk.universaldid.DidResolverError -import org.komputing.kbase58.encodeToBase58String -import pm.gnosis.model.Solidity - -/** - * This is a DID resolver implementation that supports the "uport" DID method. - * It accepts uport dids or simple mnids and produces a document described at: - * https://w3c-ccg.github.io/did-spec/#did-documents - * - * Example uport did: "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX#owner" - * Example mnid: "2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX" - */ -@Deprecated( - "This identity method is no longer supported and will be removed in the next major release." + - "Please switch to a more sustainable method such as ethr-did" -) -open class UportDIDResolver( - private val rpc: JsonRPC, - private val httpClient: HttpClient = HttpClient() -) : DIDResolver { - override val method: String = "uport" - - override suspend fun resolve(did: String): DIDDocument = withContext(Dispatchers.IO) { - if (canResolve(did)) { - val (_, mnid) = parseDIDString(did) - val ddo = getProfileDocumentFor(mnid) - - ddo?.convertToDIDDocument(did) - ?: throw BlankDocumentError("unable to fetch profile document for $did") - - } else { - throw IllegalArgumentException("The DID('$did') cannot be resolved by the uPort DID resolver") - } - } - - override fun canResolve(potentialDID: String): Boolean { - val (method, mnid) = parseDIDString(potentialDID) - return if (method == this.method) { - MNID.isMNID(mnid) - } else { - MNID.isMNID(potentialDID) - } - } - - private fun decodeMnidTargets(issuerId: String?, subjectId: String?): Pair { - val issuer = MNID.decode(issuerId ?: subjectId ?: "") - - val subject = MNID.decode(subjectId ?: "") - - if (issuer.network != subject.network) { - throw(IllegalArgumentException("Issuer and subject must be on the same network")) - } - return Pair(issuer, subject) - } - - private suspend fun getDocAddressFromUportRegistry( - subjectId: String?, - issuerId: String? = null, - registrationIdentifier: String = "uPortProfileIPFS1220" - ): String { - - val (issuer, subject) = decodeMnidTargets(issuerId, subjectId) - - val network = Networks.get(issuer.network) - - val registryAddress = MNID.decode(network.uPortRegistry).address - - if (registryAddress.isBlank()) { - throw IllegalStateException("uPort DID registry for [${issuer.network}] was not configured.") - } - - val encodedFunctionCall = encodeRegistryGetCall(registrationIdentifier, issuer, subject) - - return try { - rpc.ethCall(registryAddress, encodedFunctionCall) - } catch (err: JsonRpcException) { - throw DidResolverError( - "RPC endpoint returned an error during uPort registry query", - err - ) - } - } - - internal fun encodeRegistryGetCall( - registrationIdentifier: String, - issuer: Account, - subject: Account - ): String { - val solRegistryIdentifier = Solidity.Bytes32(registrationIdentifier.toByteArray()) - val solIssuer = Solidity.Address(issuer.address.hexToBigInteger()) - val solSubject = Solidity.Address(subject.address.hexToBigInteger()) - - return UportRegistry.Get.encode(solRegistryIdentifier, solIssuer, solSubject) - } - - /** - * Given an MNID, obtains the IPFS hash of the UportDIDResolver document by eth_call to the uport registry - */ - internal suspend fun getIpfsHash(mnid: String): String { - val docAddressHex = getDocAddressFromUportRegistry(mnid) - return if (docAddressHex.isBlank()) { - return "" - } else { - "1220${docAddressHex.clean0xPrefix()}".hexToByteArray().encodeToBase58String() - } - } - - private suspend fun getJsonProfile(mnid: String): String { - - val ipfsHash = getIpfsHash(mnid) - - val url = "https://ipfs.infura.io/ipfs/$ipfsHash" - - return httpClient.urlGet(url) - } - - /** - * Given an [mnid], obtains the JSON encoded DID doc then tries to convert it to a [UportIdentityDocument] object - * - * Should return `null` if anything goes wrong - */ - @Suppress("DEPRECATION") - internal suspend fun getProfileDocumentFor(mnid: String): UportIdentityDocument? { - val rawJsonDDO = getJsonProfile(mnid) - - return UportIdentityDocument.fromJson(rawJsonDDO) - } - - companion object { - //language=RegExp - val uportDIDPattern = "^(did:(uport):)?([1-9A-HJ-NP-Za-km-z]{34,38})(.*)".toRegex() - - internal fun parseDIDString(did: String): Pair { - val matchResult = uportDIDPattern.find(did) ?: return ("" to did) - val (_, method, mnid) = matchResult.destructured - return (method to mnid) - } - } -} diff --git a/uport-did/src/main/java/me/uport/sdk/uportdid/UportIdentityDocument.kt b/uport-did/src/main/java/me/uport/sdk/uportdid/UportIdentityDocument.kt deleted file mode 100644 index 83f24e7..0000000 --- a/uport-did/src/main/java/me/uport/sdk/uportdid/UportIdentityDocument.kt +++ /dev/null @@ -1,128 +0,0 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") - -package me.uport.sdk.uportdid - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration -import me.uport.sdk.core.clean0xPrefix -import me.uport.sdk.universaldid.AuthenticationEntry -import me.uport.sdk.universaldid.DIDDocument -import me.uport.sdk.universaldid.PublicKeyEntry -import me.uport.sdk.universaldid.PublicKeyType.Companion.Curve25519EncryptionPublicKey -import me.uport.sdk.universaldid.PublicKeyType.Companion.Secp256k1SignatureAuthentication2018 -import me.uport.sdk.universaldid.PublicKeyType.Companion.Secp256k1VerificationKey2018 -import me.uport.sdk.uportdid.UportDIDResolver.Companion.parseDIDString - -/** - * A class that encapsulates the legacy uport-did profile document - * - * See [identity_document spec](https://github.com/uport-project/specs/blob/develop/pki/identitydocument.md) - * - */ -@Suppress("DEPRECATION") -@Serializable -@Deprecated(message = "this was replaced by UportDIDDocument. use `convertToDIDDocument` to make the transition") -data class UportIdentityDocument( - @SerialName("@context") - val context: String? = "http://schema.org", - - @SerialName("@type") - val type: String, //ex: "Organization", "Person" - - val publicKey: String? = null, //ex: "0x04613bb3a4874d27032618f020614c21cbe4c4e4781687525f6674089f9bd3d6c7f6eb13569053d31715a3ba32e0b791b97922af6387f087d6b5548c06944ab062" - - val publicEncKey: String? = null, //ex: "0x04613bb3a4874d27032618f020614c21cbe4c4e4781687525f6674089f9bd3d6c7f6eb13569053d31715a3ba32e0b791b97922af6387f087d6b5548c06944ab062" - - val image: ProfilePicture? = null, //ex: {"@type":"ImageObject","name":"avatar","contentUrl":"/ipfs/QmSCnmXC91Arz2gj934Ce4DeR7d9fULWRepjzGMX6SSazB"} - - val name: String? = null, //ex: "uPort @ Devcon3" , "Vitalik Buterout" - - val description: String? = null // ex: "uPort Attestation" -) { - - /** - * Converts the deprecated profile document model to a DID standard compliant [DIDDocument] - */ - fun convertToDIDDocument(did: String): DIDDocument { - - val normalizedDid = normalizeDID(did) - - val publicVerificationKey = PublicKeyEntry( - id = "$normalizedDid#keys-1", - type = Secp256k1VerificationKey2018, - owner = normalizedDid, - publicKeyHex = this.publicKey?.clean0xPrefix() - ) - val authEntries = listOf( - AuthenticationEntry( - type = Secp256k1SignatureAuthentication2018, - publicKey = "$normalizedDid#keys-1" - ) - ) - - val pkEntries = listOf(publicVerificationKey).toMutableList() - - if (publicEncKey != null) { - pkEntries.add( - PublicKeyEntry( - id = "$normalizedDid#keys-2", - type = Curve25519EncryptionPublicKey, - owner = normalizedDid, - publicKeyBase64 = publicEncKey - ) - ) - } - - return UportDIDDocument( - context = "https://w3id.org/did/v1", - id = normalizedDid, - publicKey = pkEntries, - authentication = authEntries, - uportProfile = copy( - context = null, - publicEncKey = null, - publicKey = null - ) - ) - } - - private fun normalizeDID(did: String): String { - val (_, mnid) = parseDIDString(did) - return "did:uport:$mnid" - } - - companion object { - - fun fromJson(json: String): UportIdentityDocument? = jsonParser.parse(serializer(), json) - - /** - * Attempts to deserialize a json string into a profile document - */ - private val jsonParser = - Json( - JsonConfiguration( - encodeDefaults = false, - isLenient = true, - ignoreUnknownKeys = true - ) - ) - } -} - -/** - * encapsulates a profile picture field of a profile document - */ -@Suppress("unused") -@Serializable -class ProfilePicture( - @SerialName("@type") - val type: String? = "ImageObject", - - val name: String? = "avatar", - - @Suppress("unused") - val contentUrl: String? = "" -) - diff --git a/uport-did/src/main/java/me/uport/sdk/uportdid/UportRegistry.kt b/uport-did/src/main/java/me/uport/sdk/uportdid/UportRegistry.kt deleted file mode 100644 index 7dccc75..0000000 --- a/uport-did/src/main/java/me/uport/sdk/uportdid/UportRegistry.kt +++ /dev/null @@ -1,33 +0,0 @@ -@file:Suppress("UndocumentedPublicFunction", "UndocumentedPublicClass") - -package me.uport.sdk.uportdid - -import pm.gnosis.model.Solidity -import pm.gnosis.model.SolidityBase - -/** - * This is the minimalistic interface for the UportRegistry contract. - * To get the full interface use the [bivrost](https://github.com/gnosis/bivrost-kotlin) - * code generating tool with the UportRegistry.json ABI as input - */ -class UportRegistry { - object Get { - private const val METHOD_ID: String = "447885f0" - - fun encode( - registrationIdentifier: Solidity.Bytes32, - issuer: Solidity.Address, - subject: Solidity.Address - ): String { - - return "0x$METHOD_ID${SolidityBase - .encodeFunctionArguments( - registrationIdentifier, - issuer, - subject - )}" - } - - } - -} diff --git a/uport-did/src/test/java/me/uport/sdk/uportdid/UportDIDResolverTest.kt b/uport-did/src/test/java/me/uport/sdk/uportdid/UportDIDResolverTest.kt deleted file mode 100644 index 8b56761..0000000 --- a/uport-did/src/test/java/me/uport/sdk/uportdid/UportDIDResolverTest.kt +++ /dev/null @@ -1,157 +0,0 @@ -@file:Suppress("DEPRECATION") - -package me.uport.sdk.uportdid - -import assertk.assertThat -import assertk.assertions.isEqualTo -import assertk.assertions.isFalse -import assertk.assertions.isNotNull -import assertk.assertions.isTrue -import io.mockk.coEvery -import io.mockk.mockk -import io.mockk.slot -import io.mockk.spyk -import kotlinx.coroutines.runBlocking -import me.uport.mnid.Account -import me.uport.sdk.core.HttpClient -import me.uport.sdk.core.Networks -import me.uport.sdk.core.clean0xPrefix -import me.uport.sdk.jsonrpc.JsonRPC -import me.uport.sdk.universaldid.PublicKeyType.Companion.Curve25519EncryptionPublicKey -import me.uport.sdk.universaldid.PublicKeyType.Companion.Secp256k1VerificationKey2018 -import org.junit.Test - -class UportDIDResolverTest { - - @Test - fun `can encode a uPort registry Get method call`() { - val expectedEncoding = - "0x447885f075506f727450726f66696c654950465331323230000000000000000000000000000000000000000000000000f12c30cd32b4a027710c150ae742f50db0749213000000000000000000000000f12c30cd32b4a027710c150ae742f50db0749213" - val acc = - Account.from(network = "0x04", address = "0xf12c30cd32b4a027710c150ae742f50db0749213") - val rpc = mockk() - val encoding = UportDIDResolver(rpc).encodeRegistryGetCall("uPortProfileIPFS1220", acc, acc) - - assertThat(encoding).isEqualTo(expectedEncoding) - } - - @Test - fun `calls registry with correct payload`() = runBlocking { - - val encodedCallSlot = slot() - - val rpc = mockk() { - coEvery { - ethCall( - any(), - capture(encodedCallSlot) - ) - } returns "0x807a7cb8b670125774d70cf94d35e2355bb18bb51cf604f376c9996057f92fbf" - } - - val docAddressHex = UportDIDResolver(rpc).getIpfsHash("2ozs2ntCXceKkAQKX4c9xp2zPS8pvkJhVqC") - - assertThat(encodedCallSlot.captured).isEqualTo("0x447885f075506f727450726f66696c654950465331323230000000000000000000000000000000000000000000000000f12c30cd32b4a027710c150ae742f50db0749213000000000000000000000000f12c30cd32b4a027710c150ae742f50db0749213") - assertThat(docAddressHex).isEqualTo("QmWzBDtv8m21ph1aM57yVDWxdG7LdQd3rNf5xrRiiV2D2E") - } - - @Test - fun `can convert legacy UportIdentityDocument to DIDDocument`() { - val publicKeyHex = - "0x04e8989d1826cd6258906cfaa71126e2db675eaef47ddeb9310ee10db69b339ab960649e1934dc1e1eac1a193a94bd7dc5542befc5f7339845265ea839b9cbe56f" - val publicEncKey = "k8q5G4YoIMP7zvqMC9q84i7xUBins6dXGt8g5H007F0=" - val legacyDDO = UportIdentityDocument( - context = "http://schema.org", - type = "Person", - publicKey = publicKeyHex, - publicEncKey = publicEncKey, - description = null, - image = ProfilePicture(), - name = null - ) - - val convertedDDO = legacyDDO.convertToDIDDocument("2ozs2ntCXceKkAQKX4c9xp2zPS8pvkJhVqC") - - val expectedOwner = "did:uport:2ozs2ntCXceKkAQKX4c9xp2zPS8pvkJhVqC" - assertThat(convertedDDO.id).isEqualTo(expectedOwner) - - val verificationPkMatch = convertedDDO.publicKey.find { it -> - it.id.startsWith(expectedOwner) && - it.owner == expectedOwner && - it.type == Secp256k1VerificationKey2018 && - it.publicKeyHex == publicKeyHex.clean0xPrefix() - } - assertThat(verificationPkMatch).isNotNull() - - val encPkMatch = convertedDDO.publicKey.find { it -> - it.id.startsWith(expectedOwner) && - it.owner == expectedOwner && - it.type == Curve25519EncryptionPublicKey && - it.publicKeyBase64 == publicEncKey - } - assertThat(encPkMatch).isNotNull() - } - - @Test - fun `can get profile document for mnid`() = runBlocking { - val http = mockk() { - //language=json - coEvery { urlGet(any()) } returns """{"@context":"http://schema.org","@type":"Person","publicKey":"0x04e8989d1826cd6258906cfaa71126e2db675eaef47ddeb9310ee10db69b339ab960649e1934dc1e1eac1a193a94bd7dc5542befc5f7339845265ea839b9cbe56f","publicEncKey":"k8q5G4YoIMP7zvqMC9q84i7xUBins6dXGt8g5H007F0="}""" - } - val rpc = spyk(JsonRPC(Networks.rinkeby.rpcUrl, http)) { - coEvery { - ethCall( - any(), - any() - ) - } returns "0x807a7cb8b670125774d70cf94d35e2355bb18bb51cf604f376c9996057f92fbf" - } - - val expectedDDO = UportIdentityDocument( - context = "http://schema.org", - type = "Person", - publicKey = "0x04e8989d1826cd6258906cfaa71126e2db675eaef47ddeb9310ee10db69b339ab960649e1934dc1e1eac1a193a94bd7dc5542befc5f7339845265ea839b9cbe56f", - publicEncKey = "k8q5G4YoIMP7zvqMC9q84i7xUBins6dXGt8g5H007F0=", - description = null, - image = null, - name = null - ) - - val ddo = UportDIDResolver( - rpc, - http - ).getProfileDocumentFor(mnid = "2ozs2ntCXceKkAQKX4c9xp2zPS8pvkJhVqC") - - assertThat(ddo).isEqualTo(expectedDDO) - } - - - @Test - fun can_resolve_valid_dids() { - val tested = UportDIDResolver(JsonRPC(Networks.rinkeby.rpcUrl)) - listOf( - "2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", - "5A8bRWU3F7j3REx3vkJWxdjQPp4tqmxFPmab1Tr", - "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", - "did:uport:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX#owner" - ).forEach { - assertThat(tested.canResolve(it)).isTrue() - } - } - - @Test - fun fails_on_invalid_dids() { - val tested = UportDIDResolver(JsonRPC(Networks.rinkeby.rpcUrl)) - listOf( - "did:something:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", //different method - "QmXuNqXmrkxs4WhTDC2GCnXEep4LUD87bu97LQMn1rkxmQ", //not mnid - "1GbVUSW5WJmRCpaCJ4hanUny77oDaWW4to", //not mnid - "0x00521965e7bd230323c423d96c657db5b79d099f", //not mnid - "did:2nQtiQG6Cgm1GYTBaaKAgr76uY7iSexUkqX", //missing method - "did:uport:", //missing mnid - "did:uport" //missing mnid and colon - ).forEach { - assertThat(tested.canResolve(it)).isFalse() - } - } -} diff --git a/uport-did/src/test/java/me/uport/sdk/uportdid/UportIdentityDocumentTest.kt b/uport-did/src/test/java/me/uport/sdk/uportdid/UportIdentityDocumentTest.kt deleted file mode 100644 index f888b2b..0000000 --- a/uport-did/src/test/java/me/uport/sdk/uportdid/UportIdentityDocumentTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -@file:Suppress("DEPRECATION") - -package me.uport.sdk.uportdid - -import assertk.assertThat -import assertk.assertions.isNotNull -import org.junit.Test - -class UportIdentityDocumentTest { - - @Test - fun `can parse legacy Identity document`() { - val legacyDoc = - """{"name":"uPort Demo","@type":"App","publicKey":"0x04171fcc7654cad14745b9835bc534d8e59038ae6929c793d7f8dd2c934580ca39ff1e2de3d7ef69a8daba5e5590d3ec80486a273cbe2bd1b76ebd01f949b41463","description":"Demo App","url":"demo.uport.me","image":{"contentUrl":"/ipfs/Qmez4bdFmxPknbAoGzHmpjpLjQFChq39h5UMPGiwUHgt8f"},"address":"2oeXufHGDpU51bfKBsZDdu7Je9weJ3r7sVG"}""" - val parsed = UportIdentityDocument.fromJson(legacyDoc) - assertThat(parsed).isNotNull() - } -} diff --git a/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt b/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt index 7268ec7..1f58948 100644 --- a/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt +++ b/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt @@ -65,7 +65,6 @@ class WebDIDResolverTest { service = emptyList() ) - @Test fun `can resolve valid dids`() { listOf( @@ -154,7 +153,6 @@ class WebDIDResolverTest { assertThat(response).isEqualTo(exampleDidDoc) } - @Test fun `resolves documents through universal resolver`() = runBlocking { @@ -173,5 +171,3 @@ class WebDIDResolverTest { } } - - From 622fcbbce2c07c32da8c6d115f12f9ba1d48407e Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:28:26 +0100 Subject: [PATCH 3/7] refactor: remove support for the deprecated `UniversalDID` global please use `DIDResolver.Builder` to register resolvers as needed --- .../me/uport/sdk/universaldid/UniversalDID.kt | 104 ------------------ .../sdk/universaldid/UniversalDIDTest.kt | 103 ----------------- .../uport/sdk/httpsdid/WebDIDResolverTest.kt | 19 ---- 3 files changed, 226 deletions(-) delete mode 100644 universal-did/src/main/java/me/uport/sdk/universaldid/UniversalDID.kt delete mode 100644 universal-did/src/test/java/me/uport/sdk/universaldid/UniversalDIDTest.kt diff --git a/universal-did/src/main/java/me/uport/sdk/universaldid/UniversalDID.kt b/universal-did/src/main/java/me/uport/sdk/universaldid/UniversalDID.kt deleted file mode 100644 index aecce00..0000000 --- a/universal-did/src/main/java/me/uport/sdk/universaldid/UniversalDID.kt +++ /dev/null @@ -1,104 +0,0 @@ -package me.uport.sdk.universaldid - -import me.uport.sdk.universaldid.UniversalDID.method -import me.uport.sdk.universaldid.UniversalDID.registerResolver - -/** - * A class to abstract resolving Decentralized Identity (DID) documents - * from specific implementations based on the [method] component of a DID [String] - * - * [DIDResolver] implementations need to be registered using [registerResolver] - * - * Known implementations of [DIDResolver] are [ethr-did] and [uport-did] - */ -@Suppress("DEPRECATION") -@Deprecated( - "Resolving DIDs using the UniversalDID singleton is deprecated " + - "in favor of using the DIDResolver Builder." + - "This will be removed in the next major release.", - ReplaceWith( - """val resolver : DIDResolver = DIDResolver.Builder - .addResolver(ethrDidResolver) - .addResolver(uportDidResolver) - .addResolver(webDidResolver) - .build()""" - ) -) -object UniversalDID : DIDResolver { - - private val resolvers = mapOf().toMutableMap() - - /** - * Register a resolver for a particular DID [method] - */ - fun registerResolver(resolver: DIDResolver) { - if (resolver.method.isBlank()) { - return - } - resolvers[resolver.method] = resolver - } - - /** - * @hide - */ - fun clearResolvers() = resolvers.clear() - - /** - * This universal resolver can't be used for any one particular did but for all [DIDResolver]s - * that have been added using [registerResolver] - */ - override val method: String = "" - - /** - * Checks if any of the registered resolvers can resolve - */ - override fun canResolve(potentialDID: String): Boolean { - val resolver = resolvers.values.find { - it.canResolve(potentialDID) - } - return (resolver != null) - } - - /** - * Looks for a [DIDResolver] that can resolve the provided [did] either by method if the did contains one or by trial - * - * @throws IllegalStateException if the proper resolver is not registered or produces `null` - * @throws IllegalArgumentException if the given [did] has no `method` but could be resolved by one of the registered resolvers and that one fails with `null` - */ - override suspend fun resolve(did: String): DIDDocument { - val (method, _) = parse(did) - - if (method.isBlank() || !resolvers.containsKey(method)) { - //if there is no clear mapping to a resolver, try each one that claims it can resolve - return resolvers.filterValues { - it.canResolve(did) - }.values.mapNotNull { - try { - it.resolve(did) - } catch (ex: Exception) { - null - } - }.firstOrNull() - ?: throw IllegalArgumentException("The provided did ($did) could not be resolved by any of the ${resolvers.size} registered resolvers") - } //no else clause, carry on - - if (resolvers.containsKey(method)) { - return resolvers[method]?.resolve(did) - ?: throw IllegalStateException("There DIDResolver for '$method' failed to resolve '$did' for an unknown reason.") - } else { - throw IllegalStateException("There is no DIDResolver registered to resolve '$method' DIDs and none of the other ${resolvers.size} registered ones can do it.") - } - } - - /** - * @hide - */ - internal fun parse(did: String): Pair { - val matchResult = didPattern.find(did) ?: return ("" to "") - val (method, identifier) = matchResult.destructured - return (method to identifier) - } - - //language=RegExp - private val didPattern = "^did:(.*?):(.+)".toRegex() -} diff --git a/universal-did/src/test/java/me/uport/sdk/universaldid/UniversalDIDTest.kt b/universal-did/src/test/java/me/uport/sdk/universaldid/UniversalDIDTest.kt deleted file mode 100644 index 2dadb53..0000000 --- a/universal-did/src/test/java/me/uport/sdk/universaldid/UniversalDIDTest.kt +++ /dev/null @@ -1,103 +0,0 @@ -package me.uport.sdk.universaldid - -import assertk.all -import assertk.assertThat -import assertk.assertions.isEmpty -import assertk.assertions.isEqualTo -import assertk.assertions.isFailure -import assertk.assertions.isInstanceOf -import kotlinx.coroutines.runBlocking -import me.uport.sdk.testhelpers.coAssert -import org.junit.Test - -class UniversalDIDTest { - - private val testDDO = object : DIDDocument { - override val context: String = "test context" - override val id: String = "1234" - override val publicKey: List = emptyList() - override val authentication: List = emptyList() - override val service: List = emptyList() - } - - private val testResolver = object : DIDResolver { - override fun canResolve(potentialDID: String): Boolean = true - - override val method: String = "test" - - override suspend fun resolve(did: String): DIDDocument { - return if (did.contains("test")) testDDO else throw IllegalArgumentException("can't use test resolver") - } - } - - @Test - fun `blank resolves to error`() { - UniversalDID.clearResolvers() - - coAssert { - UniversalDID.resolve("") - }.isFailure().all { - isInstanceOf(IllegalArgumentException::class) - } - } - - @Test - fun `testResolver resolves to error with blank`() { - UniversalDID.clearResolvers() - UniversalDID.registerResolver(testResolver) - - coAssert { - UniversalDID.resolve("") - }.isFailure().all { - isInstanceOf(IllegalArgumentException::class) - } - } - - @Test - fun `can register and find resolver`() = runBlocking { - UniversalDID.clearResolvers() - UniversalDID.registerResolver(testResolver) - - val ddo = UniversalDID.resolve("did:test:this is a test did") - assertThat(ddo).isEqualTo(testDDO) - } - - private val validDIDs = listOf( - "did:generic:0x0011223344556677889900112233445566778899", - "did:generic:01234", - "did:generic:has spaces", - "did:generic:more:colons", - "did:generic:01234#fragment-attached", - "did:generic:01234?key=value", - "did:generic:01234?key=value&other-key=other-value" - ) - - private val invalidDIDs = listOf( - "", - "0x0011223344556677889900112233445566778899", - "ethr:0x0011223344556677889900112233445566778899", - "did:ethr", - "did::something", - "did:ethr:" - ) - - @Test - fun `parses dids correctly`() { - validDIDs.forEach { - val (method, _) = UniversalDID.parse(it) - assertThat(method).isEqualTo("generic") - } - - invalidDIDs.forEach { - val (method, _) = UniversalDID.parse(it) - assertThat(method).isEmpty() - } - } - - @Test - fun `serializes to basic doc`() { - val docString = DIDDocumentImpl("test context", "example document").toJson() - //language=json - assertThat(docString).isEqualTo("""{"@context":"test context","id":"example document","publicKey":[],"authentication":[],"service":[]}""") - } -} diff --git a/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt b/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt index 1f58948..8837e55 100644 --- a/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt +++ b/web-did/src/test/java/me/uport/sdk/httpsdid/WebDIDResolverTest.kt @@ -18,7 +18,6 @@ import me.uport.sdk.universaldid.DIDDocumentImpl import me.uport.sdk.universaldid.DidResolverError import me.uport.sdk.universaldid.PublicKeyEntry import me.uport.sdk.universaldid.PublicKeyType -import me.uport.sdk.universaldid.UniversalDID import org.junit.Test import java.io.IOException @@ -152,22 +151,4 @@ class WebDIDResolverTest { val response = tested.resolve("did:web:example.com") assertThat(response).isEqualTo(exampleDidDoc) } - - @Test - fun `resolves documents through universal resolver`() = runBlocking { - - val http = mockk() - val tested = WebDIDResolver(http) - - coEvery { http.urlGet(any()) } returns exampleDidDocString - - UniversalDID.registerResolver(tested) - - val responseWeb = UniversalDID.resolve("did:web:example.com") - assertThat(responseWeb).isEqualTo(exampleDidDoc) - - val responseHttps = UniversalDID.resolve("did:https:example.com") - assertThat(responseHttps).isEqualTo(exampleDidDoc) - } - } From ea7278178e644f363ecbce427805d59801ca9c33 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:29:02 +0100 Subject: [PATCH 4/7] style: cleanup detekt baseline --- detekt_baseline.xml | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/detekt_baseline.xml b/detekt_baseline.xml index 00cd5c7..83f56c5 100644 --- a/detekt_baseline.xml +++ b/detekt_baseline.xml @@ -1,13 +1,5 @@ - - MaxLineLength:UniversalDID.kt$UniversalDID$ override suspend fun resolve(did: String): DIDDocument - MaxLineLength:UniversalDID.kt$UniversalDID$?: - MaxLineLength:UniversalDID.kt$UniversalDID$throw IllegalStateException("There is no DIDResolver registered to resolve '$method' DIDs and none of the other ${resolvers.size} registered ones can do it.") - MaxLineLength:UportIdentityDocument.kt$UportIdentityDocument$val image: ProfilePicture? = null - MaxLineLength:UportIdentityDocument.kt$UportIdentityDocument$val publicEncKey: String? = null - MaxLineLength:UportIdentityDocument.kt$UportIdentityDocument$val publicKey: String? = null - TooGenericExceptionCaught:UniversalDID.kt$UniversalDID$ex: Exception - + From 860545559a326087f6bfbab898a14e45a31f75f9 Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:45:42 +0100 Subject: [PATCH 5/7] refactor: remove the deprecated EthrDIDResolver constructor please use the EthrDIDResolver.Builder() helper with multi-network support --- .../me/uport/sdk/ethrdid/EthrDIDResolver.kt | 31 +---- .../uport/sdk/ethrdid/EthrDIDResolverTest.kt | 4 +- .../java/me/uport/sdk/jwt/JWTToolsJVMTest.kt | 2 - .../java/me/uport/sdk/jwt/TimestampTests.kt | 127 +----------------- 4 files changed, 7 insertions(+), 157 deletions(-) diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt index 1335fc8..5903ecb 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt @@ -42,34 +42,11 @@ import java.util.* * * Example ethr did: "did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a" */ -open class EthrDIDResolver : DIDResolver { +open class EthrDIDResolver private constructor(registryMap: RegistryMap, clock: ITimeProvider) : + DIDResolver { - private val _registryMap: RegistryMap - private val _timeProvider: ITimeProvider - - private constructor(registryMap: RegistryMap, clock: ITimeProvider) { - _timeProvider = clock - this._registryMap = registryMap - } - - @Deprecated( - "Constructing the resolver directly has been deprecated " + - "in favor of the Builder pattern that can supply multi-network configurations." + - "This will be removed in the next major release.", - ReplaceWith( - """EthrDIDResolver.Builder().addNetwork(EthrDIDNetwork("", registryAddress, rpc, "0x1")).build()""", - "me.uport.sdk.ethrdid.EthrDIDResolver.Companion.DEFAULT_REGISTRY_ADDRESS" - ) - ) - constructor( - rpc: JsonRPC, - registryAddress: String = DEFAULT_REGISTRY_ADDRESS, - timeProvider: ITimeProvider = SystemTimeProvider - ) { - val net = EthrDIDNetwork(DEFAULT_NETWORK_NAME, registryAddress, rpc, "0x1") - this._timeProvider = timeProvider - this._registryMap = RegistryMap().registerNetwork(net) - } + private val _registryMap: RegistryMap = registryMap + private val _timeProvider: ITimeProvider = clock override val method = "ethr" diff --git a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt index 45bc3e7..132c058 100644 --- a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt +++ b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt @@ -28,6 +28,7 @@ import me.uport.sdk.core.HttpClient import me.uport.sdk.core.Networks import me.uport.sdk.core.hexToBigInteger import me.uport.sdk.ethrdid.EthereumDIDRegistry.Events.DIDOwnerChanged +import me.uport.sdk.ethrdid.EthrDIDResolver.Companion.DEFAULT_REGISTRY_ADDRESS import me.uport.sdk.jsonrpc.JsonRPC import me.uport.sdk.jsonrpc.model.JsonRpcLogItem import me.uport.sdk.jsonrpc.model.exceptions.JSON_RPC_INTERNAL_ERROR_CODE @@ -804,10 +805,9 @@ class EthrDIDResolverTest { @Test fun `throws when registry is not configured`() { - val rpc = mockk() val resolver = EthrDIDResolver.Builder() - .addNetwork(EthrDIDNetwork("", "", rpc, "0x1")) + .addNetwork(EthrDIDNetwork("", DEFAULT_REGISTRY_ADDRESS, mockk(), "0x1")) .build() coAssert { resolver.resolve("did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a") diff --git a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt index 4888ab3..f52958d 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/JWTToolsJVMTest.kt @@ -1,5 +1,3 @@ -@file:Suppress("LargeClass") - package me.uport.sdk.jwt import assertk.all diff --git a/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt b/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt index 3606a5f..0db74ea 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/TimestampTests.kt @@ -24,9 +24,7 @@ import org.junit.Test class TimestampTests { companion object { - //mock timestamps - private const val NOW: Long = 1_500_000L //milliseconds private const val PAST: Long = 1_100L //seconds private const val FUTURE: Long = 1_900L //seconds @@ -36,35 +34,12 @@ class TimestampTests { @Before fun `mock DID documents before every test`() { - val jrpc = mockk() - //intentionally suppress deprecation here to test that the old constructor still works - @Suppress("DEPRECATION") - resolver = spyk(EthrDIDResolver(jrpc)) + resolver = mockk() coEvery { resolver.resolve(any()) } returns mockDocForAddress("0xcf03dd0a894ef79cb5b601a43c4b25e3ae4c67ed") } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `pass when nbf exists in the past (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - - val jwt = - """eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJuYmYiOjExMDAsImlzcyI6IjB4Y2YwM2RkMGE4OTRlZjc5Y2I1YjYwMWE0M2M0YjI1ZTNhZTRjNjdlZCJ9.w14TBtuK2k65tGYk1QmkehfQt3CBwTS0h23yKIliZZNB3wLgidyNpm8hIr04PLv4j-ayDlOLCZL73fGkd6YIJw""" - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded["nbf"]).isEqualTo(PAST) - assertThat(decoded.containsKey("iat")).isEqualTo(false) - - coAssert { - tested.verify(jwt, resolver) - }.isSuccess() - Unit - } - @Test fun `pass when nbf exists in the past`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) @@ -97,26 +72,6 @@ class TimestampTests { Unit } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `pass when nbf exists in the past and iat in the future (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - - val jwt = - """eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJuYmYiOjExMDAsImlhdCI6MTkwMCwiaXNzIjoiMHhjZjAzZGQwYTg5NGVmNzljYjViNjAxYTQzYzRiMjVlM2FlNGM2N2VkIn0.qX5KAuGp7MZzpnH4AIeoy3qy9ndXD-A4F9SwsquYxDP4DKdfD32J1HqRmg55JDnRqAMwKy7OrhXL-RlaXqp7kA""" - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded["nbf"]).isEqualTo(PAST) - assertThat(decoded["iat"]).isEqualTo(FUTURE) - - coAssert { - tested.verify(jwt, resolver) - }.isSuccess() - Unit - } - @Test fun `pass when nbf exists in the past and iat in the future`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) @@ -149,28 +104,6 @@ class TimestampTests { Unit } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `fail when nbf exists in the future (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - - val jwt = - """eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJuYmYiOjE5MDAsImlzcyI6IjB4Y2YwM2RkMGE4OTRlZjc5Y2I1YjYwMWE0M2M0YjI1ZTNhZTRjNjdlZCJ9.4Zk9GBiRuoTYT1PSCh5tlAYgjJmm9Oi-kA3--e2Jkw4MK3jUa09V-mDeIBHVxdmnKJ-F3XP2Rno3_gxcpuAciQ""" - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded["nbf"]).isEqualTo(FUTURE) - assertThat(decoded.containsKey("iat")).isEqualTo(false) - - coAssert { - tested.verify(jwt, resolver) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - hasMessage("Jwt not valid before nbf: $FUTURE") - } - } - @Test fun `fail when nbf exists in the future`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) @@ -195,28 +128,6 @@ class TimestampTests { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `fail when nbf exists in the future and iat in the past (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - - val jwt = - """eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJuYmYiOjE5MDAsImlhdCI6MTEwMCwiaXNzIjoiMHhjZjAzZGQwYTg5NGVmNzljYjViNjAxYTQzYzRiMjVlM2FlNGM2N2VkIn0.jzpRnNfKQdamPMSg9Pcz8iz24H9qICMYdIquNb1kFPrE4S5RlX4jWAr5RKgakknmOanSzl2mM5znjjH8hfrj4Q""" - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded["nbf"]).isEqualTo(FUTURE) - assertThat(decoded["iat"]).isEqualTo(PAST) - - coAssert { - tested.verify(jwt, resolver) - }.isFailure().all { - isInstanceOf(InvalidJWTException::class) - hasMessage("Jwt not valid before nbf: $FUTURE") - } - } - @Test fun `fail when nbf exists in the future and iat in the past`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) @@ -241,27 +152,6 @@ class TimestampTests { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `pass when nbf missing and iat in the past (deprecated)`() = runBlocking { - val tested = JWTTools(TestTimeProvider(NOW)) - val jwt = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpYXQiOjExMDAsImlzcyI6IjB4Y2YwM2RkMGE4OTRlZjc5Y2I1YjYwMWE0M2M0YjI1ZTNhZTRjNjdlZCJ9.PpTCCQ3goDOvFTZ-owZul6IXfA5Wk2sypnWLgyn2LWrS2Eu2bWBVZ8FIt52AzKoaX1yW79S3WT5ZRjdf4NtCzA" - - val (_, decoded, _) = tested.decodeRaw(jwt) - assertThat(decoded.containsKey("nbf")).isEqualTo(false) - assertThat(decoded["iat"]).isEqualTo(PAST) - - coAssert { - tested.verify(jwt, resolver) - }.isSuccess() - - Unit - } - @Test fun `pass when nbf missing and iat in the past`() = runBlocking { val tested = JWTTools(TestTimeProvider(NOW)) @@ -318,21 +208,6 @@ class TimestampTests { } } - @Deprecated( - "This test references the deprecated variant of JWTTools().verify()" + - "This will be removed in the next major release." - ) - @Test - fun `pass when nbf and iat both missing (deprecated)`() = runBlocking { - val jwt = - "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksifQ.eyJpc3MiOiIweGNmMDNkZDBhODk0ZWY3OWNiNWI2MDFhNDNjNGIyNWUzYWU0YzY3ZWQifQ.0z278XpJdjQIgvaqSiJMoqBPBjp5Fy-QqjyT8Sgcbe0KGpCyd7001vLXr09X5aJ5kdcQYnnJ6QFYZeStQWId4w" - val tested = JWTTools(TestTimeProvider(NOW)) - coAssert { - tested.verify(jwt, resolver) - }.isSuccess() - Unit - } - @Test fun `pass when nbf and iat both missing`() = runBlocking { From a7e28452b6f0f4f110129dc02ca35bf0be56c3eb Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 17:50:56 +0100 Subject: [PATCH 6/7] refactor: rename package for credential status test --- .../UniversalStatusResolverTests.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename credential-status/src/test/java/me/uport/sdk/{credential_status => credentialstatus}/UniversalStatusResolverTests.kt (98%) diff --git a/credential-status/src/test/java/me/uport/sdk/credential_status/UniversalStatusResolverTests.kt b/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt similarity index 98% rename from credential-status/src/test/java/me/uport/sdk/credential_status/UniversalStatusResolverTests.kt rename to credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt index 868094e..dfb577e 100644 --- a/credential-status/src/test/java/me/uport/sdk/credential_status/UniversalStatusResolverTests.kt +++ b/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt @@ -1,6 +1,6 @@ @file:Suppress("UndocumentedPublicFunction", "UndocumentedPublicClass") -package me.uport.sdk.credential_status +package me.uport.sdk.credentialstatus import assertk.all import assertk.assertThat From a9803514bb0e3d0f63a1d7b107aea1367b01540e Mon Sep 17 00:00:00 2001 From: Mircea Nistor Date: Sat, 21 Mar 2020 18:16:35 +0100 Subject: [PATCH 7/7] refactor: rename the Eth Contract ABI wrappers and make them internal --- .../UniversalStatusResolverTests.kt | 2 -- ...EthereumDIDRegistry.kt => Erc1056Contract.kt} | 4 ++-- .../main/java/me/uport/sdk/ethrdid/EthrDID.kt | 10 +++++----- .../java/me/uport/sdk/ethrdid/EthrDIDResolver.kt | 11 ++++++----- .../me/uport/sdk/ethrdid/EthrDIDResolverTest.kt | 16 ++++++++++------ .../uport/sdk/ethrstatus/RevocationContract.kt | 4 ++-- jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt | 1 - .../java/me/uport/sdk/jwt/model/JwtHeader.kt | 4 +--- .../java/me/uport/sdk/jwt/model/JwtPayload.kt | 4 +--- .../me/uport/sdk/jwt/SerializationTesting.kt | 5 ++--- publishing.gradle | 3 +-- .../me/uport/sdk/universaldid/DIDDocument.kt | 2 +- 12 files changed, 31 insertions(+), 35 deletions(-) rename ethr-did/src/main/java/me/uport/sdk/ethrdid/{EthereumDIDRegistry.kt => Erc1056Contract.kt} (98%) diff --git a/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt b/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt index dfb577e..03f670b 100644 --- a/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt +++ b/credential-status/src/test/java/me/uport/sdk/credentialstatus/UniversalStatusResolverTests.kt @@ -1,5 +1,3 @@ -@file:Suppress("UndocumentedPublicFunction", "UndocumentedPublicClass") - package me.uport.sdk.credentialstatus import assertk.all diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthereumDIDRegistry.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/Erc1056Contract.kt similarity index 98% rename from ethr-did/src/main/java/me/uport/sdk/ethrdid/EthereumDIDRegistry.kt rename to ethr-did/src/main/java/me/uport/sdk/ethrdid/Erc1056Contract.kt index 019f8ff..a3b3465 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthereumDIDRegistry.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/Erc1056Contract.kt @@ -1,4 +1,4 @@ -@file:Suppress("UndocumentedPublicFunction", "UndocumentedPublicClass", "MagicNumber") +@file:Suppress("MagicNumber") package me.uport.sdk.ethrdid @@ -15,7 +15,7 @@ import java.math.BigInteger * To generate the full interface use the * [bivrost](https://github.com/gnosis/bivrost-kotlin) tool on `/abi/EthereumDIDRegistry.json` */ -class EthereumDIDRegistry { +internal class Erc1056Contract { object Changed { private const val METHOD_ID: String = "f96d0f9f" diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt index fa7dc16..3e9cdb9 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDID.kt @@ -57,7 +57,7 @@ class EthrDID( suspend fun lookupOwner(cache: Boolean = true): String { if (cache && this.owner != null) return this.owner val encodedCall = - EthereumDIDRegistry.IdentityOwner.encode(Solidity.Address(address.hexToBigInteger())) + Erc1056Contract.IdentityOwner.encode(Solidity.Address(address.hexToBigInteger())) val rawResult = rpc.ethCall(registry, encodedCall) return rawResult.substring(rawResult.length - 40).prepend0xPrefix() } @@ -65,7 +65,7 @@ class EthrDID( suspend fun changeOwner(newOwner: String, txOptions: TransactionOptions? = null): String { val owner = lookupOwner() - val encodedCall = EthereumDIDRegistry.ChangeOwner.encode( + val encodedCall = Erc1056Contract.ChangeOwner.encode( Solidity.Address(address.hexToBigInteger()), Solidity.Address(newOwner.hexToBigInteger()) ) @@ -80,7 +80,7 @@ class EthrDID( ): String { val owner = lookupOwner() - val encodedCall = EthereumDIDRegistry.AddDelegate.encode( + val encodedCall = Erc1056Contract.AddDelegate.encode( Solidity.Address(this.address.hexToBigInteger()), Solidity.Bytes32(options.delegateType.name.toByteArray(utf8)), Solidity.Address(delegate.hexToBigInteger()), @@ -96,7 +96,7 @@ class EthrDID( txOptions: TransactionOptions? = null ): String { val owner = this.lookupOwner() - val encodedCall = EthereumDIDRegistry.RevokeDelegate.encode( + val encodedCall = Erc1056Contract.RevokeDelegate.encode( Solidity.Address(this.address.hexToBigInteger()), Solidity.Bytes32(delegateType.name.toByteArray(utf8)), Solidity.Address(delegate.hexToBigInteger()) @@ -112,7 +112,7 @@ class EthrDID( txOptions: TransactionOptions? = null ): String { val owner = this.lookupOwner() - val encodedCall = EthereumDIDRegistry.SetAttribute.encode( + val encodedCall = Erc1056Contract.SetAttribute.encode( Solidity.Address(this.address.hexToBigInteger()), Solidity.Bytes32(key.toByteArray(utf8)), Solidity.Bytes(value.toByteArray(utf8)), diff --git a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt index 5903ecb..6d8f32d 100644 --- a/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt +++ b/ethr-did/src/main/java/me/uport/sdk/ethrdid/EthrDIDResolver.kt @@ -9,9 +9,9 @@ import me.uport.sdk.core.hexToBigInteger import me.uport.sdk.core.hexToByteArray import me.uport.sdk.core.prepend0xPrefix import me.uport.sdk.core.toBase64 -import me.uport.sdk.ethrdid.EthereumDIDRegistry.Events.DIDAttributeChanged -import me.uport.sdk.ethrdid.EthereumDIDRegistry.Events.DIDDelegateChanged -import me.uport.sdk.ethrdid.EthereumDIDRegistry.Events.DIDOwnerChanged +import me.uport.sdk.ethrdid.Erc1056Contract.Events.DIDAttributeChanged +import me.uport.sdk.ethrdid.Erc1056Contract.Events.DIDDelegateChanged +import me.uport.sdk.ethrdid.Erc1056Contract.Events.DIDOwnerChanged import me.uport.sdk.jsonrpc.JsonRPC import me.uport.sdk.jsonrpc.model.exceptions.JsonRpcException import me.uport.sdk.signer.Signer @@ -79,7 +79,8 @@ open class EthrDIDResolver private constructor(registryMap: RegistryMap, clock: val registryAddress = ethNetworkConfig.registryAddress require(registryAddress.isNotBlank()) { - "The registry address configured for network `$networkIdentifier` is blank." + "The registryAddress configured for network `${ethNetworkConfig.name}` is blank. " + + "Please check the configuration you use in your EthrDIDResolver.Builder" } val normalizedDid = normalizeDid(did) @@ -102,7 +103,7 @@ open class EthrDIDResolver private constructor(registryMap: RegistryMap, clock: registryAddress: String ): String { val encodedCall = - EthereumDIDRegistry.Changed.encode(Solidity.Address(identity.hexToBigInteger())) + Erc1056Contract.Changed.encode(Solidity.Address(identity.hexToBigInteger())) return try { rpc.ethCall(registryAddress, encodedCall) } catch (err: JsonRpcException) { diff --git a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt index 132c058..922ab7f 100644 --- a/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt +++ b/ethr-did/src/test/java/me/uport/sdk/ethrdid/EthrDIDResolverTest.kt @@ -27,7 +27,7 @@ import kotlinx.coroutines.runBlocking import me.uport.sdk.core.HttpClient import me.uport.sdk.core.Networks import me.uport.sdk.core.hexToBigInteger -import me.uport.sdk.ethrdid.EthereumDIDRegistry.Events.DIDOwnerChanged +import me.uport.sdk.ethrdid.Erc1056Contract.Events.DIDOwnerChanged import me.uport.sdk.ethrdid.EthrDIDResolver.Companion.DEFAULT_REGISTRY_ADDRESS import me.uport.sdk.jsonrpc.JsonRPC import me.uport.sdk.jsonrpc.model.JsonRpcLogItem @@ -386,7 +386,7 @@ class EthrDIDResolverTest { val identity = "0xf3beac30c498d9e26865f34fcaa57dbb935b0d74" val owner = identity - val event = EthereumDIDRegistry.Events.DIDAttributeChanged.Arguments( + val event = Erc1056Contract.Events.DIDAttributeChanged.Arguments( identity = Solidity.Address(identity.hexToBigInteger()), name = Solidity.Bytes32("did/pub/Secp256k1/veriKey/base64".toByteArray()), value = Solidity.Bytes("0x02b97c30de767f084ce3080168ee293053ba33b235d7116a3263d29f1450936b71".hexToByteArray()), @@ -804,15 +804,19 @@ class EthrDIDResolverTest { } @Test - fun `throws when registry is not configured`() { + fun `throws when registry address is not configured`() { val resolver = EthrDIDResolver.Builder() - .addNetwork(EthrDIDNetwork("", DEFAULT_REGISTRY_ADDRESS, mockk(), "0x1")) + .addNetwork(EthrDIDNetwork("", "", mockk(), "0x1")) .build() coAssert { resolver.resolve("did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a") }.isFailure().all { isInstanceOf(IllegalArgumentException::class) + hasMessage( + "The registryAddress configured for network `` is blank. " + + "Please check the configuration you use in your EthrDIDResolver.Builder" + ) } } @@ -820,7 +824,7 @@ class EthrDIDResolverTest { fun `parses attribute changed event with trailing null chars`() = runBlocking { val resolver = EthrDIDResolver.Builder().build() - val event = EthereumDIDRegistry.Events.DIDAttributeChanged.Arguments( + val event = Erc1056Contract.Events.DIDAttributeChanged.Arguments( identity = Solidity.Address(BigInteger("1318742768210968905798991064222156353846287247782")), name = Solidity.Bytes32("0x6469642f7075622f736563703235366b312f766572694b65792f686578000000".hexToByteArray()), value = Solidity.Bytes("0x0295dda1dca7f80e308ef60155ddeac00e46b797fd40ef407f422e88d2467a27eb".hexToByteArray()), @@ -856,7 +860,7 @@ class EthrDIDResolverTest { } throws JsonRpcException(JSON_RPC_INTERNAL_ERROR_CODE, "fake error") val resolver = EthrDIDResolver.Builder() - .addNetwork(EthrDIDNetwork("", "0xregistry", rpc, "0x1")).build() + .addNetwork(EthrDIDNetwork("", DEFAULT_REGISTRY_ADDRESS, rpc, "0x1")).build() coAssert { resolver.lastChanged("0xb9c5714089478a327f09197987f16f9e5d936e8a", rpc, "0xregistry") }.isFailure().all { diff --git a/ethr-status/src/main/java/me/uport/sdk/ethrstatus/RevocationContract.kt b/ethr-status/src/main/java/me/uport/sdk/ethrstatus/RevocationContract.kt index e6b0d1a..27b203b 100644 --- a/ethr-status/src/main/java/me/uport/sdk/ethrstatus/RevocationContract.kt +++ b/ethr-status/src/main/java/me/uport/sdk/ethrstatus/RevocationContract.kt @@ -1,4 +1,4 @@ -@file:Suppress("UndocumentedPublicFunction", "UndocumentedPublicClass", "unused") +@file:Suppress("unused") package me.uport.sdk.ethrstatus @@ -10,7 +10,7 @@ import pm.gnosis.model.SolidityBase * * This class was generated using the bivrost tools */ -class RevocationContract { +internal class RevocationContract { object Revoked { private const val METHOD_ID: String = "e46e3846" diff --git a/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt b/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt index 6de0cbe..e5f8a9e 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/JWTTools.kt @@ -1,6 +1,5 @@ @file:Suppress( "KDocUnresolvedReference", - "EXPERIMENTAL_API_USAGE", "ThrowsCount", "MagicNumber" ) diff --git a/jwt/src/main/java/me/uport/sdk/jwt/model/JwtHeader.kt b/jwt/src/main/java/me/uport/sdk/jwt/model/JwtHeader.kt index 1305774..4730105 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/model/JwtHeader.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/model/JwtHeader.kt @@ -1,5 +1,3 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") - package me.uport.sdk.jwt.model import kotlinx.serialization.Serializable @@ -26,6 +24,6 @@ class JwtHeader( jsonAdapter.parse(serializer(), headerString) private val jsonAdapter = - Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true)) + Json(JsonConfiguration.Stable.copy(isLenient = true, ignoreUnknownKeys = true)) } } diff --git a/jwt/src/main/java/me/uport/sdk/jwt/model/JwtPayload.kt b/jwt/src/main/java/me/uport/sdk/jwt/model/JwtPayload.kt index 3abd273..f013b2c 100644 --- a/jwt/src/main/java/me/uport/sdk/jwt/model/JwtPayload.kt +++ b/jwt/src/main/java/me/uport/sdk/jwt/model/JwtPayload.kt @@ -1,5 +1,3 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") - package me.uport.sdk.jwt.model import kotlinx.serialization.ContextualSerialization @@ -83,6 +81,6 @@ data class JwtPayload( jsonAdapter.parse(serializer(), payloadString) private val jsonAdapter = - Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true)) + Json(JsonConfiguration.Stable.copy(isLenient = true, ignoreUnknownKeys = true)) } } diff --git a/jwt/src/test/java/me/uport/sdk/jwt/SerializationTesting.kt b/jwt/src/test/java/me/uport/sdk/jwt/SerializationTesting.kt index d3cd703..3016805 100644 --- a/jwt/src/test/java/me/uport/sdk/jwt/SerializationTesting.kt +++ b/jwt/src/test/java/me/uport/sdk/jwt/SerializationTesting.kt @@ -1,5 +1,3 @@ -@file:Suppress("MemberVisibilityCanBePrivate", "EXPERIMENTAL_API_USAGE") - package me.uport.sdk.jwt import assertk.assertThat @@ -45,7 +43,8 @@ class SerializationTesting { ) ) ) - val serialized = Json.stringify(CompoundTestObject.serializer(), aa) + val serialized = + Json(JsonConfiguration.Stable).stringify(CompoundTestObject.serializer(), aa) assertThat(serialized).isEqualTo("""{"generic":{"hello":"world","missing":null,"some number":4321,"number as string":"1234","boolean":false,"boolean as string":"true","custom object":{"@context":["asdf"]},"obj":{"a":"b","c":null}}}""") } diff --git a/publishing.gradle b/publishing.gradle index 47655bf..d30b8b8 100644 --- a/publishing.gradle +++ b/publishing.gradle @@ -2,7 +2,6 @@ // bintray_api_key // bintray_username - def gitUrl = "https://github.com/uport-project/kotlin-did-jwt.git" def groupID = "com.github.uport-project.kotlin-did-jwt" def siteUrl = "https://developer.uport.me" @@ -53,7 +52,7 @@ subprojects { subproject -> } task sourcesJar(type: Jar) { - classifier = 'sources' + archiveClassifier.set('sources') if (subproject.hasProperty("android")) { from android.sourceSets.main.javaDirectories } else { diff --git a/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt b/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt index 31ab91e..04ee1c3 100644 --- a/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt +++ b/universal-did/src/main/java/me/uport/sdk/universaldid/DIDDocument.kt @@ -1,4 +1,4 @@ -@file:Suppress("EXPERIMENTAL_API_USAGE") +@file:Suppress("unused") package me.uport.sdk.universaldid