Skip to content

Commit

Permalink
feat(encryption): initial api + tests (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhamann committed Jul 18, 2022
1 parent 80d845f commit 6289d42
Show file tree
Hide file tree
Showing 14 changed files with 767 additions and 24 deletions.
347 changes: 343 additions & 4 deletions RowndFramework.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,20 @@
<dict>
<key>SchemeUserState</key>
<dict>
<key>RowndFrameworkTestApp.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>45</integer>
</dict>
<key>RowndSDK.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>37</integer>
<integer>41</integer>
</dict>
<key>RowndTests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>44</integer>
</dict>
</dict>
</dict>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
6 changes: 6 additions & 0 deletions RowndFrameworkTestApp/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
21 changes: 21 additions & 0 deletions RowndFrameworkTestApp/ContentView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// ContentView.swift
// RowndFrameworkTestApp
//
// Created by Matt Hamann on 7/15/22.
//

import SwiftUI

struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
17 changes: 17 additions & 0 deletions RowndFrameworkTestApp/RowndFrameworkTestAppApp.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// RowndFrameworkTestAppApp.swift
// RowndFrameworkTestApp
//
// Created by Matt Hamann on 7/15/22.
//

import SwiftUI

@main
struct RowndFrameworkTestAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
101 changes: 101 additions & 0 deletions RowndTests/EncryptionTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//
// EncryptionTests.swift
// RowndTests
//
// Created by Matt Hamann on 7/15/22.
//

import XCTest
@testable import Rownd

class EncryptionTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
RowndEncryption.deleteKey(keyId: "my-test-account")
try super.setUpWithError()
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
RowndEncryption.deleteKey(keyId: "my-test-account")
try super.tearDownWithError()
}

func testGenerateSymmetricKey() throws {
let key = RowndEncryption.generateKey()
print("base64 key:", String(decoding: key.asData().base64EncodedData(), as: UTF8.self))
XCTAssertNotNil(key, "Generated encryption key was nil")
}

func testStoreSymmetricKey() throws {
let key = RowndEncryption.generateKey()
try RowndEncryption.storeKey(key: key, keyId: "my-test-account")
print("base64 key:", String(decoding: key.asData().base64EncodedData(), as: UTF8.self))
let atch = XCTAttachment(data: key.asData().base64EncodedData())
self.add(atch)
}

func testRetrieveSymmetricKey() throws {
let origKey = RowndEncryption.generateKey()
try RowndEncryption.storeKey(key: origKey, keyId: "my-test-account")
print("stored key:", String(decoding: origKey.asData().base64EncodedData(), as: UTF8.self))
let retKey = try RowndEncryption.loadKey(keyId: "my-test-account")
XCTAssertNotNil(retKey, "Failed to retrieve a key that should exist")
XCTAssertEqual(String(decoding: origKey.asData().base64EncodedData(), as: UTF8.self), String(decoding: retKey?.asData().base64EncodedData() ?? Data(), as: UTF8.self), "Stored and retrieved keys are not equal")

guard let key = retKey else {
return
}

print("retrieved key:", String(decoding: key.asData().base64EncodedData(), as: UTF8.self))
// print(key.asData().base64EncodedData())
let atch = XCTAttachment(data: key.asData().base64EncodedData())
self.add(atch)
}

func testEncryptingData() throws {
let keyId = "test-key"
let key = Array(Data(base64Encoded: "4f4a6IInDuSga0wyQQQpMSrDHIZ/ryoc9w6s5xVF/VQ=")!)
try RowndEncryption.storeKey(key: key, keyId: keyId)

let plainText = "This super secret string will never be known."
let cipherText: String = try RowndEncryption.encrypt(plaintext: plainText, withKeyId: keyId)

print(cipherText)

XCTAssertNotNil(cipherText, "Failed to encrypt plaintext into ciphertext")
}

func testDecryptingData() throws {
let keyId = "test-key"
let key = Array(Data(base64Encoded: "4f4a6IInDuSga0wyQQQpMSrDHIZ/ryoc9w6s5xVF/VQ=")!)
try RowndEncryption.storeKey(key: key, keyId: keyId)

let expectedPlainText = "This super secret string will never be known."
let cipherText = "Di0IyYbC141WIPKzFnlsQc0BIi1AWKSpLf6Th9TcDDJiidPfkVazXtFibnsqJyKFaQf7SaF68yihnqJXidodfKqKzjM2MnbHbh+O8wpxFO3gO6OhVg=="

let computedPlainText: String = try RowndEncryption.decrypt(ciphertext: cipherText, withKeyId: keyId)

print(computedPlainText)

XCTAssertEqual(expectedPlainText, computedPlainText, "The computed plaintext did not match the expected")
}

func testEncryptThenDecrypt() throws {
let keyId = "test-key"
let key = RowndEncryption.generateKey()
try RowndEncryption.storeKey(key: key, keyId: keyId)

let plainText = "This super secret string will never be known."
let cipherText: String = try RowndEncryption.encrypt(plaintext: plainText, withKeyId: keyId)

print(cipherText)

let computedPlainText: String = try RowndEncryption.decrypt(ciphertext: cipherText, withKeyId: keyId)

print(computedPlainText)

XCTAssertEqual(plainText, computedPlainText, "The original and computed plaintexts do not match even though the key matched")
}
}
35 changes: 35 additions & 0 deletions RowndTests/RowndTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// RowndTests.swift
// RowndTests
//
// Created by Matt Hamann on 7/15/22.
//

import XCTest

class RowndTests: XCTestCase {

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
// Any test you write for XCTest can be annotated as throws and async.
// Mark your test throws to produce an unexpected failure when your test encounters an uncaught error.
// Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards.
}

func testPerformanceExample() throws {
// This is an example of a performance test case.
measure {
// Put the code you want to measure the time of here.
}
}

}
2 changes: 1 addition & 1 deletion Sources/Rownd/Views/HubWebView/HubWebViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public enum HubPageSelector {
public class HubWebViewController: UIViewController, WKUIDelegate {

var webView: WKWebView!
var url = URL(string: "https://api.rownd.io/mobile_app")!
var url = URL(string: "https://hub.rownd.io/mobile_app")!
var hubViewController: HubViewProtocol?
var jsFunctionArgsAsJson: String = "{}"

Expand Down
2 changes: 1 addition & 1 deletion Sources/Rownd/framework/APIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ extension NetworkRequest {
logger.trace("API request body: \(String(decoding: body, as: UTF8.self))")
}

let task = URLSession.shared.dataTask(with: request) { [weak self] (data, resp , error) -> Void in
let task = URLSession.shared.dataTask(with: request) { [weak self] (data, resp, error) -> Void in
guard error == nil else {
logger.error("Network request failed: \(String(describing: error))")
return
Expand Down
Loading

0 comments on commit 6289d42

Please sign in to comment.