Skip to content

Commit 616a4f2

Browse files
pinkisemilsdlon
authored andcommitted
Add MullvadApi to MullvadVPNUITetsts
1 parent bfd6afa commit 616a4f2

File tree

3 files changed

+222
-5
lines changed

3 files changed

+222
-5
lines changed

ios/MullvadVPN.xcodeproj/project.pbxproj

+58-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
objects = {
88

99
/* Begin PBXBuildFile section */
10+
01EF6F2A2B6A473900125696 /* MullvadApi.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EF6F292B6A473900125696 /* MullvadApi.swift */; };
11+
01EF6F342B6A590700125696 /* libmullvad_api.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 01EF6F332B6A590700125696 /* libmullvad_api.a */; };
1012
062B45A328FD4CA700746E77 /* le_root_cert.cer in Resources */ = {isa = PBXBuildFile; fileRef = 06799AB428F98CE700ACD94E /* le_root_cert.cer */; };
1113
062B45BC28FD8C3B00746E77 /* RESTDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = 062B45BB28FD8C3B00746E77 /* RESTDefaults.swift */; };
1214
063687BA28EB234F00BE7161 /* PacketTunnelTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063687B928EB234F00BE7161 /* PacketTunnelTransport.swift */; };
@@ -1206,6 +1208,12 @@
12061208
/* End PBXCopyFilesBuildPhase section */
12071209

12081210
/* Begin PBXFileReference section */
1211+
01EF6F292B6A473900125696 /* MullvadApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadApi.swift; sourceTree = "<group>"; };
1212+
01EF6F2D2B6A51B100125696 /* mullvad-api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "mullvad-api.h"; sourceTree = "<group>"; };
1213+
01EF6F2F2B6A588300125696 /* aarch64-apple-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "aarch64-apple-ios"; path = "../target/aarch64-apple-ios"; sourceTree = "<group>"; };
1214+
01EF6F312B6A58F000125696 /* debug */ = {isa = PBXFileReference; lastKnownFileType = folder; name = debug; path = "../target/aarch64-apple-ios/debug"; sourceTree = "<group>"; };
1215+
01EF6F332B6A590700125696 /* libmullvad_api.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmullvad_api.a; path = "../target/aarch64-apple-ios/debug/libmullvad_api.a"; sourceTree = "<group>"; };
1216+
01EF6F352B6A5AEF00125696 /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
12091217
01F1FF1D29F0627D007083C3 /* libshadowsocks_proxy.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libshadowsocks_proxy.a; path = ../target/debug/libshadowsocks_proxy.a; sourceTree = "<group>"; };
12101218
062B45BB28FD8C3B00746E77 /* RESTDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTDefaults.swift; sourceTree = "<group>"; };
12111219
063687AF28EB083800BE7161 /* ProxyURLRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyURLRequest.swift; sourceTree = "<group>"; };
@@ -2078,6 +2086,7 @@
20782086
isa = PBXFrameworksBuildPhase;
20792087
buildActionMask = 2147483647;
20802088
files = (
2089+
01EF6F342B6A590700125696 /* libmullvad_api.a in Frameworks */,
20812090
);
20822091
runOnlyForDeploymentPostprocessing = 0;
20832092
};
@@ -2574,6 +2583,9 @@
25742583
584F991F2902CBDD001F858D /* Frameworks */ = {
25752584
isa = PBXGroup;
25762585
children = (
2586+
01EF6F332B6A590700125696 /* libmullvad_api.a */,
2587+
01EF6F312B6A58F000125696 /* debug */,
2588+
01EF6F2F2B6A588300125696 /* aarch64-apple-ios */,
25772589
584023282A407F5F007B27AC /* libtunnel_obfuscator_proxy.a */,
25782590
01F1FF1D29F0627D007083C3 /* libshadowsocks_proxy.a */,
25792591
);
@@ -3390,12 +3402,15 @@
33903402
852969262B4D9C1F007EAD4C /* MullvadVPNUITests */ = {
33913403
isa = PBXGroup;
33923404
children = (
3393-
8518F6392B601910009EB113 /* Test base classes */,
3394-
852969312B4E9220007EAD4C /* Pages */,
33953405
852969272B4D9C1F007EAD4C /* AccountTests.swift */,
3406+
01EF6F352B6A5AEF00125696 /* BridgingHeader.h */,
3407+
852969372B4ED20E007EAD4C /* Info.plist */,
3408+
01EF6F2D2B6A51B100125696 /* mullvad-api.h */,
3409+
01EF6F292B6A473900125696 /* MullvadApi.swift */,
3410+
852969312B4E9220007EAD4C /* Pages */,
33963411
850201DA2B503D7700EF8C96 /* RelayTests.swift */,
3412+
8518F6392B601910009EB113 /* Test base classes */,
33973413
85557B152B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift */,
3398-
852969372B4ED20E007EAD4C /* Info.plist */,
33993414
);
34003415
path = MullvadVPNUITests;
34013416
sourceTree = "<group>";
@@ -3610,6 +3625,13 @@
36103625
/* End PBXGroup section */
36113626

36123627
/* Begin PBXHeadersBuildPhase section */
3628+
01EF6F2C2B6A517900125696 /* Headers */ = {
3629+
isa = PBXHeadersBuildPhase;
3630+
buildActionMask = 2147483647;
3631+
files = (
3632+
);
3633+
runOnlyForDeploymentPostprocessing = 0;
3634+
};
36133635
06799AB728F98E1D00ACD94E /* Headers */ = {
36143636
isa = PBXHeadersBuildPhase;
36153637
buildActionMask = 2147483647;
@@ -4077,6 +4099,8 @@
40774099
isa = PBXNativeTarget;
40784100
buildConfigurationList = 8529692F2B4D9C1F007EAD4C /* Build configuration list for PBXNativeTarget "MullvadVPNUITests" */;
40794101
buildPhases = (
4102+
01EF6F2C2B6A517900125696 /* Headers */,
4103+
01EF6F2B2B6A512C00125696 /* ShellScript */,
40804104
852969212B4D9C1F007EAD4C /* Sources */,
40814105
852969222B4D9C1F007EAD4C /* Frameworks */,
40824106
852969232B4D9C1F007EAD4C /* Resources */,
@@ -4343,6 +4367,24 @@
43434367
/* End PBXResourcesBuildPhase section */
43444368

43454369
/* Begin PBXShellScriptBuildPhase section */
4370+
01EF6F2B2B6A512C00125696 /* ShellScript */ = {
4371+
isa = PBXShellScriptBuildPhase;
4372+
alwaysOutOfDate = 1;
4373+
buildActionMask = 2147483647;
4374+
files = (
4375+
);
4376+
inputFileListPaths = (
4377+
);
4378+
inputPaths = (
4379+
);
4380+
outputFileListPaths = (
4381+
);
4382+
outputPaths = (
4383+
);
4384+
runOnlyForDeploymentPostprocessing = 0;
4385+
shellPath = /bin/sh;
4386+
shellScript = "# Type a script or drag a script file from your workspace to insert its path.\nCARGO_TARGET_DIR=${PROJECT_DIR}/../target bash ${PROJECT_DIR}/build-rust-library.sh mullvad-api\n";
4387+
};
43464388
580E3F212A9860F20061809D /* Run SwiftLint */ = {
43474389
isa = PBXShellScriptBuildPhase;
43484390
alwaysOutOfDate = 1;
@@ -5304,6 +5346,7 @@
53045346
850201E32B51A93C00EF8C96 /* SettingsPage.swift in Sources */,
53055347
8518F6382B60157E009EB113 /* LoggedInWithoutTimeUITestCase.swift in Sources */,
53065348
852969282B4D9C1F007EAD4C /* AccountTests.swift in Sources */,
5349+
01EF6F2A2B6A473900125696 /* MullvadApi.swift in Sources */,
53075350
85557B162B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift in Sources */,
53085351
8529693A2B4F0238007EAD4C /* TermsOfServicePage.swift in Sources */,
53095352
850201DF2B5040A500EF8C96 /* TunnelControlPage.swift in Sources */,
@@ -6658,11 +6701,13 @@
66586701
DEVELOPMENT_TEAM = "";
66596702
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F;
66606703
"DEVELOPMENT_TEAM[sdk=macosx*]" = CKG9MXH72F;
6661-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
6704+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
66626705
GCC_C_LANGUAGE_STANDARD = gnu17;
66636706
GENERATE_INFOPLIST_FILE = YES;
6707+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
66646708
INFOPLIST_FILE = MullvadVPNUITests/Info.plist;
66656709
IPHONEOS_DEPLOYMENT_TARGET = 14.2;
6710+
"LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/debug";
66666711
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
66676712
MARKETING_VERSION = 1.0;
66686713
PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests";
@@ -6672,6 +6717,7 @@
66726717
SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN;
66736718
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
66746719
SWIFT_EMIT_LOC_STRINGS = NO;
6720+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
66756721
SWIFT_VERSION = 5.0;
66766722
TARGETED_DEVICE_FAMILY = "1,2";
66776723
TEST_TARGET_NAME = MullvadVPN;
@@ -6683,17 +6729,20 @@
66836729
buildSettings = {
66846730
APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN;
66856731
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
6686-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
6732+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
66876733
GCC_C_LANGUAGE_STANDARD = gnu17;
66886734
GENERATE_INFOPLIST_FILE = YES;
6735+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
66896736
INFOPLIST_FILE = MullvadVPNUITests/Info.plist;
66906737
IPHONEOS_DEPLOYMENT_TARGET = 14.2;
6738+
"LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/release";
66916739
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
66926740
MARKETING_VERSION = 1.0;
66936741
PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests";
66946742
PRODUCT_NAME = "$(TARGET_NAME)";
66956743
SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN;
66966744
SWIFT_EMIT_LOC_STRINGS = NO;
6745+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
66976746
SWIFT_VERSION = 5.0;
66986747
TARGETED_DEVICE_FAMILY = "1,2";
66996748
TEST_TARGET_NAME = MullvadVPN;
@@ -7276,14 +7325,18 @@
72767325
A93A1D062B59145C00F7796C /* Staging */ = {
72777326
isa = XCBuildConfiguration;
72787327
buildSettings = {
7328+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
72797329
PRODUCT_NAME = MullvadVPNUITests;
7330+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
72807331
};
72817332
name = Staging;
72827333
};
72837334
A93A1D072B59145C00F7796C /* MockRelease */ = {
72847335
isa = XCBuildConfiguration;
72857336
buildSettings = {
7337+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
72867338
PRODUCT_NAME = MullvadVPNUITests;
7339+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
72877340
};
72887341
name = MockRelease;
72897342
};
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//
2+
// BridgingHeader.h
3+
// MullvadVPN
4+
//
5+
// Created by Emils on 31/01/2024.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
#ifndef BridgingHeader_h
10+
#define BridgingHeader_h
11+
#include "mullvad-api.h"
12+
13+
#endif /* BridgingHeader_h */
+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
//
2+
// MullvadApi.swift
3+
// MullvadVPNUITests
4+
//
5+
// Created by Emils on 31/01/2024.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
struct ApiError: Error {
12+
let description: String
13+
let kind: MullvadApiErrorKind
14+
init(_ result: MullvadApiError) {
15+
kind = result.kind
16+
if result.description != nil {
17+
description = String(cString: result.description)
18+
} else {
19+
description = "No error"
20+
}
21+
mullvad_api_error_drop(result)
22+
}
23+
24+
func throwIfErr() throws {
25+
if self.kind.rawValue != 0 {
26+
throw self
27+
}
28+
}
29+
}
30+
31+
struct InitMutableBufferError: Error {
32+
let description = "Failed to allocate memory for mutable buffer"
33+
}
34+
35+
class MullvadApi {
36+
private var clientContext = MullvadApiClient()
37+
38+
init(apiAddress: String, hostname: String) throws {
39+
let result = mullvad_api_client_initialize(
40+
&clientContext,
41+
apiAddress,
42+
hostname
43+
)
44+
try ApiError(result).throwIfErr()
45+
}
46+
47+
/// Removes all devices assigned to the specified account
48+
func removeAllDevices(forAccount: String) throws {
49+
let result = mullvad_api_remove_all_devices(
50+
clientContext,
51+
forAccount
52+
)
53+
54+
try ApiError(result).throwIfErr()
55+
}
56+
57+
/// Public key must be at least 32 bytes long - only 32 bytes of it will be read
58+
func addDevice(forAccount: String, publicKey: Data) throws {
59+
var device = MullvadApiDevice()
60+
let result = mullvad_api_add_device(
61+
clientContext,
62+
forAccount,
63+
(publicKey as NSData).bytes,
64+
&device
65+
)
66+
67+
try ApiError(result).throwIfErr()
68+
}
69+
70+
/// Returns a unix timestamp of the expiry date for the specified account.
71+
func getExpiry(forAccount: String) throws -> UInt64 {
72+
var expiry = UInt64(0)
73+
let result = mullvad_api_get_expiry(clientContext, forAccount, &expiry)
74+
75+
try ApiError(result).throwIfErr()
76+
77+
return expiry
78+
}
79+
80+
func createAccount() throws -> String {
81+
guard let data = NSMutableData(length: 128) else {
82+
throw InitMutableBufferError()
83+
}
84+
85+
var dataLen = data.count
86+
var newAccountPtr: UnsafePointer<CChar>?
87+
let result = mullvad_api_create_account(
88+
clientContext,
89+
&newAccountPtr
90+
)
91+
try ApiError(result).throwIfErr()
92+
93+
let newAccount = String(cString: newAccountPtr!)
94+
return newAccount
95+
}
96+
97+
func listDevices(forAccount: String) throws -> [Device] {
98+
var iterator = MullvadApiDeviceIterator()
99+
let result = mullvad_api_list_devices(clientContext, forAccount, &iterator)
100+
try ApiError(result).throwIfErr()
101+
102+
return DeviceIterator(iter: iterator).collect()
103+
}
104+
105+
func delete(account: String) throws {
106+
let result = mullvad_api_delete_account(clientContext, account)
107+
try ApiError(result).throwIfErr()
108+
}
109+
110+
deinit {
111+
mullvad_api_client_drop(clientContext)
112+
}
113+
114+
struct Device {
115+
let name: String
116+
let id: UUID
117+
118+
init(device_struct: MullvadApiDevice) {
119+
name = String(cString: device_struct.name_ptr)
120+
id = UUID(uuid: device_struct.id)
121+
}
122+
}
123+
124+
class DeviceIterator {
125+
private let backingIter: MullvadApiDeviceIterator
126+
127+
init(iter: MullvadApiDeviceIterator) {
128+
backingIter = iter
129+
}
130+
131+
func collect() -> [Device] {
132+
var nextDevice = MullvadApiDevice()
133+
var devices: [Device] = []
134+
while mullvad_api_device_iter_next(backingIter, &nextDevice) {
135+
devices.append(Device(device_struct: nextDevice))
136+
mullvad_api_device_drop(nextDevice)
137+
}
138+
return devices
139+
}
140+
141+
deinit {
142+
mullvad_api_device_iter_drop(backingIter)
143+
}
144+
}
145+
}
146+
147+
private extension String {
148+
func lengthOfBytes() -> UInt {
149+
return UInt(self.lengthOfBytes(using: String.Encoding.utf8))
150+
}
151+
}

0 commit comments

Comments
 (0)