Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Threema/ThreemaTests/   (Social Medium ©)  Datei vom 26.9.2026 mit Größe 13 kB image not shown  

Quelle  SafeTests.swift   Sprache: JAVA

 

import RemoteSecretProtocolTestHelper
import ThreemaEssentials
import XCTest
@testable import Threema
@testable import ThreemaFramework

final class SafeTests: XCTestCase {

    override func setUp() {
        super.setUp()
        
        AppGroup.setGroupID("group.ch.threema") // THREEMA_GROUP_IDENTIFIER @"group.ch.threema"
        
        // Workaround to ensure remote secret is initialized
        let remoteSecretManagerMock = RemoteSecretManagerMock()
        AppLaunchManager.shared.setRemoteSecretManager(remoteSecretManagerMock)
    }

    func testSafeJsonParserCreate() {
        let parser = SafeJsonParser()
        let safeBackupData = parser.getSafeBackupData()
        let json = parser.getJsonAsString(from: safeBackupData)

        XCTAssertNotNil(json)
        XCTAssertNotNil(json?.range(of: "{\"info\":{"))
        XCTAssertNotNil(json?.range(of: "\"version\":1"))
        XCTAssertNotNil(json?.range(of: ","))
        XCTAssertNotNil(json?.range(of: "\"device\":\"ios\""))
        XCTAssertNotNil(json?.range(of: "}}"))
    }

    func testSafeJsonParserUser() {
        let user = SafeJsonParser.SafeBackupData.User(privatekey: "key123")
        user.nickname = "nicki"
        user.profilePic = "pic source"
        user.profilePicRelease = ["ECHOECHO", "TEST1234"]
        user.links = [SafeJsonParser.SafeBackupData.User.Link(type: "email", value: "a@a.a")]

        let parser = SafeJsonParser()
        var safeBackupData = parser.getSafeBackupData()
        safeBackupData.user = user

        let json = parser.getJsonAsString(from: safeBackupData)

        XCTAssertNotNil(json)
        XCTAssertNotNil(json?.range(of: "\"privatekey\":\"key123\""))
        XCTAssertNotNil(json?.range(of: "\"nickname\":\"nicki\""))
        XCTAssertNotNil(json?.range(of: "\"profilePic\":\"pic source\""))
        XCTAssertNotNil(json?.range(of: "\"profilePicRelease\":[\"ECHOECHO\",\"TEST1234\"]"))
        XCTAssertNotNil(json?.range(of: "\"links\":[{"))
        XCTAssertNotNil(json?.range(of: "\"type\":\"email\""))
        XCTAssertNotNil(json?.range(of: "\"value\":\"a@a.a\""))
        XCTAssertNotNil(json?.range(of: "}]"))
    }

    func testSafeJsonParserLoad() {
        let json =
            "{\"info\":{\"version\":1,\"device\":\"ios\"},\"user\":{\"links\":[{\"type\":\"email\",\"name\":\"privat\",\"value\":\"a@a.a\"}],\"nickname\":\"nicki\",\"privatekey\":\"key123\",\"profilePic\":\"pic source\",\"profilePicRelease\":[\"ECHOECHO\",\"TEST1234\"]}}"
        let parser = SafeJsonParser()
        let safeBackupData = try! parser.getSafeBackupData(from: Data(json.utf8))

        XCTAssertNotNil(safeBackupData)
        XCTAssertEqual(safeBackupData.user?.nickname, "nicki")
    }

    func testSafeStoreCreateKey() {
        let result = SafeStore.createKey(identity: "ECHOECHO", safePassword: "shootdeathstar")

        XCTAssertEqual(
            hexString(data: result!),
            "066384d3695fbbd9f31a7d533900fd0cd8d1373beb6a28678522d2a49980c9c351c3d8d752fb6e1fd3199ead7f0895d6e3893ff691f2a5ee1976ed0897fc2f66"
        )
    }

    func testSafeStoreGetBackupIDAndGetEncrptionKey() {
        let key = SafeStore.createKey(identity: "ECHOECHO", safePassword: "shootdeathstar")
        let backupID = SafeStore.getBackupID(key: key!)
        let encryptionKey = SafeStore.getEncryptionKey(key: key!)

        XCTAssertNotNil(backupID)
        XCTAssertNotNil(encryptionKey)
        XCTAssertEqual(32, backupID?.count)
        XCTAssertEqual(32, encryptionKey?.count)
        XCTAssertFalse(backupID!.elementsEqual(encryptionKey!))
    }

    private func hexString(data: [UInt8]) -> String {
        data.map { String(format: "%02hhx", $0) }.joined(separator: "")
    }

    func testSafeStoreBackupDataEncryptDecrypt() {
        let user = SafeJsonParser.SafeBackupData.User(privatekey: "key123")
        user.nickname = "nicki"
        let parser = SafeJsonParser()
        var dataIn = parser.getSafeBackupData()
        dataIn.user = user

        let store = SafeStore(
            safeConfigManager: SafeConfigManager(),
            serverApiConnector: ServerAPIConnector(),
            groupManager: GroupManagerMock(),
            myIdentityStore: MyIdentityStoreMock(),
            phoneNumberNormalizer: PhoneNumberNormalizerMock()
        )
        let key = SafeStore.createKey(identity: "ECHOECHO", safePassword: "shootdeathstar")
        let encryptedData = try! store.encryptBackupData(key: key!, data: parser.getJsonAsBytes(from: dataIn)!)
        let decryptedData = try! SafeStore.decryptBackupData(key: key!, data: encryptedData)

        let dataOut = try! parser.getSafeBackupData(from: Data(decryptedData))

        XCTAssertNotNil(dataOut.user)
        XCTAssertEqual("key123", dataOut.user?.privatekey)
        XCTAssertEqual("nicki", dataOut.user?.nickname)
    }
    
    func testSafeStoreDecryptBackupDataWithTooLittleData() throws {
        XCTAssertThrowsExpectedError(
            _ = try SafeStore.decryptBackupData(
                key: Array(repeating: 0x1, count: SafeStore.masterKeyLength),
                data: Array(repeating: 0x1, count: 23)
            ),
            SafeError.restoreError(.invalidData)
        )
    }
    
    func testSafeStoreDecryptBackupDataWithUndecryptableData() throws {
        XCTAssertThrowsExpectedError(
            _ = try SafeStore.decryptBackupData(
                key: Array(repeating: 0x1, count: SafeStore.masterKeyLength),
                data: Array(repeating: 0x1, count: 24)
            ),
            SafeError.restoreError(.invalidData)
        )
    }

    func testSafeManagerIsPasswordBad() {
        let passwordTests = [
            ["", true],
            ["1", true],
            ["a", true],
            ["aaaaaaaa", true],
            ["11111111", true],
            ["1111111w", false],
            ["83497585", true],
            ["123456789012345", true],
            ["1234567890123456", false],
            ["7777777777777777", true],
            ["834975 8", false],
            ["83497 8", true],
            ["        ", true],
            ["0000000000d", true],
            ["ronaldo7", true],
            ["Zzzzzzz1", true],
        ]

        for passwordTest in passwordTests {
            let isBad = SafeManager.isPasswordBad(password: passwordTest[0] as! String)

            if passwordTest[1] as! Bool {
                XCTAssert(isBad, "\(passwordTest[0]) isBad:\(isBad)")
            }
            else {
                XCTAssertFalse(isBad, "\(passwordTest[0]) isBad:\(isBad)")
            }
        }
    }

    func testSafeManagerIsPasswordPatternValid() {
        let passwordTests = [
            ["", false],
            ["12345678aA", true],
            ["123456789aA", true],
            ["1234567aA", false],
            ["12345678aa", false],
        ]

        // Password min. length 10 with min. one lowercase and one uppercase character
        let regExPattern = "(?=(.*[0-9]))(?=.*[a-z])(?=(.*[A-Z]))(?=(.*)).{10,}"
        
        for passwordTest in passwordTests {
            let result = try? SafeManager.isPasswordPatternValid(
                password: passwordTest[0] as! String,
                regExPattern: regExPattern
            )
            
            XCTAssertEqual(result, passwordTest[1] as! Bool)
        }
    }

    func testSafeSeverToDisplay() {
        let store = SafeStore(
            safeConfigManager: SafeConfigManagerMock(server: nil),
            serverApiConnector: ServerAPIConnector(),
            groupManager: GroupManagerMock(),
            myIdentityStore: MyIdentityStoreMock(),
            phoneNumberNormalizer: PhoneNumberNormalizerMock()
        )

        let result = store.getSafeServerToDisplay()

        XCTAssertNotNil(result)
    }

    func testSafeServerURLDefault() {
        let store = SafeStore(
            safeConfigManager: SafeConfigManagerMock(server: nil),
            serverApiConnector: ServerAPIConnector(),
            groupManager: GroupManagerMock(),
            myIdentityStore: MyIdentityStoreMock(),
            phoneNumberNormalizer: PhoneNumberNormalizerMock()
        )
        
        let key = SafeStore.createKey(identity: "ECHOECHO", safePassword: "shootdeathstar")!

        store.getSafeServer(key: key) { result in
            switch result {
            case let .success(safeServer):
                XCTAssertEqual(safeServer.server.absoluteString, "https://safe-06.threema.ch")

                XCTAssertEqual(
                    safeServer.server
                        .appendingPathComponent(
                            "backups/\(BytesUtility.toHexString(bytes: SafeStore.getBackupID(key: key)!))"
                        )
                        .absoluteString,
                    "https://safe-06.threema.ch/backups/066384d3695fbbd9f31a7d533900fd0cd8d1373beb6a28678522d2a49980c9c3"
                )
            case let .failure(error):
                XCTFail("\(error)")
            }
        }
    }

    func testSafeServerURLCustom() {
        let store = SafeStore(
            safeConfigManager: SafeConfigManagerMock(server: "http://test.com"),
            serverApiConnector: ServerAPIConnector(),
            groupManager: GroupManagerMock(),
            myIdentityStore: MyIdentityStoreMock(),
            phoneNumberNormalizer: PhoneNumberNormalizerMock()
        )
        
        let key = SafeStore.createKey(identity: "ECHOECHO", safePassword: "shootdeathstar")!

        store.getSafeServer(key: key) { result in
            switch result {
            case let .success(safeServer):
                XCTAssertEqual(safeServer.server.absoluteString, "http://test.com")

                XCTAssertEqual(
                    safeServer.server
                        .appendingPathComponent(
                            "backups/\(BytesUtility.toHexString(bytes: SafeStore.getBackupID(key: key)!))"
                        )
                        .absoluteString,
                    "http://test.com/backups/066384d3695fbbd9f31a7d533900fd0cd8d1373beb6a28678522d2a49980c9c3"
                )
            case let .failure(error):
                XCTFail("\(error)")
            }
        }
    }

    func testExtractSafeServerAuth() {
        let serverURLTests = [
            ["https://example.com/", nil, nil, "https://example.com/"],
            ["https://test.tester%40app.com:@example.com/", "test.tester@app.com", "", "https://example.com/"],
            [
                "https://test.tester%40app.com:passphrase@example.com/",
                "test.tester@app.com",
                "passphrase",
                "https://example.com/",
            ],
            [
                "https://test.tester%40app.com:p%C3%BCssiK%C3%B6sch@example.com",
                "test.tester@app.com",
                "püssiKösch",
                "https://example.com",
            ],
            ["https://:passphrase@example.com/", "", "passphrase", "https://example.com/"],
            ["https://passphrase@example.com/", "passphrase", nil, "https://example.com/"],
            ["HTTPS://example.com", nil, nil, "HTTPS://example.com"],
            ["HTtPS://example.com", nil, nil, "HTtPS://example.com"],
            ["http://example.com", nil, nil, "http://example.com"],
        ]

        for serverURLTest in serverURLTests {
            let safeServer = SafeStore.extractSafeServerAuth(server: URL(string: serverURLTest[0]!)!)

            XCTAssertEqual(serverURLTest[1], safeServer.serverUser)
            XCTAssertEqual(serverURLTest[2], safeServer.serverPassword)
            XCTAssertEqual(URL(string: serverURLTest[3]!)!, safeServer.server)
        }
    }
    
    func testEncodeDecodeSafeData() {
        let key: [UInt8] = [23]
        let customServer = "customServer"
        let server = "server"
        let maxBackupBytes = 64
        let retentionDays = 31
        let backupSize: Int64 = 64
        let backupStartedAt: Date = .now
        let lastBackup: Date = .distantPast
        let lastResult = "success"
        let lastChecksum: [UInt8] = [20]
        let lastAlertBackupFailed: Date = .distantFuture
        let isTriggered = true
        
        let safeConfigManager = SafeConfigManager()
        safeConfigManager.setKey(key)
        safeConfigManager.setCustomServer(customServer)
        safeConfigManager.setServer(server)
        safeConfigManager.setMaxBackupBytes(maxBackupBytes)
        safeConfigManager.setRetentionDays(retentionDays)
        safeConfigManager.setBackupSize(backupSize)
        safeConfigManager.setBackupStartedAt(backupStartedAt)
        safeConfigManager.setLastBackup(lastBackup)
        safeConfigManager.setLastResult(lastResult)
        safeConfigManager.setLastChecksum(lastChecksum)
        safeConfigManager.setLastAlertBackupFailed(lastAlertBackupFailed)
        safeConfigManager.setIsTriggered(isTriggered)
        
        XCTAssertEqual(safeConfigManager.getKey(), key)
        XCTAssertEqual(safeConfigManager.getCustomServer(), customServer)
        XCTAssertEqual(safeConfigManager.getServer(), server)
        XCTAssertEqual(safeConfigManager.getMaxBackupBytes(), maxBackupBytes)
        XCTAssertEqual(safeConfigManager.getRetentionDays(), retentionDays)
        XCTAssertEqual(safeConfigManager.getBackupSize(), backupSize)
        XCTAssertEqual(safeConfigManager.getBackupStartedAt(), backupStartedAt)
        XCTAssertEqual(safeConfigManager.getLastBackup(), lastBackup)
        XCTAssertEqual(safeConfigManager.getLastResult(), lastResult)
        XCTAssertEqual(safeConfigManager.getLastChecksum(), lastChecksum)
        XCTAssertEqual(safeConfigManager.getLastAlertBackupFailed(), lastAlertBackupFailed)
        XCTAssertEqual(safeConfigManager.getIsTriggered(), isTriggered)
    }
}

private func XCTAssertThrowsExpectedError<E: Error & Equatable>(
    _ expression: @autoclosure () throws -> some Any,
    _ expectedError: E,
    _ message: String = "",
    file: StaticString = #file,
    line: UInt = #line
) {
    XCTAssertThrowsError(try expression(), message, file: file, line: line) { error in
        XCTAssertNotNil(error as? E)
        XCTAssertEqual(error as? E, expectedError)
    }
}

Messung
CHZG
100100100100

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.