Skip to content

Commit a12adbf

Browse files
committed
Add MullvadApi to MullvadVPNUITetsts
1 parent a995728 commit a12adbf

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 */; };
@@ -1202,6 +1204,12 @@
12021204
/* End PBXCopyFilesBuildPhase section */
12031205

12041206
/* Begin PBXFileReference section */
1207+
01EF6F292B6A473900125696 /* MullvadApi.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MullvadApi.swift; sourceTree = "<group>"; };
1208+
01EF6F2D2B6A51B100125696 /* mullvad-api.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "mullvad-api.h"; sourceTree = "<group>"; };
1209+
01EF6F2F2B6A588300125696 /* aarch64-apple-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "aarch64-apple-ios"; path = "../target/aarch64-apple-ios"; sourceTree = "<group>"; };
1210+
01EF6F312B6A58F000125696 /* debug */ = {isa = PBXFileReference; lastKnownFileType = folder; name = debug; path = "../target/aarch64-apple-ios/debug"; sourceTree = "<group>"; };
1211+
01EF6F332B6A590700125696 /* libmullvad_api.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmullvad_api.a; path = "../target/aarch64-apple-ios/debug/libmullvad_api.a"; sourceTree = "<group>"; };
1212+
01EF6F352B6A5AEF00125696 /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = "<group>"; };
12051213
01F1FF1D29F0627D007083C3 /* libshadowsocks_proxy.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libshadowsocks_proxy.a; path = ../target/debug/libshadowsocks_proxy.a; sourceTree = "<group>"; };
12061214
062B45BB28FD8C3B00746E77 /* RESTDefaults.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RESTDefaults.swift; sourceTree = "<group>"; };
12071215
063687AF28EB083800BE7161 /* ProxyURLRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyURLRequest.swift; sourceTree = "<group>"; };
@@ -2070,6 +2078,7 @@
20702078
isa = PBXFrameworksBuildPhase;
20712079
buildActionMask = 2147483647;
20722080
files = (
2081+
01EF6F342B6A590700125696 /* libmullvad_api.a in Frameworks */,
20732082
);
20742083
runOnlyForDeploymentPostprocessing = 0;
20752084
};
@@ -2564,6 +2573,9 @@
25642573
584F991F2902CBDD001F858D /* Frameworks */ = {
25652574
isa = PBXGroup;
25662575
children = (
2576+
01EF6F332B6A590700125696 /* libmullvad_api.a */,
2577+
01EF6F312B6A58F000125696 /* debug */,
2578+
01EF6F2F2B6A588300125696 /* aarch64-apple-ios */,
25672579
584023282A407F5F007B27AC /* libtunnel_obfuscator_proxy.a */,
25682580
01F1FF1D29F0627D007083C3 /* libshadowsocks_proxy.a */,
25692581
);
@@ -3378,12 +3390,15 @@
33783390
852969262B4D9C1F007EAD4C /* MullvadVPNUITests */ = {
33793391
isa = PBXGroup;
33803392
children = (
3381-
8518F6392B601910009EB113 /* Test base classes */,
3382-
852969312B4E9220007EAD4C /* Pages */,
33833393
852969272B4D9C1F007EAD4C /* AccountTests.swift */,
3394+
01EF6F352B6A5AEF00125696 /* BridgingHeader.h */,
3395+
852969372B4ED20E007EAD4C /* Info.plist */,
3396+
01EF6F2D2B6A51B100125696 /* mullvad-api.h */,
3397+
01EF6F292B6A473900125696 /* MullvadApi.swift */,
3398+
852969312B4E9220007EAD4C /* Pages */,
33843399
850201DA2B503D7700EF8C96 /* RelayTests.swift */,
3400+
8518F6392B601910009EB113 /* Test base classes */,
33853401
85557B152B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift */,
3386-
852969372B4ED20E007EAD4C /* Info.plist */,
33873402
);
33883403
path = MullvadVPNUITests;
33893404
sourceTree = "<group>";
@@ -3598,6 +3613,13 @@
35983613
/* End PBXGroup section */
35993614

36003615
/* Begin PBXHeadersBuildPhase section */
3616+
01EF6F2C2B6A517900125696 /* Headers */ = {
3617+
isa = PBXHeadersBuildPhase;
3618+
buildActionMask = 2147483647;
3619+
files = (
3620+
);
3621+
runOnlyForDeploymentPostprocessing = 0;
3622+
};
36013623
06799AB728F98E1D00ACD94E /* Headers */ = {
36023624
isa = PBXHeadersBuildPhase;
36033625
buildActionMask = 2147483647;
@@ -4065,6 +4087,8 @@
40654087
isa = PBXNativeTarget;
40664088
buildConfigurationList = 8529692F2B4D9C1F007EAD4C /* Build configuration list for PBXNativeTarget "MullvadVPNUITests" */;
40674089
buildPhases = (
4090+
01EF6F2C2B6A517900125696 /* Headers */,
4091+
01EF6F2B2B6A512C00125696 /* ShellScript */,
40684092
852969212B4D9C1F007EAD4C /* Sources */,
40694093
852969222B4D9C1F007EAD4C /* Frameworks */,
40704094
852969232B4D9C1F007EAD4C /* Resources */,
@@ -4331,6 +4355,24 @@
43314355
/* End PBXResourcesBuildPhase section */
43324356

43334357
/* Begin PBXShellScriptBuildPhase section */
4358+
01EF6F2B2B6A512C00125696 /* ShellScript */ = {
4359+
isa = PBXShellScriptBuildPhase;
4360+
alwaysOutOfDate = 1;
4361+
buildActionMask = 2147483647;
4362+
files = (
4363+
);
4364+
inputFileListPaths = (
4365+
);
4366+
inputPaths = (
4367+
);
4368+
outputFileListPaths = (
4369+
);
4370+
outputPaths = (
4371+
);
4372+
runOnlyForDeploymentPostprocessing = 0;
4373+
shellPath = /bin/sh;
4374+
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";
4375+
};
43344376
580E3F212A9860F20061809D /* Run SwiftLint */ = {
43354377
isa = PBXShellScriptBuildPhase;
43364378
alwaysOutOfDate = 1;
@@ -5288,6 +5330,7 @@
52885330
850201E32B51A93C00EF8C96 /* SettingsPage.swift in Sources */,
52895331
8518F6382B60157E009EB113 /* LoggedInWithoutTimeUITestCase.swift in Sources */,
52905332
852969282B4D9C1F007EAD4C /* AccountTests.swift in Sources */,
5333+
01EF6F2A2B6A473900125696 /* MullvadApi.swift in Sources */,
52915334
85557B162B5ABBBE00795FE1 /* XCUIElementQuery+Extensions.swift in Sources */,
52925335
8529693A2B4F0238007EAD4C /* TermsOfServicePage.swift in Sources */,
52935336
850201DF2B5040A500EF8C96 /* TunnelControlPage.swift in Sources */,
@@ -6642,11 +6685,13 @@
66426685
DEVELOPMENT_TEAM = "";
66436686
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = CKG9MXH72F;
66446687
"DEVELOPMENT_TEAM[sdk=macosx*]" = CKG9MXH72F;
6645-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
6688+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
66466689
GCC_C_LANGUAGE_STANDARD = gnu17;
66476690
GENERATE_INFOPLIST_FILE = YES;
6691+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
66486692
INFOPLIST_FILE = MullvadVPNUITests/Info.plist;
66496693
IPHONEOS_DEPLOYMENT_TARGET = 14.2;
6694+
"LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/debug";
66506695
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
66516696
MARKETING_VERSION = 1.0;
66526697
PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests";
@@ -6656,6 +6701,7 @@
66566701
SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN;
66576702
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
66586703
SWIFT_EMIT_LOC_STRINGS = NO;
6704+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
66596705
SWIFT_VERSION = 5.0;
66606706
TARGETED_DEVICE_FAMILY = "1,2";
66616707
TEST_TARGET_NAME = MullvadVPN;
@@ -6667,17 +6713,20 @@
66676713
buildSettings = {
66686714
APPLICATION_IDENTIFIER = net.mullvad.MullvadVPN;
66696715
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
6670-
ENABLE_USER_SCRIPT_SANDBOXING = YES;
6716+
ENABLE_USER_SCRIPT_SANDBOXING = NO;
66716717
GCC_C_LANGUAGE_STANDARD = gnu17;
66726718
GENERATE_INFOPLIST_FILE = YES;
6719+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
66736720
INFOPLIST_FILE = MullvadVPNUITests/Info.plist;
66746721
IPHONEOS_DEPLOYMENT_TARGET = 14.2;
6722+
"LIBRARY_SEARCH_PATHS[arch=*]" = "$(PROJECT_DIR)/../target/aarch64-apple-ios/release";
66756723
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
66766724
MARKETING_VERSION = 1.0;
66776725
PRODUCT_BUNDLE_IDENTIFIER = "$(APPLICATION_IDENTIFIER).MullvadVPNUITests";
66786726
PRODUCT_NAME = "$(TARGET_NAME)";
66796727
SECURITY_GROUP_IDENTIFIER = group.net.mullvad.MullvadVPN;
66806728
SWIFT_EMIT_LOC_STRINGS = NO;
6729+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
66816730
SWIFT_VERSION = 5.0;
66826731
TARGETED_DEVICE_FAMILY = "1,2";
66836732
TEST_TARGET_NAME = MullvadVPN;
@@ -7260,14 +7309,18 @@
72607309
A93A1D062B59145C00F7796C /* Staging */ = {
72617310
isa = XCBuildConfiguration;
72627311
buildSettings = {
7312+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
72637313
PRODUCT_NAME = MullvadVPNUITests;
7314+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
72647315
};
72657316
name = Staging;
72667317
};
72677318
A93A1D072B59145C00F7796C /* MockRelease */ = {
72687319
isa = XCBuildConfiguration;
72697320
buildSettings = {
7321+
HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../mullvad-api/include";
72707322
PRODUCT_NAME = MullvadVPNUITests;
7323+
SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/MullvadVPNUITests/BridgingHeader.h";
72717324
};
72727325
name = MockRelease;
72737326
};
+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)