From 38a7aff70e398da79f71d6118ccba813f0a6c349 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Fri, 3 Jun 2022 11:21:57 +0200
Subject: [PATCH] Add Identity codable model

---
 Package.swift                                 | 12 +++++-
 Sources/ElixxirDAppsSDK/Identity.swift        | 27 +++++++++++++
 .../ElixxirDAppsSDKTests/IdentityTests.swift  | 38 +++++++++++++++++++
 Tests/ElixxirDAppsSDKTests/TestHelpers.swift  | 17 +++++++++
 4 files changed, 93 insertions(+), 1 deletion(-)
 create mode 100644 Sources/ElixxirDAppsSDK/Identity.swift
 create mode 100644 Tests/ElixxirDAppsSDKTests/IdentityTests.swift
 create mode 100644 Tests/ElixxirDAppsSDKTests/TestHelpers.swift

diff --git a/Package.swift b/Package.swift
index 4cf23277..5f0bf3ed 100644
--- a/Package.swift
+++ b/Package.swift
@@ -26,6 +26,12 @@ let package = Package(
       targets: ["ElixxirDAppsSDK"]
     ),
   ],
+  dependencies: [
+    .package(
+      url: "https://github.com/pointfreeco/swift-custom-dump.git",
+      .upToNextMajor(from: "0.4.0")
+    ),
+  ],
   targets: [
     .target(
       name: "ElixxirDAppsSDK",
@@ -37,7 +43,11 @@ let package = Package(
     .testTarget(
       name: "ElixxirDAppsSDKTests",
       dependencies: [
-        .target(name: "ElixxirDAppsSDK")
+        .target(name: "ElixxirDAppsSDK"),
+        .product(
+          name: "CustomDump",
+          package: "swift-custom-dump"
+        ),
       ],
       swiftSettings: swiftSettings
     ),
diff --git a/Sources/ElixxirDAppsSDK/Identity.swift b/Sources/ElixxirDAppsSDK/Identity.swift
new file mode 100644
index 00000000..116fea14
--- /dev/null
+++ b/Sources/ElixxirDAppsSDK/Identity.swift
@@ -0,0 +1,27 @@
+import Foundation
+
+public struct Identity: Equatable, Codable {
+  enum CodingKeys: String, CodingKey {
+    case id = "ID"
+    case rsaPrivatePem = "RSAPrivatePem"
+    case salt = "Salt"
+    case dhKeyPrivate = "DHKeyPrivate"
+  }
+
+  public init(
+    id: Data,
+    rsaPrivatePem: Data,
+    salt: Data,
+    dhKeyPrivate: Data
+  ) {
+    self.id = id
+    self.rsaPrivatePem = rsaPrivatePem
+    self.salt = salt
+    self.dhKeyPrivate = dhKeyPrivate
+  }
+
+  public var id: Data
+  public var rsaPrivatePem: Data
+  public var salt: Data
+  public var dhKeyPrivate: Data
+}
diff --git a/Tests/ElixxirDAppsSDKTests/IdentityTests.swift b/Tests/ElixxirDAppsSDKTests/IdentityTests.swift
new file mode 100644
index 00000000..1a4fb85f
--- /dev/null
+++ b/Tests/ElixxirDAppsSDKTests/IdentityTests.swift
@@ -0,0 +1,38 @@
+import CustomDump
+import XCTest
+@testable import ElixxirDAppsSDK
+
+final class IdentityTests: XCTestCase {
+  func testCoding() throws {
+    let userId = secureRandomData(count: 32)
+    let rsaPrivateKey = secureRandomData(count: 32)
+    let salt = secureRandomData(count: 32)
+    let dhKeyPrivate = secureRandomData(count: 32)
+    let jsonString = """
+    {
+      "ID": \(userId.jsonEncodedBase64()),
+      "RSAPrivatePem": \(rsaPrivateKey.jsonEncodedBase64()),
+      "Salt": \(salt.jsonEncodedBase64()),
+      "DHKeyPrivate": \(dhKeyPrivate.jsonEncodedBase64())
+    }
+    """
+    let jsonData = jsonString.data(using: .utf8)!
+    let decoder = JSONDecoder()
+    decoder.dataDecodingStrategy = .base64
+    let identity = try decoder.decode(Identity.self, from: jsonData)
+
+    XCTAssertNoDifference(identity, Identity(
+      id: userId,
+      rsaPrivatePem: rsaPrivateKey,
+      salt: salt,
+      dhKeyPrivate: dhKeyPrivate
+    ))
+
+    let encoder = JSONEncoder()
+    encoder.dataEncodingStrategy = .base64
+    let encodedIdentity = try encoder.encode(identity)
+    let decodedIdentity = try decoder.decode(Identity.self, from: encodedIdentity)
+
+    XCTAssertNoDifference(decodedIdentity, identity)
+  }
+}
diff --git a/Tests/ElixxirDAppsSDKTests/TestHelpers.swift b/Tests/ElixxirDAppsSDKTests/TestHelpers.swift
new file mode 100644
index 00000000..ff545db0
--- /dev/null
+++ b/Tests/ElixxirDAppsSDKTests/TestHelpers.swift
@@ -0,0 +1,17 @@
+import Foundation
+
+func secureRandomData(count: Int) -> Data {
+  var bytes = [Int8](repeating: 0, count: count)
+  let status = SecRandomCopyBytes(kSecRandomDefault, count, &bytes)
+  assert(status == errSecSuccess)
+  return Data(bytes: bytes, count: count)
+}
+
+extension Data {
+  func jsonEncodedBase64() -> String {
+    let encoder = JSONEncoder()
+    encoder.dataEncodingStrategy = .base64
+    let data = try! encoder.encode(self)
+    return String(data: data, encoding: .utf8)!
+  }
+}
-- 
GitLab