Skip to content

Commit c34ad58

Browse files
committed
Add DTO for User Storage
1 parent b4a8be6 commit c34ad58

22 files changed

+234
-78
lines changed

MIRACLTrust/MIRACLTrust-Sources/Authentication/Authenticator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ struct Authenticator: Sendable, AuthenticatorBlueprint {
152152
if let clientErrorData, clientErrorData.code == MPINID_EXPIRED || clientErrorData.code == EXPIRED_MPINID {
153153
let user = user.revoke()
154154

155-
try? userStorage.update(user: user)
155+
try? userStorage.update(user: user.toUserDTO())
156156

157157
callCompletionHandler(with: AuthenticationError.revoked)
158158
return
@@ -225,7 +225,7 @@ struct Authenticator: Sendable, AuthenticatorBlueprint {
225225
case MPINID_REVOKED, REVOKED_MPINID:
226226
let user = user.revoke()
227227

228-
try? userStorage.update(user: user)
228+
try? userStorage.update(user: user.toUserDTO())
229229

230230
callCompletionHandler(with: AuthenticationError.revoked)
231231
return

MIRACLTrust/MIRACLTrust-Sources/MIRACLTrust.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import Foundation
66
// MARK: Public properties
77

88
@objc public var users: [User] {
9-
userStorage.all()
9+
userStorage.all().map {
10+
$0.toUser()
11+
}
1012
}
1113

1214
@objc public var projectId: String
@@ -847,15 +849,15 @@ import Foundation
847849
/// - userId: id of the user. Can be email or any other string.
848850
/// - Returns: User object from the database. Returns nil if there is no such object in the storage.
849851
@objc public func getUser(by userId: String) -> User? {
850-
userStorage.getUser(by: userId, projectId: projectId)
852+
userStorage.getUser(by: userId, projectId: projectId)?.toUser()
851853
}
852854

853855
// MARK: Identities Removal
854856

855857
/// Delete a registered user.
856858
/// - Parameter user: object that needs to be deleted.
857859
@objc public func delete(user: User) throws {
858-
try userStorage.delete(user: user)
860+
try userStorage.delete(user: user.toUserDTO())
859861
}
860862

861863
// MARK: Private methods

MIRACLTrust/MIRACLTrust-Sources/Push Notification Authentication/PushNotificationAuthenticator.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ struct PushNotificationAuthenticator: Sendable {
3939
return
4040
}
4141

42-
guard let user = userStorage.getUser(by: userId, projectId: projectId) else {
42+
guard let user = userStorage.getUser(by: userId, projectId: projectId)?.toUser() else {
4343
callCompletionHandler(
4444
authenticated: false,
4545
error: AuthenticationError.userNotFound

MIRACLTrust/MIRACLTrust-Sources/Registration/Registrator.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ final class Registrator: Sendable {
299299
category: .registration
300300
)
301301

302-
try userStorage.update(user: user)
302+
try userStorage.update(user: user.toUserDTO())
303303

304304
DispatchQueue.main.async {
305305
self.completionHandler(user, nil)
@@ -310,7 +310,7 @@ final class Registrator: Sendable {
310310
category: .registration
311311
)
312312

313-
try userStorage.add(user: user)
313+
try userStorage.add(user: user.toUserDTO())
314314

315315
DispatchQueue.main.async {
316316
self.completionHandler(user, nil)

MIRACLTrust/MIRACLTrust-Sources/Signing/Signer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ struct Signer: Sendable {
123123
logOperation(operation: LoggingConstants.signingExecution)
124124

125125
// User could be updated from WaM.
126-
let user = userStorage.getUser(by: user.userId, projectId: user.projectId) ?? user
126+
let user = userStorage.getUser(by: user.userId, projectId: user.projectId)?.toUser() ?? user
127127
let timestamp = Date()
128128

129129
guard let publicKey = user.publicKey else {

MIRACLTrust/MIRACLTrust-Sources/User Storage/SQLiteUserStorage.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ final class SQLiteUserStorage: NSObject, UserStorage {
7979
}
8080
}
8181

82-
func add(user: User) throws {
82+
func add(user: UserDTO) throws {
8383
let insertUser = """
8484
INSERT INTO
8585
User(userId, projectId, revoked, pinLength, mpinId, token, dtas, publicKey) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
@@ -119,7 +119,7 @@ final class SQLiteUserStorage: NSObject, UserStorage {
119119
}
120120
}
121121

122-
func delete(user: User) throws {
122+
func delete(user: UserDTO) throws {
123123
let deleteUser = """
124124
DELETE FROM User WHERE userId = ? AND projectId = ?
125125
"""
@@ -136,7 +136,7 @@ final class SQLiteUserStorage: NSObject, UserStorage {
136136
)
137137
}
138138

139-
func update(user: User) throws {
139+
func update(user: UserDTO) throws {
140140
let updateUser = """
141141
UPDATE User
142142
SET revoked = ?, pinLength = ? , mpinId = ?, token = ?, dtas = ?, publicKey = ?
@@ -178,13 +178,13 @@ final class SQLiteUserStorage: NSObject, UserStorage {
178178
)
179179
}
180180

181-
func all() -> [User] {
181+
func all() -> [UserDTO] {
182182
let selectAllUsers = """
183183
SELECT * FROM User
184184
"""
185185

186186
do {
187-
var users = [User]()
187+
var users = [UserDTO]()
188188
try sqliteHelper.select(
189189
statement: selectAllUsers,
190190
bindingsBlock: nil,
@@ -223,7 +223,7 @@ final class SQLiteUserStorage: NSObject, UserStorage {
223223
publicKey = data
224224
}
225225

226-
let iteratedUser = User(
226+
let iteratedUser = UserDTO(
227227
userId: userId,
228228
projectId: projectId,
229229
revoked: revoked,
@@ -242,13 +242,13 @@ final class SQLiteUserStorage: NSObject, UserStorage {
242242
}
243243
}
244244

245-
func getUser(by userId: String, projectId: String) -> User? {
245+
func getUser(by userId: String, projectId: String) -> UserDTO? {
246246
let selectUserByUserIdAndProjectId = """
247247
SELECT * FROM User WHERE userId = ? AND projectId = ?
248248
"""
249249

250250
do {
251-
var user: User?
251+
var user: UserDTO?
252252
try sqliteHelper.select(
253253
statement: selectUserByUserIdAndProjectId,
254254
bindingsBlock: { statement in
@@ -291,7 +291,7 @@ final class SQLiteUserStorage: NSObject, UserStorage {
291291

292292
publicKey = data
293293
}
294-
user = User(
294+
user = UserDTO(
295295
userId: userId,
296296
projectId: projectId,
297297
revoked: revoked,

MIRACLTrust/MIRACLTrust-Sources/User Storage/User.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,18 @@ import Foundation
8181
)
8282
}
8383
}
84+
85+
extension User {
86+
func toUserDTO() -> UserDTO {
87+
UserDTO(
88+
userId: userId,
89+
projectId: projectId,
90+
revoked: revoked,
91+
pinLength: pinLength,
92+
mpinId: mpinId,
93+
token: token,
94+
dtas: dtas,
95+
publicKey: publicKey
96+
)
97+
}
98+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import Foundation
2+
3+
/// Defines the persistent data representation of a user.
4+
///
5+
/// A user is uniquely identified by the composite key of (`userId`, `projectId`).
6+
///
7+
/// - warning: This object contains sensitive data.
8+
/// Implementers must ensure secure storage (e.g., encryption at rest).
9+
public final class UserDTO: NSObject, Sendable {
10+
/// The identifier of the user, which is unique within the scope of a project. Could be email, username, etc.
11+
public let userId: String
12+
13+
/// The identifier of the project this user belongs to.
14+
public let projectId: String
15+
16+
/// The revocation status of the user.
17+
public let revoked: Bool
18+
19+
/// The user's PIN's number of digits.
20+
public let pinLength: Int
21+
22+
/// The identifier of this user registration in the MIRACL Trust Platform.
23+
public let mpinId: Data
24+
25+
/// A secure user token.
26+
///
27+
/// - warning:
28+
/// This field contain sensitive data. The storage implementation
29+
/// is responsible for its secure handling, including encryption at rest.
30+
public let token: Data
31+
32+
/// Data required for a server-side validation.
33+
public let dtas: String
34+
35+
/// The public part of the user's signing key.
36+
public let publicKey: Data?
37+
38+
public init(
39+
userId: String,
40+
projectId: String,
41+
revoked: Bool,
42+
pinLength: Int,
43+
mpinId: Data,
44+
token: Data,
45+
dtas: String,
46+
publicKey: Data?
47+
) {
48+
self.userId = userId
49+
self.projectId = projectId
50+
self.revoked = revoked
51+
self.pinLength = pinLength
52+
self.mpinId = mpinId
53+
self.token = token
54+
self.dtas = dtas
55+
self.publicKey = publicKey
56+
}
57+
}
58+
59+
extension UserDTO {
60+
func toUser() -> User {
61+
User(
62+
userId: userId,
63+
projectId: projectId,
64+
revoked: revoked,
65+
pinLength: pinLength,
66+
mpinId: mpinId,
67+
token: token,
68+
dtas: dtas,
69+
publicKey: publicKey
70+
)
71+
}
72+
}

MIRACLTrust/MIRACLTrust-Sources/User Storage/UserStorage.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,22 @@ public protocol UserStorage: Sendable {
1010

1111
/// Adds a new user to the storage.
1212
/// - Parameter user: a user that needs to be added to the storage.
13-
func add(user: User) throws
13+
func add(user: UserDTO) throws
1414

1515
/// Deletes the user from the storage.
1616
/// - Parameter user: a user that needs to be deleted to the storage.
17-
func delete(user: User) throws
17+
func delete(user: UserDTO) throws
1818

1919
/// Updates the user in the storage
2020
/// - Parameter user: a user that needs to be updated to the storage.
21-
func update(user: User) throws
21+
func update(user: UserDTO) throws
2222

2323
/// Get all users written in the storage.
24-
func all() -> [User]
24+
func all() -> [UserDTO]
2525

2626
/// Get User object by its user id and project id. If User isn't present in the storage this method returns nil.
2727
/// - Parameters:
2828
/// - userId: a user id to be checked in the storage.
2929
/// - projectId: a project id to be checked in the storage.
30-
func getUser(by userId: String, projectId: String) -> User?
30+
func getUser(by userId: String, projectId: String) -> UserDTO?
3131
}

MIRACLTrust/MIRACLTrust.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@
193193
6DC89F612E2FCA1000683AFB /* CrossDeviceSessionAborter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC89F602E2FCA0900683AFB /* CrossDeviceSessionAborter.swift */; };
194194
6DC89F632E2FDBE900683AFB /* CrossDeviceSessionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC89F622E2FDBE400683AFB /* CrossDeviceSessionError.swift */; };
195195
6DC987342E54C3CB00E1EDAB /* CrossDeviceSessionTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC987332E54C3C400E1EDAB /* CrossDeviceSessionTestCase.swift */; };
196+
6DC987222E5332D200E1EDAB /* UserDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DC987212E5332CF00E1EDAB /* UserDTO.swift */; };
196197
6DCDC7542834EC22006974F6 /* GetSigningSessionDetailsTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DCDC7532834EC22006974F6 /* GetSigningSessionDetailsTestCase.swift */; };
197198
6DCFDD4224AA0CEC00CED02F /* RegistrationTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DCFDD4124AA0CEC00CED02F /* RegistrationTestCase.swift */; };
198199
6DCFDD4424AA0E7D00CED02F /* QRAuthenticationTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DCFDD4324AA0E7D00CED02F /* QRAuthenticationTestCase.swift */; };
@@ -499,6 +500,7 @@
499500
6DC89F602E2FCA0900683AFB /* CrossDeviceSessionAborter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrossDeviceSessionAborter.swift; sourceTree = "<group>"; };
500501
6DC89F622E2FDBE400683AFB /* CrossDeviceSessionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrossDeviceSessionError.swift; sourceTree = "<group>"; };
501502
6DC987332E54C3C400E1EDAB /* CrossDeviceSessionTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrossDeviceSessionTestCase.swift; sourceTree = "<group>"; };
503+
6DC987212E5332CF00E1EDAB /* UserDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDTO.swift; sourceTree = "<group>"; };
502504
6DCDC7532834EC22006974F6 /* GetSigningSessionDetailsTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetSigningSessionDetailsTestCase.swift; sourceTree = "<group>"; };
503505
6DCFDD4124AA0CEC00CED02F /* RegistrationTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationTestCase.swift; sourceTree = "<group>"; };
504506
6DCFDD4324AA0E7D00CED02F /* QRAuthenticationTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRAuthenticationTestCase.swift; sourceTree = "<group>"; };
@@ -762,6 +764,7 @@
762764
6D866E8F245AC299003F7510 /* SQLChiper */,
763765
6D97CC2426A19A1200EEE8B6 /* SQLiteMigration */,
764766
6DBA72EA240FC76000561F89 /* User.swift */,
767+
6DC987212E5332CF00E1EDAB /* UserDTO.swift */,
765768
6DF2D3F2269F00B5004CAD54 /* UserStorage.swift */,
766769
6DF2D3F4269F0363004CAD54 /* SQLiteUserStorage.swift */,
767770
6DB4580C269C17DB00C4FEFA /* SQLiteHelper.swift */,
@@ -1620,6 +1623,7 @@
16201623
6DC46A0625B9BAD40099866C /* LoggingConstants.swift in Sources */,
16211624
6D6D9A0C282BEB9800316755 /* SigningSessionDetailsRequestBody.swift in Sources */,
16221625
6DC46A5225B9BAFD0099866C /* ActivationTokenError.swift in Sources */,
1626+
6DC987222E5332D200E1EDAB /* UserDTO.swift in Sources */,
16231627
6D291E962E55F8CD00C6AD80 /* DefaultUserStorageOptions.swift in Sources */,
16241628
6DF2D3F7269F03DE004CAD54 /* SQLiteUserStorageError.swift in Sources */,
16251629
6DDFB53A29EFDCCE00B981FB /* FallbackRequestErrorResponse.swift in Sources */,

0 commit comments

Comments
 (0)