Skip to content

Commit

Permalink
Merge pull request #12 from push-protocol/fix-profile-updates
Browse files Browse the repository at this point in the history
Fix profile updates
  • Loading branch information
gbogboadePush authored Apr 2, 2024
2 parents f5bb6a4 + 1540b0f commit 87f982a
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 43 deletions.
2 changes: 2 additions & 0 deletions lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
implementation("ch.qos.logback:logback-classic:1.2.5")
implementation("org.json:json:20210307")
implementation("com.soywiz.korlibs.krypto:krypto:2.4.12")

api("com.google.protobuf:protobuf-kotlin-lite:3.22.3")


Expand Down
28 changes: 27 additions & 1 deletion lib/src/main/kotlin/push/kotlin/sdk/Helpers/Hash.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package push.kotlin.sdk.HahHelper

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import org.web3j.crypto.Hash


Expand All @@ -14,10 +16,34 @@ fun GenerateSHA256Hash(message:String):String{
return hashBytes.joinToString("") { "%02x".format(it) }
}


fun GenerateSHA256Hash(message:Any):String{
val jsonString = GsonBuilder().serializeNulls().create().toJson(message)
val utf8Bytes = jsonString.toByteArray(Charsets.UTF_8)
val hashBytes = Hash.sha256(utf8Bytes)
return hashBytes.joinToString("") { "%02x".format(it) }
}

fun GenerateSHA256Hash_(message:String ):String{
// val jsonString = Json.encodeToString(message)
// println(jsonString)
// val bytes = jsonString.toByteArray(Charsets.UTF_8)
return MessageDigest
.getInstance("SHA-256")
.digest(message.toByteArray())
.fold("", { str, it -> str + "%02x".format(it) })

// val digest = MessageDigest.getInstance("SHA-256")
// val hashBytes = digest.digest(bytes)
//
// // Convert the byte array to a hexadecimal string
// val hexString = StringBuilder()
// for (byte in hashBytes) {
// val hex = Integer.toHexString(0xff and byte.toInt())
// if (hex.length == 1) {
// hexString.append('0')
// }
// hexString.append(hex)
// }
// return hexString.toString()
}

101 changes: 78 additions & 23 deletions lib/src/main/kotlin/push/kotlin/sdk/ProfileCreator/ProfileCreator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import push.kotlin.sdk.*
import push.kotlin.sdk.HahHelper.GenerateSHA256Hash
import push.kotlin.sdk.HahHelper.GenerateSHA256Hash_
import push.kotlin.sdk.JsonHelpers.GetJsonStringFromGenericKV
import push.kotlin.sdk.JsonHelpers.GetJsonStringFromKV
import push.kotlin.sdk.JsonHelpers.ListToJsonString
Expand All @@ -25,26 +26,67 @@ fun ByteArray.toHexString(): String {
}

data class UserProfileBlock(val userAddress: String, val userPgpPrivateKey: String, val addresses:List<String>, val env: ENV,){
public fun block():Result<Boolean>{
val _addresses = addresses.map { el -> Helpers.walletToPCAIP(el) }
/* public fun block():Result<Boolean>{
val addresses = addresses.map { el -> Helpers.walletToPCAIP(el) }
val user = PushUser.getUser(userAddress, env) ?: return Result.failure(IllegalStateException("User $userAddress not found"))
val userProfile = user.profile
val user = PushUser.getUser(userAddress, env) ?: return Result.failure(IllegalStateException("User $userAddress not found"))
val userProfile = user.profile
print("blocked list: ");
if(userProfile.blockedUsersList == null){
userProfile.blockedUsersList = _addresses
}else{
val _lists:MutableList<String> = userProfile.blockedUsersList!!.toMutableList()
_addresses.forEach { el ->
if(userProfile.blockedUsersList == null){
// userProfile.blockedUsersList = addresses
userProfile.blockedUsersList = emptyList()
}
// else{
// val lists:MutableList<String> = userProfile.blockedUsersList!!.toMutableList()
// addresses.forEach { el ->
// if (!userProfile.blockedUsersList!!.contains(Helpers.walletToPCAIP(el))){
// lists += el
// }
// }
//
// userProfile.blockedUsersList = lists
// }
val lists:MutableList<String> = userProfile.blockedUsersList!!.toMutableList()
addresses.forEach { el ->
if (!userProfile.blockedUsersList!!.contains(Helpers.walletToPCAIP(el))){
_lists += el
lists += el
}
}
userProfile.blockedUsersList = _lists
userProfile.blockedUsersList = lists
return ProfileUpdater(userAddress, userProfile, userPgpPrivateKey, env).updateUserProfile()
}
*/

return ProfileUpdater(userAddress, userProfile, userPgpPrivateKey, env).updateUserProfile()
public fun block(): Result<Boolean> {
val user = PushUser.getUser(userAddress, env)
?: return Result.failure(IllegalStateException("User $userAddress not found"))


val userProfile = user.profile

val addressAlreadyBlock: List<String> =
userProfile.blockedUsersList ?: emptyList()

val addressToBlock: MutableList<String> = mutableListOf()
addressToBlock.addAll(addressAlreadyBlock)

val newAddressesToBlock = Helpers.walletsToPCAIP(addresses)

for (address in newAddressesToBlock) {
if (!addressAlreadyBlock.contains(address)) {
addressToBlock.add(address)
}
}

userProfile.blockedUsersList = addressToBlock
val profile = PushUser.ProfileInfo(picture = userProfile.picture, name = userProfile.name, blockedUsersList = addressToBlock,
desc = userProfile.desc, verificationProof = null)
return PushUser.updateUser(userAddress = userAddress, userProfile = profile, userPgpPrivateKey = userPgpPrivateKey, env)
}

public fun unblock():Result<Boolean>{
Expand All @@ -70,7 +112,7 @@ data class UserProfileBlock(val userAddress: String, val userPgpPrivateKey: Stri


class ProfileUpdater(val userAddress: String, val userProfile: PushUser.ProfileInfo, val userPgpPrivateKey:String, val env: ENV){
public fun updateUserProfile():Result<Boolean>{
fun updateUserProfile(): Result<Boolean> {
val hash = getUpdatedProfileHash(userProfile)
val sig = Pgp.sign(userPgpPrivateKey, hash).getOrElse { exception -> return Result.failure(exception) }
val sigType = "pgpv2"
Expand All @@ -80,15 +122,28 @@ class ProfileUpdater(val userAddress: String, val userProfile: PushUser.ProfileI
return updateUserService(payload, userAddress, env)
}

data class UpdateUserPayload(val name:String, val desc:String, val picture:String, val blockedUsersList:List<String>, val verificationProof:String)
data class UpdateUserPayload(val name: String?, val desc: String?, val picture: String?, val blockedUsersList: List<String>?, val verificationProof: String)

companion object{
fun getUpdatedProfileHashV2(updatedUser: PushUser.ProfileInfo): String {
val jsonString = mapOf(
"name" to if (updatedUser.name != null) updatedUser.name else " ",
"desc" to if (updatedUser.desc != null) updatedUser.desc else " ",
"picture" to if (updatedUser.picture != null) updatedUser.picture else " ",
"blockedUsersList" to if (updatedUser.blockedUsersList == null) emptyList() else
updatedUser.blockedUsersList,
)
println("body to sign $jsonString")

return GenerateSHA256Hash(jsonString)
}

fun getUpdatedProfileHash(updatedUser:PushUser.ProfileInfo):String{
var profileJsonString = GetJsonStringFromGenericKV(listOf(
Pair("name", JsonPrimitive(updatedUser.name ?: " ")),
Pair("desc", JsonPrimitive(updatedUser.desc ?: " ")),
Pair("picture", JsonPrimitive(updatedUser.picture ?: " ")),
"blockedUsersList" to JsonPrimitive("--members--replace"),
Pair("name", JsonPrimitive(updatedUser.name ?: " ")),
Pair("desc", JsonPrimitive(updatedUser.desc ?: " ")),
Pair("picture", JsonPrimitive(updatedUser.picture ?: " ")),
"blockedUsersList" to JsonPrimitive("--members--replace"),
))

val members:List<String> = updatedUser.blockedUsersList ?: listOf<String>();
Expand All @@ -97,14 +152,14 @@ class ProfileUpdater(val userAddress: String, val userProfile: PushUser.ProfileI
profileJsonString = profileJsonString.replace("\"[","[")
profileJsonString = profileJsonString.replace("]\"","]")

return GenerateSHA256Hash(profileJsonString)
return GenerateSHA256Hash_(profileJsonString)
}

fun getUpdateUserPayload(updatedUser: PushUser.ProfileInfo, verificationProof: String):UpdateUserPayload{
return UpdateUserPayload(
name = updatedUser.name ?: " ",
desc = updatedUser.desc ?: " ",
picture = updatedUser.picture ?: " ",
name = updatedUser.name ?: " ",
desc = updatedUser.desc ?: " ",
picture = updatedUser.picture ?: " ",
blockedUsersList = updatedUser.blockedUsersList ?: listOf(),
verificationProof = verificationProof
)
Expand All @@ -114,7 +169,7 @@ class ProfileUpdater(val userAddress: String, val userProfile: PushUser.ProfileI
try {
val url = PushURI.updateUser(env, userAddress)
val mediaType = "application/json; charset=utf-8".toMediaType()
val body = Gson().toJson(payload).toRequestBody(mediaType)
val body = GsonBuilder().serializeNulls().create().toJson(payload).toRequestBody(mediaType)

val client = OkHttpClient()
val request = Request.Builder().url(url).put(body).build()
Expand Down
2 changes: 1 addition & 1 deletion lib/src/main/kotlin/push/kotlin/sdk/User/PushUser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class PushUser {
}

public fun blockUser(userAddress: String, userPgpPrivateKey: String, addressToBlock:List<String>,env: ENV):Result<Boolean>{
return UserProfileBlock(userAddress, userPgpPrivateKey, addressToBlock, env).block()
return UserProfileBlock(userAddress=userAddress,userPgpPrivateKey= userPgpPrivateKey,addresses= addressToBlock, env).block()
}

public fun unblockUser(userAddress: String, userPgpPrivateKey: String, addressToUnBlock:List<String>,env: ENV):Result<Boolean>{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package push.kotlin.sdk.GroupTests

import BASE_64_IMAGE
import com.google.gson.Gson
import getNewSinger
import getSingerWithKey
import org.junit.jupiter.api.Test
import push.kotlin.sdk.*
import push.kotlin.sdk.ChatFunctions.ApproveOptions
import push.kotlin.sdk.ChatFunctions.ChatApprover
import push.kotlin.sdk.Group.PushGroup
import push.kotlin.sdk.HahHelper.GenerateSHA256Hash
import kotlin.test.assertEquals

class UpdateGroupTest {
Expand Down Expand Up @@ -226,6 +223,7 @@ class UpdateGroupTest {
val newUser = PushUser.createUser(signer, ENV.staging).getOrThrow()
val pgpPK = DecryptPgp.decryptPgpKey(newUser.encryptedPrivateKey, signer).getOrThrow()


val createOptions = PushGroup.CreateGroupOptionsV2(
name = "$newAddress group",
description = "group made my the user $newAddress for testing",
Expand Down
77 changes: 62 additions & 15 deletions lib/src/test/kotlin/push/kotlin/sdk/PushUser.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package push.kotlin.sdk

import BASE_64_IMAGE
import getNewSinger
import getSingerWithKey
import kotlinx.serialization.json.JsonPrimitive
import push.kotlin.sdk.HahHelper.GenerateSHA256Hash
import push.kotlin.sdk.HahHelper.GenerateSHA256Hash_
import push.kotlin.sdk.JsonHelpers.GetJsonStringFromGenericKV
import push.kotlin.sdk.ProfileCreator.ProfileCreator
import kotlin.test.Test
import kotlin.test.assertEquals
Expand Down Expand Up @@ -85,41 +91,82 @@ class PushUserTest {
assertEquals(userAgain.profile.picture, "Updated user $userAddress")
}

@Test fun userBlockUnBlock(){
@Test
fun updateUserUpdate() {
val (userAddress, signer) = getNewSinger()
val user = PushUser.createUser(signer, ENV.staging).getOrThrow();

val pgpPK = DecryptPgp.decryptPgpKey(user.encryptedPrivateKey, signer).getOrThrow()

val userData = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")

userData.profile.blockedUsersList = mutableListOf("eip155:0x1669d6484494eed4995bf4985e545245a280c38e")

PushUser.updateUser(userAddress, userData.profile, pgpPK, ENV.staging).getOrThrow()

val userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")

// assertEquals(userAgain.profile.picture, picture)

// assertEquals(userAgain.profile.blockedUsersList?.size, 1)
}

@Test
fun updateUserForSigner() {

val (userAddress, signer) = getSingerWithKey("14908f59f935507f280b92f88127df9af92ec31cc7799dddb1e001a59de1d6fe")

val userData = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
val pgpPK = DecryptPgp.decryptPgpKey(userData.encryptedPrivateKey, signer).getOrThrow()

val picture = BASE_64_IMAGE

userData.profile.blockedUsersList = mutableListOf("eip155:0x1669d6484494eed4995bf4985e545245a280c38e")

val (addrs1, _) = getNewSinger()
val (addrs2, _) = getNewSinger()
PushUser.updateUser(userAddress, userData.profile, pgpPK, ENV.staging).getOrThrow()

val userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")


assertEquals(userAgain.profile.blockedUsersList?.size, 1)
}

@Test fun userBlockUnBlock(){
val (userAddress, signer) = getNewSinger()

val user = PushUser.createUser(signer, ENV.staging).getOrThrow();
val pgpPK = DecryptPgp.decryptPgpKey(user.encryptedPrivateKey, signer).getOrThrow()

val (address1, _) = getNewSinger()
val (address2, _) = getNewSinger()

// Block tests
PushUser.blockUser(userAddress, pgpPK, listOf(addrs1),ENV.staging).getOrThrow()
var userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.blockUser(userAddress, pgpPK, listOf(address1), ENV.staging).getOrThrow()
var userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 1)

PushUser.blockUser(userAddress, pgpPK, listOf(addrs1),ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.blockUser(userAddress, pgpPK, listOf(address1), ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 1)

PushUser.blockUser(userAddress, pgpPK, listOf(addrs2),ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.blockUser(userAddress, pgpPK, listOf(address2), ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 2)

// Un Block tests
PushUser.unblockUser(userAddress, pgpPK, listOf(addrs2),ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.unblockUser(userAddress, pgpPK, listOf(address2), ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 1)

PushUser.unblockUser(userAddress, pgpPK, listOf(addrs2),ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.unblockUser(userAddress, pgpPK, listOf(address2), ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 1)

PushUser.unblockUser(userAddress, pgpPK, listOf(addrs1),ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
PushUser.unblockUser(userAddress, pgpPK, listOf(address1), ENV.staging).getOrThrow()
userAgain = PushUser.getUser(userAddress, ENV.staging) ?: throw IllegalStateException("")
assertEquals(userAgain.profile.blockedUsersList!!.size, 0)

}


}
1 change: 1 addition & 0 deletions lib/src/test/kotlin/testHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fun getRandomEthPrivateKey(): String {
}
fun getNewSinger():Pair<String, Signer>{
val privateKey = getRandomEthPrivateKey()
println("privateKey: $privateKey ")
val signer = PrivateKeySigner(privateKey)
val address = signer.getAddress().getOrThrow()

Expand Down

0 comments on commit 87f982a

Please sign in to comment.